Merge pull request #25589 from ant-design/master

chore: merge master into feature
This commit is contained in:
偏右 2020-07-12 18:38:18 +08:00 committed by GitHub
commit 4b2bc6c6fb
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
31 changed files with 384 additions and 172 deletions

View File

@ -15,6 +15,25 @@ timeline: true
---
## 4.4.2
`2020-07-11`
- 🛠 Adjust Alert animation to remove directly dom operation. [#dd8e9f8](https://github.com/ant-design/ant-design/commit/dd8e9f8) [@Yunfly](https://github.com/Yunfly)
- Select
- 🐞 Fix Select shifts vertically when searching. [#25536](https://github.com/ant-design/ant-design/pull/25536) [@07akioni](https://github.com/07akioni)
- 💄 Add `@select-item-select-color` to control the color when Select item is selected. [#25476](https://github.com/ant-design/ant-design/pull/25476)
- 🐞 Fix Form.Item warning for `preserve` as invalidate dom prop. [#25518](https://github.com/ant-design/ant-design/pull/25518)
- 🐞 Fix Card cover margin bug when bordered is false. [#25515](https://github.com/ant-design/ant-design/pull/25515) [@yutingzhao1991](https://github.com/yutingzhao1991)
- 💄 Adjust Typography style to set `overflow-wrap: break-word` as default. [#25516](https://github.com/ant-design/ant-design/pull/25516)
- 🐞 Fix Table `expandedRowRender` nested Table cell background color. [#25498](https://github.com/ant-design/ant-design/pull/25498)
- 🐞 Fix Popover wrong positioning on Radio.Button. [#25449](https://github.com/ant-design/ant-design/pull/25449) [@zgoby](https://github.com/zgoby)
- 🐞 Fix RangePicker clear icon position issue when `size=small`. [#25458](https://github.com/ant-design/ant-design/pull/25458)
- 🆕 Upload supports to show thumbnail for non-image files as `thumbUrl` configured in `onChange` event. [#25432](https://github.com/ant-design/ant-design/pull/25432) [@AlbertAZ1992](https://github.com/AlbertAZ1992)
- 🐞 Fix Table `onChange` triggered multiple times when change page size. [#25520](https://github.com/ant-design/ant-design/pull/25520) [@zhangchen915](https://github.com/zhangchen915)
- 🛠 Remove `babel-runtime` and add `@babel/runtime` in dependencies, reduce gzipped bundle size `18.6KB`. [#25530](https://github.com/ant-design/ant-design/pull/25530)
- 🇪🇸 Improve es_ES localization. [#25460](https://github.com/ant-design/ant-design/pull/25460) [@gersongams](https://github.com/gersongams)
## 4.4.1
`2020-07-06`

View File

@ -15,6 +15,25 @@ timeline: true
---
## 4.4.2
`2020-07-11`
- 🛠 调整 Alert 组件关闭动画实现移除直接的 dom 操作。[#dd8e9f8](https://github.com/ant-design/ant-design/commit/dd8e9f8) [@Yunfly](https://github.com/Yunfly)
- Select
- 🐞 修正了 Select 在搜索时纵向位移的问题。[#25536](https://github.com/ant-design/ant-design/pull/25536) [@07akioni](https://github.com/07akioni)
- 💄 增加 `@select-item-selected-color` 以控制 Select 选项选中时的颜色。[#25476](https://github.com/ant-design/ant-design/pull/25476)
- 🐞 修复 Form.Item 警告 `preserve` 是无效 dom 属性的问题。[#25518](https://github.com/ant-design/ant-design/pull/25518)
- 🐞 修复当 Card 组件无边框时封面图边距的问题。[#25515](https://github.com/ant-design/ant-design/pull/25515) [@yutingzhao1991](https://github.com/yutingzhao1991)
- 💄 调整 Typography 样式添加 `overflow-wrap: break-word` 默认样式。[#25516](https://github.com/ant-design/ant-design/pull/25516)
- 🐞 修复 Table `expandedRowRender` 内嵌 Table 时单元格背景丢失的问题。[#25498](https://github.com/ant-design/ant-design/pull/25498)
- 🐞 修复 Radio.Button 上使用 Popover 时的位置异常问题。[#25449](https://github.com/ant-design/ant-design/pull/25449) [@zgoby](https://github.com/zgoby)
- 🐞 修复 RangePicker 在 `size=small` 时清除按钮的位置问题。[#25458](https://github.com/ant-design/ant-design/pull/25458)
- 🆕 Upload 支持上传非图片文件时在 `onChange` 事件中设置 `thumbUrl` 来展示缩略图。[#25432](https://github.com/ant-design/ant-design/pull/25432) [@AlbertAZ1992](https://github.com/AlbertAZ1992)
- 🐞 修复 Table 切换页条目数时 `onChange` 触发多次的问题。[#25520](https://github.com/ant-design/ant-design/pull/25520) [@zhangchen915](https://github.com/zhangchen915)
- 🛠 移除 `babel-runtime` 并添加 `@babel/runtime` 依赖,减少 gzipped 包体积 `18.6KB`。[#25530](https://github.com/ant-design/ant-design/pull/25530)
- 🇪🇸 改进 es_ES 国际化。[#25460](https://github.com/ant-design/ant-design/pull/25460) [@gersongams](https://github.com/gersongams)
## 4.4.1
`2020-07-06`

View File

@ -88,13 +88,6 @@ const Alert: AlertInterface = ({
const prefixCls = getPrefixCls('alert', customizePrefixCls);
const handleClose = (e: React.MouseEvent<HTMLButtonElement>) => {
e.preventDefault();
const dom = ref.current as HTMLElement;
dom.style.height = `${dom.offsetHeight}px`;
// Magic code
// 重复一次后才能正确设置 height
dom.style.height = `${dom.offsetHeight}px`;
setClosing(true);
props.onClose?.(e);
};

View File

@ -7,6 +7,7 @@
.reset-component;
position: relative;
max-height: 1000vh;
padding: 8px 15px 8px 37px;
word-wrap: break-word;
border-radius: @border-radius-base;
@ -146,7 +147,7 @@
}
&&-closing {
height: 0 !important;
max-height: 0;
margin: 0;
padding-top: 0;
padding-bottom: 0;

View File

@ -4199,7 +4199,7 @@ exports[`renders ./components/calendar/demo/notice-calendar.md correctly 1`] = `
`;
exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
<div>
Array [
<div
class="ant-alert ant-alert-info ant-alert-no-icon"
data-show="true"
@ -4212,7 +4212,7 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
<span
class="ant-alert-description"
/>
</div>
</div>,
<div
class="ant-picker-calendar ant-picker-calendar-full"
>
@ -5151,6 +5151,6 @@ exports[`renders ./components/calendar/demo/select.md correctly 1`] = `
</div>
</div>
</div>
</div>
</div>
</div>,
]
`;

View File

@ -37,12 +37,12 @@ class App extends React.Component {
render() {
const { value, selectedValue } = this.state;
return (
<div>
<>
<Alert
message={`You selected date: ${selectedValue && selectedValue.format('YYYY-MM-DD')}`}
/>
<Calendar value={value} onSelect={this.onSelect} onPanelChange={this.onPanelChange} />
</div>
</>
);
}
}

View File

@ -559,7 +559,7 @@ exports[`renders ./components/carousel/demo/fade.md correctly 1`] = `
`;
exports[`renders ./components/carousel/demo/position.md correctly 1`] = `
<div>
Array [
<div
class="ant-radio-group ant-radio-group-outline"
style="margin-bottom:8px"
@ -641,7 +641,7 @@ exports[`renders ./components/carousel/demo/position.md correctly 1`] = `
Right
</span>
</label>
</div>
</div>,
<div
class="ant-carousel"
>
@ -854,6 +854,6 @@ exports[`renders ./components/carousel/demo/position.md correctly 1`] = `
</li>
</ul>
</div>
</div>
</div>
</div>,
]
`;

View File

@ -26,7 +26,7 @@ class PositionCarouselDemo extends React.Component {
render() {
const { dotPosition } = this.state;
return (
<div>
<>
<Radio.Group
onChange={this.handlePositionChange}
value={dotPosition}
@ -51,7 +51,7 @@ class PositionCarouselDemo extends React.Component {
<h3>4</h3>
</div>
</Carousel>
</div>
</>
);
}
}

View File

@ -460,7 +460,7 @@ exports[`renders ./components/collapse/demo/custom.md correctly 1`] = `
`;
exports[`renders ./components/collapse/demo/extra.md correctly 1`] = `
<div>
Array [
<div
class="ant-collapse ant-collapse-icon-position-left"
>
@ -651,11 +651,11 @@ exports[`renders ./components/collapse/demo/extra.md correctly 1`] = `
</div>
</div>
</div>
</div>
<br />
</div>,
<br />,
<span>
Expand Icon Position:
</span>
</span>,
<div
class="ant-select ant-select-single ant-select-show-arrow"
style="margin:0 8px"
@ -715,8 +715,8 @@ exports[`renders ./components/collapse/demo/extra.md correctly 1`] = `
</svg>
</span>
</span>
</div>
</div>
</div>,
]
`;
exports[`renders ./components/collapse/demo/ghost.md correctly 1`] = `

View File

@ -51,7 +51,7 @@ class Demo extends React.Component {
render() {
const { expandIconPosition } = this.state;
return (
<div>
<>
<Collapse
defaultActiveKey={['1']}
onChange={callback}
@ -77,7 +77,7 @@ class Demo extends React.Component {
<Option value="left">left</Option>
<Option value="right">right</Option>
</Select>
</div>
</>
);
}
}

View File

@ -41,3 +41,10 @@ exports[`Grid should render Row 1`] = `
class="ant-row"
/>
`;
exports[`Grid when typeof gutter is object array in large screen 1`] = `
<div
class="ant-row"
style="margin-left:-20px;margin-right:-20px;margin-top:-200px;margin-bottom:200px"
/>
`;

View File

@ -4,6 +4,7 @@ import { Col, Row } from '..';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import useBreakpoint from '../hooks/useBreakpoint';
import ResponsiveObserve from '../../_util/responsiveObserve';
describe('Grid', () => {
mountTest(Row);
@ -24,7 +25,12 @@ describe('Grid', () => {
it('when typeof gutter is object', () => {
const wrapper = mount(<Row gutter={{ xs: 8, sm: 16, md: 24 }} />);
expect(wrapper.instance().getGutter()).toEqual([8, 0]);
expect(wrapper.find('div').first().props().style).toEqual(
expect.objectContaining({
marginLeft: -4,
marginRight: -4,
}),
);
});
it('when typeof gutter is object array', () => {
@ -36,11 +42,16 @@ describe('Grid', () => {
]}
/>,
);
expect(wrapper.instance().getGutter()).toEqual([8, 8]);
expect(wrapper.find('div').first().props().style).toEqual(
expect.objectContaining({
marginLeft: -4,
marginRight: -4,
}),
);
});
it('when typeof gutter is object array in large screen', () => {
const wrapper = mount(
const wrapper = render(
<Row
gutter={[
{ xs: 8, sm: 16, md: 24, lg: 32, xl: 40 },
@ -48,10 +59,7 @@ describe('Grid', () => {
]}
/>,
);
wrapper.setState({
screens: { md: true, lg: true, xl: true },
});
expect(wrapper.instance().getGutter()).toEqual([40, 400]);
expect(wrapper).toMatchSnapshot();
});
it('renders wrapped Col correctly', () => {
@ -68,10 +76,10 @@ describe('Grid', () => {
});
it('when component has been unmounted, componentWillUnmount should be called', () => {
const wrapper = mount(<Row />);
const willUnmount = jest.spyOn(wrapper.instance(), 'componentWillUnmount');
const Unmount = jest.spyOn(ResponsiveObserve, 'unsubscribe');
const wrapper = mount(<Row gutter={{ xs: 20 }} />);
wrapper.unmount();
expect(willUnmount).toHaveBeenCalled();
expect(Unmount).toHaveBeenCalled();
});
it('should work correct when gutter is object', () => {

View File

@ -44,9 +44,8 @@ function parseFlex(flex: FlexType): string {
return flex;
}
export default class Col extends React.Component<ColProps, {}> {
renderCol = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const { props } = this;
const Col = React.forwardRef<HTMLDivElement, ColProps>((props, ref) => {
const renderCol = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
span,
@ -123,7 +122,7 @@ export default class Col extends React.Component<ColProps, {}> {
}
return (
<div {...others} style={mergedStyle} className={classes}>
<div {...others} style={mergedStyle} className={classes} ref={ref}>
{children}
</div>
);
@ -132,7 +131,9 @@ export default class Col extends React.Component<ColProps, {}> {
);
};
render() {
return <ConfigConsumer>{this.renderCol}</ConfigConsumer>;
}
}
return <ConfigConsumer>{renderCol}</ConfigConsumer>;
});
Col.displayName = 'Col';
export default Col;

View File

@ -20,48 +20,37 @@ export interface RowProps extends React.HTMLAttributes<HTMLDivElement> {
prefixCls?: string;
}
export interface RowState {
screens: ScreenMap;
}
const Row = React.forwardRef<HTMLDivElement, RowProps>((props, ref) => {
const [screens, setScreens] = React.useState<ScreenMap>({
xs: true,
sm: true,
md: true,
lg: true,
xl: true,
xxl: true,
});
const gutterRef = React.useRef<Gutter | [Gutter, Gutter]>();
gutterRef.current = props.gutter;
export default class Row extends React.Component<RowProps, RowState> {
static defaultProps = {
gutter: 0,
};
state: RowState = {
screens: {
xs: true,
sm: true,
md: true,
lg: true,
xl: true,
xxl: true,
},
};
token: number;
componentDidMount() {
this.token = ResponsiveObserve.subscribe(screens => {
const { gutter } = this.props;
React.useEffect(() => {
const token = ResponsiveObserve.subscribe(screen => {
const currentGutter = gutterRef.current || 0;
if (
(!Array.isArray(gutter) && typeof gutter === 'object') ||
(Array.isArray(gutter) && (typeof gutter[0] === 'object' || typeof gutter[1] === 'object'))
(!Array.isArray(currentGutter) && typeof currentGutter === 'object') ||
(Array.isArray(currentGutter) &&
(typeof currentGutter[0] === 'object' || typeof currentGutter[1] === 'object'))
) {
this.setState({ screens });
setScreens(screen);
}
});
}
return () => {
ResponsiveObserve.unsubscribe(token);
};
}, []);
componentWillUnmount() {
ResponsiveObserve.unsubscribe(this.token);
}
getGutter(): [number, number] {
const getGutter = (): [number, number] => {
const results: [number, number] = [0, 0];
const { gutter } = this.props;
const { screens } = this.state;
const { gutter = 0 } = props;
const normalizedGutter = Array.isArray(gutter) ? gutter : [gutter, 0];
normalizedGutter.forEach((g, index) => {
if (typeof g === 'object') {
@ -77,9 +66,9 @@ export default class Row extends React.Component<RowProps, RowState> {
}
});
return results;
}
};
renderRow = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const renderRow = ({ getPrefixCls, direction }: ConfigConsumerProps) => {
const {
prefixCls: customizePrefixCls,
justify,
@ -88,9 +77,9 @@ export default class Row extends React.Component<RowProps, RowState> {
style,
children,
...others
} = this.props;
} = props;
const prefixCls = getPrefixCls('row', customizePrefixCls);
const gutter = this.getGutter();
const gutter = getGutter();
const classes = classNames(
prefixCls,
{
@ -120,14 +109,16 @@ export default class Row extends React.Component<RowProps, RowState> {
return (
<RowContext.Provider value={{ gutter }}>
<div {...otherProps} className={classes} style={rowStyle}>
<div {...otherProps} className={classes} style={rowStyle} ref={ref}>
{children}
</div>
</RowContext.Provider>
);
};
render() {
return <ConfigConsumer>{this.renderRow}</ConfigConsumer>;
}
}
return <ConfigConsumer>{renderRow}</ConfigConsumer>;
});
Row.displayName = 'Row';
export default Row;

View File

@ -20465,7 +20465,7 @@ exports[`Locale Provider should display the text as ca 1`] = `
type="button"
>
<span>
OK
Dacord
</span>
</button>
</div>
@ -20522,7 +20522,7 @@ exports[`Locale Provider should display the text as ca 1`] = `
<span
class="ant-transfer-list-header-selected"
>
0 item
0 ítem
</span>
<span
class="ant-transfer-list-header-title"
@ -20537,7 +20537,7 @@ exports[`Locale Provider should display the text as ca 1`] = `
<div>
<input
class="ant-input ant-transfer-list-search"
placeholder="Cercar aquí"
placeholder="Cercar"
type="text"
value=""
/>
@ -20720,7 +20720,7 @@ exports[`Locale Provider should display the text as ca 1`] = `
<span
class="ant-transfer-list-header-selected"
>
0 item
0 ítem
</span>
<span
class="ant-transfer-list-header-title"
@ -20735,7 +20735,7 @@ exports[`Locale Provider should display the text as ca 1`] = `
<div>
<input
class="ant-input ant-transfer-list-search"
placeholder="Cercar aquí"
placeholder="Cercar"
type="text"
value=""
/>
@ -21989,7 +21989,7 @@ exports[`Locale Provider should display the text as ca 1`] = `
type="button"
>
<span>
OK
Dacord
</span>
</button>
</div>

View File

@ -1,21 +1,34 @@
/* eslint-disable no-template-curly-in-string */
import Pagination from 'rc-pagination/lib/locale/ar_EG';
import DatePicker from '../date-picker/locale/ar_EG';
import TimePicker from '../time-picker/locale/ar_EG';
import Calendar from '../calendar/locale/ar_EG';
import { Locale } from '../locale-provider';
const typeTemplate = 'صالحًا ${type} من نوع ${label} ليس';
const localeValues: Locale = {
locale: 'ar',
Pagination,
DatePicker,
TimePicker,
Calendar,
global: {
placeholder: 'يرجى التحديد',
},
Table: {
filterTitle: 'الفلاتر',
filterConfirm: 'تأكيد',
filterReset: 'إعادة ضبط',
selectAll: 'اختيار الكل',
selectInvert: 'إلغاء الاختيار',
selectionAll: 'حدد جميع البيانات',
sortTitle: 'رتب',
expand: 'توسيع الصف',
collapse: 'طي الصف',
triggerDesc: 'ترتيب تنازلي',
triggerAsc: 'ترتيب تصاعدي',
cancelSort: 'إلغاء الترتيب',
},
Modal: {
okText: 'تأكيد',
@ -41,6 +54,67 @@ const localeValues: Locale = {
Empty: {
description: 'لا توجد بيانات',
},
Icon: {
icon: 'أيقونة',
},
Text: {
edit: 'تعديل',
copy: 'نسخ',
copied: 'نقل',
expand: 'وسع',
},
PageHeader: {
back: 'عودة',
},
Form: {
defaultValidateMessages: {
default: '${label} خطأ في حقل الإدخال',
required: '${label} يرجى إدخال',
enum: '[${enum}] يجب أن يكون واحدا من ${label}',
whitespace: 'لا يمكن أن يكون حرفًا فارغًا ${label}',
date: {
format: 'تنسيق التاريخ غير صحيح ${label}',
parse: 'لا يمكن تحويلها إلى تاريخ ${label}',
invalid: 'غير صحيح ${label} تاريخ',
},
types: {
string: typeTemplate,
method: typeTemplate,
array: typeTemplate,
object: typeTemplate,
number: typeTemplate,
date: typeTemplate,
boolean: typeTemplate,
integer: typeTemplate,
float: typeTemplate,
regexp: typeTemplate,
email: typeTemplate,
url: typeTemplate,
hex: typeTemplate,
},
string: {
len: 'أحرف ${len} ان يكون ${label} يجب',
min: 'أحرف ${min} على الأقل ${label}',
max: 'أحرف ${max} يصل إلى ${label}',
range: 'أحرف ${max}-${min} ان يكون مابين ${label} يجب',
},
number: {
len: '${len} ان يساوي ${label} يجب',
min: '${min} الأدنى هو ${label} حد',
max: '${max} الأقصى هو ${label} حد',
range: '${max}-${min} ان يكون مابين ${label} يجب',
},
array: {
len: '${len} طوله ${label} يجب أن يكون',
min: '${min} طوله الأدنى ${label} يجب أن يكون',
max: '${max} طوله الأقصى ${label} يجب أن يكون',
range: '${max}-${min} طوله مابين ${label} يجب أن يكون',
},
pattern: {
mismatch: '${pattern} مع ${label} لا يتطابق',
},
},
},
};
export default localeValues;

View File

@ -1,44 +1,128 @@
/* eslint-disable no-template-curly-in-string */
import Pagination from 'rc-pagination/lib/locale/ca_ES';
import DatePicker from '../date-picker/locale/ca_ES';
import TimePicker from '../time-picker/locale/ca_ES';
import Calendar from '../calendar/locale/ca_ES';
import { Locale } from '../locale-provider';
const typeTemplate = '${label} no és un ${type} vàlid';
const localeValues: Locale = {
locale: 'ca',
Pagination,
DatePicker,
TimePicker,
Calendar,
global: {
placeholder: 'Seleccionar',
},
Table: {
filterTitle: 'Filtrar Menu',
filterConfirm: 'OK',
filterReset: 'Restablir',
filterTitle: 'Filtrar el menú',
filterConfirm: 'Dacord',
filterReset: 'Reiniciar',
filterEmptyText: 'Sense filtres',
selectAll: 'Seleccionar la pàgina actual',
selectInvert: 'Invertir la selecció',
selectionAll: 'Seleccionar-ho tot',
sortTitle: 'Ordenar',
expand: 'Ampliar la fila',
collapse: 'Plegar la fila',
triggerDesc: 'Ordre descendent',
triggerAsc: 'Ordre ascendent',
cancelSort: 'Desactivar lordre',
},
Modal: {
okText: 'OK',
okText: 'Dacord',
cancelText: 'Cancel·lar',
justOkText: 'OK',
justOkText: 'Dacord',
},
Popconfirm: {
okText: 'OK',
okText: 'Dacord',
cancelText: 'Cancel·lar',
},
Transfer: {
searchPlaceholder: 'Cercar aquí',
itemUnit: 'item',
itemsUnit: 'items',
titles: ['', ''],
searchPlaceholder: 'Cercar',
itemUnit: 'ítem',
itemsUnit: 'ítems',
remove: 'Eliminar',
selectCurrent: 'Seleccionar la pàgina actual',
removeCurrent: 'Eliminar la selecció',
selectAll: 'Seleccionar-ho tot',
removeAll: 'Eliminar-ho tot',
selectInvert: 'Invertir la selecció',
},
Upload: {
uploading: 'Carregant...',
removeFile: 'Elimina el fitxer',
uploading: 'Carregant',
removeFile: 'Eliminar el fitxer',
uploadError: 'Error de càrrega',
previewFile: 'Vista prèvia del fitxer',
downloadFile: "Descarrega l'arxiu",
downloadFile: 'Baixar el fitxer',
},
Empty: {
description: 'Sense dades',
},
Icon: {
icon: 'icona',
},
Text: {
edit: 'Editar',
copy: 'Copiar',
copied: 'Copiat',
expand: 'Ampliar',
},
PageHeader: {
back: 'Enrere',
},
Form: {
defaultValidateMessages: {
default: 'Error de validació del camp ${label}',
required: 'Introdueix ${label}',
enum: '${label} ha de ser un de [${enum}]',
whitespace: '${label} no pot ser un caràcter en blanc',
date: {
format: 'El format de la data de ${label} és invàlid',
parse: '${label} no es pot convertir a cap data',
invalid: '${label} és una data invàlida',
},
types: {
string: typeTemplate,
method: typeTemplate,
array: typeTemplate,
object: typeTemplate,
number: typeTemplate,
date: typeTemplate,
boolean: typeTemplate,
integer: typeTemplate,
float: typeTemplate,
regexp: typeTemplate,
email: typeTemplate,
url: typeTemplate,
hex: typeTemplate,
},
string: {
len: '${label} ha de ser de ${len} caràcters',
min: '${label} ha de tenir com a mínim ${min} caràcters',
max: '${label} ha de tenir com a màxim ${max} caràcters',
range: '${label} ha destar entre ${min} i ${max} caràcters',
},
number: {
len: '${label} ha de ser igual a ${len}',
min: '${label} ha de tenir un valor mínim de ${min}',
max: '${label} ha de tenir un valor màxim de ${max}',
range: '${label} ha de tenir un valor entre ${min} i ${max}',
},
array: {
len: 'La llargada de ${label} ha de ser de ${len}',
min: 'La llargada de ${label} ha de ser com a mínim de ${min}',
max: 'La llargada de ${label} ha de ser com a màxim de ${max}',
range: 'La llargada de ${label} ha destar entre ${min} i ${max}',
},
pattern: {
mismatch: '${label} no coincideix amb el patró ${pattern}',
},
},
},
};
export default localeValues;

View File

@ -31,7 +31,7 @@ A long list can be divided into several pages using `Pagination`, and only one p
| pageSizeOptions | Specify the sizeChanger options | string\[] | \[`10`, `20`, `50`, `100`] | |
| showLessItems | Show less page items | boolean | false | |
| showQuickJumper | Determine whether you can jump to pages directly | boolean \| { goButton: ReactNode } | false | |
| showSizeChanger | Determine whether to show `pageSize` select, it will be `true` when `total>=50` | boolean | - | |
| showSizeChanger | Determine whether to show `pageSize` select, it will be true when `total > 50` | boolean | - | |
| showTitle | Show page item's title | boolean | true | |
| showTotal | To display the total number and range | function(total, range) | - | |
| simple | Whether to use simple mode | boolean | - | |

View File

@ -32,7 +32,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/1vqv2bj68/Pagination.svg
| pageSizeOptions | 指定每页可以显示多少条 | string\[] | \[`10`, `20`, `50`, `100`] | |
| showLessItems | 是否显示较少页面内容 | boolean | false | |
| showQuickJumper | 是否可以快速跳转至某页 | boolean \| { goButton: ReactNode } | false | |
| showSizeChanger | 是否展示 `pageSize` 切换器,当 `total` 大于 `50` 时默认为 `true` | boolean | - | |
| showSizeChanger | 是否展示 `pageSize` 切换器,当 `total` 大于 50 时默认为 true | boolean | - | |
| showTitle | 是否显示原生 tooltip 页码提示 | boolean | true | |
| showTotal | 用于显示数据总量和当前数据顺序 | function(total, range) | - | |
| simple | 当添加该属性时,显示为简单分页 | boolean | - | |

View File

@ -86,6 +86,10 @@
.@{select-prefix-cls}-selection-search-input {
height: @select-height-without-border;
}
&::after {
line-height: @select-height-without-border;
}
}
}
@ -123,6 +127,7 @@
.@{select-prefix-cls}-selector {
height: @input-height;
&::after,
.@{select-prefix-cls}-selection-item,
.@{select-prefix-cls}-selection-placeholder {
line-height: @input-height - 2 * @border-width-base;

View File

@ -100,7 +100,7 @@ describe('Table.pagination', () => {
wrapper.find('.ant-select-selector').simulate('mousedown');
wrapper.find('.ant-select-item').last().simulate('click');
expect(scrollTo).toHaveBeenCalledTimes(3);
expect(scrollTo).toHaveBeenCalledTimes(2);
});
it('fires change event', () => {
@ -334,6 +334,24 @@ describe('Table.pagination', () => {
expect(wrapper.render()).toMatchSnapshot();
});
it('should call onChange when change pagination size', () => {
const onChange = jest.fn();
const wrapper = mount(
createTable({
pagination: {
total: 200,
showSizeChanger: true,
},
onChange,
}),
);
wrapper.find('.ant-select-selector').simulate('mousedown');
const dropdownWrapper = mount(wrapper.find('Trigger').instance().getComponent());
dropdownWrapper.find('.ant-select-item-option').at(2).simulate('click');
expect(onChange).toBeCalledTimes(1)
});
it('dynamic warning', () => {
resetWarned();
const errorSpy = jest.spyOn(console, 'error').mockImplementation(() => {});

View File

@ -72,9 +72,6 @@ const data = [
const SortableItem = sortableElement(props => <tr {...props} />);
const SortableContainer = sortableContainer(props => <tbody {...props} />);
const DragableBodyRow = ({ index, className, style, ...restProps }) => (
<SortableItem index={restProps['data-row-key']} {...restProps} />
);
class SortableTable extends React.Component {
state = {
@ -90,6 +87,13 @@ class SortableTable extends React.Component {
}
};
DraggableBodyRow = ({ className, style, ...restProps }) => {
const { dataSource } = this.state;
// function findIndex base on Table rowKey props and should always be a right array index
const index = dataSource.findIndex(x => x.index === restProps['data-row-key']);
return <SortableItem index={index} {...restProps} />;
};
render() {
const { dataSource } = this.state;
const DraggableContainer = props => (
@ -109,7 +113,7 @@ class SortableTable extends React.Component {
components={{
body: {
wrapper: DraggableContainer,
row: DragableBodyRow,
row: this.DraggableBodyRow,
},
}}
/>

View File

@ -7,11 +7,11 @@ title:
## zh-CN
集成 [react-resizable](https://github.com/STRML/react-resizable) 来实现可伸缩列。
集成 [react-resizable](https://github.com/STRML/react-resizable) 来实现可伸缩列。如果有排序需要,可以通过[额外标记](https://codesandbox.io/s/zrj8xvyzxx)阻止触发排序。
## en-US
Implement resizable column by integrate with [react-resizable](https://github.com/STRML/react-resizable).
Implement resizable column by integrate with [react-resizable](https://github.com/STRML/react-resizable). When sort needed, you can use [additional mark](https://codesandbox.io/s/zrj8xvyzxx) to prevent resize trigger sort.
```jsx
import { Table } from 'antd';

View File

@ -75,37 +75,24 @@ export default function usePagination(
}
}
const refreshPagination = (current: number = 1) => {
const refreshPagination = (current: number = 1, pageSize?: number) => {
setInnerPagination({
...mergedPagination,
current,
pageSize: pageSize || mergedPagination.pageSize,
});
};
const onInternalChange: PaginationProps['onChange'] = (...args) => {
const [current] = args;
refreshPagination(current);
onChange(current, args[1] || mergedPagination.pageSize!);
if (pagination && pagination.onChange) {
pagination.onChange(...args);
const onInternalChange: PaginationProps['onChange'] = (current, pageSize) => {
const paginationPageSize = mergedPagination?.pageSize;
if (pageSize && pageSize !== paginationPageSize) {
current = 1;
if (pagination && pagination.onShowSizeChange) pagination.onShowSizeChange(current, pageSize);
}
};
if (pagination && pagination.onChange) pagination.onChange(current, pageSize);
const onInternalShowSizeChange: PaginationProps['onShowSizeChange'] = (...args) => {
const [, pageSize] = args;
setInnerPagination({
...mergedPagination,
current: 1,
pageSize,
});
onChange(1, pageSize);
if (pagination && pagination.onShowSizeChange) {
pagination.onShowSizeChange(...args);
}
refreshPagination(current, pageSize);
onChange(current, pageSize || paginationPageSize!);
};
if (pagination === false) {
@ -116,7 +103,6 @@ export default function usePagination(
{
...mergedPagination,
onChange: onInternalChange,
onShowSizeChange: onInternalShowSizeChange,
},
refreshPagination,
];

View File

@ -17,8 +17,6 @@ Controlled mode lets parent nodes reflect the status of child nodes more intelli
import React, { useState } from 'react';
import { Tree } from 'antd';
const { TreeNode } = Tree;
const treeData = [
{
title: '0-0',

View File

@ -16,8 +16,6 @@ The most basic usage, tell you how to use checkable, selectable, disabled, defau
```tsx
import { Tree } from 'antd';
const { TreeNode } = Tree;
const treeData = [
{
title: 'parent 1',

View File

@ -17,8 +17,6 @@ To load data asynchronously when click to expand a treeNode.
import React, { useState } from 'react';
import { Tree } from 'antd';
const { TreeNode } = Tree;
interface DataNode {
title: string;
key: string;

View File

@ -53,6 +53,10 @@ antd use shallow compare of props to optimize performance. You should always pas
Try `defaultValue` or `onChange` to change `value`, and please read [React's documentation](https://facebook.github.io/react/docs/forms.html#controlled-components).
### Components are not vertically aligned when placed in single row.
Try [Space](https://ant.design/components/space/) component to make them aligned.
### antd overrides my global styles
Yes, antd is designed to develop a complete background application, we override some global styles for styling convenience, and it can't be removed now. More info at https://github.com/ant-design/ant-design/issues/4331 .

View File

@ -53,6 +53,10 @@ antd 内部会对 props 进行浅比较实现性能优化。当状态变更,
尝试使用 `defaultValue``onChange` 来改变 `value`,请参考 [React 的文档](https://reactjs.org/docs/forms.html#controlled-components)。
### 多个组件放一排时没有垂直对齐怎么办?
尝试使用 [Space](https://ant.design/components/space-cn/) 组件来使他们对齐。
### antd 覆盖了我的全局样式!
是的antd 在设计的时候就是用来开发一个完整的应用的,为了方便,我们覆盖了一些全局样式,现在还不能移除,想要了解更多请追踪这个 issuehttps://github.com/ant-design/ant-design/issues/4331 ,或者参考这个教程 [How to avoid modifying global styles?](docs/react/customize-theme#How-to-avoid-modifying-global-styles-?)

View File

@ -1,6 +1,6 @@
{
"name": "antd",
"version": "4.4.1",
"version": "4.4.2",
"description": "An enterprise-class UI design language and React components implementation",
"keywords": [
"ant",

View File

@ -16,49 +16,49 @@ interface Recommend {
const LIST_CN: Recommend[] = [
{
title: '蚂蚁金服体验技术部招聘啦!',
title: 'Ant Design 1.0 背后的故事:把艺术变成技术',
description:
'欢迎志同道合的你加入我们,一同在「引领全球体验科技,创造一流用户体验」的愿景指引下前行。',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*BPVATKTgfXwAAAAAAAAAAABkARQnAQ',
href: 'https://www.yuque.com/uf44r1/wqrwsg/alwufg',
'Ant Design 是一个设计体系,而 Ant Designers 是一群人。本文将讲讲 Ant Design 1.0 背后的故事,还原那些人、那些事。',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*h21tT45dgD8AAAAAAAAAAABkARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/104027273',
popularize: true,
},
{
title: '图表库 G2Plot 1.0 发布了!',
title: 'Ant Design Pro V5 已经支持预览',
description:
'开箱即用图表库 G2Plot 1.0 发布,支持 40+ 图表类型,高级统计分析组件和复杂交互内置。',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*UsnLRpUZChQAAAAAAAAAAABkARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/113888415',
'经过长时间的准备Pro V5 已经基本完成。在新版本中我们进行了很多预设,对于数据流和布局更是进行了大刀阔斧的改进。',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*oY1sTrR5FswAAAAAAAAAAABkARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/141740103',
},
{
title: 'Ant Design 暗黑模式设计解析',
description: '让我们一起来看下Ant Design 这一针对企业级的设计体系是如何设计暗黑模式的?',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*pxK_TboMzL8AAAAAAAAAAABkARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/112470365',
title: 'JCD 驱动 - 复杂系统设计应对之道',
description: '基于蚂蚁集团 CTO 线的业务土壤,我们探索出以 JCD 为核心的企业级产品设计思维,助力设计师在深耕业务上有章可循,有方法可用。',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*dGDxQZQ7ymoAAAAAAAAAAABkARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/103237648',
},
];
const LIST_EN: Recommend[] = [
{
title: 'Ant Experience Technology Department Wants You!',
title: 'The Story behind Ant Design 1.0: Turn Art into Technology',
description:
'⚡️ Our vision is To Lead Global Experience Technology, to Create First-Class User Experience.. Welcome to join us.',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*Jd4sQJ9mmaQAAAAAAAAAAABkARQnAQ',
href: 'https://www.yuque.com/uf44r1/wqrwsg/alwufg',
'🌺 While Ant Design is a design system, Ant Designers are a group of people. This article will tell you the story behind Ant Design 1.0.',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*h21tT45dgD8AAAAAAAAAAABkARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/104027273',
popularize: true,
},
{
title: 'Chart Library G2Plot 1.0 has Come!',
title: 'Ant Design Pro V5 has Supported Preview!',
description:
'📈 G2Plot 1.0 supports 40+ types of charts, including built-in statistic & analysis components and complicated interactions. Now it is ready for use out of the box.',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*UsnLRpUZChQAAAAAAAAAAABkARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/113888415',
'📈 After a long time of preparation, Pro V5 has been basically completed. In this new version, we have done a lot of presets, and have made radical improvements to the data flow and layouts.',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*oY1sTrR5FswAAAAAAAAAAABkARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/141740103',
},
{
title: 'Dark Theme of Ant Design',
description: '🌃 Let us take a look at how to design the dark theme of Ant Design.',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*pxK_TboMzL8AAAAAAAAAAABkARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/112470365',
title: 'Driven by JCD: How to Design Complicated Systems',
description: '🏦 Based on the business practice of Ant Group CTO line, we have summed up a design thinking system of enterprise product, which is called JCD.',
img: 'https://gw.alipayobjects.com/mdn/rms_08e378/afts/img/A*dGDxQZQ7ymoAAAAAAAAAAABkARQnAQ',
href: 'https://zhuanlan.zhihu.com/p/103237648',
},
];