Browse Source

Merge branch 'main' into release

林艳 1 year ago
parent
commit
cdfb939baa

+ 1 - 1
content/show/collapse/index-en-US.md

@@ -183,7 +183,7 @@ import { IconCopy } from '@douyinfe/semi-icons';
 | keepDOM | Whether to keep the hidden panel in DOM tree, destroyed by default | boolean | `false` | 0.25.0  |
 | keepDOM | Whether to keep the hidden panel in DOM tree, destroyed by default | boolean | `false` | 0.25.0  |
 | motion | Toggle whether to have animation | boolean | `true` | 1.4.0   |
 | motion | Toggle whether to have animation | boolean | `true` | 1.4.0   |
 | expandIconPosition | Expand icon position | `left`, `right` | `right` | 1.12.0  |
 | expandIconPosition | Expand icon position | `left`, `right` | `right` | 1.12.0  |
-| lazyRender | Used with keepDOM, when true, the component will not be rendered when mounting                                         | boolean | `false` | 2.25.1  |
+| lazyRender | Used with keepDOM, when true, the component will not be rendered when mounting                                         | boolean | `false` | 2.54.1  |
 | style | Inline CSS style | CSSProperties | {} | -       |
 | style | Inline CSS style | CSSProperties | {} | -       |
 | onChange | Callback function when switching panel | function(activeKey: string \| string[], e: event) | - | -       |
 | onChange | Callback function when switching panel | function(activeKey: string \| string[], e: event) | - | -       |
 
 

+ 1 - 1
content/show/collapse/index.md

@@ -182,7 +182,7 @@ import { IconCopy } from '@douyinfe/semi-icons';
 | expandIconPosition | 展开图标位置 | `left`, `right` | `right` | 1.12.0 |
 | expandIconPosition | 展开图标位置 | `left`, `right` | `right` | 1.12.0 |
 | keepDOM | 是否保留隐藏的面板 DOM 树,默认销毁 | bool | `false` | 0.25.0 |
 | keepDOM | 是否保留隐藏的面板 DOM 树,默认销毁 | bool | `false` | 0.25.0 |
 | motion | 是否开启动画 | boolean | `true` | 1.4.0  |
 | motion | 是否开启动画 | boolean | `true` | 1.4.0  |
-| lazyRender | 配合 keepDOM 使用,为 true 时挂载时不会渲染组件 | boolean | `false` | 2.25.1 |
+| lazyRender | 配合 keepDOM 使用,为 true 时挂载时不会渲染组件 | boolean | `false` | 2.54.1 |
 | style | 内联 CSS 样式 | CSSProperties | {} | -      |
 | style | 内联 CSS 样式 | CSSProperties | {} | -      |
 | onChange | 切换面板的回调 | function(activeKey: string \| string[], e: event) | 无 | -      |
 | onChange | 切换面板的回调 | function(activeKey: string \| string[], e: event) | 无 | -      |
 
 

+ 1 - 1
content/show/collapsible/index.md

@@ -216,7 +216,7 @@ import { Collapsible, Button } from '@douyinfe/semi-ui';
 | fade | 是否开启淡入淡出 | boolean | false   | 2.21.0 |
 | fade | 是否开启淡入淡出 | boolean | false   | 2.21.0 |
 | isOpen | 是否展开内容区域 | boolean | `false` | -      |
 | isOpen | 是否展开内容区域 | boolean | `false` | -      |
 | keepDOM | 是否保留隐藏的面板 DOM 树,默认销毁 | boolean | `false` | 0.25.0 |
 | keepDOM | 是否保留隐藏的面板 DOM 树,默认销毁 | boolean | `false` | 0.25.0 |
-| lazyRender | 配合 keepDOM 使用,为 true 时挂载时不会渲染组件 | boolean | `false` | 2.25   |
+| lazyRender | 配合 keepDOM 使用,为 true 时挂载时不会渲染组件 | boolean | `false` | 2.54.0   |
 | motion | 是否开启动画 | boolean | `true`  | -      |
 | motion | 是否开启动画 | boolean | `true`  | -      |
 | onMotionEnd | 动画结束的回调 | () => void | -       | -      |
 | onMotionEnd | 动画结束的回调 | () => void | -       | -      |
 | reCalcKey | 当 reCalcKey 改变时,将重新计算子节点的高度,用于优化动态渲染时的计算 | number \| string | -       | 1.5.0  |
 | reCalcKey | 当 reCalcKey 改变时,将重新计算子节点的高度,用于优化动态渲染时的计算 | number \| string | -       | 1.5.0  |

