浏览代码

feat: add showArrow and disabled API to Collapse (#1000)

YannLynn 3 年之前
父节点
当前提交
c712e7009c

+ 49 - 0
content/show/collapse/index-en-US.md

@@ -62,6 +62,52 @@ import { Collapse } from '@douyinfe/semi-ui';
 );
 );
 ```
 ```
 
 
+### Disable Panel
+
+Use `disabled` to disabled panel.
+
+```jsx live=true
+import React from 'react';
+import { Collapse } from '@douyinfe/semi-ui';
+
+() => (
+    <Collapse accordion>
+        <Collapse.Panel header="This is panel header 1" itemKey="1" disabled>
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+        <Collapse.Panel header="This is panel header 2" itemKey="2">
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+        <Collapse.Panel header="This is panel header 3" itemKey="3">
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+    </Collapse>
+);
+```
+
+### Hide The Panel Icon
+
+Use `showArrow` to hide the panel icon.
+
+```jsx live=true
+import React from 'react';
+import { Collapse } from '@douyinfe/semi-ui';
+
+() => (
+    <Collapse accordion>
+        <Collapse.Panel header="This is panel header 1" itemKey="1" showArrow={false}>
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+        <Collapse.Panel header="This is panel header 2" itemKey="2">
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+        <Collapse.Panel header="This is panel header 3" itemKey="3">
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+    </Collapse>
+);
+```
+
 ### Custom Icon
 ### Custom Icon
 
 
 You can use `expandIcon` to set the expanding icon and `collapseIcon` for folded icon.
 You can use `expandIcon` to set the expanding icon and `collapseIcon` for folded icon.
@@ -143,10 +189,12 @@ import { IconCopy } from '@douyinfe/semi-icons';
 | Properties | Instructions | type | Default |version|
 | Properties | Instructions | type | Default |version|
 | --- | --- | --- | --- | --- |
 | --- | --- | --- | --- | --- |
 | className | className of Panel | string | - ||
 | className | className of Panel | string | - ||
+| disabled  | If true, the panel is disabled | boolean     |  false  | v2.17.0   |
 | extra | Custom rendering of the auxiliary content in the upper right-hand corner of each panel(only work when header is string) | ReactNode | - ||
 | extra | Custom rendering of the auxiliary content in the upper right-hand corner of each panel(only work when header is string) | ReactNode | - ||
 | header | Panel head content | ReactNode | - | - ||
 | header | Panel head content | ReactNode | - | - ||
 | itemKey | Required and must be unique, used to match `activeKey`, `defaultActiveKey` | string | - ||
 | itemKey | Required and must be unique, used to match `activeKey`, `defaultActiveKey` | string | - ||
 | reCalcKey | When reCalcKey changes, the height of children will be reset. Used for optimize dynamic content rendering. | string \| number |-| 1.5.0 |
 | reCalcKey | When reCalcKey changes, the height of children will be reset. Used for optimize dynamic content rendering. | string \| number |-| 1.5.0 |
+| showArrow | whether to show arrows icon | boolean                 |  true  | v2.17.0   |
 | style | inline CSS style | CSSProperties | - ||
 | style | inline CSS style | CSSProperties | - ||
 
 
 
 
@@ -157,6 +205,7 @@ import { IconCopy } from '@douyinfe/semi-icons';
 - The button on the right side of the panel header is set to `aria-hidden=true`
 - The button on the right side of the panel header is set to `aria-hidden=true`
 - The interactive part of the panel header is set to the `aria-owns` value corresponding to the panel content
 - The interactive part of the panel header is set to the `aria-owns` value corresponding to the panel content
 - The content of the panel is set with `aria-hidden`, and its value is automatically switched between true and false with the display of the panel content
 - The content of the panel is set with `aria-hidden`, and its value is automatically switched between true and false with the display of the panel content
+- The panel `aria-disabled` is synchronized with the `disabled` property, indicating that the panel is disabled
 
 
 ## Design Tokens
 ## Design Tokens
 
 

+ 51 - 3
content/show/collapse/index.md

@@ -61,6 +61,52 @@ import { Collapse } from '@douyinfe/semi-ui';
 );
 );
 ```
 ```
 
 
