Skip to content

Commit

Permalink
feat: improve a11y behavior (#354)
Browse files Browse the repository at this point in the history
  • Loading branch information
afc163 authored Oct 28, 2024
1 parent 5b50798 commit 06a04d0
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 38 deletions.
4 changes: 2 additions & 2 deletions assets/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
margin: 0 16px 0 auto;
}
}
.@{prefixCls}-header-collapsible-only {
.@{prefixCls}-collapsible-header {
cursor: default;
.@{prefixCls}-header-text {
cursor: pointer;
Expand All @@ -68,7 +68,7 @@
cursor: pointer;
}
}
.@{prefixCls}-icon-collapsible-only {
.@{prefixCls}-collapsible-icon {
cursor: default;
.@{prefixCls}-expand-icon {
cursor: pointer;
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"@rc-component/father-plugin": "^1.0.1",
"@testing-library/jest-dom": "^6.1.4",
"@testing-library/react": "^14.1.2",
"@testing-library/user-event": "^14.5.2",
"@types/classnames": "^2.2.9",
"@types/jest": "^29.4.0",
"@types/react": "^18.0.0",
Expand Down
63 changes: 28 additions & 35 deletions src/Panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,37 +29,39 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop
} = props;

const disabled = collapsible === 'disabled';
const collapsibleHeader = collapsible === 'header';
const collapsibleIcon = collapsible === 'icon';

const ifExtraExist = extra !== null && extra !== undefined && typeof extra !== 'boolean';

const handleItemClick = () => {
onItemClick?.(panelKey!);
};

const handleKeyDown = (e: React.KeyboardEvent) => {
if (e.key === 'Enter' || e.keyCode === KeyCode.ENTER || e.which === KeyCode.ENTER) {
handleItemClick();
}
const collapsibleProps = {
onClick: () => {
onItemClick?.(panelKey);
},
onKeyDown: (e: React.KeyboardEvent) => {
if (e.key === 'Enter' || e.keyCode === KeyCode.ENTER || e.which === KeyCode.ENTER) {
onItemClick?.(panelKey);
}
},
role: accordion ? 'tab' : 'button',
['aria-expanded']: isActive,
['aria-disabled']: disabled,
tabIndex: disabled ? -1 : 0,
};

// ======================== Icon ========================
let iconNode = typeof expandIcon === 'function' ? expandIcon(props) : <i className="arrow" />;
if (iconNode) {
iconNode = (
<div
className={`${prefixCls}-expand-icon`}
onClick={['header', 'icon'].includes(collapsible as string) ? handleItemClick : undefined}
>
{iconNode}
</div>
);
}
const iconNodeInner =
typeof expandIcon === 'function' ? expandIcon(props) : <i className="arrow" />;
const iconNode = iconNodeInner && (
<div
className={`${prefixCls}-expand-icon`}
{...(['header', 'icon'].includes(collapsible) ? collapsibleProps : {})}
>
{iconNodeInner}
</div>
);

const collapsePanelClassNames = classNames(
`${prefixCls}-item`,
{
[`${prefixCls}-item`]: true,
[`${prefixCls}-item-active`]: isActive,
[`${prefixCls}-item-disabled`]: disabled,
},
Expand All @@ -68,37 +70,28 @@ const CollapsePanel = React.forwardRef<HTMLDivElement, CollapsePanelProps>((prop

const headerClassName = classNames(
headerClass,
`${prefixCls}-header`,
{
[`${prefixCls}-header`]: true,
[`${prefixCls}-header-collapsible-only`]: collapsibleHeader,
[`${prefixCls}-icon-collapsible-only`]: collapsibleIcon,
[`${prefixCls}-collapsible-${collapsible}`]: !!collapsible,
},
customizeClassNames.header,
);

// ======================== HeaderProps ========================
const headerProps: React.HTMLAttributes<HTMLDivElement> = {
className: headerClassName,
'aria-expanded': isActive,
'aria-disabled': disabled,
onKeyDown: handleKeyDown,
style: styles.header,
role: accordion ? 'tab' : 'button',
...(['header', 'icon'].includes(collapsible) ? {} : collapsibleProps),
};

if (!collapsibleHeader && !collapsibleIcon) {
headerProps.onClick = handleItemClick;
headerProps.tabIndex = disabled ? -1 : 0;
}

// ======================== Render ========================
return (
<div {...resetProps} ref={ref} className={collapsePanelClassNames}>
<div {...headerProps}>
{showArrow && iconNode}
<span
className={`${prefixCls}-header-text`}
onClick={collapsible === 'header' ? handleItemClick : undefined}
{...(collapsible === 'header' ? collapsibleProps : {})}
>
{header}
</span>
Expand Down
2 changes: 1 addition & 1 deletion tests/__snapshots__/index.spec.tsx.snap
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ exports[`collapse props items should work with nested 1`] = `
<div
aria-disabled="true"
aria-expanded="false"
class="rc-collapse-header"
class="rc-collapse-header rc-collapse-collapsible-disabled"
role="button"
tabindex="-1"
>
Expand Down

0 comments on commit 06a04d0

Please sign in to comment.