+ 9 - 0
cypress/e2e/cascader.spec.js

@@ -119,5 +119,14 @@ describe('cascader', () => {
         cy.get('.semi-cascader-selection').click();
         cy.get('.semi-cascader-selection').click();
         cy.get('.semi-checkbox.semi-checkbox-checked').eq(0).should('exist');
         cy.get('.semi-checkbox.semi-checkbox-checked').eq(0).should('exist');
     });
     });
+
+    it('esc close panel', () => {
+        cy.visit('http://127.0.0.1:6006/iframe.html?id=cascader--searchable');
+        cy.get('.semi-cascader-selection').eq(0).trigger('click');
+        cy.get('.semi-input').type('中');
+        cy.get('.semi-cascader-popover').should('have.length', 1);
+        cy.get('.semi-input').type('{esc}', { force: true });
+        cy.get('.semi-cascader-popover').should('not.exist');
+    })
     
     
 });
 });

+ 9 - 0
cypress/e2e/treeSelect.spec.js

@@ -194,5 +194,14 @@ describe('treeSelect', () => {
         cy.get('#invisible-span').eq(0).trigger('mousedown');
         cy.get('#invisible-span').eq(0).trigger('mousedown');
         cy.get('.semi-tree-select-popover').should('not.exist');
         cy.get('.semi-tree-select-popover').should('not.exist');
     })
     })
+
+    it('esc close panel', () => {
+        cy.visit('http://127.0.0.1:6006/iframe.html?id=treeselect--search-position-in-trigger-and-virtualize');
+        cy.get('.semi-input').trigger('click');
+        cy.get('.semi-input').type('中');
+        cy.get('.semi-tree-select-popover').should('have.length', 1);
+        cy.get('.semi-input').type('{esc}', { force: true });
+        cy.get('.semi-tree-select-popover').should('not.exist');
+    })
 });
 });
 
 

+ 5 - 0
packages/semi-foundation/button/button.scss

@@ -387,6 +387,11 @@ $module: #{$prefix}-button;
                 border-top-right-radius: $radius-button_group;
                 border-top-right-radius: $radius-button_group;
                 border-bottom-right-radius: $radius-button_group;
                 border-bottom-right-radius: $radius-button_group;
             }
             }
+
+            &-outline:not(:last-child) {
+               border-right-color: transparent;
+               margin-right: -1 * $width-button_outline-border;
+            }
         }
         }
 
 
         &-line {
         &-line {

+ 1 - 1
packages/semi-foundation/button/constants.ts

@@ -9,7 +9,7 @@ const strings = {
     iconPositions: ['left', 'right'],
     iconPositions: ['left', 'right'],
     htmlTypes: ['button', 'reset', 'submit'],
     htmlTypes: ['button', 'reset', 'submit'],
     btnTypes: ['primary', 'secondary', 'tertiary', 'warning', 'danger'],
     btnTypes: ['primary', 'secondary', 'tertiary', 'warning', 'danger'],
-    themes: ['solid', 'borderless', 'light'],
+    themes: ['solid', 'borderless', 'light', 'outline'],
     DEFAULT_ICON_SIZE: 'default',
     DEFAULT_ICON_SIZE: 'default',
     DEFAULT_ICON_POSITION: 'left',
     DEFAULT_ICON_POSITION: 'left',
 } as const;
 } as const;

+ 1 - 1
packages/semi-foundation/cascader/constants.ts

@@ -28,4 +28,4 @@ export {
     numbers
     numbers
 };
 };
 
 
-export const VALUE_SPLIT = '_SEMI_CASCADER_SPLIT_';
+export const VALUE_SPLIT = '_SEMI_CASCADER_SPLIT_';

+ 8 - 0
packages/semi-foundation/cascader/foundation.ts