+### 禁用面板
+
+可以通过设置 `disabled` 禁用面板。
+
+```jsx live=true
+import React from 'react';
+import { Collapse } from '@douyinfe/semi-ui';
+
+() => (
+    <Collapse accordion>
+        <Collapse.Panel header="This is panel header 1" itemKey="1" disabled>
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+        <Collapse.Panel header="This is panel header 2" itemKey="2">
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+        <Collapse.Panel header="This is panel header 3" itemKey="3">
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+    </Collapse>
+);
+```
+
+### 隐藏面板展开/收起图标
+
+可以通过设置 `showArrow` 隐藏面板展开/收起图标。
+
+```jsx live=true
+import React from 'react';
+import { Collapse } from '@douyinfe/semi-ui';
+
+() => (
+    <Collapse accordion>
+        <Collapse.Panel header="This is panel header 1" itemKey="1" showArrow={false}>
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+        <Collapse.Panel header="This is panel header 2" itemKey="2">
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+        <Collapse.Panel header="This is panel header 3" itemKey="3">
+            <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+        </Collapse.Panel>
+    </Collapse>
+);
+```
+
 ### 自定义展开图标
 ### 自定义展开图标
 
 
 可以通过 `expandIcon` 设置展开图标,`collapseIcon` 设置折叠图标。
 可以通过 `expandIcon` 设置展开图标,`collapseIcon` 设置折叠图标。
@@ -143,20 +189,22 @@ import { IconCopy } from '@douyinfe/semi-icons';
 | 属性      | 说明                                                                  | 类型                   | 默认值 |版本|
 | 属性      | 说明                                                                  | 类型                   | 默认值 |版本|
 | --------- | --------------------------------------------------------------------- | ---------------------- | ------ |--- |
 | --------- | --------------------------------------------------------------------- | ---------------------- | ------ |--- |
 | className | 样式类名                                                              | string                 |   无     ||
 | className | 样式类名                                                              | string                 |   无     ||
+| disabled  | 面板是否被禁用                                                         | boolean                 |  false  | v2.17.0   |
 | extra     | 自定义渲染每个面板右上角的辅助内容(仅当 header 为 string 时生效)    | ReactNode              | 无     ||
 | extra     | 自定义渲染每个面板右上角的辅助内容(仅当 header 为 string 时生效)    | ReactNode              | 无     ||
 | header    | 面板头内容                                                            | ReactNode      | 无     ||
 | header    | 面板头内容                                                            | ReactNode      | 无     ||
 | itemKey   | 必填且唯一,选中状态匹配 `activeKey`,`defaultActiveKey`              | string                 | 无     ||
 | itemKey   | 必填且唯一,选中状态匹配 `activeKey`,`defaultActiveKey`              | string                 | 无     ||
 | reCalcKey | 当 reCalcKey 改变时,将重新计算子节点的高度,用于优化动态渲染时的计算 | string \| number |无| 1.5.0  |
 | reCalcKey | 当 reCalcKey 改变时,将重新计算子节点的高度,用于优化动态渲染时的计算 | string \| number |无| 1.5.0  |
+| showArrow | 是否展示箭头                                                          | boolean                 |  true  | v2.17.0   |
 | style     | 内联 CSS 样式                                                         | CSSProperties                 |  无  |    |
 | style     | 内联 CSS 样式                                                         | CSSProperties                 |  无  |    |
 
 
-
 ## Accessibility
 ## Accessibility
 
 
 ### ARIA
 ### ARIA
 
 
 - 面板 header 右侧按钮 设置了 `aria-hidden=true`
 - 面板 header 右侧按钮 设置了 `aria-hidden=true`
-- 面版 header 可交互部分 设置了 `aria-owns` 值为对应面板内容
-- 面版内容 设置了 `aria-hidden` 随面板内容展现隐藏其值在 true 和 false 之间自动切换
+- 面板 header 可交互部分 设置了 `aria-owns` 值为对应面板内容
+- 面板内容 设置了 `aria-hidden` 随面板内容展现隐藏其值在 true 和 false 之间自动切换
+- 面板 `aria-disabled` 与 `disabled` 属性同步,表示面板禁用
 
 
 ## 设计变量
 ## 设计变量
 
 

+ 8 - 0
packages/semi-foundation/collapse/collapse.scss

@@ -61,6 +61,14 @@ $module: #{$prefix}-collapse;
             background-color: $color-collapse_header-bg-active;
             background-color: $color-collapse_header-bg-active;
         }
         }
 
 
