merge master

This commit is contained in:
zombiej 2020-03-27 13:12:37 +08:00
commit 73562d878c
68 changed files with 760 additions and 5201 deletions

15
.github/workflows/mirror.yml vendored Normal file
View File

@ -0,0 +1,15 @@
name: Mirror
on: [push]
jobs:
to_gitee:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: pixta-dev/repository-mirroring-action@v1
with:
target_repo_url:
git@gitee.com:ant-design/ant-design.git
ssh_private_key:
${{ secrets.GITEE_SSH_PRIVATE_KEY }}

View File

@ -102,6 +102,7 @@ Veja [i18n](http://ant.design/docs/react/i18n).
- [CodeSandbox Template](https://u.ant.design/codesandbox-repro) para relatório de erros
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
- [Customize Theme](http://ant.design/docs/react/customize-theme)
- [How to Apply for Being A Collaborator](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)
## ⌨️ Desenvolvimento

View File

@ -72,9 +72,13 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
你也可以使用 [babel-plugin-import](https://ant.design/docs/react/getting-started-cn#按需加载)。
### 🌈 定制主题
参考 [定制主题](https://ant.design/docs/react/customize-theme-cn) 文档。
### 🛡 TypeScript
参考 [在 TypeScript 中使用](https://ant.design/docs/react/use-in-typescript-cn)
参考 [在 TypeScript 中使用](https://ant.design/docs/react/use-in-typescript-cn)
## 🌍 国际化
@ -103,6 +107,7 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
- [CodeSandbox 模板](https://u.ant.design/codesandbox-repro) for bug reports
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
- [定制主题](http://ant.design/docs/react/customize-theme-cn)
- [成为社区协作成员](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)
## ⌨️ 本地开发

View File

@ -102,6 +102,7 @@ See [i18n](http://ant.design/docs/react/i18n).
- [CodeSandbox Template](https://u.ant.design/codesandbox-repro) for bug reports
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
- [Customize Theme](http://ant.design/docs/react/customize-theme)
- [How to Apply for Being A Collaborator](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)
## ⌨️ Development

View File

@ -1,7 +1,10 @@
import React from 'react';
import { mount } from 'enzyme';
import Alert from '..';
import Tooltip from '../../tooltip';
import Popconfirm from '../../popconfirm';
import rtlTest from '../../../tests/shared/rtlTest';
import { sleep } from '../../../tests/utils';
const { ErrorBoundary } = Alert;
@ -66,4 +69,46 @@ describe('Alert', () => {
// eslint-disable-next-line jest/no-standalone-expect
expect(wrapper.render()).toMatchSnapshot();
});
it('could be used with Tooltip', async () => {
jest.useRealTimers();
const wrapper = mount(
<Tooltip title="xxx" mouseEnterDelay={0}>
<Alert
message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text"
type="warning"
/>
</Tooltip>,
);
wrapper.find('.ant-alert').simulate('mouseenter');
await sleep(0);
expect(
wrapper
.find(Tooltip)
.instance()
.getPopupDomNode(),
).toBeTruthy();
jest.useFakeTimers();
});
it('could be used with Popconfirm', async () => {
jest.useRealTimers();
const wrapper = mount(
<Popconfirm title="xxx">
<Alert
message="Warning Text Warning Text Warning TextW arning Text Warning Text Warning TextWarning Text"
type="warning"
/>
</Popconfirm>,
);
wrapper.find('.ant-alert').simulate('click');
await sleep(0);
expect(
wrapper
.find(Popconfirm)
.instance()
.getPopupDomNode(),
).toBeTruthy();
jest.useFakeTimers();
});
});

View File

@ -42,6 +42,9 @@ export interface AlertProps {
className?: string;
banner?: boolean;
icon?: React.ReactNode;
onMouseEnter?: React.MouseEventHandler<HTMLDivElement>;
onMouseLeave?: React.MouseEventHandler<HTMLDivElement>;
onClick?: React.MouseEventHandler<HTMLDivElement>;
}
export interface AlertState {
@ -103,6 +106,9 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
className = '',
style,
icon,
onMouseEnter,
onMouseLeave,
onClick,
} = this.props;
let { closable, type, showIcon } = this.props;
const { closing, closed } = this.state;
@ -173,7 +179,15 @@ export default class Alert extends React.Component<AlertProps, AlertState> {
transitionName={`${prefixCls}-slide-up`}
onEnd={this.animationEnd}
>
<div data-show={!closing} className={alertCls} style={style} {...dataOrAriaProps}>
<div
data-show={!closing}
className={alertCls}
style={style}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
onClick={onClick}
{...dataOrAriaProps}
>
{showIcon ? iconNode : null}
<span className={`${prefixCls}-message`}>{message}</span>
<span className={`${prefixCls}-description`}>{description}</span>

View File

@ -450,7 +450,7 @@ exports[`renders ./components/avatar/demo/dynamic.md correctly 1`] = `
</span>
<button
class="ant-btn ant-btn-sm"
style="margin-left:16px;vertical-align:middle"
style="margin:0 16px;vertical-align:middle"
type="button"
>
<span>

View File

@ -33,7 +33,11 @@ const Autoset: React.FC = () => {
<Avatar style={{ backgroundColor: color, verticalAlign: 'middle' }} size="large">
{user}
</Avatar>
<Button size="small" style={{ marginLeft: 16, verticalAlign: 'middle' }} onClick={changeUser}>
<Button
size="small"
style={{ margin: '0 16px', verticalAlign: 'middle' }}
onClick={changeUser}
>
Change
</Button>
</div>

View File

@ -48,6 +48,12 @@
animation-name: antZoomBadgeOutRtl;
}
}
&-not-a-wrapper {
.@{badge-prefix-cls}-count {
transform: none;
}
}
}
@keyframes antZoomBadgeInRtl {

View File

@ -70,7 +70,8 @@
> span + span,
& + .@{btnClassName},
& + & {
.@{btnClassName}-rtl& {
.@{btnClassName}-rtl&,
.@{btnClassName}-group-rtl& {
margin-right: -1px;
margin-left: auto;
}

View File

@ -47,6 +47,7 @@
display: block;
width: @checkbox-size;
height: @checkbox-size;
direction: ltr;
background-color: @checkbox-check-bg;
border: @checkbox-border-width @border-style-base @border-color-base;
border-radius: @border-radius-base;

View File

@ -11611,7 +11611,9 @@ exports[`ConfigProvider components Table configProvider 1`] = `
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="config-table-thead"
>
<tr>
<th
class="config-table-cell config-table-column-has-sorters"
@ -11851,82 +11853,6 @@ exports[`ConfigProvider components Table configProvider 1`] = `
</div>
</div>
</div>
<ul
class="config-pagination config-table-pagination"
unselectable="unselectable"
>
<li
aria-disabled="true"
class="config-pagination-prev config-pagination-disabled"
title="Previous Page"
>
<a
class="config-pagination-item-link"
disabled=""
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</a>
</li>
<li
class="config-pagination-item config-pagination-item-0 config-pagination-disabled config-pagination-item-disabled"
tabindex="0"
title="0"
>
<a>
0
</a>
</li>
<li
aria-disabled="true"
class="config-pagination-next config-pagination-disabled"
title="Next Page"
>
<a
class="config-pagination-item-link"
disabled=""
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>
@ -11957,7 +11883,9 @@ exports[`ConfigProvider components Table normal 1`] = `
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
@ -12197,82 +12125,6 @@ exports[`ConfigProvider components Table normal 1`] = `
</div>
</div>
</div>
<ul
class="ant-pagination ant-table-pagination"
unselectable="unselectable"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-0 ant-pagination-disabled ant-pagination-item-disabled"
tabindex="0"
title="0"
>
<a>
0
</a>
</li>
<li
aria-disabled="true"
class="ant-pagination-next ant-pagination-disabled"
title="Next Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>
@ -12303,7 +12155,9 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="prefix-Table-thead"
>
<tr>
<th
class="prefix-Table-cell prefix-Table-column-has-sorters"
@ -12543,82 +12397,6 @@ exports[`ConfigProvider components Table prefixCls 1`] = `
</div>
</div>
</div>
<ul
class="ant-pagination prefix-Table-pagination"
unselectable="unselectable"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-0 ant-pagination-disabled ant-pagination-item-disabled"
tabindex="0"
title="0"
>
<a>
0
</a>
</li>
<li
aria-disabled="true"
class="ant-pagination-next ant-pagination-disabled"
title="Next Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>

View File

@ -135,6 +135,11 @@
line-height: @font-size-lg;
text-align: center;
cursor: default;
.@{picker-prefix-cls}-range-separator & {
.@{picker-prefix-cls}-disabled & {
cursor: not-allowed;
}
}
}
// ======================== Range =========================

View File

@ -80,4 +80,8 @@ ReactDOM.render(
#components-dropdown-demo-dropdown-button .ant-dropdown-button {
margin: 0 8px 8px 0;
}
#components-dropdown-demo-dropdown-button .ant-btn-group-rtl.ant-dropdown-button {
margin: 0 0 8px 8px;
}
```

View File

@ -520,7 +520,9 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -597,82 +599,6 @@ exports[`renders ./components/empty/demo/config-provider.md correctly 1`] = `
</div>
</div>
</div>
<ul
class="ant-pagination ant-table-pagination"
unselectable="unselectable"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-0 ant-pagination-disabled ant-pagination-item-disabled"
tabindex="0"
title="0"
>
<a>
0
</a>
</li>
<li
aria-disabled="true"
class="ant-pagination-next ant-pagination-disabled"
title="Next Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>

View File

@ -87,7 +87,6 @@ function FormItem(props: FormItemProps): React.ReactElement {
const formContext = React.useContext(FormContext);
const { updateItemErrors } = React.useContext(FormItemContext);
const [domErrorVisible, innerSetDomErrorVisible] = React.useState(!!help);
// const [inlineErrors, innerSetInlineErrors] = React.useState<Record<string, string[]>>({});
const [inlineErrors, setInlineErrors] = useFrameState<Record<string, string[]>>({});
function setDomErrorVisible(visible: boolean) {
@ -304,6 +303,12 @@ function FormItem(props: FormItemProps): React.ReactElement {
'Must set `name` or use render props when `dependencies` is set.',
);
} else if (React.isValidElement(children)) {
warning(
(children.props as any).defaultValue === undefined,
'Form.Item',
'`defaultValue` will not work on controlled Field. You should use `initialValues` of Form instead.',
);
const childProps = { ...children.props, ...mergedControl };
// We should keep user origin event handler

View File

@ -6,6 +6,7 @@ import Input from '../../input';
import Button from '../../button';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { sleep } from '../../../tests/utils';
jest.mock('scroll-into-view-if-needed');
@ -25,10 +26,7 @@ describe('Form', () => {
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});
async function change(wrapper, index, value) {
wrapper
.find(Input)
.at(index)
.simulate('change', { target: { value } });
wrapper.find(Input).at(index).simulate('change', { target: { value } });
await delay(50);
wrapper.update();
}
@ -74,10 +72,7 @@ describe('Form', () => {
);
async function operate(className) {
wrapper
.find(className)
.last()
.simulate('click');
wrapper.find(className).last().simulate('click');
await delay();
wrapper.update();
}
@ -90,6 +85,7 @@ describe('Form', () => {
await change(wrapper, 1, '');
wrapper.update();
await sleep(0);
expect(wrapper.find('.ant-form-item-explain').length).toBe(1);
await operate('.remove');
@ -115,10 +111,7 @@ describe('Form', () => {
it('correct onFinish values', async () => {
async function click(wrapper, className) {
wrapper
.find(className)
.last()
.simulate('click');
wrapper.find(className).last().simulate('click');
await delay();
wrapper.update();
}
@ -405,22 +398,12 @@ describe('Form', () => {
/* eslint-disable no-await-in-loop */
for (let i = 0; i < 3; i += 1) {
await change(wrapper, 0, '');
expect(
wrapper
.find('.ant-form-item-explain')
.first()
.text(),
).toEqual("'name' is required");
expect(wrapper.find('.ant-form-item-explain').first().text()).toEqual("'name' is required");
await change(wrapper, 0, 'p');
await delay(100);
wrapper.update();
expect(
wrapper
.find('.ant-form-item-explain')
.first()
.text(),
).toEqual('not a p');
expect(wrapper.find('.ant-form-item-explain').first().text()).toEqual('not a p');
}
/* eslint-enable */
});
@ -441,12 +424,7 @@ describe('Form', () => {
const wrapper = mount(<App />);
wrapper.find('button').simulate('click');
expect(
wrapper
.find('.ant-form-item')
.first()
.hasClass('ant-form-item-with-help'),
).toBeTruthy();
expect(wrapper.find('.ant-form-item').first().hasClass('ant-form-item-with-help')).toBeTruthy();
expect(wrapper.find('.ant-form-item-explain').text()).toEqual('bamboo');
});
@ -674,4 +652,18 @@ describe('Form', () => {
expect(renderTimes).toEqual(1);
expect(wrapper.find('input').props().value).toEqual('a');
});
it('warning with `defaultValue`', () => {
mount(
<Form>
<Form.Item name="light">
<input defaultValue="should warning" />
</Form.Item>
</Form>,
);
expect(errorSpy).toHaveBeenCalledWith(
'Warning: [antd: Form.Item] `defaultValue` will not work on controlled Field. You should use `initialValues` of Form instead.',
);
});
});

View File

@ -32,7 +32,7 @@ interface ModalFormProps {
}
// reset form fields when modal is form, closed
const useResetFormOnCloseModal = ({ visible }) => {
const useResetFormOnCloseModal = ({ form, visible }) => {
const prevVisibleRef = useRef();
useEffect(() => {
prevVisibleRef.current = visible;

View File

@ -308,6 +308,10 @@ validator(rule, value, callback) => {
Before Modal open, children elements do not exist in the view. You can set `forceRender` on Modal to pre-render its children. Click [here](https://codesandbox.io/s/antd-reproduction-template-ibu5c) to view an example.
### 为什么 Form.Item 下的子组件 defaultValue 不生效?
当你为 Form.Item 设置 `name` 属性后,子组件会转为受控模式。因而 `defaultValue` 不会生效。你需要在 Form 上通过 `initialValues` 设置默认值。
<style>
.site-form-item-icon {
color: rgba(0, 0, 0, 0.25);

View File

@ -309,6 +309,10 @@ validator(rule, value, callback) => {
这是因为你在调用 form 方法时Modal 还未初始化导致 form 没有关联任何 Form 组件。你可以通过给 Modal 设置 `forceRender` 将其预渲染。示例点击[此处](https://codesandbox.io/s/antd-reproduction-template-ibu5c)。
### 为什么 Form.Item 下的子组件 defaultValue 不生效?
当你为 Form.Item 设置 `name` 属性后,子组件会转为受控模式。因而 `defaultValue` 不会生效。你需要在 Form 上通过 `initialValues` 设置默认值。
<style>
.site-form-item-icon {
color: rgba(0, 0, 0, 0.25);

View File

@ -13,7 +13,6 @@
@form-prefix-cls: ~'@{ant-prefix}-form';
@form-item-prefix-cls: ~'@{form-prefix-cls}-item';
@form-font-height: ceil(@font-size-base * @line-height-base);
@form-item-label-height: @input-height-base;
.@{form-prefix-cls} {
.reset-component;

View File

@ -109,15 +109,21 @@ export function useFrameState<ValueType>(
const [value, setValue] = React.useState(defaultValue);
const frameRef = React.useRef<number | null>(null);
const batchRef = React.useRef<Updater<ValueType>[]>([]);
const destroyRef = React.useRef(false);
React.useEffect(
() => () => {
destroyRef.current = true;
raf.cancel(frameRef.current!);
},
[],
);
function setFrameValue(updater: Updater<ValueType>) {
if (destroyRef.current) {
return;
}
if (frameRef.current === null) {
batchRef.current = [];
frameRef.current = raf(() => {

View File

@ -890,6 +890,42 @@ exports[`renders ./components/input/demo/align.md correctly 1`] = `
</span>
</span>
</span>
<span
class="ant-input-affix-wrapper"
style="width:50px"
>
<input
class="ant-input"
type="text"
value=""
/>
<span
class="ant-input-suffix"
>
Y
</span>
</span>
<input
class="ant-input"
style="width:50px"
type="text"
value=""
/>
<span
class="ant-input-affix-wrapper"
style="width:50px"
>
<input
class="ant-input"
type="text"
value="1"
/>
<span
class="ant-input-suffix"
>
Y
</span>
</span>
</div>
`;

View File

@ -28,6 +28,10 @@ const RadioGroup = Radio.Group;
const Option = Select.Option;
const { MonthPicker, RangePicker } = DatePicker;
const narrowStyle = {
width: 50,
};
const options = [
{
value: 'zhejiang',
@ -94,6 +98,9 @@ ReactDOM.render(
<AutoComplete style={{ width: 100 }} placeholder="input here" />
<br />
<Input prefix="$" addonBefore="Http://" addonAfter=".com" defaultValue="mysite" />
<Input style={narrowStyle} suffix="Y" />
<Input style={narrowStyle} />
<Input style={narrowStyle} defaultValue="1" suffix="Y" />
</div>,
mountNode,
);

View File

@ -17,6 +17,12 @@
box-shadow: none;
}
}
&::before {
width: 0;
visibility: hidden;
content: '\a0';
}
}
&-prefix,

View File

@ -84,6 +84,14 @@
}
&&-compact {
& > *:not(:last-child) {
.@{inputClass}-group-rtl& {
margin-right: 0;
margin-left: -@border-width-base;
border-left-width: @border-width-base;
}
}
& > *:first-child,
& > .@{ant-prefix}-select:first-child > .@{ant-prefix}-select-selector,
& > .@{ant-prefix}-calendar-picker:first-child .@{ant-prefix}-input,
@ -108,7 +116,6 @@
& > .@{ant-prefix}-mention-wrapper:last-child .@{ant-prefix}-mention-editor,
& > .@{ant-prefix}-time-picker:last-child .@{ant-prefix}-time-picker-input {
.@{inputClass}-group-rtl& {
border-right-width: 0;
border-left-width: @border-width-base;
border-top-left-radius: @border-radius-base;
border-top-right-radius: 0;
@ -133,6 +140,11 @@
border: @border-width-base @border-style-base @input-border-color;
border-left: 0;
}
&:hover,
&:focus {
border-color: @input-hover-border-color;
}
}
& + .@{ant-prefix}-input-group-addon,

View File

@ -26,7 +26,8 @@
}
}
&-line &-text {
&-line &-text,
&-steps &-text {
.@{progress-prefix-cls}-rtl& {
margin-right: 8px;
margin-left: 0;

View File

@ -33,7 +33,6 @@ Select component to select value from options.
| dropdownMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set `min-width` same as input. `false` will disable virtual scroll | boolean \| number | true | |
| dropdownRender | Customize dropdown content | (menuNode: ReactNode, props) => ReactNode | - | |
| dropdownStyle | style of dropdown menu | object | - | |
| dropdownMenuStyle | additional style applied to dropdown menu | object | - | |
| filterOption | If true, filter options by input, if function, filter options against it. The function will receive two arguments, `inputValue` and `option`, if the function returns `true`, the option will be included in the filtered set; Otherwise, it will be excluded. | boolean or function(inputValue, option) | true | |
| firstActiveValue | Value of action option by default | string\|string\[] | - | |
| getPopupContainer | Parent Node which the selector should be rendered to. Default to `body`. When position issues happen, try to modify it into scrollable content and position it relative. [Example](https://codesandbox.io/s/4j168r7jw0) | function(triggerNode) | () => document.body | |

View File

@ -34,7 +34,6 @@ title: Select
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 `min-width`。`false` 时会关闭虚拟滚动 | boolean \| number | true | |
| dropdownRender | 自定义下拉框内容 | (menuNode: ReactNode, props) => ReactNode | - | |
| dropdownStyle | 下拉菜单的 style 属性 | object | - | |
| dropdownMenuStyle | dropdown 菜单自定义样式 | object | - | |
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 `inputValue` `option` 两个参数,当 `option` 符合筛选条件时,应返回 `true`,反之则返回 `false`。 | boolean or function(inputValue, option) | true | |
| firstActiveValue | 默认高亮的选项 | string\|string\[] | - | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。[示例](https://codesandbox.io/s/4j168r7jw0) | Function(triggerNode) | () => document.body | |

View File

@ -210,6 +210,7 @@
&-group {
color: @text-color-secondary;
font-size: @font-size-sm;
cursor: default;
}
// =========== Option ===========

View File

@ -31,6 +31,18 @@
direction: rtl;
}
}
// ========================= Options =========================
&-item {
&-option {
&-grouped {
.@{select-prefix-cls}-dropdown-rtl & {
padding-right: @control-padding-horizontal * 2;
padding-left: @control-padding-horizontal;
}
}
}
}
}
// multiple
@ -43,6 +55,12 @@
);
.@{select-prefix-cls}-multiple {
&.@{select-prefix-cls}-allow-clear .@{select-prefix-cls}-selector {
.@{select-prefix-cls}-rtl& {
padding-right: @input-padding-vertical-base;
padding-left: @font-size-sm + @control-padding-horizontal;
}
}
// ======================== Selections ========================
.@{select-prefix-cls}-selection-item {
.@{select-prefix-cls}-rtl& {

View File

@ -264,7 +264,7 @@ exports[`renders ./components/slider/demo/input-number.md correctly 1`] = `
>
<div
class="ant-input-number"
style="margin-left:16px"
style="margin:0 16px"
>
<div
class="ant-input-number-handler-wrap"
@ -384,7 +384,7 @@ exports[`renders ./components/slider/demo/input-number.md correctly 1`] = `
>
<div
class="ant-input-number"
style="margin-left:16px"
style="margin:0 16px"
>
<div
class="ant-input-number-handler-wrap"

View File

@ -43,7 +43,7 @@ class IntegerStep extends React.Component {
<InputNumber
min={1}
max={20}
style={{ marginLeft: 16 }}
style={{ margin: '0 16px' }}
value={inputValue}
onChange={this.onChange}
/>
@ -84,7 +84,7 @@ class DecimalStep extends React.Component {
<InputNumber
min={0}
max={1}
style={{ marginLeft: 16 }}
style={{ margin: '0 16px' }}
step={0.01}
value={inputValue}
onChange={this.onChange}

View File

@ -163,3 +163,14 @@
}
}
}
// label
.@{steps-prefix-cls}-label-vertical {
.@{steps-prefix-cls}-item {
&-title {
.@{steps-prefix-cls}-rtl& {
padding-left: 0;
}
}
}
}

View File

@ -331,6 +331,7 @@
@form-vertical-label-padding: 0 0 8px;
@form-vertical-label-margin: 0;
@form-item-label-font-size: @font-size-base;
@form-item-label-height: @input-height-base;
@form-item-label-colon-margin-right: 8px;
@form-item-label-colon-margin-left: 2px;
@form-error-input-bg: @input-bg;

View File

@ -442,7 +442,7 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
internalRefs={internalRefs as any}
transformColumns={transformColumns}
/>
{bottomPaginationNode}
{pageData && pageData.length > 0 && bottomPaginationNode}
</Spin>
</div>
);

View File

@ -70,12 +70,7 @@ describe('Table.filter', () => {
it('renders menu correctly', () => {
const wrapper = mount(createTable());
const dropdownWrapper = mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
expect(dropdownWrapper.render()).toMatchSnapshot();
});
@ -90,12 +85,7 @@ describe('Table.filter', () => {
],
}),
);
const dropdownWrapper = mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
expect(dropdownWrapper.render()).toMatchSnapshot();
});
@ -112,12 +102,7 @@ describe('Table.filter', () => {
}),
);
const dropdownWrapper = mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
expect(dropdownWrapper.render()).toMatchSnapshot();
});
@ -175,20 +160,10 @@ describe('Table.filter', () => {
// try to use confirm btn
wrapper.find('span.ant-dropdown-trigger').simulate('click', nativeEvent);
wrapper.find('#setSelectedKeys').simulate('click');
expect(
getFilterMenu()
.find('Dropdown')
.first()
.props().visible,
).toBeTruthy();
expect(getFilterMenu().find('Dropdown').first().props().visible).toBeTruthy();
wrapper.find('#confirm').simulate('click');
expect(getFilterMenu().props().filterState.filteredKeys).toEqual([42]);
expect(
getFilterMenu()
.find('Dropdown')
.first()
.props().visible,
).toBeFalsy();
expect(getFilterMenu().find('Dropdown').first().props().visible).toBeFalsy();
// Simulate onSelect, setSelectedKeys & confirm
wrapper.find('span.ant-dropdown-trigger').simulate('click', nativeEvent);
@ -237,15 +212,8 @@ describe('Table.filter', () => {
);
expect(wrapper.find('FilterDropdown').props().filterState.filteredKeys).toBeFalsy();
wrapper
.find('FilterDropdown')
.find('input[type="checkbox"]')
.first()
.simulate('click');
wrapper
.find('FilterDropdown')
.find('.ant-table-filter-dropdown-btns .ant-btn-primary')
.simulate('click');
wrapper.find('FilterDropdown').find('input[type="checkbox"]').first().simulate('click');
wrapper.find('FilterDropdown').find('.confirm').simulate('click');
expect(wrapper.find('FilterDropdown').props().filterState.filteredKeys).toEqual(['boy']);
wrapper.setProps({ dataSource: [...data, { key: 999, name: 'Chris' }] });
expect(wrapper.find('FilterDropdown').props().filterState.filteredKeys).toEqual(['boy']);
@ -264,10 +232,7 @@ describe('Table.filter', () => {
}),
);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
expect(handleChange).toHaveBeenCalledWith(true);
});
@ -376,20 +341,10 @@ describe('Table.filter', () => {
const handleChange = jest.fn();
const wrapper = mount(createTable({ onChange: handleChange }));
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper
.find('FilterDropdown')
.find('MenuItem')
.first()
.simulate('click');
wrapper
.find('FilterDropdown')
.find('.ant-table-filter-dropdown-btns .ant-btn-primary')
.simulate('click');
wrapper.find('FilterDropdown').find('MenuItem').first().simulate('click');
wrapper.find('FilterDropdown').find('.confirm').simulate('click');
expect(handleChange).toHaveBeenCalledWith(
{},
@ -405,11 +360,8 @@ describe('Table.filter', () => {
const handleChange = jest.fn();
const wrapper = mount(createTable({ onChange: handleChange }));
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-link').simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('.clear').simulate('click');
expect(handleChange).not.toHaveBeenCalled();
});
@ -497,27 +449,15 @@ describe('Table.filter', () => {
}),
);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
jest.useFakeTimers();
wrapper
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('MenuItem').first().simulate('click');
// This test can be remove if refactor
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper.update();
expect(
wrapper
.find('FilterDropdown')
.find('Checkbox')
.at(0)
.props().checked,
).toEqual(true);
expect(wrapper.find('FilterDropdown').find('Checkbox').at(0).props().checked).toEqual(true);
expect(typeof wrapper.find('FilterDropdown').props().filterState.filteredKeys[0]).toEqual(
'string',
@ -529,17 +469,10 @@ describe('Table.filter', () => {
});
// Another time of Filter show
// https://github.com/ant-design/ant-design/issues/15593
wrapper
.find('MenuItem')
.first()
.simulate('click');
expect(
wrapper
.find('FilterDropdown')
.find('Checkbox')
.at(0)
.props().checked,
).toEqual(false);
wrapper.find('MenuItem').first().simulate('click');
expect(wrapper.find('FilterDropdown').find('Checkbox').at(0).props().checked).toEqual(
false,
);
jest.useRealTimers();
});
});
@ -579,16 +512,10 @@ describe('Table.filter', () => {
const wrapper = mount(<App />);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper.find('MenuItem').first().simulate('click');
wrapper.find('.confirm').simulate('click');
wrapper.update();
expect(renderedNames(wrapper)).toEqual(['Jack']);
@ -650,18 +577,9 @@ describe('Table.filter', () => {
}),
);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper
.find('.ant-dropdown-menu-item')
.first()
.simulate('click');
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('.ant-dropdown-menu-item').first().simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
expect(handleChange).toHaveBeenCalled();
expect(handleChange.mock.calls[0][3].currentDataSource.length).toBe(1);
@ -682,32 +600,14 @@ describe('Table.filter', () => {
}),
);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper
.find('.ant-dropdown-menu-item')
.first()
.simulate('click');
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('.ant-dropdown-menu-item').first().simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
expect(wrapper.find('.customize-icon').render()).toMatchSnapshot();
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper
.find('.ant-dropdown-menu-item')
.first()
.simulate('click');
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('.ant-dropdown-menu-item').first().simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
expect(wrapper.find('.customize-icon').render()).toMatchSnapshot();
});
@ -783,18 +683,12 @@ describe('Table.filter', () => {
}
const wrapper = mount(<Demo />);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('.ant-input').simulate('change', { target: { value: 'test' } });
expect(wrapper.find('.ant-input').instance().value).toBe('test');
wrapper.find('.ant-btn').simulate('click');
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
expect(wrapper.find('.ant-input').instance().value).toBe('');
});
@ -817,18 +711,12 @@ describe('Table.filter', () => {
],
}),
);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper
.find('input')
.first()
.simulate('change', { target: { value: 'whatevervalue' } });
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
expect(onChange).not.toHaveBeenCalled();
});
@ -871,15 +759,9 @@ describe('Table.filter', () => {
/>,
);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('MenuItem').first().simulate('click');
wrapper.find('.confirm').simulate('click');
expect(onChange).toHaveBeenCalled();
onChange.mockReset();
expect(onChange).not.toHaveBeenCalled();
@ -893,11 +775,8 @@ describe('Table.filter', () => {
],
});
wrapper
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper.find('MenuItem').first().simulate('click');
wrapper.find('.confirm').simulate('click');
expect(onChange).toHaveBeenCalled();
});
@ -993,20 +872,14 @@ describe('Table.filter', () => {
const wrapper = mount(<Test />);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
expect(filterDropdownMock).toHaveBeenCalledWith(
expect.objectContaining({
visible: true,
}),
);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
expect(filterDropdownMock).toHaveBeenCalledWith(
expect.objectContaining({
visible: false,
@ -1024,15 +897,9 @@ describe('Table.filter', () => {
}),
);
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('MenuItem').first().simulate('click');
wrapper.find('.confirm').simulate('click');
expect(handleChange).toHaveBeenCalledWith(
{
@ -1045,7 +912,7 @@ describe('Table.filter', () => {
currentDataSource: [],
},
);
expect(wrapper.find('.ant-pagination-item').text()).toBe('0');
expect(wrapper.find('.ant-pagination-item')).toHaveLength(0);
});
it('should keep pagination current after filter', () => {
@ -1061,15 +928,9 @@ describe('Table.filter', () => {
);
expect(wrapper.find('.ant-pagination-item-active').text()).toBe('3');
wrapper
.find('.ant-dropdown-trigger')
.first()
.simulate('click');
wrapper
.find('MenuItem')
.first()
.simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper.find('.ant-dropdown-trigger').first().simulate('click');
wrapper.find('MenuItem').first().simulate('click');
wrapper.find('.confirm').simulate('click');
expect(handleChange).toHaveBeenCalledWith(
{
@ -1158,11 +1019,8 @@ describe('Table.filter', () => {
// Filter it
onChange.mockReset();
wrapper.find('span.ant-dropdown-trigger').simulate('click', nativeEvent);
wrapper
.find('.ant-dropdown-menu-item')
.first()
.simulate('click');
wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').simulate('click');
wrapper.find('.ant-dropdown-menu-item').first().simulate('click');
wrapper.find('.ant-table-filter-dropdown-link.confirm').simulate('click');
expect(onChange).toHaveBeenCalledWith(
expect.anything(),
{
@ -1192,15 +1050,8 @@ describe('Table.filter', () => {
}),
);
expect(wrapper.find('.ant-table-filter-dropdown-btns .ant-btn-primary').text()).toEqual(
'Bamboo',
);
expect(
wrapper
.find('.ant-table-filter-dropdown-btns .ant-btn-link')
.last()
.text(),
).toEqual('Reset');
expect(wrapper.find('.ant-table-filter-dropdown-link').first().text()).toEqual('Bamboo');
expect(wrapper.find('.ant-table-filter-dropdown-link').last().text()).toEqual('Reset');
});
it('filtered should work', () => {

View File

@ -104,28 +104,19 @@ describe('Table.rowSelection', () => {
.find('input')
.first()
.simulate('change', { target: { checked: true } });
expect(
wrapper
.find('Checkbox')
.first()
.props(),
).toEqual(expect.objectContaining({ checked: true, indeterminate: false }));
expect(wrapper.find('Checkbox').first().props()).toEqual(
expect.objectContaining({ checked: true, indeterminate: false }),
);
pagers.at(1).simulate('click');
expect(
wrapper
.find('Checkbox')
.first()
.props(),
).toEqual(expect.objectContaining({ checked: false, indeterminate: false }));
expect(wrapper.find('Checkbox').first().props()).toEqual(
expect.objectContaining({ checked: false, indeterminate: false }),
);
pagers.at(0).simulate('click');
expect(
wrapper
.find('Checkbox')
.first()
.props(),
).toEqual(expect.objectContaining({ checked: true, indeterminate: false }));
expect(wrapper.find('Checkbox').first().props()).toEqual(
expect.objectContaining({ checked: true, indeterminate: false }),
);
});
// https://github.com/ant-design/ant-design/issues/4020
@ -242,12 +233,7 @@ describe('Table.rowSelection', () => {
selections: true,
};
const wrapper = mount(createTable({ rowSelection }));
const dropdownWrapper = render(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
const dropdownWrapper = render(wrapper.find('Trigger').instance().getComponent());
expect(dropdownWrapper).toMatchSnapshot();
});
@ -262,16 +248,8 @@ describe('Table.rowSelection', () => {
checkboxes.at(1).simulate('change', { target: { checked: true } });
const dropdownWrapper = mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
dropdownWrapper
.find('.ant-dropdown-menu-item')
.last()
.simulate('click');
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
dropdownWrapper.find('.ant-dropdown-menu-item').last().simulate('click');
expect(handleSelectInvert).toHaveBeenCalledWith([1, 2, 3]);
});
@ -297,24 +275,13 @@ describe('Table.rowSelection', () => {
};
const wrapper = mount(createTable({ rowSelection }));
const dropdownWrapper = mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
expect(dropdownWrapper.find('.ant-dropdown-menu-item').length).toBe(4);
dropdownWrapper
.find('.ant-dropdown-menu-item')
.at(2)
.simulate('click');
dropdownWrapper.find('.ant-dropdown-menu-item').at(2).simulate('click');
expect(handleSelectOdd).toHaveBeenCalledWith([0, 1, 2, 3]);
dropdownWrapper
.find('.ant-dropdown-menu-item')
.at(3)
.simulate('click');
dropdownWrapper.find('.ant-dropdown-menu-item').at(3).simulate('click');
expect(handleSelectEven).toHaveBeenCalledWith([0, 1, 2, 3]);
});
@ -333,12 +300,7 @@ describe('Table.rowSelection', () => {
],
};
const wrapper = mount(createTable({ rowSelection }));
const dropdownWrapper = mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
expect(dropdownWrapper.find('.ant-dropdown-menu-item').length).toBe(2);
});
@ -361,24 +323,13 @@ describe('Table.rowSelection', () => {
};
const wrapper = mount(createTable({ rowSelection }));
const dropdownWrapper = mount(
wrapper
.find('Trigger')
.instance()
.getComponent(),
);
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
expect(dropdownWrapper.find('.ant-dropdown-menu-item').length).toBe(2);
dropdownWrapper
.find('.ant-dropdown-menu-item')
.at(0)
.simulate('click');
dropdownWrapper.find('.ant-dropdown-menu-item').at(0).simulate('click');
expect(handleSelectOdd).toHaveBeenCalledWith([0, 1, 2, 3]);
dropdownWrapper
.find('.ant-dropdown-menu-item')
.at(1)
.simulate('click');
dropdownWrapper.find('.ant-dropdown-menu-item').at(1).simulate('click');
expect(handleSelectEven).toHaveBeenCalledWith([0, 1, 2, 3]);
});
@ -443,10 +394,7 @@ describe('Table.rowSelection', () => {
dataSource: newData,
}),
);
wrapper
.find('Pager')
.last()
.simulate('click'); // switch to second page
wrapper.find('Pager').last().simulate('click'); // switch to second page
wrapper.update();
wrapper
.find('input')
@ -473,12 +421,7 @@ describe('Table.rowSelection', () => {
.find('input')
.at(1)
.simulate('change', { target: { checked: true } });
expect(
wrapper
.find('tbody tr')
.at(0)
.hasClass('ant-table-row-selected'),
).toBe(true);
expect(wrapper.find('tbody tr').at(0).hasClass('ant-table-row-selected')).toBe(true);
});
it('fix selection column on the left', () => {
@ -580,24 +523,14 @@ describe('Table.rowSelection', () => {
}}
/>,
);
expect(
wrapper
.find('thead tr th')
.at(0)
.text(),
).toBe('多选');
expect(wrapper.find('thead tr th').at(0).text()).toBe('多选');
wrapper.setProps({
rowSelection: {
type: 'radio',
columnTitle: '单选',
},
});
expect(
wrapper
.find('thead tr th')
.at(0)
.text(),
).toBe('单选');
expect(wrapper.find('thead tr th').at(0).text()).toBe('单选');
});
// https://github.com/ant-design/ant-design/issues/11384
@ -632,10 +565,7 @@ describe('Table.rowSelection', () => {
function clickFilter(indexList) {
indexList.forEach(index => {
wrapper
.find('.ant-dropdown-menu-item .ant-checkbox-wrapper')
.at(index)
.simulate('click');
wrapper.find('.ant-dropdown-menu-item .ant-checkbox-wrapper').at(index).simulate('click');
});
wrapper
.find('.ant-table-filter-dropdown-btns .ant-btn-primary')
@ -695,20 +625,14 @@ describe('Table.rowSelection', () => {
const checkboxes = wrapper.find('input');
checkboxes.at(1).simulate('change', { target: { checked: true } });
expect(
wrapper
.find('Checkbox')
.first()
.props(),
).toEqual(expect.objectContaining({ indeterminate: true, checked: false }));
expect(wrapper.find('Checkbox').first().props()).toEqual(
expect.objectContaining({ indeterminate: true, checked: false }),
);
checkboxes.at(2).simulate('change', { target: { checked: true } });
expect(
wrapper
.find('Checkbox')
.first()
.props(),
).toEqual(expect.objectContaining({ indeterminate: false, checked: true }));
expect(wrapper.find('Checkbox').first().props()).toEqual(
expect.objectContaining({ indeterminate: false, checked: true }),
);
});
// https://github.com/ant-design/ant-design/issues/16614
@ -773,10 +697,7 @@ describe('Table.rowSelection', () => {
it('select by checkbox to trigger stopPropagation', () => {
const wrapper = mount(createTable());
expect(() => {
wrapper
.find('span')
.at(10)
.simulate('click');
wrapper.find('span').at(10).simulate('click');
}).not.toThrow();
});
@ -802,10 +723,23 @@ describe('Table.rowSelection', () => {
wrapper.find('.ant-table-row-expand-icon').simulate('click');
expect(() => {
wrapper
.find('input')
.last()
.simulate('change');
wrapper.find('input').last().simulate('change');
}).not.toThrow();
});
it('should onRowClick not called when checkbox clicked', () => {
const onRowClick = jest.fn();
const wrapper = mount(
createTable({
onRow: () => ({
onClick: onRowClick,
}),
}),
);
wrapper.find('input').last().simulate('click');
expect(onRowClick).not.toHaveBeenCalled();
});
});

View File

@ -25,7 +25,9 @@ exports[`Table.expand click to expand 1`] = `
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"

View File

@ -75,7 +75,9 @@ exports[`Table.filter renders custom filter icon as string correctly 1`] = `
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -197,7 +199,9 @@ exports[`Table.filter renders custom filter icon with right Tooltip title 1`] =
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -327,7 +331,9 @@ exports[`Table.filter renders filter correctly 1`] = `
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -660,7 +666,9 @@ exports[`Table.filter should support getPopupContainer 1`] = `
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -893,7 +901,9 @@ exports[`Table.filter should support getPopupContainer from ConfigProvider 1`] =
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"

View File

@ -25,7 +25,9 @@ exports[`Table.pagination Accepts pagination as true 1`] = `
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -188,7 +190,9 @@ exports[`Table.pagination renders pagination correctly 1`] = `
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"

View File

@ -20,7 +20,7 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
class="ant-table-content"
>
<table
style="table-layout:auto"
style="table-layout:fixed"
>
<colgroup>
<col
@ -31,7 +31,9 @@ exports[`Table.rowSelection fix expand on th left when selection column fixed on
/>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-row-expand-icon-cell ant-table-cell-fix-left"
@ -337,7 +339,7 @@ exports[`Table.rowSelection fix selection column on the left 1`] = `
class="ant-table-content"
>
<table
style="table-layout:auto"
style="table-layout:fixed"
>
<colgroup>
<col
@ -345,7 +347,9 @@ exports[`Table.rowSelection fix selection column on the left 1`] = `
/>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column ant-table-cell-fix-left ant-table-cell-fix-left-last"
@ -607,7 +611,7 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
class="ant-table-content"
>
<table
style="table-layout:auto"
style="table-layout:fixed"
>
<colgroup>
<col
@ -615,7 +619,9 @@ exports[`Table.rowSelection fix selection column on the left when any other colu
/>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column ant-table-cell-fix-left"
@ -917,7 +923,9 @@ exports[`Table.rowSelection use column as selection column when key is \`selecti
/>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column"

View File

@ -1,7 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP
exports[`Table.sorter renders sorter icon correctly 1`] = `
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
@ -91,7 +93,9 @@ exports[`Table.sorter should support defaultOrder in Column 1`] = `
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-column-sort ant-table-column-has-sorters"

View File

@ -27,7 +27,9 @@ exports[`Table renders JSX correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -133,7 +135,9 @@ exports[`Table rtl render component should be rendered correctly in RTL directio
<colgroup>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -202,82 +206,6 @@ exports[`Table rtl render component should be rendered correctly in RTL directio
</div>
</div>
</div>
<ul
class="ant-pagination ant-table-pagination ant-pagination-rtl"
unselectable="unselectable"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-0 ant-pagination-disabled ant-pagination-item-disabled"
tabindex="0"
title="0"
>
<a>
0
</a>
</li>
<li
aria-disabled="true"
class="ant-pagination-next ant-pagination-disabled"
title="Next Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>

View File

@ -31,7 +31,9 @@ exports[`renders ./components/table/demo/ajax.md correctly 1`] = `
/>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
@ -205,82 +207,6 @@ exports[`renders ./components/table/demo/ajax.md correctly 1`] = `
</div>
</div>
</div>
<ul
class="ant-pagination ant-table-pagination"
unselectable="unselectable"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-0 ant-pagination-disabled ant-pagination-item-disabled"
tabindex="0"
title="0"
>
<a>
0
</a>
</li>
<li
aria-disabled="true"
class="ant-pagination-next ant-pagination-disabled"
title="Next Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>
@ -315,7 +241,9 @@ exports[`renders ./components/table/demo/basic.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -616,7 +544,9 @@ exports[`renders ./components/table/demo/bordered.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -824,7 +754,9 @@ exports[`renders ./components/table/demo/colspan-rowspan.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -1106,7 +1038,9 @@ exports[`renders ./components/table/demo/custom-filter-panel.md correctly 1`] =
/>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -1435,7 +1369,9 @@ exports[`renders ./components/table/demo/drag-sorting.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -2361,7 +2297,9 @@ exports[`renders ./components/table/demo/dynamic-settings.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-row-expand-icon-cell"
@ -3406,7 +3344,9 @@ exports[`renders ./components/table/demo/edit-cell.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -3618,7 +3558,9 @@ exports[`renders ./components/table/demo/edit-row.md correctly 1`] = `
/>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -4119,7 +4061,9 @@ exports[`renders ./components/table/demo/ellipsis.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -4400,7 +4344,9 @@ exports[`renders ./components/table/demo/expand.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-row-expand-icon-cell"
@ -4694,7 +4640,9 @@ exports[`renders ./components/table/demo/expand-children.md correctly 1`] = `
style="width:30%;min-width:30%"
/>
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column"
@ -4963,7 +4911,9 @@ exports[`renders ./components/table/demo/fixed-columns.md correctly 1`] = `
style="width:100px;min-width:100px"
/>
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-cell-fix-left"
@ -5322,7 +5272,9 @@ exports[`renders ./components/table/demo/fixed-columns-header.md correctly 1`] =
style="width:0;min-width:0"
/>
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-cell-fix-left"
@ -6319,7 +6271,9 @@ exports[`renders ./components/table/demo/fixed-header.md correctly 1`] = `
style="width:0;min-width:0"
/>
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -7505,7 +7459,9 @@ exports[`renders ./components/table/demo/grouping-columns.md correctly 1`] = `
style="width:0;min-width:0"
/>
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-cell-fix-left ant-table-cell-fix-left-last"
@ -8412,7 +8368,9 @@ exports[`renders ./components/table/demo/head.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-column-has-sorters"
@ -8848,7 +8806,9 @@ exports[`renders ./components/table/demo/jsx.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -9171,7 +9131,9 @@ exports[`renders ./components/table/demo/multiple-sorter.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -9580,7 +9542,9 @@ exports[`renders ./components/table/demo/nested-table.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-row-expand-icon-cell"
@ -9920,7 +9884,9 @@ exports[`renders ./components/table/demo/reset-filter.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-cell-ellipsis ant-table-column-has-sorters"
@ -10392,7 +10358,9 @@ exports[`renders ./components/table/demo/resizable-column.md correctly 1`] = `
/>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell react-resizable"
@ -10754,7 +10722,9 @@ exports[`renders ./components/table/demo/row-selection.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column"
@ -11102,7 +11072,9 @@ exports[`renders ./components/table/demo/row-selection-and-operation.md correctl
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column"
@ -11690,7 +11662,9 @@ exports[`renders ./components/table/demo/row-selection-custom.md correctly 1`] =
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column"
@ -12696,7 +12670,9 @@ exports[`renders ./components/table/demo/size.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -12891,7 +12867,9 @@ exports[`renders ./components/table/demo/size.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -13087,7 +13065,9 @@ exports[`renders ./components/table/demo/summary.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -13280,7 +13260,9 @@ exports[`renders ./components/table/demo/virtual-list.md correctly 1`] = `
style="width:0;min-width:0"
/>
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"

View File

@ -32,7 +32,9 @@ exports[`Table renders empty table 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -176,7 +178,9 @@ exports[`Table renders empty table with custom emptyText 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -263,7 +267,7 @@ exports[`Table renders empty table with fixed columns 1`] = `
class="ant-table-content"
>
<table
style="table-layout:auto"
style="table-layout:fixed"
>
<colgroup>
<col
@ -284,7 +288,9 @@ exports[`Table renders empty table with fixed columns 1`] = `
style="width:100px;min-width:100px"
/>
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-cell-fix-left"
@ -468,7 +474,9 @@ exports[`Table renders empty table without emptyText when loading 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell"
@ -575,82 +583,6 @@ exports[`Table renders empty table without emptyText when loading 1`] = `
</div>
</div>
</div>
<ul
class="ant-pagination ant-table-pagination"
unselectable="unselectable"
>
<li
aria-disabled="true"
class="ant-pagination-prev ant-pagination-disabled"
title="Previous Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="left"
class="anticon anticon-left"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="left"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M724 218.3V141c0-6.7-7.7-10.4-12.9-6.3L260.3 486.8a31.86 31.86 0 000 50.3l450.8 352.1c5.3 4.1 12.9.4 12.9-6.3v-77.3c0-4.9-2.3-9.6-6.1-12.6l-360-281 360-281.1c3.8-3 6.1-7.7 6.1-12.6z"
/>
</svg>
</span>
</a>
</li>
<li
class="ant-pagination-item ant-pagination-item-0 ant-pagination-disabled ant-pagination-item-disabled"
tabindex="0"
title="0"
>
<a>
0
</a>
</li>
<li
aria-disabled="true"
class="ant-pagination-next ant-pagination-disabled"
title="Next Page"
>
<a
class="ant-pagination-item-link"
disabled=""
>
<span
aria-label="right"
class="anticon anticon-right"
role="img"
>
<svg
aria-hidden="true"
class=""
data-icon="right"
fill="currentColor"
focusable="false"
height="1em"
viewBox="64 64 896 896"
width="1em"
>
<path
d="M765.7 486.8L314.9 134.7A7.97 7.97 0 00302 141v77.3c0 4.9 2.3 9.6 6.1 12.6l360 281.1-360 281.1c-3.9 3-6.1 7.7-6.1 12.6V883c0 6.7 7.7 10.4 12.9 6.3l450.8-352.1a31.96 31.96 0 000-50.4z"
/>
</svg>
</span>
</a>
</li>
</ul>
</div>
</div>
</div>

View File

@ -321,6 +321,7 @@ export default function useSelection<RecordType>(
<Radio
{...checkboxPropsMap.get(key)}
checked={checked}
onClick={e => e.stopPropagation()}
onChange={event => {
if (!keySet.has(key)) {
triggerSingleSelection(key, true, [key], event.nativeEvent);
@ -342,6 +343,7 @@ export default function useSelection<RecordType>(
<Checkbox
{...checkboxPropsMap.get(key)}
checked={checked}
onClick={e => e.stopPropagation()}
onChange={({ nativeEvent }) => {
const { shiftKey } = nativeEvent;

View File

@ -33,8 +33,8 @@
}
// ============================= Cell =============================
thead > tr > th,
tbody > tr > td,
&-thead > tr > th,
&-tbody > tr > td,
tfoot > tr > th,
tfoot > tr > td {
position: relative;
@ -74,7 +74,7 @@
}
// ============================ Header ============================
thead {
&-thead {
> tr {
> th {
color: @table-header-color;
@ -98,7 +98,7 @@
}
// ============================= Body =============================
tbody {
&-tbody {
> tr {
> td {
border-bottom: @border-width-base @border-style-base @border-color-split;
@ -132,7 +132,7 @@
background: transparent;
}
tbody > tr:last-child > td {
&-tbody > tr:last-child > td {
border-bottom: 0;
&:first-child,
@ -165,7 +165,7 @@
// ================================================================
// ============================ Sorter ============================
thead th.@{table-prefix-cls}-column-has-sorters {
&-thead th.@{table-prefix-cls}-column-has-sorters {
padding: 0;
cursor: pointer;
transition: all 0.3s;
@ -179,7 +179,7 @@
}
}
thead th.@{table-prefix-cls}-column-sort {
&-thead th.@{table-prefix-cls}-column-sort {
background: @table-header-sort-bg;
}
td&-column-sort {
@ -250,7 +250,7 @@
&-open,
&:hover,
thead th.@{table-prefix-cls}-column-has-sorters:hover &:hover {
.@{table-prefix-cls}-thead th.@{table-prefix-cls}-column-has-sorters:hover &:hover {
background: @table-header-filter-active-bg;
}
}
@ -464,7 +464,8 @@
}
// ========================= Placeholder ==========================
tbody > tr&-placeholder {
&-tbody > tr&-placeholder {
text-align: center;
&:hover {
> td {
background: @component-background;

View File

@ -18,7 +18,7 @@
}
// ============================ Header ============================
thead {
&-thead {
> tr {
> th {
&[colspan]:not([colspan='1']) {
@ -35,7 +35,7 @@
}
// ============================= Body =============================
tbody {
&-tbody {
> tr {
// ========================= Nest Table ===========================
.@{table-prefix-cls} {

View File

@ -9,8 +9,8 @@
.@{table-prefix-cls}.@{table-prefix-cls}-@{size} {
.@{table-prefix-cls}-title,
.@{table-prefix-cls}-footer,
thead > tr > th,
tbody > tr > td {
.@{table-prefix-cls}-thead > tr > th,
.@{table-prefix-cls}-tbody > tr > td {
padding: @padding-vertical @padding-horizontal;
}
@ -35,7 +35,7 @@
.table-size(~'small', @table-padding-vertical-sm, @table-padding-horizontal-sm);
.@{table-prefix-cls}.@{table-prefix-cls}-small {
thead > tr > th {
.@{table-prefix-cls}-thead > tr > th {
background-color: @table-header-bg-sm;
}
}

View File

@ -16,16 +16,6 @@
}
}
&-tab-prev,
&-tab-next {
&-icon {
.@{tab-prefix-cls}-rtl & {
right: 50%;
left: auto;
}
}
}
&-tab-next {
.@{tab-prefix-cls}-rtl & {
right: auto;

View File

@ -116,4 +116,20 @@
}
}
}
&.@{timeline-prefix-cls}-label {
.@{timeline-prefix-cls}-item-label {
.@{timeline-prefix-cls}-rtl& {
text-align: left;
}
}
.@{timeline-prefix-cls}-item-right {
.@{timeline-prefix-cls}-item-label {
.@{timeline-prefix-cls}-rtl& {
right: calc(50% + 14px);
text-align: right;
}
}
}
}
}

View File

@ -253,7 +253,7 @@ describe('Tooltip', () => {
);
expect(wrapper.find('.ant-tooltip-inner').getDOMNode().innerHTML).toBe('0');
});
it('autoAdjustOverflow should be object or undefined', () => {
expect(() => {
mount(
@ -286,7 +286,7 @@ describe('Tooltip', () => {
</span>
</Tooltip>,
);
await sleep(500);
await sleep(600);
expect(wrapper.instance().getPopupDomNode().className).toContain('placement-bottomLeft');
});

View File

@ -2251,7 +2251,9 @@ exports[`renders ./components/transfer/demo/table-transfer.md correctly 1`] = `
<col />
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column"
@ -2931,7 +2933,9 @@ exports[`renders ./components/transfer/demo/table-transfer.md correctly 1`] = `
/>
<col />
</colgroup>
<thead>
<thead
class="ant-table-thead"
>
<tr>
<th
class="ant-table-cell ant-table-selection-column"

View File

@ -1,3 +1,3 @@
import { version } from '../../package.json';
import packageInfo from '../../package.json';
export default version;
export default packageInfo.version;

View File

@ -68,3 +68,7 @@ After cloning antd, run `npm install` to fetch its dependencies. Then, you can r
1. `npm test` runs the complete test suite.
1. `npm run compile` compiles TypeScript code to the `lib` and `es` directory.
1. `npm run dist` creates UMD build of antd.
## Being a collaborator
If you are a active contributor and are willing to work with Ant Design Team in our opensource workflow, you can [apply to be a outside collaborator](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator).

View File

@ -68,3 +68,7 @@ Ant Design 团队会关注所有的 pull request我们会 review 以及合并
3. `npm test` 运行测试。
4. `npm run compile` 编译 TypeScript 代码到 lib 和 es 目录。
5. `npm run dist` 构建 antd 的 UMD 版本到 dist 目录。
## 加入社区
如果你贡献度度足够活跃,希望和 Ant Design 团队一起参与维护工作,你可以[申请成为社区协作者](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)。

View File

@ -141,6 +141,7 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
- [CodeSandbox Template](https://u.ant.design/codesandbox-repro) for bug reports
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
- [Customize Theme](/docs/react/customize-theme)
- [How to Apply for Being A Collaborator](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)
## Companies using antd

View File

@ -144,6 +144,7 @@ import 'antd/dist/antd.css'; // or 'antd/dist/antd.less'
- [CodeSandbox 模板](https://u.ant.design/codesandbox-repro) for bug reports
- [Awesome Ant Design](https://github.com/websemantics/awesome-ant-design)
- [定制主题](/docs/react/customize-theme)
- [成为社区协作成员](https://github.com/ant-design/ant-design/wiki/Collaborators#how-to-apply-for-being-a-collaborator)
## 谁在使用

View File

@ -120,8 +120,8 @@ const Demo = () => (
- Tree, Select, TreeSelect, AutoComplete rewrite
- use virtual scrolling.
- `onBlur` no longer trigger value change.
- `dropdownMatchSelectWidth={false}` will no longer automatically adapt dropdown to the content width, please set the dropdown width with numbers.
- AutoComplete no longer support `optionLabelProp`. Please set Option `value` directly.
- Select remove `dropdownMenuStyle` prop.
- The Grid component uses flex layout.
- Button's `danger` is now treated as a property instead of a button type.
- Input, Select set `value` to `undefined` is uncontrolled mode now.

View File

@ -120,8 +120,8 @@ const Demo = () => (
- Tree、Select、TreeSelect、AutoComplete 重新写
- 使用虚拟滚动。
- `onBlur` 时不再修改选中值。
- `dropdownMatchSelectWidth={false}` 时下拉菜单不再会自动适应内容宽度,请用数字设置下拉宽度。
- AutoComplete 不再支持 `optionLabelProp`,请直接设置 Option `value` 属性。
- Select 移除 `dropdownMenuStyle` 属性。
- Grid 组件使用 flex 布局。
- Button 的 `danger` 现在作为一个属性而不是按钮类型。
- Input、Select 的 `value``undefined` 时改为非受控状态。

View File

@ -85,7 +85,7 @@ Do you want to know the story behind the Ant Design design system? How can I bet
## Reference
Please find below the books that inspired us, saved our time and helped us to overcome difficulties when designing components and patterns. If you want to know more about UI design, we recommend you these awesome design systems: [Fiori Design](https://experience.sap.com/fiori-design-web/) [Human Interface Guidelines](https://developer.apple.com/ios/human-interface-guidelines/overview/themes/)、 [Lightning Design System](https://lightningdesignsystem.com/getting-started/)、 [Material Design](https://material.io/)
Please find below the books that inspired us, saved our time and helped us to overcome difficulties when designing components and patterns. If you want to know more about UI design, we recommend you these awesome design systems: [Fiori Design](https://experience.sap.com/fiori-design-web/), [Human Interface Guidelines](https://developer.apple.com/ios/human-interface-guidelines/overview/themes/), [Lightning Design System](https://lightningdesignsystem.com/getting-started/), [Material Design](https://material.io/).
<div class="next-block-use-cards"></div>

View File

@ -7,7 +7,7 @@
z-index: 100;
width: 100%;
height: 100%;
background-image: url('https://os.alipayobjects.com/rmsportal/NOAjOBbnYCrNzrW.jpg');
background-color: #fff;
background-repeat: no-repeat;
background-position: center;
background-size: 100%;
@ -15,10 +15,10 @@
section {
position: absolute;
top: 48%;
left: 55%;
margin: -103px 0 0 -120px;
top: 50%;
left: 50%;
text-align: center;
transform: translate(-50%, -50%);
}
h1 {

View File

@ -1,171 +0,0 @@
.santa {
display: inline-block;
margin-right: 8px;
margin-left: 8px;
vertical-align: middle;
}
.santa-body {
display: flex;
align-items: center;
justify-content: center;
width: 1em;
height: 1em;
color: #f91047;
font-size: 24px;
background-color: currentColor;
border-radius: 50%;
box-shadow: inset 0 -0.25em rgba(0, 0, 0, 0.1);
transform-origin: center bottom;
animation: balance alternate infinite 2s ease-in-out;
}
.santa-head {
position: relative;
width: 1em;
height: 1.9em;
font-size: 0.4em;
background-color: white;
border-radius: 0.5em;
transform: translateY(-1em);
}
.santa-head::before {
position: absolute;
top: 0.65em;
left: 0;
display: block;
width: 1em;
height: 0.375em;
background-color: #ff9876;
content: '';
}
.santa-ear {
position: absolute;
top: 0.75em;
width: 0.1em;
height: 0.3em;
background-color: #fc8363;
}
.santa-ear:nth-of-type(1) {
left: -0.1em;
border-radius: 0.05em 0 0 0.05em;
}
.santa-ear:nth-of-type(2) {
right: -0.1em;
border-radius: 0 0.05em 0.05em 0;
}
.santa-hat {
position: absolute;
top: 0.5em;
left: 0;
width: 1em;
height: 0.15em;
background-color: white;
transform: scale(1.1);
content: '';
}
.santa-hat::before {
position: absolute;
top: -0.5em;
z-index: 2;
display: block;
width: 1em;
height: 0.5em;
background: #f91047;
border-radius: 0.5em 0.5em 0 0;
content: '';
}
.santa-hat::after {
position: absolute;
top: -0.72em;
right: 0;
z-index: 0;
display: block;
width: 0.25em;
height: 0.25em;
background-color: white;
border-radius: 50%;
box-shadow: -0.2em 0.2em 0 0.12em rgba(0, 0, 0, 0.2), -0.2em 0.2em 0 0.12em #f91047;
/* pompom */
content: '';
}
.santa-eye {
position: absolute;
top: 0.76em;
left: 0.2em;
width: 0.12em;
height: 0.12em;
background-color: black;
border-radius: 50%;
}
.santa-eye + .santa-eye {
right: 0.2em;
left: auto;
}
.santa-nose {
position: absolute;
top: 0.84em;
left: 50%;
width: 0.12em;
height: 0.22em;
background-color: #f24c4c;
border-radius: 0 0 0.12em 0.12em;
transform: translateX(-50%);
}
.santa-mouth {
position: absolute;
top: 50%;
left: 50%;
width: 0.18em;
height: 0.1em;
margin-top: 0.3em;
background-color: black;
border-bottom-right-radius: 5vw;
border-bottom-left-radius: 5vw;
transform: translate(-50%, -50%);
animation: hohoho 4s linear forwards infinite;
}
@keyframes hohoho {
0%,
10%,
20%,
40%,
100% {
/* smiling */
width: 0.18em;
height: 0.1em;
border-bottom-right-radius: 1vw;
border-bottom-left-radius: 1vw;
}
5%,
15%,
25%,
35% {
/* hohoho */
width: 0.15em;
height: 0.2em;
border-radius: 50%;
}
}
@keyframes balance {
from {
transform: rotate(-4deg);
}
to {
transform: rotate(4deg);
}
}

View File

@ -84,6 +84,14 @@ const RecommendBlock = ({
href={href}
target="_blank"
rel="noopener noreferrer"
onClick={() => {
if (window.gtag) {
window.gtag('event', '点击', {
event_category: '首页推广',
event_label: href,
});
}
}}
>
<img src={img} alt={title} />
{popularize && (

View File

@ -1,26 +0,0 @@
import React from 'react';
import { Tooltip } from 'antd';
export default () => {
const now = new Date();
const isChristmas = now.getMonth() === 11 && now.getDate() === 25;
return (
isChristmas && (
<Tooltip title="🎅🏻 Merry Christmas!">
<div className="santa">
<div className="santa-body">
<div className="santa-head">
<div className="santa-ear" />
<div className="santa-ear" />
<div className="santa-hat" />
<div className="santa-eye" />
<div className="santa-eye" />
<div className="santa-nose" />
<div className="santa-mouth" />
</div>
</div>
</div>
</Tooltip>
)
);
};

View File

@ -1,5 +1,7 @@
import React from 'react';
import React, { useEffect } from 'react';
import { Link } from 'bisheng/router';
import { Result, Button } from 'antd';
import { HomeOutlined } from '@ant-design/icons';
import * as utils from './utils';
export interface NotFoundProps {
@ -30,14 +32,14 @@ export default function NotFound(props: NotFoundProps) {
router,
} = props;
React.useEffect(() => {
const isZhCN = utils.isZhCN(pathname);
useEffect(() => {
const directLinks = Object.keys(DIRECT_MAP);
for (let i = 0; i < directLinks.length; i += 1) {
const matchPath = directLinks[i];
if (pathname.includes(matchPath)) {
router.replace(
utils.getLocalizedPathname(`/${DIRECT_MAP[matchPath]}`, utils.isZhCN(pathname)),
);
router.replace(utils.getLocalizedPathname(`/${DIRECT_MAP[matchPath]}`, isZhCN));
}
}
}, []);
@ -45,11 +47,20 @@ export default function NotFound(props: NotFoundProps) {
return (
<div id="page-404">
<section>
<h1>404!</h1>
<p>
<Link to={utils.getLocalizedPathname('/', utils.isZhCN(pathname))}></Link>
</p>
<Result
status="404"
title="404"
subTitle={
isZhCN ? '你访问的页面貌似不存在?' : 'Sorry, the page you visited does not exist.'
}
extra={
<Link to={utils.getLocalizedPathname('/', isZhCN)}>
<Button type="primary" icon={<HomeOutlined />}>
{isZhCN ? '返回 Ant Design 首页' : 'Back to home page'}
</Button>
</Link>
}
/>
</section>
<style
dangerouslySetInnerHTML={{