@@ -20,6 +20,7 @@ import {
 } from './util';
 } from './util';
 import { strings } from './constants';
 import { strings } from './constants';
 import isEnterPress from '../utils/isEnterPress';
 import isEnterPress from '../utils/isEnterPress';
+import { ESC_KEY } from '../utils/keyCode';
 
 
 export interface BasicData {
 export interface BasicData {
     data: BasicCascaderData;
     data: BasicCascaderData;
@@ -257,6 +258,13 @@ export default class CascaderFoundation extends BaseFoundation<CascaderAdapter,
         }
         }
     }
     }
 
 
+    handleKeyDown = (e: any) => {
+        if (e.key === ESC_KEY) {
+            const isOpen = this.getState('isOpen');
+            isOpen && this.close(e);
+        } 
+    }
+
     destroy() {
     destroy() {
         this._adapter.unregisterClickOutsideHandler();
         this._adapter.unregisterClickOutsideHandler();
     }
     }

+ 1 - 1
packages/semi-foundation/treeSelect/constants.ts

@@ -22,4 +22,4 @@ export {
     cssClasses,
     cssClasses,
     strings,
     strings,
     numbers
     numbers
-};
+};

+ 8 - 0
packages/semi-foundation/treeSelect/foundation.ts

@@ -24,6 +24,7 @@ import {
 } from '../tree/foundation';
 } from '../tree/foundation';
 import { Motion } from '../utils/type';
 import { Motion } from '../utils/type';
 import isEnterPress from '../utils/isEnterPress';
 import isEnterPress from '../utils/isEnterPress';
+import { ESC_KEY } from '../utils/keyCode';
 
 
 /* Here ValidateStatus is the same as ValidateStatus in baseComponent */
 /* Here ValidateStatus is the same as ValidateStatus in baseComponent */
 export type ValidateStatus = 'error' | 'warning' | 'default';
 export type ValidateStatus = 'error' | 'warning' | 'default';
@@ -310,6 +311,13 @@ export default class TreeSelectFoundation<P = Record<string, any>, S = Record<st
         }
         }
     }
     }
 
 
