浏览代码

fix: input group disabled prop override bug (#958)

走鹃 3 年之前
父节点
当前提交
2fbfc48290

+ 1 - 1
content/input/input/index-en-US.md

@@ -455,7 +455,7 @@ Answers to some questions:
 
 ### InputGroup
 
-Common attributes will be set to the child elements of InputGroup, such as disabled, onFocus, etc.
+Common attributes will be set to the child elements of InputGroup, such as disabled, onFocus, etc. If you set onFocus, onBlur or disabled on the child, it will override the corresponding property value of InputGroup.
 
 
 | Property      | Instructions                                | Type                                                          | Default |

+ 1 - 1
content/input/input/index.md

@@ -464,7 +464,7 @@ import { Input, Typography, Form, TextArea, Button } from '@douyinfe/semi-ui';
 
 ### InputGroup
 
-通用属性将设置到 InputGroup 的子级元素上,例如 disabled、onFocus 等。
+通用属性将设置到 InputGroup 的子级元素上,例如 disabled、onFocus 等。如果你在子级设置了 onFocus、onBlur 或 disabled,会覆盖掉 InputGroup 对应属性值。
 
 
 | 属性          | 说明                           | 类型                                                          | 默认值    |

+ 0 - 1
packages/semi-ui/autoComplete/index.tsx

@@ -169,7 +169,6 @@ class AutoComplete<T extends AutoCompleteItems> extends BaseComponent<AutoComple
         position: 'bottomLeft' as const,
         data: [] as [],
         showClear: false,
-        disabled: false,
         size: 'default' as const,
         onFocus: noop,
         onSearch: noop,

+ 0 - 1
packages/semi-ui/cascader/index.tsx

@@ -180,7 +180,6 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
         showClear: false,
         autoClearSearchValue: true,
         changeOnSelect: false,
-        disabled: false,
         disableStrictly: false,
         autoMergeValue: true,
         multiple: false,

+ 0 - 1
packages/semi-ui/datePicker/datePicker.tsx

@@ -138,7 +138,6 @@ export default class DatePicker extends BaseComponent<DatePickerProps, DatePicke
         type: 'date',
         size: 'default',
         density: 'default',
-        disabled: false,
         multiple: false,
         defaultOpen: false,
         disabledHours: noop,

+ 31 - 0
packages/semi-ui/input/__test__/input.test.js

@@ -3,6 +3,7 @@ import Icon from '../../icons/index';
 import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants';
 import GraphemeSplitter from 'grapheme-splitter';
 import { isString, isFunction } from 'lodash';
+import { InputGroup, InputNumber } from '../../index';
 
 function getValueLength(str) {
   if (isString(str)) {
@@ -251,4 +252,34 @@ describe('Input', () => {
       expect(truncateValue(value, length, fc)).toBe(result);
     }
   })
+
+  it('input group', () => {
+    const groupFocus = sinon.spy(() => {
+      console.log('group focus');
+    });
+    const groupBlur = sinon.spy(() => {
+      console.log('group focus');
+    });
+    const inputFocus = sinon.spy(() => {
+      console.log('input focus');
+    });
+    const inputBlur = sinon.spy(() => {
+      console.log('input blur');
+    });
+    const inputGroup = mount(
+      <InputGroup disabled={true} onFocus={groupFocus} onBlur={groupBlur}>
+          <Input disabled={false} onFocus={inputFocus} onBlur={inputBlur} placeholder="Name" style={{ width: 100 }} />
+          <InputNumber placeholder="Score" style={{ width: 140 }} />
+      </InputGroup>
+    );
+
+    inputGroup.find('input').at(0).simulate('focus');
+    expect(inputFocus.called).toBe(true);
+    expect(groupFocus.called).toBe(true);
+    inputGroup.find('input').at(0).simulate('blur');
+    expect(inputBlur.called).toBe(true);
+    expect(groupBlur.called).toBe(true);
+    expect(inputGroup.find('input').at(0).instance().disabled).toBe(false);
+    expect(inputGroup.find('input').at(1).instance().disabled).toBe(true);
+  })
 });

+ 24 - 1
packages/semi-ui/input/_story/input.stories.js

