mirror of
https://github.com/ant-design/ant-design.git
synced 2025-08-15 13:38:29 +02:00
commit
06ef05d7da
8 changed files with 72 additions and 55 deletions
|
@ -2,7 +2,7 @@
|
|||
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
|
||||
{
|
||||
"name": "ant-design",
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-22-bookworm",
|
||||
"image": "mcr.microsoft.com/devcontainers/typescript-node:2-22-bookworm",
|
||||
"postCreateCommand": "pnpm install",
|
||||
"customizations": {
|
||||
"vscode": {
|
||||
|
|
|
@ -100,21 +100,19 @@ const ThemeSwitch: React.FC<ThemeSwitchProps> = () => {
|
|||
return;
|
||||
}
|
||||
|
||||
// 校验当前主题是否包含要切换的主题(避免 timeout in DOM update)
|
||||
if (theme.includes(key as ThemeName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 亮色/暗色模式切换时应用动画效果
|
||||
if (key === 'dark' || key === 'light') {
|
||||
lastThemeKey.current = key;
|
||||
toggleAnimationTheme(domEvent, theme.includes('dark'));
|
||||
}
|
||||
|
||||
const themeKey = key as ThemeName;
|
||||
|
||||
// 亮色/暗色模式是互斥的
|
||||
if (['light', 'dark'].includes(key)) {
|
||||
// 校验当前主题是否包含要切换的主题(避免 timeout in DOM update)
|
||||
if (theme.includes(themeKey)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 亮色/暗色模式切换时应用动画效果
|
||||
lastThemeKey.current = key;
|
||||
toggleAnimationTheme(domEvent, theme.includes('dark'));
|
||||
|
||||
const filteredTheme = theme.filter((t) => !['light', 'dark'].includes(t));
|
||||
updateSiteConfig({
|
||||
theme: [...filteredTheme, themeKey],
|
||||
|
|
|
@ -156,7 +156,8 @@ export default function useClosable(
|
|||
}
|
||||
mergedCloseIcon = React.isValidElement<HTMLAriaDataAttributes>(mergedCloseIcon) ? (
|
||||
React.cloneElement(mergedCloseIcon, {
|
||||
'aria-label': contextLocale.close,
|
||||
...mergedCloseIcon.props,
|
||||
'aria-label': mergedCloseIcon.props?.['aria-label'] ?? contextLocale.close,
|
||||
...ariaOrDataProps,
|
||||
})
|
||||
) : (
|
||||
|
|
|
@ -130,16 +130,12 @@ const Collapse = React.forwardRef<HTMLDivElement, CollapseProps>((props, ref) =>
|
|||
);
|
||||
return cloneElement(icon, () => ({
|
||||
className: classNames(
|
||||
(
|
||||
icon as React.ReactElement<{
|
||||
className?: string;
|
||||
}>
|
||||
)?.props?.className,
|
||||
(icon as React.ReactElement<{ className?: string }>).props?.className,
|
||||
`${prefixCls}-arrow`,
|
||||
),
|
||||
}));
|
||||
},
|
||||
[mergedExpandIcon, prefixCls],
|
||||
[mergedExpandIcon, prefixCls, direction],
|
||||
);
|
||||
|
||||
const collapseClassName = classNames(
|
||||
|
@ -156,35 +152,35 @@ const Collapse = React.forwardRef<HTMLDivElement, CollapseProps>((props, ref) =>
|
|||
hashId,
|
||||
cssVarCls,
|
||||
);
|
||||
const openMotion: CSSMotionProps = {
|
||||
...initCollapseMotion(rootPrefixCls),
|
||||
motionAppear: false,
|
||||
leavedClassName: `${prefixCls}-content-hidden`,
|
||||
};
|
||||
|
||||
const openMotion = React.useMemo<CSSMotionProps>(
|
||||
() => ({
|
||||
...initCollapseMotion(rootPrefixCls),
|
||||
motionAppear: false,
|
||||
leavedClassName: `${prefixCls}-content-hidden`,
|
||||
}),
|
||||
[rootPrefixCls, prefixCls],
|
||||
);
|
||||
|
||||
const items = React.useMemo<React.ReactNode[] | null>(() => {
|
||||
if (children) {
|
||||
return toArray(children).map((child, index) => {
|
||||
const childProps = (
|
||||
child as React.ReactElement<{
|
||||
disabled?: boolean;
|
||||
collapsible?: CollapsibleType;
|
||||
}>
|
||||
).props;
|
||||
|
||||
if (childProps?.disabled) {
|
||||
const key = child.key ?? String(index);
|
||||
const mergedChildProps: Omit<CollapseProps, 'items'> & { key: React.Key } = {
|
||||
...omit(child.props as any, ['disabled']),
|
||||
key,
|
||||
collapsible: childProps.collapsible ?? 'disabled',
|
||||
};
|
||||
return cloneElement(child, mergedChildProps);
|
||||
}
|
||||
return child;
|
||||
});
|
||||
if (!children) {
|
||||
return null;
|
||||
}
|
||||
return null;
|
||||
return toArray(children).map((child, index) => {
|
||||
const childProps = (
|
||||
child as React.ReactElement<{ disabled?: boolean; collapsible?: CollapsibleType }>
|
||||
).props;
|
||||
if (childProps?.disabled) {
|
||||
const key = child.key ?? String(index);
|
||||
const mergedChildProps: Omit<CollapseProps, 'items'> & { key: React.Key } = {
|
||||
...omit(child.props as any, ['disabled']),
|
||||
key,
|
||||
collapsible: childProps.collapsible ?? 'disabled',
|
||||
};
|
||||
return cloneElement(child, mergedChildProps);
|
||||
}
|
||||
return child;
|
||||
});
|
||||
}, [children]);
|
||||
|
||||
return wrapCSSVar(
|
||||
|
|
|
@ -254,6 +254,7 @@ const floatButtonGroupStyle: GenerateStyle<FloatButtonToken, CSSObject> = (token
|
|||
borderEndEndRadius: borderRadiusLG,
|
||||
},
|
||||
'&:not(:last-child)': {
|
||||
borderBottom: 'none',
|
||||
borderInlineEnd: `${unit(token.lineWidth)} ${token.lineType} ${token.colorSplit}`,
|
||||
},
|
||||
},
|
||||
|
|
|
@ -63,8 +63,8 @@ const App: React.FC = () => {
|
|||
},
|
||||
) => (
|
||||
<Space size={12} className="toolbar-wrapper">
|
||||
<LeftOutlined onClick={() => onActive?.(-1)} />
|
||||
<RightOutlined onClick={() => onActive?.(1)} />
|
||||
<LeftOutlined disabled={current === 0} onClick={() => onActive?.(-1)} />
|
||||
<RightOutlined disabled={current === imageList.length - 1} onClick={() => onActive?.(1)} />
|
||||
<DownloadOutlined onClick={onDownload} />
|
||||
<SwapOutlined rotate={90} onClick={onFlipY} />
|
||||
<SwapOutlined onClick={onFlipX} />
|
||||
|
|
|
@ -161,16 +161,21 @@ const SplitBar: React.FC<SplitBarProps> = (props) => {
|
|||
setStartPos(null);
|
||||
};
|
||||
|
||||
window.addEventListener('touchmove', handleTouchMove);
|
||||
window.addEventListener('touchend', handleTouchEnd);
|
||||
window.addEventListener('mousemove', onMouseMove);
|
||||
window.addEventListener('mouseup', onMouseUp);
|
||||
const eventHandlerMap: Partial<Record<keyof WindowEventMap, EventListener>> = {
|
||||
mousemove: onMouseMove as EventListener,
|
||||
mouseup: onMouseUp,
|
||||
touchmove: handleTouchMove as EventListener,
|
||||
touchend: handleTouchEnd,
|
||||
};
|
||||
|
||||
for (const [event, handler] of Object.entries(eventHandlerMap)) {
|
||||
window.addEventListener(event, handler);
|
||||
}
|
||||
|
||||
return () => {
|
||||
window.removeEventListener('touchmove', handleTouchMove);
|
||||
window.removeEventListener('touchend', handleTouchEnd);
|
||||
window.removeEventListener('mousemove', onMouseMove);
|
||||
window.removeEventListener('mouseup', onMouseUp);
|
||||
for (const [event, handler] of Object.entries(eventHandlerMap)) {
|
||||
window.removeEventListener(event, handler);
|
||||
}
|
||||
};
|
||||
}
|
||||
}, [startPos]);
|
||||
|
|
|
@ -219,4 +219,20 @@ describe('Tag', () => {
|
|||
);
|
||||
expect(container.querySelector('.ant-tag-close-icon')?.textContent).toEqual('X');
|
||||
});
|
||||
|
||||
it('should not override aria-label in custom closeIcon', () => {
|
||||
const { getByRole } = render(
|
||||
<Tag
|
||||
closable
|
||||
closeIcon={
|
||||
<button type="button" aria-label="Remove This Filter">
|
||||
x
|
||||
</button>
|
||||
}
|
||||
>
|
||||
Filter
|
||||
</Tag>,
|
||||
);
|
||||
expect(getByRole('button')).toHaveAttribute('aria-label', 'Remove This Filter');
|
||||
});
|
||||
});
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue