mirror of
https://github.com/ant-design/ant-design.git
synced 2024-11-25 11:40:04 +08:00
commit
e6d58f30df
@ -110,7 +110,7 @@ timeline: true
|
||||
- 💄 修复 RTL 下 Input.Search 边框样式问题。[#37980](https://github.com/ant-design/ant-design/pull/37980) [@foryuki](https://github.com/foryuki)
|
||||
- 🐞 修复 AutoComplete 会报未使用的废弃属性 `dropdownClassName` 的问题。[#37974](https://github.com/ant-design/ant-design/pull/37974) [@heiyu4585](https://github.com/heiyu4585)
|
||||
- 🐞 修复 Typography 省略算法在计算一些元素 fontSize 时为空字符串的情况[#37928](https://github.com/ant-design/ant-design/pull/37928) [@zheeeng](https://github.com/zheeeng)
|
||||
- 🐞 Fix Tabs 添加按钮在某些边界情况下无法展示的问题。[#37937](https://github.com/ant-design/ant-design/pull/37937)
|
||||
- 🐞 修复 Tabs 添加按钮在某些边界情况下无法展示的问题。[#37937](https://github.com/ant-design/ant-design/pull/37937)
|
||||
- 🐞 修复 RangePicker 在某些情况下面板会闪烁的问题。[#439](https://github.com/react-component/picker/pull/439)
|
||||
- 🛠 重构 Spin 为 Function Component。[#37969](https://github.com/ant-design/ant-design/pull/37969) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
- 🛠 重构 Statistic.Countdown 为 Function Component.[#37938](https://github.com/ant-design/ant-design/pull/37938) [@li-jia-nan](https://github.com/li-jia-nan)
|
||||
@ -1463,7 +1463,7 @@ timeline: true
|
||||
- Dropdown
|
||||
- 🐞 修复 Dropdown 带图标的菜单项禁用样式丢失的问题。[#29433](https://github.com/ant-design/ant-design/pull/29433)
|
||||
- 🐞 修复 Dropdown 内 Menu 不支持 `expandIcon` 的问题。[#29338](https://github.com/ant-design/ant-design/pull/29338)
|
||||
- 🐞 Fix 在本地开发时会报 tree-shaking 警告信息的问题。[#29378](https://github.com/ant-design/ant-design/pull/29378)
|
||||
- 🐞 修复在本地开发时会报 tree-shaking 警告信息的问题。[#29378](https://github.com/ant-design/ant-design/pull/29378)
|
||||
- 🇰🇷 修复 TimePicker 本地化。[#29540](https://github.com/ant-design/ant-design/pull/29540)
|
||||
- TypeScript
|
||||
- 🤖 修复 Form.Item 的泛型定义问题。[#29397](https://github.com/ant-design/ant-design/pull/29397) [@mumiao](https://github.com/mumiao)
|
||||
@ -1860,7 +1860,7 @@ timeline: true
|
||||
- Modal
|
||||
- 🆕 `modal.update()` 支持函数式更新。[#27163](https://github.com/ant-design/ant-design/pull/27163) [@Mongkii](https://github.com/Mongkii)
|
||||
- 🆕 Modal method 增加 `bodyStyle` 属性。[#27292](https://github.com/ant-design/ant-design/pull/27292)
|
||||
- 🐞 Fix Modal missing `modalRender` prop。[#27272](https://github.com/ant-design/ant-design/pull/27272) [@jieny](https://github.com/jieny)
|
||||
- 🐞 修复 Modal 丢失 `modalRender` 属性 TS 定义。[#27272](https://github.com/ant-design/ant-design/pull/27272) [@jieny](https://github.com/jieny)
|
||||
- 🐞 `Modal.config` 中设置的 `rootPrefixCls` 可以对 `title` 和 `content` 下使用的 antd 组件生效。[#27376](https://github.com/ant-design/ant-design/pull/27376) [@Chersquwn](https://github.com/Chersquwn)
|
||||
- Input
|
||||
- 🆕 Input.Textarea 支持 `size` 属性。[#27110](https://github.com/ant-design/ant-design/pull/27110)
|
||||
|
@ -2,9 +2,11 @@ import classNames from 'classnames';
|
||||
import toArray from 'rc-util/lib/Children/toArray';
|
||||
import * as React from 'react';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import type { DropdownProps } from '../dropdown';
|
||||
import Menu from '../menu';
|
||||
import { cloneElement } from '../_util/reactNode';
|
||||
import warning from '../_util/warning';
|
||||
import type { BreadcrumbItemProps } from './BreadcrumbItem';
|
||||
import BreadcrumbItem from './BreadcrumbItem';
|
||||
import BreadcrumbSeparator from './BreadcrumbSeparator';
|
||||
|
||||
@ -52,7 +54,7 @@ function defaultItemRender(route: Route, params: any, routes: Route[], paths: st
|
||||
|
||||
const getPath = (path: string, params: any) => {
|
||||
path = (path || '').replace(/^\//, '');
|
||||
Object.keys(params).forEach(key => {
|
||||
Object.keys(params).forEach((key) => {
|
||||
path = path.replace(`:${key}`, params[key]);
|
||||
});
|
||||
return path;
|
||||
@ -92,18 +94,18 @@ const Breadcrumb: BreadcrumbInterface = ({
|
||||
if (routes && routes.length > 0) {
|
||||
// generated by route
|
||||
const paths: string[] = [];
|
||||
crumbs = routes.map(route => {
|
||||
crumbs = routes.map((route) => {
|
||||
const path = getPath(route.path, params);
|
||||
|
||||
if (path) {
|
||||
paths.push(path);
|
||||
}
|
||||
// generated overlay by route.children
|
||||
let overlay;
|
||||
let overlay: DropdownProps['overlay'];
|
||||
if (route.children && route.children.length) {
|
||||
overlay = (
|
||||
<Menu
|
||||
items={route.children.map(child => ({
|
||||
items={route.children.map((child) => ({
|
||||
key: child.path || child.breadcrumbName,
|
||||
label: itemRender(child, params, routes, addChildPath(paths, child.path, params)),
|
||||
}))}
|
||||
@ -111,8 +113,14 @@ const Breadcrumb: BreadcrumbInterface = ({
|
||||
);
|
||||
}
|
||||
|
||||
const itemProps: BreadcrumbItemProps = { separator };
|
||||
|
||||
if (overlay) {
|
||||
itemProps.overlay = overlay;
|
||||
}
|
||||
|
||||
return (
|
||||
<BreadcrumbItem overlay={overlay} separator={separator} key={path || route.breadcrumbName}>
|
||||
<BreadcrumbItem {...itemProps} key={path || route.breadcrumbName}>
|
||||
{itemRender(route, params, routes, paths)}
|
||||
</BreadcrumbItem>
|
||||
);
|
||||
|
@ -1,6 +1,5 @@
|
||||
import DownOutlined from '@ant-design/icons/DownOutlined';
|
||||
import * as React from 'react';
|
||||
|
||||
import warning from '../_util/warning';
|
||||
import { ConfigContext } from '../config-provider';
|
||||
import type { DropdownProps } from '../dropdown/dropdown';
|
||||
@ -23,7 +22,7 @@ export interface BreadcrumbItemProps {
|
||||
interface BreadcrumbItemInterface extends React.FC<BreadcrumbItemProps> {
|
||||
__ANT_BREADCRUMB_ITEM: boolean;
|
||||
}
|
||||
const BreadcrumbItem: BreadcrumbItemInterface = props => {
|
||||
const BreadcrumbItem: BreadcrumbItemInterface = (props) => {
|
||||
const {
|
||||
prefixCls: customizePrefixCls,
|
||||
separator = '/',
|
||||
|
@ -181,4 +181,24 @@ describe('Breadcrumb', () => {
|
||||
expect(container.querySelectorAll('.ant-breadcrumb-link')[1].textContent).toBe('0');
|
||||
expect(container.firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should console Error when `overlay` in props', () => {
|
||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
render(
|
||||
<Breadcrumb>
|
||||
<Breadcrumb.Item overlay={<div>test</div>} />
|
||||
</Breadcrumb>,
|
||||
);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Breadcrumb.Item] `overlay` is deprecated. Please use `menu` instead.',
|
||||
);
|
||||
errSpy.mockRestore();
|
||||
});
|
||||
|
||||
it('should not console Error when `overlay` not in props', () => {
|
||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
render(<Breadcrumb routes={[{ path: '/', breadcrumbName: 'Test' }]} />);
|
||||
expect(errSpy).not.toHaveBeenCalled();
|
||||
errSpy.mockRestore();
|
||||
});
|
||||
});
|
||||
|
@ -131,7 +131,7 @@ describe('DropdownButton', () => {
|
||||
'ant-btn',
|
||||
);
|
||||
});
|
||||
it('should console Error then `overlay` in props', () => {
|
||||
it('should console Error when `overlay` in props', () => {
|
||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
render(<DropdownButton overlay={<div>test</div>} />);
|
||||
expect(errSpy).toHaveBeenCalledWith(
|
||||
@ -139,7 +139,7 @@ describe('DropdownButton', () => {
|
||||
);
|
||||
errSpy.mockRestore();
|
||||
});
|
||||
it('should not console Error then `overlay` not in props', () => {
|
||||
it('should not console Error when `overlay` not in props', () => {
|
||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
render(<DropdownButton />);
|
||||
expect(errSpy).not.toHaveBeenCalled();
|
||||
|
@ -165,7 +165,7 @@ function InternalFormItem<Values = any>(props: FormItemProps<Values>): React.Rea
|
||||
// >>>>> Collect noStyle Field error to the top FormItem
|
||||
const onSubItemMetaChange = (subMeta: Meta & { destroy: boolean }, uniqueKeys: React.Key[]) => {
|
||||
// Only `noStyle` sub item will trigger
|
||||
setSubFieldErrors(prevSubFieldErrors => {
|
||||
setSubFieldErrors((prevSubFieldErrors) => {
|
||||
const clone = {
|
||||
...prevSubFieldErrors,
|
||||
};
|
||||
@ -191,7 +191,7 @@ function InternalFormItem<Values = any>(props: FormItemProps<Values>): React.Rea
|
||||
const errorList: string[] = [...meta.errors];
|
||||
const warningList: string[] = [...meta.warnings];
|
||||
|
||||
Object.values(subFieldErrors).forEach(subFieldError => {
|
||||
Object.values(subFieldErrors).forEach((subFieldError) => {
|
||||
errorList.push(...(subFieldError.errors || []));
|
||||
warningList.push(...(subFieldError.warnings || []));
|
||||
});
|
||||
@ -262,7 +262,7 @@ function InternalFormItem<Values = any>(props: FormItemProps<Values>): React.Rea
|
||||
? required
|
||||
: !!(
|
||||
rules &&
|
||||
rules.some(rule => {
|
||||
rules.some((rule) => {
|
||||
if (rule && typeof rule === 'object' && rule.required && !rule.warningOnly) {
|
||||
return true;
|
||||
}
|
||||
@ -284,13 +284,13 @@ function InternalFormItem<Values = any>(props: FormItemProps<Values>): React.Rea
|
||||
warning(
|
||||
!(shouldUpdate && dependencies),
|
||||
'Form.Item',
|
||||
"`shouldUpdate` and `dependencies` shouldn't be used together. See https://u.ant.design/#form-deps.",
|
||||
"`shouldUpdate` and `dependencies` shouldn't be used together. See https://u.ant.design/form-deps.",
|
||||
);
|
||||
if (Array.isArray(children) && hasName) {
|
||||
warning(
|
||||
false,
|
||||
'Form.Item',
|
||||
'A `Form.Item` with a `name` prop must have a single child element. For information on how to render more complex form items, see https://u.ant.design/#complex-form-item.',
|
||||
'A `Form.Item` with a `name` prop must have a single child element. For information on how to render more complex form items, see https://u.ant.design/complex-form-item.',
|
||||
);
|
||||
childNode = children;
|
||||
} else if (isRenderProps && (!(shouldUpdate || dependencies) || hasName)) {
|
||||
@ -351,7 +351,7 @@ function InternalFormItem<Values = any>(props: FormItemProps<Values>): React.Rea
|
||||
...toArray(mergedValidateTrigger),
|
||||
]);
|
||||
|
||||
triggers.forEach(eventName => {
|
||||
triggers.forEach((eventName) => {
|
||||
childProps[eventName] = (...args: any[]) => {
|
||||
mergedControl[eventName]?.(...args);
|
||||
children.props[eventName]?.(...args);
|
||||
|
@ -212,7 +212,7 @@ describe('Form', () => {
|
||||
</Form>,
|
||||
);
|
||||
expect(errorSpy).toHaveBeenCalledWith(
|
||||
"Warning: [antd: Form.Item] `shouldUpdate` and `dependencies` shouldn't be used together. See https://u.ant.design/#form-deps.",
|
||||
"Warning: [antd: Form.Item] `shouldUpdate` and `dependencies` shouldn't be used together. See https://u.ant.design/form-deps.",
|
||||
);
|
||||
});
|
||||
|
||||
@ -239,7 +239,7 @@ describe('Form', () => {
|
||||
</Form>,
|
||||
);
|
||||
expect(errorSpy).toHaveBeenCalledWith(
|
||||
'Warning: [antd: Form.Item] A `Form.Item` with a `name` prop must have a single child element. For information on how to render more complex form items, see https://u.ant.design/#complex-form-item.',
|
||||
'Warning: [antd: Form.Item] A `Form.Item` with a `name` prop must have a single child element. For information on how to render more complex form items, see https://u.ant.design/complex-form-item.',
|
||||
);
|
||||
});
|
||||
|
||||
@ -1494,7 +1494,7 @@ describe('Form', () => {
|
||||
it('item customize margin', async () => {
|
||||
const computeSpy = jest
|
||||
.spyOn(window, 'getComputedStyle')
|
||||
.mockImplementation(() => ({ marginBottom: 24 } as unknown as CSSStyleDeclaration));
|
||||
.mockImplementation(() => ({ marginBottom: 24 }) as unknown as CSSStyleDeclaration);
|
||||
|
||||
const { container } = render(
|
||||
<Form>
|
||||
|
@ -62,7 +62,7 @@ const Search = React.forwardRef<InputRef, SearchProps>((props, ref) => {
|
||||
}
|
||||
};
|
||||
|
||||
const onMouseDown: React.MouseEventHandler<HTMLElement> = e => {
|
||||
const onMouseDown: React.MouseEventHandler<HTMLElement> = (e) => {
|
||||
if (document.activeElement === inputRef.current?.input) {
|
||||
e.preventDefault();
|
||||
}
|
||||
@ -75,7 +75,7 @@ const Search = React.forwardRef<InputRef, SearchProps>((props, ref) => {
|
||||
};
|
||||
|
||||
const onPressEnter = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (composedRef.current) {
|
||||
if (composedRef.current || loading) {
|
||||
return;
|
||||
}
|
||||
onSearch(e);
|
||||
@ -140,12 +140,12 @@ const Search = React.forwardRef<InputRef, SearchProps>((props, ref) => {
|
||||
className,
|
||||
);
|
||||
|
||||
const handleOnCompositionStart: React.CompositionEventHandler<HTMLInputElement> = e => {
|
||||
const handleOnCompositionStart: React.CompositionEventHandler<HTMLInputElement> = (e) => {
|
||||
composedRef.current = true;
|
||||
onCompositionStart?.(e);
|
||||
};
|
||||
|
||||
const handleOnCompositionEnd: React.CompositionEventHandler<HTMLInputElement> = e => {
|
||||
const handleOnCompositionEnd: React.CompositionEventHandler<HTMLInputElement> = (e) => {
|
||||
composedRef.current = false;
|
||||
onCompositionEnd?.(e);
|
||||
};
|
||||
|
@ -161,6 +161,13 @@ describe('Input.Search', () => {
|
||||
expect(asFragmentWithEnterButton().firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
it('should not trigger onSearch when press enter while loading', () => {
|
||||
const onSearch = jest.fn();
|
||||
const { container } = render(<Search loading onSearch={onSearch} />);
|
||||
fireEvent.keyDown(container.querySelector('input')!, { key: 'Enter', keyCode: 13 });
|
||||
expect(onSearch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('should support addonAfter and suffix for loading', () => {
|
||||
const { asFragment } = render(<Search loading suffix="suffix" addonAfter="addonAfter" />);
|
||||
const { asFragment: asFragmentWithEnterButton } = render(
|
||||
|
@ -420,7 +420,7 @@ exports[`renders ./components/layout/demo/fixed.tsx extend context correctly 1`]
|
||||
>
|
||||
<header
|
||||
class="ant-layout-header"
|
||||
style="position:fixed;z-index:1;width:100%"
|
||||
style="position:sticky;top:0;z-index:1;width:100%"
|
||||
>
|
||||
<div
|
||||
class="logo"
|
||||
|
@ -287,7 +287,7 @@ exports[`renders ./components/layout/demo/fixed.tsx correctly 1`] = `
|
||||
>
|
||||
<header
|
||||
class="ant-layout-header"
|
||||
style="position:fixed;z-index:1;width:100%"
|
||||
style="position:sticky;top:0;z-index:1;width:100%"
|
||||
>
|
||||
<div
|
||||
class="logo"
|
||||
|
@ -5,7 +5,7 @@ const { Header, Content, Footer } = Layout;
|
||||
|
||||
const App: React.FC = () => (
|
||||
<Layout>
|
||||
<Header style={{ position: 'fixed', zIndex: 1, width: '100%' }}>
|
||||
<Header style={{ position: 'sticky', top: 0, zIndex: 1, width: '100%' }}>
|
||||
<div className="logo" />
|
||||
<Menu
|
||||
theme="dark"
|
||||
|
@ -11,7 +11,9 @@ import warning from '../_util/warning';
|
||||
import { renderCloseIcon, renderFooter } from './PurePanel';
|
||||
import useStyle from './style';
|
||||
|
||||
let mousePosition: { x: number; y: number } | null;
|
||||
type MousePosition = { x: number; y: number } | null;
|
||||
|
||||
let mousePosition: MousePosition;
|
||||
|
||||
// ref: https://github.com/ant-design/ant-design/issues/15795
|
||||
const getClickPosition = (e: MouseEvent) => {
|
||||
@ -82,6 +84,7 @@ export interface ModalProps {
|
||||
modalRender?: (node: React.ReactNode) => React.ReactNode;
|
||||
focusTriggerAfterClose?: boolean;
|
||||
children?: React.ReactNode;
|
||||
mousePosition?: MousePosition;
|
||||
|
||||
// Legacy
|
||||
/** @deprecated Please use `open` instead. */
|
||||
@ -137,7 +140,7 @@ export interface ModalLocale {
|
||||
justOkText: string;
|
||||
}
|
||||
|
||||
const Modal: React.FC<ModalProps> = props => {
|
||||
const Modal: React.FC<ModalProps> = (props) => {
|
||||
const {
|
||||
getPopupContainer: getContextPopupContainer,
|
||||
getPrefixCls,
|
||||
@ -208,7 +211,7 @@ const Modal: React.FC<ModalProps> = props => {
|
||||
onCancel: handleCancel,
|
||||
})}
|
||||
visible={open ?? visible}
|
||||
mousePosition={mousePosition}
|
||||
mousePosition={restProps.mousePosition ?? mousePosition}
|
||||
onClose={handleCancel}
|
||||
closeIcon={renderCloseIcon(prefixCls, closeIcon)}
|
||||
focusTriggerAfterClose={focusTriggerAfterClose}
|
||||
|
@ -92,6 +92,25 @@ describe('Modal', () => {
|
||||
).toBeTruthy();
|
||||
});
|
||||
|
||||
it('custom mouse position', () => {
|
||||
const Demo = () => {
|
||||
const containerRef = React.useRef<HTMLDivElement>(null);
|
||||
return (
|
||||
<div ref={containerRef}>
|
||||
<Modal
|
||||
open
|
||||
getContainer={() => containerRef.current!}
|
||||
mousePosition={{ x: 100, y: 100 }}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
const { container } = render(<Demo />);
|
||||
expect(
|
||||
(container.querySelectorAll('.ant-modal')[0] as HTMLDivElement).style.transformOrigin,
|
||||
).toBe('100px 100px');
|
||||
});
|
||||
|
||||
it('deprecated warning', () => {
|
||||
resetWarned();
|
||||
const errSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
|
||||
|
@ -104,6 +104,17 @@ exports[`renders ./components/modal/demo/confirm-router.tsx extend context corre
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/custom-mouse-position.tsx extend context correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Open Modal
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/dark.tsx extend context correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
|
@ -104,6 +104,17 @@ exports[`renders ./components/modal/demo/confirm-router.tsx correctly 1`] = `
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/custom-mouse-position.tsx correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
type="button"
|
||||
>
|
||||
<span>
|
||||
Open Modal
|
||||
</span>
|
||||
</button>
|
||||
`;
|
||||
|
||||
exports[`renders ./components/modal/demo/dark.tsx correctly 1`] = `
|
||||
<button
|
||||
class="ant-btn ant-btn-primary"
|
||||
|
7
components/modal/demo/custom-mouse-position.md
Normal file
7
components/modal/demo/custom-mouse-position.md
Normal file
@ -0,0 +1,7 @@
|
||||
## zh-CN
|
||||
|
||||
通过 `mousePosition` 控制弹框动画原点.
|
||||
|
||||
## en-US
|
||||
|
||||
pass `mousePosition` to control modal's animation origin position
|
39
components/modal/demo/custom-mouse-position.tsx
Normal file
39
components/modal/demo/custom-mouse-position.tsx
Normal file
@ -0,0 +1,39 @@
|
||||
import { Button, Modal } from 'antd';
|
||||
import React, { useState } from 'react';
|
||||
|
||||
const App: React.FC = () => {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
|
||||
const showModal = () => {
|
||||
setIsModalOpen(true);
|
||||
};
|
||||
|
||||
const handleOk = () => {
|
||||
setIsModalOpen(false);
|
||||
};
|
||||
|
||||
const handleCancel = () => {
|
||||
setIsModalOpen(false);
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Button type="primary" onClick={showModal}>
|
||||
Open Modal
|
||||
</Button>
|
||||
<Modal
|
||||
title="Basic Modal"
|
||||
open={isModalOpen}
|
||||
onOk={handleOk}
|
||||
onCancel={handleCancel}
|
||||
mousePosition={{ x: 300, y: 300 }}
|
||||
>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
</Modal>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
export default App;
|
@ -29,41 +29,42 @@ When requiring users to interact with the application, but without jumping to a
|
||||
<code src="./demo/hooks.tsx">Use hooks to get context</code>
|
||||
<code src="./demo/modal-render.tsx">Custom modal content render</code>
|
||||
<code src="./demo/width.tsx">To customize the width of modal</code>
|
||||
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
|
||||
<code src="./demo/render-panel.tsx" debug>\_InternalPanelDoNotUseOrYouWillBeFired</code>
|
||||
<code src="./demo/custom-mouse-position.tsx" debug>控制弹框动画原点</code>
|
||||
|
||||
## API
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| afterClose | Specify a function that will be called when modal is closed completely | function | - | |
|
||||
| bodyStyle | Body style for modal body element. Such as height, padding etc | CSSProperties | | |
|
||||
| cancelButtonProps | The cancel button props | [ButtonProps](/components/button/#API) | - | |
|
||||
| cancelText | Text of the Cancel button | ReactNode | `Cancel` | |
|
||||
| centered | Centered Modal | boolean | false | |
|
||||
| closable | Whether a close (x) button is visible on top right of the modal dialog or not | boolean | true | |
|
||||
| closeIcon | Custom close icon | ReactNode | <CloseOutlined /> | |
|
||||
| confirmLoading | Whether to apply loading visual effect for OK button or not | boolean | false | |
|
||||
| destroyOnClose | Whether to unmount child components on onClose | boolean | false | |
|
||||
| focusTriggerAfterClose | Whether need to focus trigger element after dialog is closed | boolean | true | 4.9.0 |
|
||||
| footer | Footer content, set as `footer={null}` when you don't need default buttons | ReactNode | (OK and Cancel buttons) | |
|
||||
| forceRender | Force render Modal | boolean | false | |
|
||||
| getContainer | The mounted node for Modal but still display at fullscreen | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| keyboard | Whether support press esc to close | boolean | true | |
|
||||
| mask | Whether show mask or not | boolean | true | |
|
||||
| maskClosable | Whether to close the modal dialog when the mask (area outside the modal) is clicked | boolean | true | |
|
||||
| maskStyle | Style for modal's mask element | CSSProperties | | |
|
||||
| modalRender | Custom modal content render | (node: ReactNode) => ReactNode | - | 4.7.0 |
|
||||
| okButtonProps | The ok button props | [ButtonProps](/components/button/#API) | - | |
|
||||
| okText | Text of the OK button | ReactNode | `OK` | |
|
||||
| okType | Button `type` of the OK button | string | `primary` | |
|
||||
| style | Style of floating layer, typically used at least for adjusting the position | CSSProperties | - | |
|
||||
| title | The modal dialog's title | ReactNode | - | |
|
||||
| open | Whether the modal dialog is visible or not | boolean | false | |
|
||||
| width | Width of the modal dialog | string \| number | 520 | |
|
||||
| wrapClassName | The class name of the container of the modal dialog | string | - | |
|
||||
| zIndex | The `z-index` of the Modal | number | 1000 | |
|
||||
| onCancel | Specify a function that will be called when a user clicks mask, close button on top right or Cancel button | function(e) | - | |
|
||||
| onOk | Specify a function that will be called when a user clicks the OK button | function(e) | - | |
|
||||
| Property | Description | Type | Default | Version |
|
||||
| ---------------------- | ---------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | ----------------------- | ------- |
|
||||
| afterClose | Specify a function that will be called when modal is closed completely | function | - | |
|
||||
| bodyStyle | Body style for modal body element. Such as height, padding etc | CSSProperties | | |
|
||||
| cancelButtonProps | The cancel button props | [ButtonProps](/components/button/#API) | - | |
|
||||
| cancelText | Text of the Cancel button | ReactNode | `Cancel` | |
|
||||
| centered | Centered Modal | boolean | false | |
|
||||
| closable | Whether a close (x) button is visible on top right of the modal dialog or not | boolean | true | |
|
||||
| closeIcon | Custom close icon | ReactNode | <CloseOutlined /> | |
|
||||
| confirmLoading | Whether to apply loading visual effect for OK button or not | boolean | false | |
|
||||
| destroyOnClose | Whether to unmount child components on onClose | boolean | false | |
|
||||
| focusTriggerAfterClose | Whether need to focus trigger element after dialog is closed | boolean | true | 4.9.0 |
|
||||
| footer | Footer content, set as `footer={null}` when you don't need default buttons | ReactNode | (OK and Cancel buttons) | |
|
||||
| forceRender | Force render Modal | boolean | false | |
|
||||
| getContainer | The mounted node for Modal but still display at fullscreen | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| keyboard | Whether support press esc to close | boolean | true | |
|
||||
| mask | Whether show mask or not | boolean | true | |
|
||||
| maskClosable | Whether to close the modal dialog when the mask (area outside the modal) is clicked | boolean | true | |
|
||||
| maskStyle | Style for modal's mask element | CSSProperties | | |
|
||||
| modalRender | Custom modal content render | (node: ReactNode) => ReactNode | - | 4.7.0 |
|
||||
| okButtonProps | The ok button props | [ButtonProps](/components/button/#API) | - | |
|
||||
| okText | Text of the OK button | ReactNode | `OK` | |
|
||||
| okType | Button `type` of the OK button | string | `primary` | |
|
||||
| style | Style of floating layer, typically used at least for adjusting the position | CSSProperties | - | |
|
||||
| title | The modal dialog's title | ReactNode | - | |
|
||||
| open | Whether the modal dialog is visible or not | boolean | false | |
|
||||
| width | Width of the modal dialog | string \| number | 520 | |
|
||||
| wrapClassName | The class name of the container of the modal dialog | string | - | |
|
||||
| zIndex | The `z-index` of the Modal | number | 1000 | |
|
||||
| onCancel | Specify a function that will be called when a user clicks mask, close button on top right or Cancel button | function(e) | - | |
|
||||
| onOk | Specify a function that will be called when a user clicks the OK button | function(e) | - | |
|
||||
|
||||
#### Note
|
||||
|
||||
@ -83,34 +84,34 @@ There are five ways to display the information based on the content's nature:
|
||||
|
||||
The items listed above are all functions, expecting a settings object as parameter. The properties of the object are follows:
|
||||
|
||||
| Property | Description | Type | Default | Version |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| afterClose | Specify a function that will be called when modal is closed completely | function | - | 4.9.0 |
|
||||
| autoFocusButton | Specify which button to autofocus | null \| `ok` \| `cancel` | `ok` | |
|
||||
| bodyStyle | Body style for modal body element. Such as height, padding etc | CSSProperties | | 4.8.0 |
|
||||
| cancelButtonProps | The cancel button props | [ButtonProps](/components/button/#API) | - | |
|
||||
| cancelText | Text of the Cancel button with Modal.confirm | string | `Cancel` | |
|
||||
| centered | Centered Modal | boolean | false | |
|
||||
| className | The className of container | string | - | |
|
||||
| closable | Whether a close (x) button is visible on top right of the confirm dialog or not | boolean | false | 4.9.0 |
|
||||
| closeIcon | Custom close icon | ReactNode | undefined | 4.9.0 |
|
||||
| content | Content | ReactNode | - | |
|
||||
| getContainer | Return the mount node for Modal | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| icon | Custom icon | ReactNode | <QuestionCircle /> | |
|
||||
| keyboard | Whether support press esc to close | boolean | true | |
|
||||
| mask | Whether show mask or not. | boolean | true | |
|
||||
| maskClosable | Whether to close the modal dialog when the mask (area outside the modal) is clicked | boolean | false | |
|
||||
| maskStyle | Style for modal's mask element | object | {} | |
|
||||
| okButtonProps | The ok button props | [ButtonProps](/components/button/#API) | - | |
|
||||
| okText | Text of the OK button | string | `OK` | |
|
||||
| okType | Button `type` of the OK button | string | `primary` | |
|
||||
| style | Style of floating layer, typically used at least for adjusting the position | CSSProperties | - | |
|
||||
| title | Title | ReactNode | - | |
|
||||
| width | Width of the modal dialog | string \| number | 416 | |
|
||||
| wrapClassName | The class name of the container of the modal dialog | string | - | 4.18.0 |
|
||||
| zIndex | The `z-index` of the Modal | number | 1000 | |
|
||||
| onCancel | Specify a function that will be called when the user clicks the Cancel button. The parameter of this function is a function whose execution should include closing the dialog. If the function does not take any parameter (`!onCancel.length`) then modal dialog will be closed unless returned value is `true` (`!!onCancel()`). You can also just return a promise and when the promise is resolved, the modal dialog will also be closed | function(close) | - | |
|
||||
| onOk | Specify a function that will be called when the user clicks the OK button. The parameter of this function is a function whose execution should include closing the dialog. If the function does not take any parameter (`!onOk.length`) then modal dialog will be closed unless returned value is `true` (`!!onOk()`). You can also just return a promise and when the promise is resolved, the modal dialog will also be closed | function(close) | - | |
|
||||
| Property | Description | Type | Default | Version |
|
||||
| ----------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------ | --------------------- | ------- |
|
||||
| afterClose | Specify a function that will be called when modal is closed completely | function | - | 4.9.0 |
|
||||
| autoFocusButton | Specify which button to autofocus | null \| `ok` \| `cancel` | `ok` | |
|
||||
| bodyStyle | Body style for modal body element. Such as height, padding etc | CSSProperties | | 4.8.0 |
|
||||
| cancelButtonProps | The cancel button props | [ButtonProps](/components/button/#API) | - | |
|
||||
| cancelText | Text of the Cancel button with Modal.confirm | string | `Cancel` | |
|
||||
| centered | Centered Modal | boolean | false | |
|
||||
| className | The className of container | string | - | |
|
||||
| closable | Whether a close (x) button is visible on top right of the confirm dialog or not | boolean | false | 4.9.0 |
|
||||
| closeIcon | Custom close icon | ReactNode | undefined | 4.9.0 |
|
||||
| content | Content | ReactNode | - | |
|
||||
| getContainer | Return the mount node for Modal | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| icon | Custom icon | ReactNode | <QuestionCircle /> | |
|
||||
| keyboard | Whether support press esc to close | boolean | true | |
|
||||
| mask | Whether show mask or not. | boolean | true | |
|
||||
| maskClosable | Whether to close the modal dialog when the mask (area outside the modal) is clicked | boolean | false | |
|
||||
| maskStyle | Style for modal's mask element | object | {} | |
|
||||
| okButtonProps | The ok button props | [ButtonProps](/components/button/#API) | - | |
|
||||
| okText | Text of the OK button | string | `OK` | |
|
||||
| okType | Button `type` of the OK button | string | `primary` | |
|
||||
| style | Style of floating layer, typically used at least for adjusting the position | CSSProperties | - | |
|
||||
| title | Title | ReactNode | - | |
|
||||
| width | Width of the modal dialog | string \| number | 416 | |
|
||||
| wrapClassName | The class name of the container of the modal dialog | string | - | 4.18.0 |
|
||||
| zIndex | The `z-index` of the Modal | number | 1000 | |
|
||||
| onCancel | Specify a function that will be called when the user clicks the Cancel button. The parameter of this function is a function whose execution should include closing the dialog. If the function does not take any parameter (`!onCancel.length`) then modal dialog will be closed unless returned value is `true` (`!!onCancel()`). You can also just return a promise and when the promise is resolved, the modal dialog will also be closed | function(close) | - | |
|
||||
| onOk | Specify a function that will be called when the user clicks the OK button. The parameter of this function is a function whose execution should include closing the dialog. If the function does not take any parameter (`!onOk.length`) then modal dialog will be closed unless returned value is `true` (`!!onOk()`). You can also just return a promise and when the promise is resolved, the modal dialog will also be closed | function(close) | - | |
|
||||
|
||||
All the `Modal.method`s will return a reference, and then we can update and close the modal dialog by the reference.
|
||||
|
||||
|
@ -32,41 +32,42 @@ demo:
|
||||
<code src="./demo/hooks.tsx">使用 hooks 获得上下文</code>
|
||||
<code src="./demo/modal-render.tsx">自定义渲染对话框</code>
|
||||
<code src="./demo/width.tsx">自定义模态的宽度</code>
|
||||
<code src="./demo/render-panel.tsx" debug>_InternalPanelDoNotUseOrYouWillBeFired</code>
|
||||
<code src="./demo/render-panel.tsx" debug>\_InternalPanelDoNotUseOrYouWillBeFired</code>
|
||||
<code src="./demo/custom-mouse-position.tsx" debug>control modal's animation origin position</code>
|
||||
|
||||
## API
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| afterClose | Modal 完全关闭后的回调 | function | - | |
|
||||
| bodyStyle | Modal body 样式 | CSSProperties | | |
|
||||
| cancelButtonProps | cancel 按钮 props | [ButtonProps](/components/button/#API) | - | |
|
||||
| cancelText | 取消按钮文字 | ReactNode | `取消` | |
|
||||
| centered | 垂直居中展示 Modal | boolean | false | |
|
||||
| closable | 是否显示右上角的关闭按钮 | boolean | true | |
|
||||
| closeIcon | 自定义关闭图标 | ReactNode | <CloseOutlined /> | |
|
||||
| confirmLoading | 确定按钮 loading | boolean | false | |
|
||||
| destroyOnClose | 关闭时销毁 Modal 里的子元素 | boolean | false | |
|
||||
| focusTriggerAfterClose | 对话框关闭后是否需要聚焦触发元素 | boolean | true | 4.9.0 |
|
||||
| footer | 底部内容,当不需要默认底部按钮时,可以设为 `footer={null}` | ReactNode | (确定取消按钮) | |
|
||||
| forceRender | 强制渲染 Modal | boolean | false | |
|
||||
| getContainer | 指定 Modal 挂载的节点,但依旧为全局展示,`false` 为挂载在当前位置 | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| keyboard | 是否支持键盘 esc 关闭 | boolean | true | |
|
||||
| mask | 是否展示遮罩 | boolean | true | |
|
||||
| maskClosable | 点击蒙层是否允许关闭 | boolean | true | |
|
||||
| maskStyle | 遮罩样式 | CSSProperties | | |
|
||||
| modalRender | 自定义渲染对话框 | (node: ReactNode) => ReactNode | - | 4.7.0 |
|
||||
| okButtonProps | ok 按钮 props | [ButtonProps](/components/button/#API) | - | |
|
||||
| okText | 确认按钮文字 | ReactNode | `确定` | |
|
||||
| okType | 确认按钮类型 | string | `primary` | |
|
||||
| style | 可用于设置浮层的样式,调整浮层位置等 | CSSProperties | - | |
|
||||
| title | 标题 | ReactNode | - | |
|
||||
| open | 对话框是否可见 | boolean | - | |
|
||||
| width | 宽度 | string \| number | 520 | |
|
||||
| wrapClassName | 对话框外层容器的类名 | string | - | |
|
||||
| zIndex | 设置 Modal 的 `z-index` | number | 1000 | |
|
||||
| onCancel | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | - | |
|
||||
| onOk | 点击确定回调 | function(e) | - | |
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| ---------------------- | ----------------------------------------------------------------- | ------------------------------------------------------ | -------------------- | ----- |
|
||||
| afterClose | Modal 完全关闭后的回调 | function | - | |
|
||||
| bodyStyle | Modal body 样式 | CSSProperties | | |
|
||||
| cancelButtonProps | cancel 按钮 props | [ButtonProps](/components/button/#API) | - | |
|
||||
| cancelText | 取消按钮文字 | ReactNode | `取消` | |
|
||||
| centered | 垂直居中展示 Modal | boolean | false | |
|
||||
| closable | 是否显示右上角的关闭按钮 | boolean | true | |
|
||||
| closeIcon | 自定义关闭图标 | ReactNode | <CloseOutlined /> | |
|
||||
| confirmLoading | 确定按钮 loading | boolean | false | |
|
||||
| destroyOnClose | 关闭时销毁 Modal 里的子元素 | boolean | false | |
|
||||
| focusTriggerAfterClose | 对话框关闭后是否需要聚焦触发元素 | boolean | true | 4.9.0 |
|
||||
| footer | 底部内容,当不需要默认底部按钮时,可以设为 `footer={null}` | ReactNode | (确定取消按钮) | |
|
||||
| forceRender | 强制渲染 Modal | boolean | false | |
|
||||
| getContainer | 指定 Modal 挂载的节点,但依旧为全局展示,`false` 为挂载在当前位置 | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| keyboard | 是否支持键盘 esc 关闭 | boolean | true | |
|
||||
| mask | 是否展示遮罩 | boolean | true | |
|
||||
| maskClosable | 点击蒙层是否允许关闭 | boolean | true | |
|
||||
| maskStyle | 遮罩样式 | CSSProperties | | |
|
||||
| modalRender | 自定义渲染对话框 | (node: ReactNode) => ReactNode | - | 4.7.0 |
|
||||
| okButtonProps | ok 按钮 props | [ButtonProps](/components/button/#API) | - | |
|
||||
| okText | 确认按钮文字 | ReactNode | `确定` | |
|
||||
| okType | 确认按钮类型 | string | `primary` | |
|
||||
| style | 可用于设置浮层的样式,调整浮层位置等 | CSSProperties | - | |
|
||||
| title | 标题 | ReactNode | - | |
|
||||
| open | 对话框是否可见 | boolean | - | |
|
||||
| width | 宽度 | string \| number | 520 | |
|
||||
| wrapClassName | 对话框外层容器的类名 | string | - | |
|
||||
| zIndex | 设置 Modal 的 `z-index` | number | 1000 | |
|
||||
| onCancel | 点击遮罩层或右上角叉或取消按钮的回调 | function(e) | - | |
|
||||
| onOk | 点击确定回调 | function(e) | - | |
|
||||
|
||||
#### 注意
|
||||
|
||||
@ -86,34 +87,34 @@ demo:
|
||||
|
||||
以上均为一个函数,参数为 object,具体属性如下:
|
||||
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| afterClose | Modal 完全关闭后的回调 | function | - | 4.9.0 |
|
||||
| autoFocusButton | 指定自动获得焦点的按钮 | null \| `ok` \| `cancel` | `ok` | |
|
||||
| bodyStyle | Modal body 样式 | CSSProperties | | 4.8.0 |
|
||||
| cancelButtonProps | cancel 按钮 props | [ButtonProps](/components/button/#API) | - | |
|
||||
| cancelText | 设置 Modal.confirm 取消按钮文字 | string | `取消` | |
|
||||
| centered | 垂直居中展示 Modal | boolean | false | |
|
||||
| className | 容器类名 | string | - | |
|
||||
| closable | 是否显示右上角的关闭按钮 | boolean | false | 4.9.0 |
|
||||
| closeIcon | 自定义关闭图标 | ReactNode | undefined | 4.9.0 |
|
||||
| content | 内容 | ReactNode | - | |
|
||||
| getContainer | 指定 Modal 挂载的 HTML 节点, false 为挂载在当前 dom | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| icon | 自定义图标 | ReactNode | <QuestionCircle /> | |
|
||||
| keyboard | 是否支持键盘 esc 关闭 | boolean | true | |
|
||||
| mask | 是否展示遮罩 | boolean | true | |
|
||||
| maskClosable | 点击蒙层是否允许关闭 | boolean | false | |
|
||||
| maskStyle | 遮罩样式 | object | {} | |
|
||||
| okButtonProps | ok 按钮 props | [ButtonProps](/components/button/#API) | - | |
|
||||
| okText | 确认按钮文字 | string | `确定` | |
|
||||
| okType | 确认按钮类型 | string | `primary` | |
|
||||
| style | 可用于设置浮层的样式,调整浮层位置等 | CSSProperties | - | |
|
||||
| title | 标题 | ReactNode | - | |
|
||||
| width | 宽度 | string \| number | 416 | |
|
||||
| wrapClassName | 对话框外层容器的类名 | string | - | 4.18.0 |
|
||||
| zIndex | 设置 Modal 的 `z-index` | number | 1000 | |
|
||||
| onCancel | 取消回调,参数为关闭函数,返回 promise 时 resolve 后自动关闭 | function(close) | - | |
|
||||
| onOk | 点击确定回调,参数为关闭函数,返回 promise 时 resolve 后自动关闭 | function(close) | - | |
|
||||
| 参数 | 说明 | 类型 | 默认值 | 版本 |
|
||||
| ----------------- | ---------------------------------------------------------------- | ------------------------------------------------------ | --------------------- | ------ |
|
||||
| afterClose | Modal 完全关闭后的回调 | function | - | 4.9.0 |
|
||||
| autoFocusButton | 指定自动获得焦点的按钮 | null \| `ok` \| `cancel` | `ok` | |
|
||||
| bodyStyle | Modal body 样式 | CSSProperties | | 4.8.0 |
|
||||
| cancelButtonProps | cancel 按钮 props | [ButtonProps](/components/button/#API) | - | |
|
||||
| cancelText | 设置 Modal.confirm 取消按钮文字 | string | `取消` | |
|
||||
| centered | 垂直居中展示 Modal | boolean | false | |
|
||||
| className | 容器类名 | string | - | |
|
||||
| closable | 是否显示右上角的关闭按钮 | boolean | false | 4.9.0 |
|
||||
| closeIcon | 自定义关闭图标 | ReactNode | undefined | 4.9.0 |
|
||||
| content | 内容 | ReactNode | - | |
|
||||
| getContainer | 指定 Modal 挂载的 HTML 节点, false 为挂载在当前 dom | HTMLElement \| () => HTMLElement \| Selectors \| false | document.body | |
|
||||
| icon | 自定义图标 | ReactNode | <QuestionCircle /> | |
|
||||
| keyboard | 是否支持键盘 esc 关闭 | boolean | true | |
|
||||
| mask | 是否展示遮罩 | boolean | true | |
|
||||
| maskClosable | 点击蒙层是否允许关闭 | boolean | false | |
|
||||
| maskStyle | 遮罩样式 | object | {} | |
|
||||
| okButtonProps | ok 按钮 props | [ButtonProps](/components/button/#API) | - | |
|
||||
| okText | 确认按钮文字 | string | `确定` | |
|
||||
| okType | 确认按钮类型 | string | `primary` | |
|
||||
| style | 可用于设置浮层的样式,调整浮层位置等 | CSSProperties | - | |
|
||||
| title | 标题 | ReactNode | - | |
|
||||
| width | 宽度 | string \| number | 416 | |
|
||||
| wrapClassName | 对话框外层容器的类名 | string | - | 4.18.0 |
|
||||
| zIndex | 设置 Modal 的 `z-index` | number | 1000 | |
|
||||
| onCancel | 取消回调,参数为关闭函数,返回 promise 时 resolve 后自动关闭 | function(close) | - | |
|
||||
| onOk | 点击确定回调,参数为关闭函数,返回 promise 时 resolve 后自动关闭 | function(close) | - | |
|
||||
|
||||
以上函数调用后,会返回一个引用,可以通过该引用更新和关闭弹窗。
|
||||
|
||||
|
@ -41,7 +41,7 @@ describe('Table.pagination', () => {
|
||||
container
|
||||
.querySelector('.ant-table-tbody')
|
||||
?.querySelectorAll('tr')
|
||||
?.forEach(tr => {
|
||||
?.forEach((tr) => {
|
||||
namesList.push(tr.querySelector('td')?.textContent);
|
||||
});
|
||||
return namesList;
|
||||
@ -352,7 +352,7 @@ describe('Table.pagination', () => {
|
||||
rerender(
|
||||
createTable({
|
||||
pagination: { current: 10, pageSize: 10, onChange },
|
||||
dataSource: longData.filter(item => item.key < 60),
|
||||
dataSource: longData.filter((item) => item.key < 60),
|
||||
}),
|
||||
);
|
||||
|
||||
@ -418,7 +418,7 @@ describe('Table.pagination', () => {
|
||||
* to `pagination`, since they misunderstand that `pagination` can accept a boolean value.
|
||||
*/
|
||||
it('Accepts pagination as true', () => {
|
||||
const { asFragment } = render(createTable({ pagination: true } as TableProps<any>));
|
||||
const { asFragment } = render(createTable({ pagination: true as any } as TableProps<any>));
|
||||
expect(asFragment().firstChild).toMatchSnapshot();
|
||||
});
|
||||
|
||||
@ -603,7 +603,7 @@ describe('Table.pagination', () => {
|
||||
const dataProp = { data: [] } as any;
|
||||
const Demo: React.FC = () => {
|
||||
const [p, setP] = React.useState<TablePaginationConfig>({
|
||||
showTotal: t => `>${t}<`,
|
||||
showTotal: (t) => `>${t}<`,
|
||||
total: 200,
|
||||
current: 1,
|
||||
pageSize: 10,
|
||||
@ -613,7 +613,7 @@ describe('Table.pagination', () => {
|
||||
{...dataProp}
|
||||
columns={[]}
|
||||
pagination={p}
|
||||
onChange={pg => {
|
||||
onChange={(pg) => {
|
||||
setP({
|
||||
...pg,
|
||||
total: 23,
|
||||
|
@ -39,7 +39,7 @@ describe('Table.sorter', () => {
|
||||
container
|
||||
?.querySelector('.ant-table-tbody')
|
||||
?.querySelectorAll('tr')
|
||||
?.forEach(tr => {
|
||||
?.forEach((tr) => {
|
||||
namesList.push(tr.querySelector('td')?.textContent);
|
||||
});
|
||||
return namesList;
|
||||
@ -129,7 +129,7 @@ describe('Table.sorter', () => {
|
||||
expect(getNameColumn()?.getAttribute('aria-sort')).toEqual('descending');
|
||||
});
|
||||
|
||||
it('sort records with keydown', () => {
|
||||
it('sort records when press enter', () => {
|
||||
const { container } = render(createTable());
|
||||
|
||||
// ascend
|
||||
@ -141,6 +141,30 @@ describe('Table.sorter', () => {
|
||||
expect(renderedNames(container)).toEqual(['Tom', 'Lucy', 'Jack', 'Jerry']);
|
||||
});
|
||||
|
||||
// https://github.com/ant-design/ant-design/issues/38579
|
||||
it('should not sort records when press enter in filter dropdown', () => {
|
||||
const { container } = render(
|
||||
createTable({
|
||||
columns: [
|
||||
{
|
||||
...column,
|
||||
filters: [{ text: 'J', value: 'J' }],
|
||||
onFilter: (value: any, record: any) => record.name.includes(value),
|
||||
filterDropdownOpen: true,
|
||||
},
|
||||
],
|
||||
}),
|
||||
);
|
||||
|
||||
// don't trigger ascend
|
||||
fireEvent.keyDown(container.querySelector('.ant-table-filter-dropdown')!, { keyCode: 13 });
|
||||
expect(renderedNames(container)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']);
|
||||
|
||||
// don't trigger descend
|
||||
fireEvent.keyDown(container.querySelector('.ant-table-filter-dropdown')!, { keyCode: 13 });
|
||||
expect(renderedNames(container)).toEqual(['Jack', 'Lucy', 'Tom', 'Jerry']);
|
||||
});
|
||||
|
||||
describe('can be controlled by sortOrder', () => {
|
||||
it('single', () => {
|
||||
const { container } = render(
|
||||
@ -434,7 +458,7 @@ describe('Table.sorter', () => {
|
||||
class TableTest extends React.Component {
|
||||
state = { pagination: {} };
|
||||
|
||||
onChange: TableProps<any>['onChange'] = pagination => {
|
||||
onChange: TableProps<any>['onChange'] = (pagination) => {
|
||||
this.setState({ pagination });
|
||||
};
|
||||
|
||||
@ -494,7 +518,7 @@ describe('Table.sorter', () => {
|
||||
pagination: {},
|
||||
};
|
||||
|
||||
onChange: TableProps<any>['onChange'] = pagination => {
|
||||
onChange: TableProps<any>['onChange'] = (pagination) => {
|
||||
this.setState({ pagination });
|
||||
};
|
||||
|
||||
@ -561,7 +585,7 @@ describe('Table.sorter', () => {
|
||||
pagination: {},
|
||||
};
|
||||
|
||||
onChange: TableProps<any>['onChange'] = pagination => {
|
||||
onChange: TableProps<any>['onChange'] = (pagination) => {
|
||||
this.setState({ pagination });
|
||||
};
|
||||
|
||||
|
@ -1,12 +1,20 @@
|
||||
import * as React from 'react';
|
||||
import KeyCode from 'rc-util/lib/KeyCode';
|
||||
|
||||
export interface FilterDropdownMenuWrapperProps {
|
||||
children?: React.ReactNode;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const onKeyDown: React.KeyboardEventHandler<HTMLDivElement> = (event) => {
|
||||
const { keyCode } = event;
|
||||
if (keyCode === KeyCode.ENTER) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
|
||||
const FilterDropdownMenuWrapper = (props: FilterDropdownMenuWrapperProps) => (
|
||||
<div className={props.className} onClick={e => e.stopPropagation()}>
|
||||
<div className={props.className} onClick={(e) => e.stopPropagation()} onKeyDown={onKeyDown}>
|
||||
{props.children}
|
||||
</div>
|
||||
);
|
||||
|
@ -277,7 +277,7 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
const cssLineClamp = mergedEnableEllipsis && rows > 1 && cssEllipsis;
|
||||
|
||||
// >>>>> Expand
|
||||
const onExpandClick: React.MouseEventHandler<HTMLElement> = e => {
|
||||
const onExpandClick: React.MouseEventHandler<HTMLElement> = (e) => {
|
||||
setExpanded(true);
|
||||
ellipsisConfig.onExpand?.(e);
|
||||
};
|
||||
@ -510,6 +510,7 @@ const Base = React.forwardRef<HTMLElement, BlockProps>((props, ref) => {
|
||||
},
|
||||
className,
|
||||
)}
|
||||
prefixCls={customizePrefixCls}
|
||||
style={{
|
||||
...style,
|
||||
WebkitLineClamp: cssLineClamp ? rows : undefined,
|
||||
|
20
components/typography/__tests__/prefixCls.test.tsx
Normal file
20
components/typography/__tests__/prefixCls.test.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import React from 'react';
|
||||
import { render } from '../../../tests/utils';
|
||||
|
||||
import Base from '../Base';
|
||||
|
||||
describe('Typography keep prefixCls', () => {
|
||||
describe('Base', () => {
|
||||
it('should support className when has prefix', () => {
|
||||
const { container: wrapper } = render(
|
||||
<Base component="p" prefixCls="custom-prefixCls" className="custom-class">
|
||||
test prefixCls
|
||||
</Base>,
|
||||
);
|
||||
expect(
|
||||
(wrapper.firstChild as HTMLElement)?.className.includes('custom-prefixCls'),
|
||||
).toBeTruthy();
|
||||
expect((wrapper.firstChild as HTMLElement)?.className.includes('custom-class')).toBeTruthy();
|
||||
});
|
||||
});
|
||||
});
|
@ -297,7 +297,7 @@
|
||||
"sylvanas": "^0.6.1",
|
||||
"theme-switcher": "^1.0.2",
|
||||
"ts-node": "^10.8.2",
|
||||
"typescript": "~4.8.4",
|
||||
"typescript": "~4.9.3",
|
||||
"webpack-bundle-analyzer": "^4.1.0",
|
||||
"xhr-mock": "^2.4.1",
|
||||
"yaml-front-matter": "^4.0.0"
|
||||
@ -325,7 +325,7 @@
|
||||
"mode": "npm"
|
||||
},
|
||||
"lint-staged": {
|
||||
"*.{ts,tsx,js,json,less}": "rome format --write",
|
||||
"*.{md}": "prettier --ignore-unknown --write"
|
||||
"*.{ts,tsx,js}": "rome format --write",
|
||||
"*.{json,less,md}": "prettier --ignore-unknown --write"
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user