+        &-disabled {
+            color: $color-collapse_header-text-disabled;
+
+            &:hover {
+                background-color: transparent;
+            }
+        }
+
     }
     }
 
 
     &-content {
     &-content {

+ 1 - 0
packages/semi-foundation/collapse/variables.scss

@@ -1,5 +1,6 @@
 $color-collapse_item-border-default: var(--semi-color-border); // 分割线颜色
 $color-collapse_item-border-default: var(--semi-color-border); // 分割线颜色
 $color-collapse_header-text-default: var(--semi-color-text-0); // 标题文字颜色
 $color-collapse_header-text-default: var(--semi-color-text-0); // 标题文字颜色
+$color-collapse_header-text-disabled: var( --semi-color-disabled-text); // 标题文字颜色 禁用
 $color-collapse_header-icon-default: var(--semi-color-text-2); // 展开箭头图标颜色
 $color-collapse_header-icon-default: var(--semi-color-text-2); // 展开箭头图标颜色
 $color-collapse_header-bg-hover: var(--semi-color-fill-0); // 菜单项背景颜色 - 悬浮
 $color-collapse_header-bg-hover: var(--semi-color-fill-0); // 菜单项背景颜色 - 悬浮
 $color-collapse_header-bg-active: var(--semi-color-fill-1); // 菜单项背景颜色 - 按下
 $color-collapse_header-bg-active: var(--semi-color-fill-1); // 菜单项背景颜色 - 按下

+ 22 - 2
packages/semi-ui/collapse/__test__/collapse.test.js

@@ -3,11 +3,13 @@ import { BASE_CLASS_PREFIX } from '../../../semi-foundation/base/constants'; //
 
 
 import { IconPlus, IconMinus, IconCopy } from '@douyinfe/semi-icons';
 import { IconPlus, IconMinus, IconCopy } from '@douyinfe/semi-icons';
 
 
-let getCollapse = collapseProps => {
+let getCollapse = (collapseProps, panel1Props) => {
     let props = collapseProps ? collapseProps : {};
     let props = collapseProps ? collapseProps : {};
+    let panelProps = panel1Props ? panel1Props : {};
+
     return (
     return (
         <Collapse {...collapseProps}>
         <Collapse {...collapseProps}>
-            <Collapse.Panel header="This is panel header 1" itemKey="1">
+            <Collapse.Panel header="This is panel header 1" itemKey="1" {...panelProps}>
                 <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
                 <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
             </Collapse.Panel>
             </Collapse.Panel>
             <Collapse.Panel header="This is panel header 2" itemKey="2">
             <Collapse.Panel header="This is panel header 2" itemKey="2">
@@ -145,4 +147,22 @@ describe('Collapse', () => {
         expect(headers.at(1).getDOMNode().getAttribute(expandAttr)).toEqual("false");
         expect(headers.at(1).getDOMNode().getAttribute(expandAttr)).toEqual("false");
         expect(headers.at(2).getDOMNode().getAttribute(expandAttr)).toEqual("true");
         expect(headers.at(2).getDOMNode().getAttribute(expandAttr)).toEqual("true");
     });
     });
+
+    it('disable Collapse', () => {
+        let props = {
+            disabled: true,
+        };
+        const disabledPanel = mount(getCollapse({}, props));
+        expect(disabledPanel.exists('.semi-collapse-header-disabled')).toEqual(true);
+    });
+
+    it('hide the panel icon', () => {
+        const hidePanelArrow = mount( 
+        <Collapse >
+            <Collapse.Panel header="This is panel header 1" itemKey="1" showArrow={false}>
+                <p>Hi, bytedance dance dance. This is the docsite of Semi UI. </p>
+            </Collapse.Panel>
+        </Collapse>);
+        expect(hidePanelArrow.exists('.semi-collapse-header-icon')).toEqual(false);
+    });
 });
 });

+ 2 - 2
packages/semi-ui/collapse/_story/accordion.stories.js

