Browse Source

Merge branch main into release

pointhalo 1 year ago
parent
commit
008afd1eb2

+ 1 - 1
.github/workflows/performance.yaml

@@ -31,7 +31,7 @@ jobs:
                       json_data=$(curl --location 'https://api.semi.design/analyze/checkAllTask' --header 'X-TT-ENV: canary' --header "X-SEMI-Request: ${{ secrets.SEMI_REQUEST }}")
                       parsed_data=$(python -c "
           import json;
-          data = json.loads('''$json_data''');
+          data = json.loads('''$json_data''',strict=False);
           for item in data:
               if item['id'] == $id :
                   if item['status'] == 'done':

+ 10 - 3
content/start/changelog/index-en-US.md

@@ -20,12 +20,19 @@ Version:Major.Minor.Patch (follow the **Semver** specification)
     - Slider adds `showMarkLabel` to control the visibility of the label, `tooltipOnMark` to display the tooltip on the mark, and `showArrow` to control the visibility of the tooltip triangle.
     - String type avatar, the character length can be automatically adjusted according to the width of the avatar [#1917](https://github.com/DouyinFE/semi-design/issues/1917) [@LonelySnowman](https://github.com/LonelySnowman )
 - 【Fix】
-    - fixed virtualized Table showHeader bug  [#726](https://github.com/DouyinFE/semi-design/issues/726)
+    - fixed virtualized Table showHeader bug [#726](https://github.com/DouyinFE/semi-design/issues/726)
    
-#### 🎉 2.47.1 (2023-11-17)
+
+#### 🎉 2.47.1 (2023-11-28)
+- 【Fix】
+    - Fixed the problem of incorrect list filtering after filter when Option is used in Select Group grouping scenario and the key attribute is not explicitly declared. Effect version range: v2.46.0 ~ v2.47.0 [#1939](https://github.com/DouyinFE/semi-design/pull/1939)
+    - Fix the problem of clicking on Dropdown item when there is no onClick. Effect version v2.47.0 [#1936](https://github.com/DouyinFE/semi-design/issues/1936)
+
+
+#### 🎉 2.47.0 (2023-11-17)
 - 【Fix】
     - fixed Table pagination bug when given pageSize and showSizeChanger at same time  [#1885](https://github.com/DouyinFE/semi-design/issues/1885)
-    - Fix the problem that the right and middle click of Dropdown Item will also trigger onClick [#1914](https://github.com/DouyinFE/semi-design/pull/1914) (Broken version range: 2.43.0-beta.0 ~ 2.46.1)
+    - Fix the problem that the right and middle click of Dropdown Item will also trigger onClick [#1914](https://github.com/DouyinFE/semi-design/pull/1914) (Effect version range: 2.43.0-beta.0 ~ 2.46.1)
 
 #### 🎉 2.47.0-beta.0 (2023-11-15)
 - 【Feat】

+ 6 - 0
content/start/changelog/index.md

@@ -21,6 +21,12 @@ Semi 版本号遵循 **Semver** 规范(主版本号-次版本号-修订版本
     - 修复虚拟化表格 showHeader 为 false 时表格体渲染空问题  [#726](https://github.com/DouyinFE/semi-design/issues/726)
     - 修复 Input 仅使用 addOnBefore 的情况下 borderRadius 不正确的问题  [#1912 ](https://github.com/DouyinFE/semi-design/issues/1912)
 
+#### 🎉 2.47.1 (2023-11-28)
+- 【Fix】
+    - 修复 Select Group 分组场景使用 Option,未显式声明 key属性时,filter 后列表筛选错误的问题,影响范围 (v2.46.0-v2.47.0) [#1939](https://github.com/DouyinFE/semi-design/pull/1939)
+    - 修复 Dropdown item 在没有声明 onClick 时点击报错的问题,影响范围 v2.47.0 [#1936](https://github.com/DouyinFE/semi-design/issues/1936)
+
+
 #### 🎉 2.47.0 (2023-11-17)
 - 【Fix】
     - 修复 Table 分页器在同时传入 pageSize 和 showSizeChanger 时点击分页器返回第一页问题  [#1885](https://github.com/DouyinFE/semi-design/issues/1885)

+ 17 - 0
cypress/e2e/select.spec.js

@@ -63,6 +63,23 @@ describe('Select', () => {
         cy.get('.semi-select-option').should('have.text', 'Design');
     });
 
+    it('optionGroup without key setting, filter',  () => {
+        cy.visit('http://127.0.0.1:6006/iframe.html?path=/story/select--select-option-group');
+        cy.get('#without-key').eq(0).click();
+        cy.get('#without-key .semi-input').eq(0).type('dou');
+        cy.wait(500);
+        cy.get('.semi-select-option-keyword').should('have.text', 'Dou');
+        cy.get('.semi-select-group').should('have.text', 'Group1');
+        cy.get('#without-key .semi-input').eq(0).type('{backspace}{backspace}{backspace}');
+        cy.wait(500);
+        cy.get('.semi-select-group').eq(0).should('have.text', 'Group1');
+        cy.get('.semi-select-group').eq(1).should('have.text', 'Group2');
+        cy.get('.semi-select-option').eq(0).should('have.text', 'Douyin');
+        cy.get('.semi-select-option').eq(1).should('have.text', 'Ulikecam');
+        cy.get('.semi-select-option').eq(2).should('have.text', 'Capcut');
+        cy.get('.semi-select-option').eq(3).should('have.text', 'Xigua');
+    });
+
     // it('ellipsisTrigger', () => {
     //     cy.visit('http://127.0.0.1:6006/iframe.html?path=/story/select--fix-1560');
 

+ 1 - 1
packages/semi-ui/dropdown/dropdownItem.tsx

@@ -96,7 +96,7 @@ class DropdownItem extends BaseComponent<DropdownItemProps> {
                 if (eventName === "onClick") {
                     events["onMouseDown"] = (e: React.MouseEvent<HTMLLIElement, MouseEvent>)=>{
                         if (e.button===0) { 
-                            this.props[eventName](e); 
+                            this.props[eventName]?.(e);
                         }
                     };
                 } else {

+ 2 - 2
packages/semi-ui/form/baseForm.tsx

@@ -279,7 +279,7 @@ class Form<Values extends Record<string, any> = any> extends BaseComponent<BaseF
             [prefix + '-vertical']: layout === 'vertical',
             [prefix + '-horizontal']: layout === 'horizontal',
         });
-        const showldAppendRow = wrapperCol && labelCol;
+        const shouldAppendRow = wrapperCol && labelCol;
 
         const formContent = (
             <form
@@ -298,7 +298,7 @@ class Form<Values extends Record<string, any> = any> extends BaseComponent<BaseF
             <FormUpdaterContext.Provider value={updaterApi}>
                 <FormApiContext.Provider value={this.formApi}>
                     <FormStateContext.Provider value={formState}>
-                        {showldAppendRow ? withRowForm : formContent}
+                        {shouldAppendRow ? withRowForm : formContent}
                     </FormStateContext.Provider>
                 </FormApiContext.Provider>
             </FormUpdaterContext.Provider>

+ 35 - 26
packages/semi-ui/select/_story/select.stories.jsx

@@ -2101,7 +2101,6 @@ _CustomCreate.story = {
 class OptionGroupDemo extends React.Component {
   constructor(props) {
     super(props);
-    this.handleSearch = this.handleSearch.bind(this);
     this.state = {
       groups: [
         {
@@ -2143,24 +2142,6 @@ class OptionGroupDemo extends React.Component {
     };
   }
 
-  handleSearch(input) {
-    let groups = [1, 2, 3].map(i => {
-      return {
-        label: i,
-        // label: Math.random(),
-        children: [10, 20].map(j => {
-          return {
-            label: Math.random(),
-            value: Math.random(),
-          };
-        }),
-      };
-    });
-    this.setState({
-      groups,
-    });
-  }
-
   renderGroup(group, index) {
     const options = group.children.map(option => (
       <Select.Option value={option.value} label={option.label} key={option.label} />
@@ -2173,16 +2154,44 @@ class OptionGroupDemo extends React.Component {
     return (
       <>
         <Select
-          placeholder=""
+          placeholder="with key"
+          id='with-key'
           style={{
             width: 180,
           }}
           filter
-          onSearch={this.handleSearch}
-          remote
         >
           {groups.map((group, index) => this.renderGroup(group, index))}
         </Select>
+
+        <Select
+          filter={(sugInput, option) => {
+              let label = option.label.toUpperCase();
+              let sug = sugInput.toUpperCase();
+              return label.includes(sug);
+          }}
+          id='without-key'
+          style={{ width: "180px" }}
+          placeholder="without key"
+        >
+          <Select.OptGroup label="Group1">
+            <Select.Option value="douyin">
+              Douyin
+            </Select.Option>
+            <Select.Option value="ulikecam">
+              Ulikecam
+            </Select.Option>
+          </Select.OptGroup>
+          <Select.OptGroup label="Group2">
+            <Select.Option value="jianying">
+              Capcut
+            </Select.Option>
+            <Select.Option value="xigua">
+              Xigua
+            </Select.Option>
+          </Select.OptGroup>
+        </Select>
+
       </>
     );
   }
@@ -3371,10 +3380,10 @@ export const Fix1856 = () => (<VirtualizeAllowCreate />);
 
 export const TestOptionKey = () => {
   return <><Select style={{ width: 300 }}>
-      <Select.Option label='3' value='2' key='abc'></Select.Option>
-      <Select.Option label='2' value='3' key='efg'></Select.Option>
-      <Select.Option label='4' value='5'></Select.Option>
-      <Select.Option label='5' value='4'></Select.Option>
+      <Select.Option label='abc' value='2' key='abc'></Select.Option>
+      <Select.Option label='efg' value='3' key='efg'></Select.Option>
+      <Select.Option label='kkk' value='5'></Select.Option>
+      <Select.Option label='fff' value='4'></Select.Option>
     </Select>
     <br/><br/>
     <Select style={{ width: 300 }} optionList={[

+ 15 - 4
packages/semi-ui/select/utils.tsx

@@ -3,7 +3,7 @@ import warning from '@douyinfe/semi-foundation/utils/warning';
 import { OptionProps } from './option';
 import { OptionGroupProps } from './optionGroup';
 
-const generateOption = (child: React.ReactElement, parent: any, index: number): OptionProps => {
+const generateOption = (child: React.ReactElement, parent: any, index: number, newKey?: string | number): OptionProps => {
     const childProps = child.props;
     if (!child || !childProps) {
         return null;
@@ -22,7 +22,7 @@ const generateOption = (child: React.ReactElement, parent: any, index: number):
     // Props are collected from ReactNode, after React.Children.toArray
     // no need to determine whether the key exists in child
     // Even if the user does not explicitly declare it, React will always generate a key.
-    option._keyInJsx = child.key;
+    option._keyInJsx = newKey || child.key;
     
     return option;
 };
@@ -55,10 +55,21 @@ const getOptionsFromGroup = (selectChildren: React.ReactNode) => {
             type = 'group';
             // Avoid saving children (reactNode) by... removing other props from the group except children, causing performance problems
             let { children, ...restGroupProps } = child.props;
+            let originKeys = [];
+            if (Array.isArray(children)) {
+                // if group has children > 1
+                originKeys = children.map(item => item.key);
+            } else {
+                originKeys.push(children.key);
+            }
             children = React.Children.toArray(children);
-            const childrenOption = children.map((option: React.ReactElement) => {
+            const childrenOption = children.map((option: React.ReactElement, index: number) => {
+                let newKey = option.key;
+                if (originKeys[index] === null) {
+                    newKey = child.key + '' + option.key; // if option in group and didn't set key, concat parent key to avoid conflict (default generate key just like .0, .1)
+                }
                 optionIndex++;
-                return generateOption(option, restGroupProps, optionIndex);
+                return generateOption(option, restGroupProps, optionIndex, newKey);
             });
             const group = {
                 ...child.props,