inputGroup.tsx 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. import React from 'react';
  2. import cls from 'classnames';
  3. import PropTypes from 'prop-types';
  4. import { cssClasses, strings } from '@douyinfe/semi-foundation/input/constants';
  5. import BaseComponent from '../_base/baseComponent';
  6. import Label, { LabelProps } from '../form/label';
  7. import { noop } from '@douyinfe/semi-foundation/utils/function';
  8. import { get, isFunction } from 'lodash';
  9. const prefixCls = cssClasses.PREFIX;
  10. const sizeSet = strings.SIZE;
  11. export type InputSize = 'small' | 'large' | 'default';
  12. export interface InputGroupProps {
  13. className?: string;
  14. children?: React.ReactNode;
  15. size?: InputSize;
  16. style?: Record<string, any>;
  17. onBlur?: (e: React.FocusEvent<HTMLSpanElement>) => void;
  18. onFocus?: (e: React.FocusEvent<HTMLSpanElement>) => void;
  19. label?: LabelProps;
  20. labelPosition?: string;
  21. disabled?: boolean
  22. }
  23. export interface InputGroupState {}
  24. export default class inputGroup extends BaseComponent<InputGroupProps, InputGroupState> {
  25. static propTypes = {
  26. className: PropTypes.string,
  27. children: PropTypes.node,
  28. size: PropTypes.oneOf(sizeSet),
  29. style: PropTypes.object,
  30. onBlur: PropTypes.func,
  31. onFocus: PropTypes.func,
  32. label: PropTypes.object,
  33. labelPosition: PropTypes.string,
  34. };
  35. static defaultProps = {
  36. size: 'default',
  37. className: '',
  38. onBlur: noop,
  39. onFocus: noop,
  40. };
  41. renderGroupWithLabel(inner: React.ReactNode) {
  42. const { size, className, label, labelPosition, ...rest } = this.props;
  43. const groupWrapperCls = cls({
  44. [`${prefixCls}-group-wrapper`]: true,
  45. [`${prefixCls}-group-wrapper-with-top-label`]: labelPosition === 'top',
  46. [`${prefixCls}-group-wrapper-with-left-label`]: labelPosition === 'left',
  47. });
  48. const groupCls = cls(
  49. `${prefixCls}-group`,
  50. className,
  51. {
  52. [`${prefixCls}-${size}`]: size !== 'default',
  53. }
  54. );
  55. // const labelCls = cls(label.className, '');
  56. const defaultName = 'input-group';
  57. return (
  58. <div className={groupWrapperCls}>
  59. {label && label.text ? <Label name={defaultName} {...label} /> : null}
  60. <span
  61. role="group"
  62. aria-disabled={this.props.disabled}
  63. id={label && label.name || defaultName}
  64. className={groupCls}
  65. style={this.props.style}
  66. onFocus={this.props.onFocus}
  67. onBlur={this.props.onBlur}
  68. >
  69. {inner}
  70. </span>
  71. </div>
  72. );
  73. }
  74. render() {
  75. const { size, style, className, children, label, onBlur: groupOnBlur, onFocus: groupOnFocus, disabled: groupDisabled, ...rest } = this.props;
  76. const groupCls = cls(
  77. `${prefixCls}-group`,
  78. {
  79. [`${prefixCls}-${size}`]: size !== 'default',
  80. },
  81. className
  82. );
  83. let inner;
  84. if (children) {
  85. inner = (Array.isArray(children) ? children : [children]).map((item, index) => {
  86. if (item) {
  87. const { onBlur: itemOnBlur, onFocus: itemOnFocus, disabled: itemDisabled } = (item as any).props;
  88. const onBlur = isFunction(itemOnBlur) && get(itemOnBlur, 'name') !== 'noop' ? itemOnBlur : groupOnBlur;
  89. const onFocus = isFunction(itemOnFocus) && get(itemOnFocus, 'name') !== 'noop' ? itemOnFocus : groupOnFocus;
  90. const disabled = typeof itemDisabled === 'boolean' ? itemDisabled : groupDisabled;
  91. return React.cloneElement(item as any, { key: index, ...rest, size, onBlur, onFocus, disabled });
  92. }
  93. return null;
  94. });
  95. }
  96. if (label && label.text) {
  97. return this.renderGroupWithLabel(inner);
  98. }
  99. return (
  100. <span
  101. role="group"
  102. aria-label="Input group"
  103. aria-disabled={this.props.disabled}
  104. className={groupCls}
  105. style={style}
  106. onFocus={this.props.onFocus}
  107. onBlur={this.props.onBlur}
  108. >
  109. {inner}
  110. </span>
  111. );
  112. }
  113. }