mirror of
https://gitee.com/ant-design/ant-design.git
synced 2024-11-30 11:08:45 +08:00
feat: add tabindex option for paragraph button (#48567)
* feat: add tabIndex option for paragraph * test: update snapshot * test: update test case * revert: revert the testcase * test: update test case * fix: fix the coverage test * chore: code optimize * Update index.tsx Signed-off-by: lijianan <574980606@qq.com> * Update CopyBtn.tsx Signed-off-by: lijianan <574980606@qq.com> * Update transButton.tsx Signed-off-by: lijianan <574980606@qq.com> * Update copy.test.tsx Signed-off-by: lijianan <574980606@qq.com> * Update CopyBtn.tsx Signed-off-by: lijianan <574980606@qq.com> --------- Signed-off-by: lijianan <574980606@qq.com> Co-authored-by: lijianan <574980606@qq.com>
This commit is contained in:
parent
5c2e6e3651
commit
9acde83991
@ -7,10 +7,11 @@ import * as React from 'react';
|
||||
import KeyCode from 'rc-util/lib/KeyCode';
|
||||
|
||||
interface TransButtonProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
onClick?: (e?: React.MouseEvent<HTMLDivElement>) => void;
|
||||
onClick?: (e?: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
||||
noStyle?: boolean;
|
||||
autoFocus?: boolean;
|
||||
disabled?: boolean;
|
||||
tabIndex?: number;
|
||||
}
|
||||
|
||||
const inlineStyle: React.CSSProperties = {
|
||||
@ -37,7 +38,7 @@ const TransButton = React.forwardRef<HTMLDivElement, TransButtonProps>((props, r
|
||||
}
|
||||
};
|
||||
|
||||
const { style, noStyle, disabled, ...restProps } = props;
|
||||
const { style, noStyle, disabled, tabIndex = 0, ...restProps } = props;
|
||||
|
||||
let mergedStyle: React.CSSProperties = {};
|
||||
|
||||
@ -59,7 +60,7 @@ const TransButton = React.forwardRef<HTMLDivElement, TransButtonProps>((props, r
|
||||
return (
|
||||
<div
|
||||
role="button"
|
||||
tabIndex={0}
|
||||
tabIndex={tabIndex}
|
||||
ref={ref}
|
||||
{...restProps}
|
||||
onKeyDown={onKeyDown}
|
||||
|
@ -14,12 +14,12 @@ export interface CopyBtnProps extends Omit<CopyConfig, 'onCopy'> {
|
||||
prefixCls: string;
|
||||
copied: boolean;
|
||||
locale: Locale['Text'];
|
||||
onCopy: React.MouseEventHandler<HTMLDivElement>;
|
||||
onCopy: (e?: React.MouseEvent<HTMLDivElement, MouseEvent>) => void;
|
||||
iconOnly: boolean;
|
||||
loading: boolean;
|
||||
}
|
||||
|
||||
export default function CopyBtn(props: CopyBtnProps) {
|
||||
const CopyBtn: React.FC<CopyBtnProps> = (props) => {
|
||||
const { prefixCls, copied, locale = {}, onCopy, iconOnly, tooltips, icon, loading } = props;
|
||||
|
||||
const tooltipNodes = toList(tooltips);
|
||||
@ -40,8 +40,9 @@ export default function CopyBtn(props: CopyBtnProps) {
|
||||
[`${prefixCls}-copy-success`]: copied,
|
||||
[`${prefixCls}-copy-icon-only`]: iconOnly,
|
||||
})}
|
||||
onClick={onCopy as any}
|
||||
onClick={onCopy}
|
||||
aria-label={ariaLabel}
|
||||
tabIndex={props.tabIndex}
|
||||
>
|
||||
{copied
|
||||
? getNode(iconNodes[1], <CheckOutlined />, true)
|
||||
@ -49,4 +50,6 @@ export default function CopyBtn(props: CopyBtnProps) {
|
||||
</TransButton>
|
||||
</Tooltip>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default CopyBtn;
|
||||
|
@ -33,6 +33,7 @@ export interface CopyConfig {
|
||||
icon?: React.ReactNode;
|
||||
tooltips?: React.ReactNode;
|
||||
format?: 'text/plain' | 'text/html';
|
||||
tabIndex?: number;
|
||||
}
|
||||
|
||||
interface EditConfig {
|
||||
@ -48,6 +49,7 @@ interface EditConfig {
|
||||
autoSize?: boolean | AutoSizeType;
|
||||
triggerType?: ('icon' | 'text')[];
|
||||
enterIcon?: React.ReactNode;
|
||||
tabIndex?: number;
|
||||
}
|
||||
|
||||
export interface EllipsisConfig {
|
||||
@ -372,8 +374,12 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
const renderExpand = () => {
|
||||
const { expandable, symbol } = ellipsisConfig;
|
||||
|
||||
if (!expandable) return null;
|
||||
if (expanded && expandable !== 'collapsible') return null;
|
||||
if (!expandable) {
|
||||
return null;
|
||||
}
|
||||
if (expanded && expandable !== 'collapsible') {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (
|
||||
<a
|
||||
@ -389,9 +395,11 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
|
||||
// Edit
|
||||
const renderEdit = () => {
|
||||
if (!enableEdit) return;
|
||||
if (!enableEdit) {
|
||||
return;
|
||||
}
|
||||
|
||||
const { icon, tooltip } = editConfig;
|
||||
const { icon, tooltip, tabIndex } = editConfig;
|
||||
|
||||
const editTitle = toArray(tooltip)[0] || textLocale?.edit;
|
||||
const ariaLabel = typeof editTitle === 'string' ? editTitle : '';
|
||||
@ -403,6 +411,7 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
className={`${prefixCls}-edit`}
|
||||
onClick={onEditClick}
|
||||
aria-label={ariaLabel}
|
||||
tabIndex={tabIndex}
|
||||
>
|
||||
{icon || <EditOutlined role="button" />}
|
||||
</TransButton>
|
||||
|
@ -328,4 +328,28 @@ describe('Typography copy', () => {
|
||||
);
|
||||
expect(container.querySelector('.ant-typography-copy')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('tabIndex of copy button', () => {
|
||||
const { container } = render(
|
||||
<Base component="p" copyable={{ tabIndex: -1 }}>
|
||||
test
|
||||
</Base>,
|
||||
);
|
||||
expect(container.querySelector('.ant-typography-copy')?.getAttribute('tabIndex')).toBe('-1');
|
||||
});
|
||||
|
||||
it('locale text for button tooltip', async () => {
|
||||
const { container } = render(
|
||||
<Base component="p" copyable>
|
||||
test
|
||||
</Base>,
|
||||
);
|
||||
fireEvent.mouseEnter(container.querySelectorAll('.ant-typography-copy')[0]);
|
||||
await waitFakeTimer();
|
||||
await waitFor(() => {
|
||||
expect(container.querySelector('.ant-tooltip-inner')?.textContent).toBe('Copy');
|
||||
});
|
||||
fireEvent.click(container.querySelectorAll('.ant-typography-copy')[0]);
|
||||
expect(container.querySelector('.ant-tooltip-inner')?.textContent).toBe('Copied');
|
||||
});
|
||||
});
|
||||
|
@ -90,4 +90,16 @@ describe('Typography.Editable', () => {
|
||||
);
|
||||
expect(container.querySelector('.ant-typography-edit')).toBeTruthy();
|
||||
});
|
||||
|
||||
it('tabIndex of edit button', () => {
|
||||
const { container, rerender } = render(<Base component="p">test</Base>);
|
||||
expect(container.querySelector('.ant-typography-edit')).toBeFalsy();
|
||||
|
||||
rerender(
|
||||
<Base component="p" editable={{ tabIndex: -1 }}>
|
||||
test
|
||||
</Base>,
|
||||
);
|
||||
expect(container.querySelector('.ant-typography-edit')?.getAttribute('tabIndex')).toBe('-1');
|
||||
});
|
||||
});
|
||||
|
@ -92,6 +92,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
icon: ReactNode,
|
||||
tooltips: false | [ReactNode, ReactNode],
|
||||
format: 'text/plain' | 'text/html',
|
||||
tabIndex: number,
|
||||
}
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
@ -101,6 +102,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| text | The text to copy | string | - | |
|
||||
| tooltips | Custom tooltip text, hide when it is false | \[ReactNode, ReactNode] | \[`Copy`, `Copied`] | 4.4.0 |
|
||||
| onCopy | Called when copied text | function | - | |
|
||||
| tabIndex | Set tabIndex of the copy button | number | 0 | 5.17.0 |
|
||||
|
||||
### editable
|
||||
|
||||
@ -117,6 +119,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
onEnd: function,
|
||||
triggerType: ('icon' | 'text')[],
|
||||
enterIcon: ReactNode,
|
||||
tabIndex: number,
|
||||
}
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
@ -133,6 +136,7 @@ Common props ref:[Common props](/docs/react/common-props)
|
||||
| onEnd | Called when type ENTER to exit editable state | function | - | 4.14.0 |
|
||||
| triggerType | Edit mode trigger - icon, text or both (not specifying icon as trigger hides it) | Array<`icon`\|`text`> | \[`icon`] | |
|
||||
| enterIcon | Custom "enter" icon in the edit field (passing `null` removes the icon) | ReactNode | `<EnterOutlined />` | 4.17.0 |
|
||||
| tabIndex | Set tabIndex of the edit button | number | 0 | 5.17.0 |
|
||||
|
||||
### ellipsis
|
||||
|
||||
|
@ -93,6 +93,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*LT2jR41Uj2EAAA
|
||||
icon: ReactNode,
|
||||
tooltips: false | [ReactNode, ReactNode],
|
||||
format: 'text/plain' | 'text/html',
|
||||
tabIndex: number,
|
||||
}
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
@ -102,6 +103,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*LT2jR41Uj2EAAA
|
||||
| text | 拷贝到剪切板里的文本 | string | - | |
|
||||
| tooltips | 自定义提示文案,为 false 时隐藏文案 | \[ReactNode, ReactNode] | \[`复制`, `复制成功`] | 4.4.0 |
|
||||
| onCopy | 拷贝成功的回调函数 | function | - | |
|
||||
| tabIndex | 自定义复制按钮的 tabIndex | number | 0 | 5.17.0 |
|
||||
|
||||
### editable
|
||||
|
||||
@ -118,6 +120,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*LT2jR41Uj2EAAA
|
||||
onEnd: function,
|
||||
triggerType: ('icon' | 'text')[],
|
||||
enterIcon: ReactNode,
|
||||
tabIndex: number,
|
||||
}
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
@ -134,6 +137,7 @@ coverDark: https://mdn.alipayobjects.com/huamei_7uahnr/afts/img/A*LT2jR41Uj2EAAA
|
||||
| onEnd | 按 ENTER 结束编辑状态时触发 | function | - | 4.14.0 |
|
||||
| triggerType | 编辑模式触发器类型,图标、文本或者两者都设置(不设置图标作为触发器时它会隐藏) | Array<`icon`\|`text`> | \[`icon`] | |
|
||||
| enterIcon | 在编辑段中自定义“enter”图标(传递“null”将删除图标) | ReactNode | `<EnterOutlined />` | 4.17.0 |
|
||||
| tabIndex | 自定义编辑按钮的 tabIndex | number | 0 | 5.17.0 |
|
||||
|
||||
### ellipsis
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user