@@ -17,7 +17,7 @@ export default {
 export const RegularCollapse = () => (
 export const RegularCollapse = () => (
   <div>
   <div>
     <Collapse onChange={k => console.log(k)}>
     <Collapse onChange={k => console.log(k)}>
-      <Panel header="This is panel header 1" itemKey="1">
+      <Panel header="This is panel header 1" itemKey="1" showArrow={false}>
         <p>{text}</p>
         <p>{text}</p>
       </Panel>
       </Panel>
       <Panel header="This is panel header 2" itemKey="2">
       <Panel header="This is panel header 2" itemKey="2">
@@ -32,7 +32,7 @@ export const RegularCollapse = () => (
       <Panel header="This is panel header 1" itemKey="1">
       <Panel header="This is panel header 1" itemKey="1">
         <p>{text}</p>
         <p>{text}</p>
       </Panel>
       </Panel>
-      <Panel header="This is panel header 2" itemKey="124">
+      <Panel header="This is panel header 2" itemKey="124" disabled>
         <p>{text}</p>
         <p>{text}</p>
       </Panel>
       </Panel>
       <Panel header="This is panel header 3" itemKey="3" disabled>
       <Panel header="This is panel header 3" itemKey="3" disabled>

+ 20 - 6
packages/semi-ui/collapse/item.tsx

@@ -15,6 +15,8 @@ export interface CollapsePanelProps {
     children?: React.ReactNode;
     children?: React.ReactNode;
     reCalcKey?: number | string;
     reCalcKey?: number | string;
     style?: CSSProperties;
     style?: CSSProperties;
+    showArrow?: boolean,
+    disabled?: boolean,
 }
 }
 
 
 export default class CollapsePanel extends PureComponent<CollapsePanelProps> {
 export default class CollapsePanel extends PureComponent<CollapsePanelProps> {
@@ -32,6 +34,13 @@ export default class CollapsePanel extends PureComponent<CollapsePanelProps> {
             PropTypes.string,
             PropTypes.string,
             PropTypes.number,
             PropTypes.number,
         ]),
         ]),
+        showArrow: PropTypes.bool,
+        disabled: PropTypes.bool,
+    };
+
+    static defaultProps = {
+        showArrow: true,
+        disabled: false,
     };
     };
 
 
     private ariaID = getUuidShort({});
     private ariaID = getUuidShort({});
@@ -40,6 +49,7 @@ export default class CollapsePanel extends PureComponent<CollapsePanelProps> {
 
 
     renderHeader(active: boolean, expandIconEnable = true) {
     renderHeader(active: boolean, expandIconEnable = true) {
         const {
         const {
+            showArrow,
             header,
             header,
             extra,
             extra,
         } = this.props;
         } = this.props;
@@ -65,20 +75,20 @@ export default class CollapsePanel extends PureComponent<CollapsePanelProps> {
         if (typeof header === 'string') {
         if (typeof header === 'string') {
             return (
             return (
                 <>
                 <>
-                    {iconPosLeft ? icon : null}
+                    {showArrow && (iconPosLeft ? icon : null)}
                     <span>{header}</span>
                     <span>{header}</span>
                     <span className={`${cssClasses.PREFIX}-header-right`}>
                     <span className={`${cssClasses.PREFIX}-header-right`}>
                         <span>{extra}</span>
                         <span>{extra}</span>
-                        {iconPosLeft ? null : icon}
+                        {showArrow && (iconPosLeft ? null : icon)}
                     </span>
                     </span>
                 </>
                 </>
             );
             );
         }
         }
         return (
         return (
             <>
             <>
-                {iconPosLeft ? icon : null}
+                {showArrow && (iconPosLeft ? icon : null)}
                 {header}
                 {header}
-                {iconPosLeft ? null : icon}
+                {showArrow && (iconPosLeft ? null : icon)}
             </>
             </>
         );
         );
     }
     }
@@ -91,6 +101,8 @@ export default class CollapsePanel extends PureComponent<CollapsePanelProps> {
             reCalcKey,
             reCalcKey,
             header,
             header,
             extra,
             extra,
+            showArrow,
+            disabled,
             ...restProps
             ...restProps
         } = this.props;
         } = this.props;
         const {
         const {
@@ -106,6 +118,7 @@ export default class CollapsePanel extends PureComponent<CollapsePanelProps> {
         });
         });
         const headerCls = cls({
         const headerCls = cls({
             [`${cssClasses.PREFIX}-header`]: true,
             [`${cssClasses.PREFIX}-header`]: true,
+            [`${cssClasses.PREFIX}-header-disabled`]: disabled,
             [`${cssClasses.PREFIX}-header-iconLeft`]: expandIconPosition === 'left',
             [`${cssClasses.PREFIX}-header-iconLeft`]: expandIconPosition === 'left',
         });
         });
         const contentCls = cls({
         const contentCls = cls({
@@ -120,11 +133,12 @@ export default class CollapsePanel extends PureComponent<CollapsePanelProps> {
                     role="button"
                     role="button"
                     tabIndex={0}
                     tabIndex={0}
                     className={headerCls}
                     className={headerCls}
+                    aria-disabled={disabled}
                     aria-expanded={active ? 'true' : 'false'}
                     aria-expanded={active ? 'true' : 'false'}
                     aria-owns={this.ariaID}
                     aria-owns={this.ariaID}
-                    onClick={e => onClick(itemKey, e)}
+                    onClick={e => !disabled && onClick(itemKey, e)}
                 >
                 >
-                    {this.renderHeader(active, children !== undefined)}
+                    {this.renderHeader(active, children !== undefined && !disabled)}
                 </div>
                 </div>
                 {
                 {
                     children && (
                     children && (