1
0

inputGroup.tsx 4.4 KB

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