@@ -22,7 +22,8 @@ import {
   Switch,
   Form,
   Space,
-  Radio
+  Radio,
+  InputNumber
 } from '../../index';
 import './input.scss';
 import RTLWrapper from '../../configProvider/_story/RTLDirection/RTLWrapper';
@@ -936,3 +937,25 @@ export const InputA11y = () => {
   );
 }
 InputA11y.storyName = "input a11y";
+
+export const FixInputGroup = () => {
+  const groupFocus = () => {
+    console.log('group focus');
+  }
+  const groupBlur = () => {
+    console.log('group blur');
+  }
+  const inputFocus = () => {
+    console.log('input focus');
+  }
+  const inputBlur = () => {
+    console.log('input blur');
+  }
+
+  return (
+    <InputGroup disabled={true} onFocus={groupFocus} onBlur={groupBlur}>
+        <Input disabled={false} onFocus={inputFocus} onBlur={inputBlur} placeholder="Name" style={{ width: 100 }} />
+        <InputNumber placeholder="Score" style={{ width: 140 }} />
+    </InputGroup>
+  );
+}

+ 0 - 1
packages/semi-ui/input/index.tsx

@@ -124,7 +124,6 @@ class Input extends BaseComponent<InputProps, InputState> {
         addonAfter: '',
         prefix: '',
         suffix: '',
-        disabled: false,
         readonly: false,
         type: 'text',
         showClear: false,

+ 7 - 6
packages/semi-ui/input/inputGroup.tsx

@@ -7,7 +7,7 @@ import BaseComponent from '../_base/baseComponent';
 import Label, { LabelProps } from '../form/label';
 
 import { noop } from '@douyinfe/semi-foundation/utils/function';
-import { isFunction } from 'lodash';
+import { get, isFunction } from 'lodash';
 
 const prefixCls = cssClasses.PREFIX;
 const sizeSet = strings.SIZE;
@@ -84,7 +84,7 @@ export default class inputGroup extends BaseComponent<InputGroupProps, InputGrou
     }
 
     render() {
-        const { size, style, className, children, label, onBlur: groupOnBlur, onFocus: groupOnFocus, ...rest } = this.props;
+        const { size, style, className, children, label, onBlur: groupOnBlur, onFocus: groupOnFocus, disabled: groupDisabled, ...rest } = this.props;
         const groupCls = cls(
             `${prefixCls}-group`,
             {
@@ -96,10 +96,11 @@ export default class inputGroup extends BaseComponent<InputGroupProps, InputGrou
         if (children) {
             inner = (Array.isArray(children) ? children : [children]).map((item, index) => {
                 if (item) {
-                    const { onBlur: itemOnBlur, onFocus: itemOnFocus } = (item as any).props;
-                    const onBlur = isFunction(itemOnBlur) ? itemOnBlur : groupOnBlur;
-                    const onFocus = isFunction(itemOnFocus) ? itemOnFocus : groupOnFocus;
-                    return React.cloneElement(item as any, { key: index, size, onBlur, onFocus, ...rest });
+                    const { onBlur: itemOnBlur, onFocus: itemOnFocus, disabled: itemDisabled } = (item as any).props;
+                    const onBlur = isFunction(itemOnBlur) && get(itemOnBlur, 'name') !== 'noop'  ? itemOnBlur : groupOnBlur;
+                    const onFocus = isFunction(itemOnFocus) && get(itemOnFocus, 'name') !== 'noop' ? itemOnFocus : groupOnFocus;
+                    const disabled = typeof itemDisabled === 'boolean' ? itemDisabled : groupDisabled;
+                    return React.cloneElement(item as any, { key: index, ...rest, size, onBlur, onFocus, disabled });
                 }
                 return null;
             });

+ 0 - 1
packages/semi-ui/inputNumber/index.tsx

@@ -96,7 +96,6 @@ class InputNumber extends BaseComponent<InputNumberProps, InputNumberState> {
     };
 
     static defaultProps: InputNumberProps = {
-        disabled: false,
         forwardedRef: noop,
         innerButtons: false,
         keepFocus: false,

+ 0 - 1
packages/semi-ui/treeSelect/index.tsx

@@ -265,7 +265,6 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
         motionExpand: true,
         expandAll: false,
         zIndex: popoverNumbers.DEFAULT_Z_INDEX,
-        disabled: false,
         disableStrictly: false,
         multiple: false,
         filterTreeNode: false,