chore: auto merge branchs (#35528)

chore: Next merge master
This commit is contained in:
github-actions[bot] 2022-05-13 03:59:16 +00:00 committed by GitHub
commit c8dee0aa69
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 608 additions and 596 deletions

View File

@ -15,6 +15,14 @@ timeline: true
--- ---
## 4.20.4
`2022-05-11`
- 🐞 Fix broken List.Item type definition. [#35455](https://github.com/ant-design/ant-design/pull/35455) [@rsmeral](https://github.com/rsmeral)
- 🐞 Fix Checkbox margin in Tree RTL mode. [#35491](https://github.com/ant-design/ant-design/pull/35491) [@miracles1919](https://github.com/miracles1919)
- 🗑 Remove Cascader `displayRender` warning. [#35417](https://github.com/ant-design/ant-design/pull/35417) [@lalalazero](https://github.com/lalalazero)
## 4.20.3 ## 4.20.3
`2022-05-08` `2022-05-08`

View File

@ -15,6 +15,14 @@ timeline: true
--- ---
## 4.20.4
`2022-05-11`
- 🐞 修复 List.Item 类型错误。[#35455](https://github.com/ant-design/ant-design/pull/35455) [@rsmeral](https://github.com/rsmeral)
- 🐞 修复 Tree 组件 RTL 模式下 Checkbox 的间距。[#35491](https://github.com/ant-design/ant-design/pull/35491) [@miracles1919](https://github.com/miracles1919)
- 🗑 删除 Cascader `displayRender` 警告。[#35417](https://github.com/ant-design/ant-design/pull/35417) [@lalalazero](https://github.com/lalalazero)
## 4.20.3 ## 4.20.3
`2022-05-08` `2022-05-08`

View File

@ -1534,7 +1534,7 @@ exports[`renders ./components/cascader/demo/multiple.md extend context correctly
> >
<div <div
class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix"
style="opacity:1" style="opacity:1;order:0"
> >
<div <div
class="ant-select-selection-search" class="ant-select-selection-search"

View File

@ -622,7 +622,7 @@ exports[`renders ./components/cascader/demo/multiple.md correctly 1`] = `
> >
<div <div
class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix" class="ant-select-selection-overflow-item ant-select-selection-overflow-item-suffix"
style="opacity:1" style="opacity:1;order:0"
> >
<div <div
class="ant-select-selection-search" class="ant-select-selection-search"

View File

@ -14,6 +14,8 @@ title:
Components which support rtl direction are listed here, you can toggle the direction in the demo. Components which support rtl direction are listed here, you can toggle the direction in the demo.
```jsx ```jsx
import React, { useState } from 'react';
import { import {
Input, Input,
Col, Col,
@ -103,23 +105,22 @@ const cascaderOptions = [
}, },
]; ];
class Page extends React.Component { function Page(props) {
state = { const [state, setState] = useState({
currentStep: 0, currentStep: 0,
modalVisible: false, modalVisible: false,
badgeCount: 5, badgeCount: 5,
showBadge: true, showBadge: true,
}; });
selectBefore = ( const selectBefore = (
<Select defaultValue="Http://" style={{ width: 90 }}> <Select defaultValue="Http://" style={{ width: 90 }}>
<Option value="Http://">Http://</Option> <Option value="Http://">Http://</Option>
<Option value="Https://">Https://</Option> <Option value="Https://">Https://</Option>
</Select> </Select>
); );
selectAfter = ( const selectAfter = (
<Select defaultValue=".com" style={{ width: 80 }}> <Select defaultValue=".com" style={{ width: 80 }}>
<Option value=".com">.com</Option> <Option value=".com">.com</Option>
<Option value=".jp">.jp</Option> <Option value=".jp">.jp</Option>
@ -129,437 +130,438 @@ class Page extends React.Component {
); );
// ==== Cascader ==== // ==== Cascader ====
cascaderFilter = (inputValue, path) => const cascaderFilter = (inputValue, path) =>
path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1); path.some(option => option.label.toLowerCase().indexOf(inputValue.toLowerCase()) > -1);
onCascaderChange = value => { const onCascaderChange = value => {
console.log(value); console.log(value);
}; };
// ==== End Cascader ==== // ==== End Cascader ====
// ==== Modal ==== // ==== Modal ====
showModal = () => { const showModal = () => {
this.setState({ setState({
...state,
modalVisible: true, modalVisible: true,
}); });
}; };
handleOk = e => { const handleOk = e => {
console.log(e); console.log(e);
this.setState({ setState({
...state,
modalVisible: false, modalVisible: false,
}); });
}; };
handleCancel = e => { const handleCancel = e => {
console.log(e); console.log(e);
this.setState({ setState({
...state,
modalVisible: false, modalVisible: false,
}); });
}; };
// ==== End Modal ==== // ==== End Modal ====
onStepsChange = currentStep => { const onStepsChange = currentStep => {
console.log('onChange:', currentStep); console.log('onChange:', currentStep);
this.setState({ currentStep }); setState({
...state,
currentStep,
});
}; };
// ==== Badge ==== // ==== Badge ====
increaseBadge = () => { const increaseBadge = () => {
const badgeCount = this.state.badgeCount + 1; const badgeCount = state.badgeCount + 1;
this.setState({ badgeCount }); setState({
...state,
badgeCount,
});
}; };
declineBadge = () => { const declineBadge = () => {
let badgeCount = this.state.badgeCount - 1; let badgeCount = state.badgeCount - 1;
if (badgeCount < 0) { if (badgeCount < 0) {
badgeCount = 0; badgeCount = 0;
} }
this.setState({ badgeCount }); setState({
...state,
badgeCount,
});
}; };
onChangeBadge = showBadge => { const onChangeBadge = showBadge => {
this.setState({ showBadge }); setState({
...state,
showBadge,
});
}; };
// ==== End Badge ====
render() { return (
const { currentStep } = this.state; <div className="direction-components">
return ( <Row>
<div className="direction-components"> <Col span={24}>
<Row> <Divider orientation="left">Cascader example</Divider>
<Col span={24}> <Cascader
<Divider orientation="left">Cascader example</Divider> suffixIcon={<SearchIcon />}
<Cascader options={cascaderOptions}
suffixIcon={<SearchIcon />} onChange={onCascaderChange}
options={cascaderOptions} placeholder="یک مورد انتخاب کنید"
onChange={this.onCascaderChange} popupPlacement={props.popupPlacement}
placeholder="یک مورد انتخاب کنید" />
popupPlacement={this.props.popupPlacement} &nbsp;&nbsp;&nbsp;&nbsp; With search:
/> <Cascader
&nbsp;&nbsp;&nbsp;&nbsp; With search: suffixIcon={<SmileOutlined />}
<Cascader options={cascaderOptions}
suffixIcon={<SmileOutlined />} onChange={onCascaderChange}
options={cascaderOptions} placeholder="Select an item"
onChange={this.onCascaderChange} popupPlacement={props.popupPlacement}
placeholder="Select an item" showSearch={cascaderFilter}
popupPlacement={this.props.popupPlacement} />
showSearch={this.cascaderFilter} </Col>
/> </Row>
</Col> <br />
</Row> <Row>
<br /> <Col span={12}>
<Row> <Divider orientation="left">Switch example</Divider>
<Col span={12}> &nbsp;&nbsp;
<Divider orientation="left">Switch example</Divider> <Switch defaultChecked />
&nbsp;&nbsp; &nbsp;&nbsp;
<Switch defaultChecked /> <Switch loading defaultChecked />
&nbsp;&nbsp; &nbsp;&nbsp;
<Switch loading defaultChecked /> <Switch size="small" loading />
&nbsp;&nbsp; </Col>
<Switch size="small" loading /> <Col span={12}>
</Col> <Divider orientation="left">Radio Group example</Divider>
<Col span={12}>
<Divider orientation="left">Radio Group example</Divider>
<Radio.Group defaultValue="c" buttonStyle="solid"> <Radio.Group defaultValue="c" buttonStyle="solid">
<Radio.Button value="a">تهران</Radio.Button> <Radio.Button value="a">تهران</Radio.Button>
<Radio.Button value="b" disabled> <Radio.Button value="b" disabled>
اصفهان اصفهان
</Radio.Button> </Radio.Button>
<Radio.Button value="c">فارس</Radio.Button> <Radio.Button value="c">فارس</Radio.Button>
<Radio.Button value="d">خوزستان</Radio.Button> <Radio.Button value="d">خوزستان</Radio.Button>
</Radio.Group> </Radio.Group>
</Col> </Col>
</Row> </Row>
<br /> <br />
<Row> <Row>
<Col span={12}> <Col span={12}>
<Divider orientation="left">Button example</Divider> <Divider orientation="left">Button example</Divider>
<div className="button-demo"> <div className="button-demo">
<Button type="primary" icon={<DownloadOutlined />} /> <Button type="primary" icon={<DownloadOutlined />} />
<Button type="primary" shape="circle" icon={<DownloadOutlined />} /> <Button type="primary" shape="circle" icon={<DownloadOutlined />} />
<Button type="primary" shape="round" icon={<DownloadOutlined />} /> <Button type="primary" shape="round" icon={<DownloadOutlined />} />
<Button type="primary" shape="round" icon={<DownloadOutlined />}> <Button type="primary" shape="round" icon={<DownloadOutlined />}>
Download Download
</Button>
<Button type="primary" icon={<DownloadOutlined />}>
Download
</Button>
<br />
<Button.Group>
<Button type="primary">
<LeftOutlined />
Backward
</Button> </Button>
<Button type="primary" icon={<DownloadOutlined />}> <Button type="primary">
Download Forward
<RightOutlined />
</Button> </Button>
<br /> </Button.Group>
<Button.Group> <Button type="primary" loading>
<Button type="primary"> Loading
<LeftOutlined /> </Button>
Backward <Button type="primary" size="small" loading>
</Button> Loading
<Button type="primary"> </Button>
Forward </div>
<RightOutlined /> </Col>
</Button> <Col span={12}>
</Button.Group> <Divider orientation="left">Tree example</Divider>
<Button type="primary" loading> <Tree
Loading showLine
</Button> checkable
<Button type="primary" size="small" loading> defaultExpandedKeys={['0-0-0', '0-0-1']}
Loading defaultSelectedKeys={['0-0-0', '0-0-1']}
</Button> defaultCheckedKeys={['0-0-0', '0-0-1']}
</div> >
</Col> <TreeNode title="parent 1" key="0-0">
<Col span={12}> <TreeNode title="parent 1-0" key="0-0-0" disabled>
<Divider orientation="left">Tree example</Divider> <TreeNode title="leaf" key="0-0-0-0" disableCheckbox />
<Tree <TreeNode title="leaf" key="0-0-0-1" />
showLine
checkable
defaultExpandedKeys={['0-0-0', '0-0-1']}
defaultSelectedKeys={['0-0-0', '0-0-1']}
defaultCheckedKeys={['0-0-0', '0-0-1']}
>
<TreeNode title="parent 1" key="0-0">
<TreeNode title="parent 1-0" key="0-0-0" disabled>
<TreeNode title="leaf" key="0-0-0-0" disableCheckbox />
<TreeNode title="leaf" key="0-0-0-1" />
</TreeNode>
<TreeNode title="parent 1-1" key="0-0-1">
<TreeNode title={<span style={{ color: '#1890ff' }}>sss</span>} key="0-0-1-0" />
</TreeNode>
</TreeNode> </TreeNode>
</Tree> <TreeNode title="parent 1-1" key="0-0-1">
</Col> <TreeNode title={<span style={{ color: '#1890ff' }}>sss</span>} key="0-0-1-0" />
</Row> </TreeNode>
<br /> </TreeNode>
<Row> </Tree>
<Col span={24}> </Col>
<Divider orientation="left">Input (Input Group) example</Divider> </Row>
<InputGroup size="large"> <br />
<Row gutter={8}> <Row>
<Col span={5}> <Col span={24}>
<Input defaultValue="0571" /> <Divider orientation="left">Input (Input Group) example</Divider>
</Col> <InputGroup size="large">
<Col span={8}> <Row gutter={8}>
<Input defaultValue="26888888" /> <Col span={5}>
<Input defaultValue="0571" />
</Col>
<Col span={8}>
<Input defaultValue="26888888" />
</Col>
</Row>
</InputGroup>
<br />
<InputGroup compact>
<Input style={{ width: '20%' }} defaultValue="0571" />
<Input style={{ width: '30%' }} defaultValue="26888888" />
</InputGroup>
<br />
<InputGroup compact>
<Select defaultValue="Option1">
<Option value="Option1">Option1</Option>
<Option value="Option2">Option2</Option>
</Select>
<Input style={{ width: '50%' }} defaultValue="input content" />
<InputNumber />
</InputGroup>
<br />
<Search placeholder="input search text" enterButton="Search" size="large" />
<br />
<br />
<div style={{ marginBottom: 16 }}>
<Input addonBefore={selectBefore} addonAfter={selectAfter} defaultValue="mysite" />
</div>
<br />
<Row>
<Col span={12}>
<Divider orientation="left">Select example</Divider>
<Select mode="multiple" defaultValue="مورچه" style={{ width: 120 }}>
<Option value="jack">Jack</Option>
<Option value="مورچه">مورچه</Option>
<Option value="disabled" disabled>
Disabled
</Option>
<Option value="Yiminghe">yiminghe</Option>
</Select>
<Select defaultValue="مورچه" style={{ width: 120 }} disabled>
<Option value="مورچه">مورچه</Option>
</Select>
<Select defaultValue="مورچه" style={{ width: 120 }} loading>
<Option value="مورچه">مورچه</Option>
</Select>
<Select
showSearch
style={{ width: 200 }}
placeholder="Select a person"
optionFilterProp="children"
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
>
<Option value="jack">Jack</Option>
<Option value="سعید">سعید</Option>
<Option value="tom">Tom</Option>
</Select>
</Col>
<Col span={12}>
<Divider orientation="left">TreeSelect example</Divider>
<div>
<TreeSelect
showSearch
style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
placeholder="Please select"
allowClear
treeDefaultExpandAll
>
<TreeNode value="parent 1" title="parent 1" key="0-1">
<TreeNode value="parent 1-0" title="parent 1-0" key="0-1-1">
<TreeNode value="leaf1" title="my leaf" key="random" />
<TreeNode value="leaf2" title="your leaf" key="random1" />
</TreeNode>
<TreeNode value="parent 1-1" title="parent 1-1" key="random2">
<TreeNode
value="sss"
title={<b style={{ color: '#08c' }}>sss</b>}
key="random3"
/>
</TreeNode>
</TreeNode>
</TreeSelect>
</div>
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Modal example</Divider>
<div>
<Button type="primary" onClick={showModal}>
Open Modal
</Button>
<Modal
title="پنچره ساده"
visible={state.modalVisible}
onOk={handleOk}
onCancel={handleCancel}
>
<p>نگاشته‌های خود را اینجا قراردهید</p>
<p>نگاشته‌های خود را اینجا قراردهید</p>
<p>نگاشته‌های خود را اینجا قراردهید</p>
</Modal>
</div>
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Steps example</Divider>
<div>
<Steps progressDot current={state.currentStep}>
<Step title="Finished" description="This is a description." />
<Step title="In Progress" description="This is a description." />
<Step title="Waiting" description="This is a description." />
</Steps>
<br />
<Steps current={state.currentStep} onChange={onStepsChange}>
<Step title="Step 1" description="This is a description." />
<Step title="Step 2" description="This is a description." />
<Step title="Step 3" description="This is a description." />
</Steps>
</div>
</Col>
</Row>
<br />
<Row>
<Col span={12}>
<Divider orientation="left">Rate example</Divider>
<div>
<Rate defaultValue={2.5} />
<br />
<strong>* Note:</strong> Half star not implemented in RTL direction, it will be
supported after <a href="https://github.com/react-component/rate">rc-rate</a>{' '}
implement rtl support.
</div>
</Col>
<Col span={12}>
<Divider orientation="left">Badge example</Divider>
<div>
<div>
<Badge count={state.badgeCount}>
<a href="#" className="head-example" />
</Badge>
<ButtonGroup>
<Button onClick={declineBadge}>
<MinusOutlined />
</Button>
<Button onClick={increaseBadge}>
<PlusOutlined />
</Button>
</ButtonGroup>
</div>
<div style={{ marginTop: 10 }}>
<Badge dot={state.showBadge}>
<a href="#" className="head-example" />
</Badge>
<Switch onChange={onChangeBadge} checked={state.showBadge} />
</div>
</div>
</Col>
</Row>
</Col>
</Row>
<br />
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Pagination example</Divider>
<Pagination showSizeChanger defaultCurrent={3} total={500} />
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Grid System example</Divider>
<div className="grid-demo">
<div className="code-box-demo">
<p>
<strong>* Note:</strong> Every calculation in RTL grid system is from right side
(offset, push, etc.)
</p>
<Row>
<Col span={8}>col-8</Col>
<Col span={8} offset={8}>
col-8
</Col>
</Row>
<Row>
<Col span={6} offset={6}>
col-6 col-offset-6
</Col>
<Col span={6} offset={6}>
col-6 col-offset-6
</Col>
</Row>
<Row>
<Col span={12} offset={6}>
col-12 col-offset-6
</Col>
</Row>
<Row>
<Col span={18} push={6}>
col-18 col-push-6
</Col>
<Col span={6} pull={18}>
col-6 col-pull-18
</Col> </Col>
</Row> </Row>
</InputGroup>
<br />
<InputGroup compact>
<Input style={{ width: '20%' }} defaultValue="0571" />
<Input style={{ width: '30%' }} defaultValue="26888888" />
</InputGroup>
<br />
<InputGroup compact>
<Select defaultValue="Option1">
<Option value="Option1">Option1</Option>
<Option value="Option2">Option2</Option>
</Select>
<Input style={{ width: '50%' }} defaultValue="input content" />
<InputNumber />
</InputGroup>
<br />
<Search placeholder="input search text" enterButton="Search" size="large" />
<br />
<br />
<div style={{ marginBottom: 16 }}>
<Input
addonBefore={this.selectBefore}
addonAfter={this.selectAfter}
defaultValue="mysite"
/>
</div> </div>
<br /> </div>
<Row> </Col>
<Col span={12}> </Row>
<Divider orientation="left">Select example</Divider> </div>
<Select mode="multiple" defaultValue="مورچه" style={{ width: 120 }}> );
<Option value="jack">Jack</Option>
<Option value="مورچه">مورچه</Option>
<Option value="disabled" disabled>
Disabled
</Option>
<Option value="Yiminghe">yiminghe</Option>
</Select>
<Select defaultValue="مورچه" style={{ width: 120 }} disabled>
<Option value="مورچه">مورچه</Option>
</Select>
<Select defaultValue="مورچه" style={{ width: 120 }} loading>
<Option value="مورچه">مورچه</Option>
</Select>
<Select
showSearch
style={{ width: 200 }}
placeholder="Select a person"
optionFilterProp="children"
filterOption={(input, option) =>
option.props.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
>
<Option value="jack">Jack</Option>
<Option value="سعید">سعید</Option>
<Option value="tom">Tom</Option>
</Select>
</Col>
<Col span={12}>
<Divider orientation="left">TreeSelect example</Divider>
<div>
<TreeSelect
showSearch
style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
placeholder="Please select"
allowClear
treeDefaultExpandAll
>
<TreeNode value="parent 1" title="parent 1" key="0-1">
<TreeNode value="parent 1-0" title="parent 1-0" key="0-1-1">
<TreeNode value="leaf1" title="my leaf" key="random" />
<TreeNode value="leaf2" title="your leaf" key="random1" />
</TreeNode>
<TreeNode value="parent 1-1" title="parent 1-1" key="random2">
<TreeNode
value="sss"
title={<b style={{ color: '#08c' }}>sss</b>}
key="random3"
/>
</TreeNode>
</TreeNode>
</TreeSelect>
</div>
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Modal example</Divider>
<div>
<Button type="primary" onClick={this.showModal}>
Open Modal
</Button>
<Modal
title="پنچره ساده"
visible={this.state.modalVisible}
onOk={this.handleOk}
onCancel={this.handleCancel}
>
<p>نگاشته‌های خود را اینجا قراردهید</p>
<p>نگاشته‌های خود را اینجا قراردهید</p>
<p>نگاشته‌های خود را اینجا قراردهید</p>
</Modal>
</div>
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Steps example</Divider>
<div>
<Steps progressDot current={currentStep}>
<Step title="Finished" description="This is a description." />
<Step title="In Progress" description="This is a description." />
<Step title="Waiting" description="This is a description." />
</Steps>
<br />
<Steps current={currentStep} onChange={this.onStepsChange}>
<Step title="Step 1" description="This is a description." />
<Step title="Step 2" description="This is a description." />
<Step title="Step 3" description="This is a description." />
</Steps>
</div>
</Col>
</Row>
<br />
<Row>
<Col span={12}>
<Divider orientation="left">Rate example</Divider>
<div>
<Rate defaultValue={2.5} />
<br />
<strong>* Note:</strong> Half star not implemented in RTL direction, it will be
supported after <a href="https://github.com/react-component/rate">rc-rate</a>{' '}
implement rtl support.
</div>
</Col>
<Col span={12}>
<Divider orientation="left">Badge example</Divider>
<div>
<div>
<Badge count={this.state.badgeCount}>
<a href="#" className="head-example" />
</Badge>
<ButtonGroup>
<Button onClick={this.declineBadge}>
<MinusOutlined />
</Button>
<Button onClick={this.increaseBadge}>
<PlusOutlined />
</Button>
</ButtonGroup>
</div>
<div style={{ marginTop: 10 }}>
<Badge dot={this.state.showBadge}>
<a href="#" className="head-example" />
</Badge>
<Switch onChange={this.onChangeBadge} checked={this.state.showBadge} />
</div>
</div>
</Col>
</Row>
</Col>
</Row>
<br />
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Pagination example</Divider>
<Pagination showSizeChanger defaultCurrent={3} total={500} />
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Grid System example</Divider>
<div className="grid-demo">
<div className="code-box-demo">
<p>
<strong>* Note:</strong> Every calculation in RTL grid system is from right side
(offset, push, etc.)
</p>
<Row>
<Col span={8}>col-8</Col>
<Col span={8} offset={8}>
col-8
</Col>
</Row>
<Row>
<Col span={6} offset={6}>
col-6 col-offset-6
</Col>
<Col span={6} offset={6}>
col-6 col-offset-6
</Col>
</Row>
<Row>
<Col span={12} offset={6}>
col-12 col-offset-6
</Col>
</Row>
<Row>
<Col span={18} push={6}>
col-18 col-push-6
</Col>
<Col span={6} pull={18}>
col-6 col-pull-18
</Col>
</Row>
</div>
</div>
</Col>
</Row>
</div>
);
}
} }
class App extends React.Component { export default () => {
state = { const [direction, setDirection] = useState('ltr');
direction: 'ltr', const [popupPlacement, setPopupPlacement] = useState('bottomLeft');
popupPlacement: 'bottomLeft',
};
changeDirection = e => { const changeDirection = e => {
const directionValue = e.target.value; const directionValue = e.target.value;
this.setState({ direction: directionValue }); setDirection(directionValue);
if (directionValue === 'rtl') { if (directionValue === 'rtl') {
this.setState({ popupPlacement: 'bottomRight' }); setPopupPlacement('bottomRight');
} else { } else {
this.setState({ popupPlacement: 'bottomLeft' }); setPopupPlacement('bottomLeft');
} }
}; };
render() { return (
const { direction, popupPlacement } = this.state; <>
return ( <div style={{ marginBottom: 16 }}>
<> <span style={{ marginRight: 16 }}>Change direction of components: </span>
<div style={{ marginBottom: 16 }}> <Radio.Group defaultValue="ltr" onChange={changeDirection}>
<span style={{ marginRight: 16 }}>Change direction of components: </span> <Radio.Button key="ltr" value="ltr">
<Radio.Group defaultValue="ltr" onChange={this.changeDirection}> LTR
<Radio.Button key="ltr" value="ltr"> </Radio.Button>
LTR <Radio.Button key="rtl" value="rtl">
</Radio.Button> RTL
<Radio.Button key="rtl" value="rtl"> </Radio.Button>
RTL </Radio.Group>
</Radio.Button> </div>
</Radio.Group> <ConfigProvider direction={direction}>
</div> <Page className={direction} popupPlacement={popupPlacement} />
<ConfigProvider direction={direction}> </ConfigProvider>
<Page className={direction} popupPlacement={popupPlacement} /> </>
</ConfigProvider> );
</> };
);
}
}
export default App;
``` ```
```css ```css

View File

@ -55,84 +55,77 @@ const columns = [
}, },
]; ];
class Page extends React.Component { function Page() {
state = { const [visible, setVisible] = React.useState(false);
visible: false,
const showModal = () => {
setVisible(true);
}; };
showModal = () => { const hideModal = () => {
this.setState({ visible: true }); setVisible(false);
}; };
hideModal = () => { const info = () => {
this.setState({ visible: false }); Modal.info({
title: 'some info',
content: 'some info',
});
}; };
render() { const confirm = () => {
const info = () => { Modal.confirm({
Modal.info({ title: 'some info',
title: 'some info', content: 'some info',
content: 'some info', });
}); };
};
const confirm = () => { return (
Modal.confirm({ <div className="locale-components">
title: 'some info', <div className="example">
content: 'some info', <Pagination defaultCurrent={1} total={50} showSizeChanger />
});
};
return (
<div className="locale-components">
<div className="example">
<Pagination defaultCurrent={1} total={50} showSizeChanger />
</div>
<div className="example">
<Select showSearch style={{ width: 200 }}>
<Option value="jack">jack</Option>
<Option value="lucy">lucy</Option>
</Select>
<DatePicker />
<TimePicker />
<RangePicker style={{ width: 200 }} />
</div>
<div className="example">
<Button type="primary" onClick={this.showModal}>
Show Modal
</Button>
<Button onClick={info}>Show info</Button>
<Button onClick={confirm}>Show confirm</Button>
<Popconfirm title="Question?">
<a href="#">Click to confirm</a>
</Popconfirm>
</div>
<div className="example">
<Transfer dataSource={[]} showSearch targetKeys={[]} render={item => item.title} />
</div>
<div className="site-config-provider-calendar-wrapper">
<Calendar fullscreen={false} value={dayjs()} />
</div>
<div className="example">
<Table dataSource={[]} columns={columns} />
</div>
<Modal title="Locale Modal" visible={this.state.visible} onCancel={this.hideModal}>
<p>Locale Modal</p>
</Modal>
</div> </div>
); <div className="example">
} <Select showSearch style={{ width: 200 }}>
<Option value="jack">jack</Option>
<Option value="lucy">lucy</Option>
</Select>
<DatePicker />
<TimePicker />
<RangePicker style={{ width: 200 }} />
</div>
<div className="example">
<Button type="primary" onClick={showModal}>
Show Modal
</Button>
<Button onClick={info}>Show info</Button>
<Button onClick={confirm}>Show confirm</Button>
<Popconfirm title="Question?">
<a href="#">Click to confirm</a>
</Popconfirm>
</div>
<div className="example">
<Transfer dataSource={[]} showSearch targetKeys={[]} render={item => item.title} />
</div>
<div className="site-config-provider-calendar-wrapper">
<Calendar fullscreen={false} value={dayjs()} />
</div>
<div className="example">
<Table dataSource={[]} columns={columns} />
</div>
<Modal title="Locale Modal" visible={visible} onCancel={hideModal}>
<p>Locale Modal</p>
</Modal>
</div>
);
} }
class App extends React.Component { export default () => {
constructor() { const [locale, setLocale] = React.useState(enUS);
super();
this.state = {
locale: enUS,
};
}
changeLocale = e => { const changeLocale = e => {
const localeValue = e.target.value; const localeValue = e.target.value;
this.setState({ locale: localeValue }); setLocale(localeValue);
if (!localeValue) { if (!localeValue) {
dayjs.locale('en'); dayjs.locale('en');
} else { } else {
@ -140,32 +133,27 @@ class App extends React.Component {
} }
}; };
render() { return (
const { locale } = this.state; <div>
return ( <div className="change-locale">
<div> <span style={{ marginRight: 16 }}>Change locale of components: </span>
<div className="change-locale"> <Radio.Group value={locale} onChange={changeLocale}>
<span style={{ marginRight: 16 }}>Change locale of components: </span> <Radio.Button key="en" value={enUS}>
<Radio.Group value={locale} onChange={this.changeLocale}> English
<Radio.Button key="en" value={enUS}> </Radio.Button>
English <Radio.Button key="cn" value={zhCN}>
</Radio.Button> 中文
<Radio.Button key="cn" value={zhCN}> </Radio.Button>
中文 </Radio.Group>
</Radio.Button>
</Radio.Group>
</div>
<ConfigProvider locale={locale}>
<Page
key={locale ? locale.locale : 'en' /* Have to refresh for production environment */}
/>
</ConfigProvider>
</div> </div>
); <ConfigProvider locale={locale}>
} <Page
} key={locale ? locale.locale : 'en' /* Have to refresh for production environment */}
/>
export default App; </ConfigProvider>
</div>
);
};
``` ```
```css ```css

View File

@ -15,65 +15,60 @@ debug: true
Determing which panel to show with `mode` and `onPanelChange`. Determing which panel to show with `mode` and `onPanelChange`.
```jsx ```jsx
import React, { useState } from 'react';
import { DatePicker, Space } from 'antd'; import { DatePicker, Space } from 'antd';
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
class ControlledDatePicker extends React.Component { function ControlledDatePicker() {
state = { mode: 'time' }; const [mode, setMode] = useState('time');
handleOpenChange = open => { const handleOpenChange = open => {
if (open) { if (open) {
this.setState({ mode: 'time' }); setMode('time');
} }
}; };
handlePanelChange = (value, mode) => { const handlePanelChange = (value, dateMode) => {
this.setState({ mode }); setMode(dateMode);
}; };
render() { return (
return ( <DatePicker
<DatePicker mode={mode}
mode={this.state.mode} showTime
showTime onOpenChange={handleOpenChange}
onOpenChange={this.handleOpenChange} onPanelChange={handlePanelChange}
onPanelChange={this.handlePanelChange} />
/> );
);
}
} }
class ControlledRangePicker extends React.Component { function ControlledRangePicker() {
state = { const [mode, setMode] = useState(['month', 'month']);
mode: ['month', 'month'], const [value, setValue] = useState([]);
value: [],
const handlePanelChange = (dateValue, dateMode) => {
setValue(dateValue);
setMode([
dateMode[0] === 'date' ? 'month' : dateMode[0],
dateMode[1] === 'date' ? 'month' : dateMode[1],
]);
}; };
handlePanelChange = (value, mode) => { const handleChange = dateValue => {
this.setState({ setValue(dateValue);
value,
mode: [mode[0] === 'date' ? 'month' : mode[0], mode[1] === 'date' ? 'month' : mode[1]],
});
}; };
handleChange = value => { return (
this.setState({ value }); <RangePicker
}; placeholder={['Start month', 'End month']}
format="YYYY-MM"
render() { value={value}
const { value, mode } = this.state; mode={mode}
return ( onChange={handleChange}
<RangePicker onPanelChange={handlePanelChange}
placeholder={['Start month', 'End month']} />
format="YYYY-MM" );
value={value}
mode={mode}
onChange={this.handleChange}
onPanelChange={this.handlePanelChange}
/>
);
}
} }
export default () => ( export default () => (

View File

@ -18,32 +18,25 @@ import { DatePicker, Radio, Space } from 'antd';
const { RangePicker } = DatePicker; const { RangePicker } = DatePicker;
class PickerSizesDemo extends React.Component { export default () => {
state = { const [size, setSize] = React.useState('default');
size: 'default',
const handleSizeChange = e => {
setSize(e.target.value);
}; };
handleSizeChange = e => { return (
this.setState({ size: e.target.value }); <Space direction="vertical" size={12}>
}; <Radio.Group value={size} onChange={handleSizeChange}>
<Radio.Button value="large">Large</Radio.Button>
render() { <Radio.Button value="default">Default</Radio.Button>
const { size } = this.state; <Radio.Button value="small">Small</Radio.Button>
return ( </Radio.Group>
<Space direction="vertical" size={12}> <DatePicker size={size} />
<Radio.Group value={size} onChange={this.handleSizeChange}> <DatePicker size={size} picker="month" />
<Radio.Button value="large">Large</Radio.Button> <RangePicker size={size} />
<Radio.Button value="default">Default</Radio.Button> <DatePicker size={size} picker="week" />
<Radio.Button value="small">Small</Radio.Button> </Space>
</Radio.Group> );
<DatePicker size={size} /> };
<DatePicker size={size} picker="month" />
<RangePicker size={size} />
<DatePicker size={size} picker="week" />
</Space>
);
}
}
export default () => <PickerSizesDemo />;
``` ```

View File

@ -23,80 +23,76 @@ When `RangePicker` does not satisfied your requirements, try to implement simila
```jsx ```jsx
import { DatePicker, Space } from 'antd'; import { DatePicker, Space } from 'antd';
class DateRange extends React.Component { export default () => {
state = { const [state, setState] = React.useState({
startValue: null, startValue: null,
endValue: null, endValue: null,
endOpen: false, endOpen: false,
}; });
disabledStartDate = startValue => { const disabledStartDate = startValue => {
const { endValue } = this.state; const { endValue } = state;
if (!startValue || !endValue) { if (!startValue || !endValue) {
return false; return false;
} }
return startValue.valueOf() > endValue.valueOf(); return startValue.valueOf() > endValue.valueOf();
}; };
disabledEndDate = endValue => { const disabledEndDate = endValue => {
const { startValue } = this.state; const { startValue } = state;
if (!endValue || !startValue) { if (!endValue || !startValue) {
return false; return false;
} }
return endValue.valueOf() <= startValue.valueOf(); return endValue.valueOf() <= startValue.valueOf();
}; };
onChange = (field, value) => { const onChange = (field, value) => {
this.setState({ setState({
...state,
[field]: value, [field]: value,
}); });
}; };
onStartChange = value => { const onStartChange = value => {
this.onChange('startValue', value); onChange('startValue', value);
}; };
onEndChange = value => { const onEndChange = value => {
this.onChange('endValue', value); onChange('endValue', value);
}; };
handleStartOpenChange = open => { const handleStartOpenChange = open => {
if (!open) { if (!open) {
this.setState({ endOpen: true }); setState({ ...state, endOpen: true });
} }
}; };
handleEndOpenChange = open => { const handleEndOpenChange = open => {
this.setState({ endOpen: open }); setState({ ...state, endOpen: true });
}; };
render() { return (
const { startValue, endValue, endOpen } = this.state; <Space>
return ( <DatePicker
<Space> disabledDate={disabledStartDate}
<DatePicker showTime
disabledDate={this.disabledStartDate} format="YYYY-MM-DD HH:mm:ss"
showTime value={state.startValue}
format="YYYY-MM-DD HH:mm:ss" placeholder="Start"
value={startValue} onChange={onStartChange}
placeholder="Start" onOpenChange={handleStartOpenChange}
onChange={this.onStartChange} />
onOpenChange={this.handleStartOpenChange} <DatePicker
/> disabledDate={disabledEndDate}
<DatePicker showTime
disabledDate={this.disabledEndDate} format="YYYY-MM-DD HH:mm:ss"
showTime value={state.endValue}
format="YYYY-MM-DD HH:mm:ss" placeholder="End"
value={endValue} onChange={onEndChange}
placeholder="End" open={state.endOpen}
onChange={this.onEndChange} onOpenChange={handleEndOpenChange}
open={endOpen} />
onOpenChange={this.handleEndOpenChange} </Space>
/> );
</Space> };
);
}
}
export default () => <DateRange />;
``` ```

View File

@ -30,7 +30,7 @@ const StatisticNumber: React.FC<NumberProps> = props => {
int = int.replace(/\B(?=(\d{3})+(?!\d))/g, groupSeparator); int = int.replace(/\B(?=(\d{3})+(?!\d))/g, groupSeparator);
if (typeof precision === 'number') { if (typeof precision === 'number') {
decimal = padEnd(decimal, precision, '0').slice(0, precision); decimal = padEnd(decimal, precision, '0').slice(0, precision > 0 ? precision : 0);
} }
if (decimal) { if (decimal) {

View File

@ -51,6 +51,20 @@ describe('Statistic', () => {
expect(wrapper.render()).toMatchSnapshot(); expect(wrapper.render()).toMatchSnapshot();
}); });
it('allow negetive precision', () => {
[
[-1, -1112893.1212, '-1,112,893'],
[-2, -1112893.1212, '-1,112,893'],
[-3, -1112893.1212, '-1,112,893'],
[-1, -1112893, '-1,112,893'],
[-1, 1112893, '1,112,893'],
].forEach(([precision, value, expectValue]) => {
const wrapper = mount(<Statistic precision={precision} value={value} />);
expect(wrapper.find('.ant-statistic-content-value-int').text()).toEqual(expectValue);
expect(wrapper.find('.ant-statistic-content-value-decimal').length).toBe(0);
});
});
it('loading with skeleton', async () => { it('loading with skeleton', async () => {
let loading = false; let loading = false;
const wrapper = mount(<Statistic title="Active Users" value={112112} loading={loading} />); const wrapper = mount(<Statistic title="Active Users" value={112112} loading={loading} />);

View File

@ -316,3 +316,7 @@ Table can not tell what state used in `columns.render`, so it always need fully
### How to handle fixed column display over the mask layout? ### How to handle fixed column display over the mask layout?
Fixed column use `z-index` to make it over other columns. You will find sometime fixed columns also over your mask layout. You can set `z-index` on your mask layout to resolve. Fixed column use `z-index` to make it over other columns. You will find sometime fixed columns also over your mask layout. You can set `z-index` on your mask layout to resolve.
### How to custom render Table CheckboxFor example, adding Tooltip?
Since `4.1.0`, You can use [`rowSelection.renderCell`](https://ant.design/components/table/#rowSelection) to custom render Table Checkbox. If you want to add Tooltip, please refer to this [demo](https://codesandbox.io/s/table-row-tooltip-v79j2v).

View File

@ -316,3 +316,7 @@ Table 移除了在 v3 中废弃的 `onRowClick`、`onRowDoubleClick`、`onRowMou
### 固定列穿透到最上层该怎么办? ### 固定列穿透到最上层该怎么办?
固定列通过 `z-index` 属性将其悬浮于非固定列之上,这使得有时候你会发现在 Table 上放置遮罩层时固定列会被透过的情况。为遮罩层设置更高的 `z-index` 覆盖住固定列即可。 固定列通过 `z-index` 属性将其悬浮于非固定列之上,这使得有时候你会发现在 Table 上放置遮罩层时固定列会被透过的情况。为遮罩层设置更高的 `z-index` 覆盖住固定列即可。
### 如何自定义渲染可选列的勾选框(比如增加 Tooltip
`4.1.0` 起,可以通过 [rowSelection](https://ant.design/components/table-cn/#rowSelection) 的 `renderCell` 属性控制,可以参考此处 [Demo](https://codesandbox.io/s/table-row-tooltip-v79j2v) 实现展示 Tooltip 需求或其他自定义的需求。

View File

@ -56,7 +56,7 @@
} }
// >>> Checkbox // >>> Checkbox
&-checkbox { &-checkbox {
.@{tree-prefix-cls}-rtl& { .@{tree-prefix-cls}-rtl & {
margin: ((@tree-title-height - @checkbox-size) / 2) 0 0 8px; margin: ((@tree-title-height - @checkbox-size) / 2) 0 0 8px;
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "antd", "name": "antd",
"version": "4.20.3", "version": "4.20.4",
"description": "An enterprise-class UI design language and React components implementation", "description": "An enterprise-class UI design language and React components implementation",
"title": "Ant Design", "title": "Ant Design",
"keywords": [ "keywords": [