فهرست منبع

fix: the problem of Select failing to select options after clicking outside when the radio selection is controlled

linyan 2 سال پیش
والد
کامیت
4e8b7d1c24

+ 5 - 0
packages/semi-foundation/select/foundation.ts

@@ -379,6 +379,11 @@ export default class SelectFoundation extends BaseFoundation<SelectAdapter> {
     close(e?: any, closeCb?: () => void) {
         // to support A11y, closing the panel trigger does not necessarily lose focus
 
+        const isOpen = this.getState('isOpen');
+        if (!isOpen) {
+            return;
+        }
+
         this._adapter.closeMenu();
         this._adapter.notifyDropdownVisibleChange(false);
         this._adapter.setIsFocusInContainer(false);

+ 22 - 1
packages/semi-ui/select/_story/select.stories.jsx

@@ -3413,4 +3413,25 @@ export const TestOptionKey = () => {
     ]}>
     </Select>
   </>
-}
+}
+
+export const TestDemo = () => {
+  const [value, setValue] = useState("1");
+  return (
+    <Select
+      value={value}
+      onChange={(v) => {
+        setValue(v);
+        console.log(v);
+      }}
+      onBlur={()=>{
+        console.log('onBlur')
+      }}
+      placeholder="受控的Select"
+    >
+      <Select.Option value={"1"}>抖音</Select.Option>
+      <Select.Option value={"2"}>轻颜相机</Select.Option>
+      <Select.Option value={"3"}>剪映</Select.Option>
+    </Select>
+  );
+};

+ 15 - 13
packages/semi-ui/select/index.tsx

@@ -448,19 +448,21 @@ class Select extends BaseComponent<SelectProps, SelectState> {
             notifyMaxLimit: (option: OptionProps) => this.props.onExceed(option),
             getMaxLimit: () => this.props.max,
             registerClickOutsideHandler: (cb: (e: MouseEvent) => void) => {
-                const clickOutsideHandler: (e: MouseEvent) => void = e => {
-                    const optionInstance = this.optionsRef && this.optionsRef.current;
-                    const triggerDom = (this.triggerRef && this.triggerRef.current) as Element;
-                    const optionsDom = ReactDOM.findDOMNode(optionInstance as ReactInstance);
-                    // let isInPanel = optionsDom && optionsDom.contains(e.target);
-                    // let isInTrigger = triggerDom && triggerDom.contains(e.target);
-                    if (optionsDom && !optionsDom.contains(e.target as Node) &&
-                        triggerDom && !triggerDom.contains(e.target as Node)) {
-                        cb(e);
-                    }
-                };
-                this.clickOutsideHandler = clickOutsideHandler;
-                document.addEventListener('mousedown', clickOutsideHandler as any, false);
+                if (!this.clickOutsideHandler) {
+                    const clickOutsideHandler: (e: MouseEvent) => void = e => {
+                        const optionInstance = this.optionsRef && this.optionsRef.current;
+                        const triggerDom = (this.triggerRef && this.triggerRef.current) as Element;
+                        const optionsDom = ReactDOM.findDOMNode(optionInstance as ReactInstance);
+                        // let isInPanel = optionsDom && optionsDom.contains(e.target);
+                        // let isInTrigger = triggerDom && triggerDom.contains(e.target);
+                        if (optionsDom && !optionsDom.contains(e.target as Node) &&
+                            triggerDom && !triggerDom.contains(e.target as Node)) {
+                            cb(e);
+                        }
+                    };
+                    this.clickOutsideHandler = clickOutsideHandler;
+                    document.addEventListener('mousedown', clickOutsideHandler as any, false);
+                }
             },
             unregisterClickOutsideHandler: () => {
                 if (this.clickOutsideHandler) {