Browse Source

fix: [Checkbox/Cascader] add stopImmediatePropagation for the event parameter of checkbox onChange and Cascader stop propagation in multiple selection #343

chenyuling 3 years ago
parent
commit
bc45188dba

+ 14 - 4
packages/semi-foundation/checkbox/checkboxFoundation.ts

@@ -8,6 +8,9 @@ export interface BasicCheckboxEvent {
     target: BasicTargetObject;
     stopPropagation: () => void;
     preventDefault: () => void;
+    nativeEvent: {
+        stopImmediatePropagation: () => void;
+    }
 }
 export interface CheckboxAdapter<P = Record<string, any>, S = Record<string, any>> extends DefaultAdapter<P, S> {
     getIsInGroup: () => boolean;
@@ -28,7 +31,7 @@ class CheckboxFoundation<P = Record<string, any>, S = Record<string, any>> exten
     // eslint-disable-next-line @typescript-eslint/no-empty-function
     init() {}
 
-    getEvent(checked: boolean, e: MouseEvent) {
+    getEvent(checked: boolean, e: any) {
         const props = this.getProps();
         const cbValue = {
             target: {
@@ -41,16 +44,23 @@ class CheckboxFoundation<P = Record<string, any>, S = Record<string, any>> exten
             preventDefault: () => {
                 e.preventDefault();
             },
+            nativeEvent: {
+                stopImmediatePropagation: () => {
+                    if (e.nativeEvent && typeof e.nativeEvent.stopImmediatePropagation === 'function') {
+                        e.nativeEvent.stopImmediatePropagation();
+                    }
+                }
+            },
         };
         return cbValue;
     }
 
-    notifyChange(checked: boolean, e: MouseEvent) {
+    notifyChange(checked: boolean, e: any) {
         const cbValue = this.getEvent(checked, e);
         this._adapter.notifyChange(cbValue);
     }
 
-    handleChange(e: MouseEvent) {
+    handleChange(e: any) {
         const disabled = this.getProp('disabled');
 
         if (disabled) {
@@ -78,7 +88,7 @@ class CheckboxFoundation<P = Record<string, any>, S = Record<string, any>> exten
         }
     }
 
-    handleChangeInGroup(e: MouseEvent) {
+    handleChangeInGroup(e: any) {
         const { value } = this.getProps();
         const groupValue = this._adapter.getGroupValue();
         const checked = groupValue.includes(value);

+ 3 - 0
packages/semi-ui/cascader/item.tsx

@@ -104,6 +104,9 @@ export default class Item extends PureComponent<CascaderItemProps> {
         const { onItemCheckboxClick } = this.props;
         // Prevent Checkbox's click event bubbling to trigger the li click event
         e.stopPropagation();
+        if (e.nativeEvent && typeof e.nativeEvent.stopImmediatePropagation === 'function') {
+            e.nativeEvent.stopImmediatePropagation();
+        }
         onItemCheckboxClick(item);
     };
 

+ 72 - 0
packages/semi-ui/checkbox/_story/checkbox.stories.js

@@ -1,6 +1,8 @@
 import React, { useCallback, useMemo, useState } from 'react';
 import Button from '../../button';
 import Popover from '../../popover';
+import Tag from '../../tag';
+import Cascader from '../../cascader';
 import Checkbox from '../index';
 import CheckboxGroup from '../checkboxGroup';
 import { Col, Input, Row } from '../../index';
@@ -941,3 +943,73 @@ export const CheckboxGroupPureCardStyle = () => (
     </CheckboxGroup>
   </>
 );
+
+export const CheckboxOnChangeEvent = () =>  (
+  <div style={{marginLeft: 100}}>
+      <div>查看 onChange 入参</div>
+      <Checkbox onChange={e => console.log(e)}>
+          Apple
+      </Checkbox>
+      <div style={{marginTop: 30}}>Popover 内套 Popover, 且 content 为 checkbox</div>
+      <Popover
+          trigger={'click'}
+          onClickOutSide={e => console.log('onClickOutSide')}
+          content={
+              <Popover
+                  trigger='click'
+                  content={
+                      <Checkbox
+                          onChange={e => {
+                              console.log('checkbox onChange', e);
+                              e.stopPropagation();
+                              e.nativeEvent && e.nativeEvent.stopImmediatePropagation();
+                          }}
+                      >
+                          Semi Design
+                      </Checkbox>
+                  }
+              >
+                  trigger
+              </Popover>
+          }
+      >
+          <Tag>点击此处</Tag>
+      </Popover>
+      <div style={{marginTop: 30}}>Popover 内套 Cascader 多选</div>
+      <Popover
+          trigger={'click'}
+          content={
+              <Cascader
+                  defaultValue={['zhejiang', 'ningbo', 'jiangbei']}
+                  style={{ width: 300 }}
+                  treeData={[
+                      {
+                          label: '浙江省',
+                          value: 'zhejiang',
+                          children: [
+                              {
+                                  label: '杭州市',
+                                  value: 'hangzhou',
+                                  children: [
+                                      {
+                                          label: '西湖区',
+                                          value: 'xihu',
+                                      },
+                                  ],
+                              },
+                          ],
+                      }
+                  ]}
+                  placeholder="请选择所在地区"
+                  multiple
+              />
+          }
+      >
+          <Tag>点击此处</Tag>
+      </Popover>
+  </div>
+);
+
+CheckboxOnChangeEvent.story = {
+  name: 'checkbox onChange event',
+};