label.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import React, { PureComponent } from 'react';
  2. import classNames from 'classnames';
  3. import PropTypes from 'prop-types';
  4. import { cssClasses } from '@douyinfe/semi-foundation/form/constants';
  5. import LocaleConsumer from '../locale/localeConsumer';
  6. import { Locale } from '../locale/interface';
  7. const prefixCls = cssClasses.PREFIX;
  8. export interface LabelProps {
  9. /** text-align of label */
  10. align?: string;
  11. className?: string;
  12. children?: React.ReactNode;
  13. disabled?: boolean;
  14. id?: string;
  15. /** Whether to display the required * symbol */
  16. required?: boolean;
  17. /** Content of label */
  18. text?: React.ReactNode;
  19. /** Used to configure the htmlFor attribute of the label tag */
  20. name?: string;
  21. /** width of label */
  22. width?: number | string;
  23. style?: React.CSSProperties;
  24. extra?: React.ReactNode;
  25. optional?: boolean;
  26. }
  27. export default class Label extends PureComponent<LabelProps> {
  28. static defaultProps = {
  29. required: false,
  30. name: '',
  31. align: 'left',
  32. className: '',
  33. optional: false,
  34. };
  35. static propTypes = {
  36. id: PropTypes.string,
  37. children: PropTypes.node,
  38. required: PropTypes.bool,
  39. text: PropTypes.node,
  40. disabled: PropTypes.bool,
  41. name: PropTypes.string,
  42. align: PropTypes.string,
  43. width: PropTypes.oneOfType([PropTypes.number, PropTypes.string]),
  44. style: PropTypes.object,
  45. className: PropTypes.string,
  46. extra: PropTypes.node,
  47. optional: PropTypes.bool,
  48. };
  49. render() {
  50. const { children, required, text, disabled, name, width, align, style, className, extra, id, optional } = this.props;
  51. const labelCls = classNames(className, {
  52. [`${prefixCls}-field-label`]: true,
  53. [`${prefixCls}-field-label-left`]: align === 'left',
  54. [`${prefixCls}-field-label-right`]: align === 'right',
  55. [`${prefixCls}-field-label-required`]: required,
  56. [`${prefixCls}-field-label-disabled`]: disabled,
  57. [`${prefixCls}-field-label-with-extra`]: extra,
  58. });
  59. const labelStyle = style ? style : {};
  60. width ? labelStyle.width = width : null;
  61. const optionalText = (
  62. <LocaleConsumer<Locale['Form']> componentName="Form" >
  63. {(locale: Locale['Form']) => (
  64. <span className={`${prefixCls}-field-label-optional-text`}>{locale.optional}</span>
  65. )}
  66. </LocaleConsumer>
  67. );
  68. const textContent = (
  69. <div className={`${prefixCls}-field-label-text`} x-semi-prop="label">
  70. {typeof text !== 'undefined' ? text : children}
  71. {optional ? optionalText : null}
  72. </div>
  73. );
  74. const contentWithExtra = (
  75. <>
  76. {textContent}
  77. <div className={`${prefixCls}-field-label-extra`}>{extra}</div>
  78. </>
  79. );
  80. return (
  81. <label className={labelCls} htmlFor={name} style={labelStyle} id={id}>
  82. {extra ? contentWithExtra : textContent}
  83. </label>
  84. );
  85. }
  86. }