+    handleKeyDown = (e: any) => {
+        if (e.key === ESC_KEY) {
+            const isOpen = this.getState('isOpen');
+            isOpen && this.close(e);
+        } 
+    }
+
     getTreeNodeProps(key: string) {
     getTreeNodeProps(key: string) {
         const {
         const {
             expandedKeys = new Set([]),
             expandedKeys = new Set([]),

+ 7 - 0
packages/semi-ui/button/_story/button.stories.jsx

@@ -135,6 +135,13 @@ export const ButtonGroupDemo = () => (
       <Button>剪切</Button>
       <Button>剪切</Button>
     </ButtonGroup>
     </ButtonGroup>
     <br />
     <br />
+    <br />
+    <ButtonGroup theme={'outline'}>
+      <Button>拷贝</Button>
+      <Button>查询</Button>
+      <Button>剪切</Button>
+    </ButtonGroup>
+    <br />
   </div>
   </div>
 );
 );
 
 

+ 4 - 7
packages/semi-ui/button/buttonGroup.tsx

@@ -8,7 +8,7 @@ import { Type, Size, ButtonProps } from './Button';
 
 
 import '@douyinfe/semi-foundation/button/button.scss';
 import '@douyinfe/semi-foundation/button/button.scss';
 
 
-export type Theme = 'solid' | 'borderless' | 'light';
+export type Theme = 'solid' | 'borderless' | 'light' | 'outline';
 
 
 export interface ButtonGroupProps extends BaseProps {
 export interface ButtonGroupProps extends BaseProps {
     disabled?: boolean;
     disabled?: boolean;
@@ -42,14 +42,13 @@ export default class ButtonGroup extends BaseComponent<ButtonGroupProps> {
 
 
     getInnerWithLine(inner) {
     getInnerWithLine(inner) {
         const innerWithLine: ReactNode[] = [];
         const innerWithLine: ReactNode[] = [];
-        let lineCls = `${prefixCls}-group-line`;
         if (inner.length > 1) {
         if (inner.length > 1) {
             inner.slice(0, -1).forEach((item, index) => {
             inner.slice(0, -1).forEach((item, index) => {
                 const isButtonType = get(item, 'type.elementType') === 'Button';
                 const isButtonType = get(item, 'type.elementType') === 'Button';
                 const buttonProps = get(item, 'props') as ButtonProps;
                 const buttonProps = get(item, 'props') as ButtonProps;
-                if (buttonProps) {
-                    const { type, theme, disabled } = buttonProps;
-                    lineCls = classNames(
+                const { type, theme, disabled } = buttonProps ?? {};
+                if (isButtonType && theme !== 'outline') {
+                    const lineCls = classNames(
                         `${prefixCls}-group-line`,
                         `${prefixCls}-group-line`,
                         `${prefixCls}-group-line-${theme ?? 'light'}`,
                         `${prefixCls}-group-line-${theme ?? 'light'}`,
                         `${prefixCls}-group-line-${type ?? 'primary'}`,
                         `${prefixCls}-group-line-${type ?? 'primary'}`,
@@ -57,8 +56,6 @@ export default class ButtonGroup extends BaseComponent<ButtonGroupProps> {
                             [`${prefixCls}-group-line-disabled`]: disabled,
                             [`${prefixCls}-group-line-disabled`]: disabled,
                         }
                         }
                     );
                     );
-                }
-                if (isButtonType) {
                     innerWithLine.push(item, <span className={lineCls} key={`line-${index}`} />);
                     innerWithLine.push(item, <span className={lineCls} key={`line-${index}`} />);
                 } else {
                 } else {
                     innerWithLine.push(item);
                     innerWithLine.push(item);

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

@@ -699,7 +699,7 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
         const popoverCls = cls(dropdownClassName, `${prefixcls}-popover`);
         const popoverCls = cls(dropdownClassName, `${prefixcls}-popover`);
         const renderData = this.foundation.getRenderData();
         const renderData = this.foundation.getRenderData();
         const content = (
         const content = (
-            <div className={popoverCls} role="listbox" style={dropdownStyle}>
+            <div className={popoverCls} role="listbox" style={dropdownStyle} onKeyDown={this.foundation.handleKeyDown}>
                 {topSlot}
                 {topSlot}
                 <Item
                 <Item
                     activeKeys={activeKeys}
                     activeKeys={activeKeys}
@@ -1026,6 +1026,7 @@ class Cascader extends BaseComponent<CascaderProps, CascaderState> {
                 aria-describedby={this.props['aria-describedby']}
                 aria-describedby={this.props['aria-describedby']}
                 aria-required={this.props['aria-required']}
                 aria-required={this.props['aria-required']}
                 id={id}
                 id={id}
+                onKeyDown={this.foundation.handleKeyDown}
                 {...mouseEvent}
                 {...mouseEvent}
                 // eslint-disable-next-line jsx-a11y/role-has-required-aria-props
                 // eslint-disable-next-line jsx-a11y/role-has-required-aria-props
                 role="combobox"
                 role="combobox"

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

@@ -815,7 +815,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
         const style = { minWidth: dropdownMinWidth, ...dropdownStyle };
         const style = { minWidth: dropdownMinWidth, ...dropdownStyle };
         const popoverCls = cls(dropdownClassName, `${prefixcls}-popover`);
         const popoverCls = cls(dropdownClassName, `${prefixcls}-popover`);
         return (
         return (
-            <div className={popoverCls} style={style}>
+            <div className={popoverCls} style={style} onKeyDown={this.foundation.handleKeyDown}>
                 {this.renderTree()}
                 {this.renderTree()}
             </div>
             </div>
         );
         );
@@ -1166,6 +1166,7 @@ class TreeSelect extends BaseComponent<TreeSelectProps, TreeSelectState> {
                 ref={this.triggerRef}
                 ref={this.triggerRef}
                 onClick={this.handleClick}
                 onClick={this.handleClick}
                 onKeyPress={this.handleSelectionEnterPress}
                 onKeyPress={this.handleSelectionEnterPress}
+                onKeyDown={this.foundation.handleKeyDown}
                 aria-invalid={this.props['aria-invalid']}
                 aria-invalid={this.props['aria-invalid']}
                 aria-errormessage={this.props['aria-errormessage']}
                 aria-errormessage={this.props['aria-errormessage']}
                 aria-label={this.props['aria-label']}
                 aria-label={this.props['aria-label']}