chore: auto merge branchs (#35553)

chore: merge master into next
This commit is contained in:
github-actions[bot] 2022-05-14 10:03:09 +00:00 committed by GitHub
commit fb9c2fc51e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 770 additions and 900 deletions

View File

@ -19,144 +19,136 @@ import { PlusOutlined } from '@ant-design/icons';
const { Option } = Select;
class DrawerForm extends React.Component {
state = { visible: false };
export default () => {
const [visible, setVisible] = React.useState(false);
showDrawer = () => {
this.setState({
visible: true,
});
const showDrawer = () => {
setVisible(true);
};
onClose = () => {
this.setState({
visible: false,
});
const onClose = () => {
setVisible(false);
};
render() {
return (
<>
<Button type="primary" onClick={this.showDrawer} icon={<PlusOutlined />}>
New account
</Button>
<Drawer
title="Create a new account"
width={720}
onClose={this.onClose}
visible={this.state.visible}
bodyStyle={{ paddingBottom: 80 }}
extra={
<Space>
<Button onClick={this.onClose}>Cancel</Button>
<Button onClick={this.onClose} type="primary">
Submit
</Button>
</Space>
}
>
<Form layout="vertical" hideRequiredMark>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="name"
label="Name"
rules={[{ required: true, message: 'Please enter user name' }]}
>
<Input placeholder="Please enter user name" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="url"
label="Url"
rules={[{ required: true, message: 'Please enter url' }]}
>
<Input
style={{ width: '100%' }}
addonBefore="http://"
addonAfter=".com"
placeholder="Please enter url"
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="owner"
label="Owner"
rules={[{ required: true, message: 'Please select an owner' }]}
>
<Select placeholder="Please select an owner">
<Option value="xiao">Xiaoxiao Fu</Option>
<Option value="mao">Maomao Zhou</Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="type"
label="Type"
rules={[{ required: true, message: 'Please choose the type' }]}
>
<Select placeholder="Please choose the type">
<Option value="private">Private</Option>
<Option value="public">Public</Option>
</Select>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="approver"
label="Approver"
rules={[{ required: true, message: 'Please choose the approver' }]}
>
<Select placeholder="Please choose the approver">
<Option value="jack">Jack Ma</Option>
<Option value="tom">Tom Liu</Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="dateTime"
label="DateTime"
rules={[{ required: true, message: 'Please choose the dateTime' }]}
>
<DatePicker.RangePicker
style={{ width: '100%' }}
getPopupContainer={trigger => trigger.parentElement}
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={24}>
<Form.Item
name="description"
label="Description"
rules={[
{
required: true,
message: 'please enter url description',
},
]}
>
<Input.TextArea rows={4} placeholder="please enter url description" />
</Form.Item>
</Col>
</Row>
</Form>
</Drawer>
</>
);
}
}
export default () => <DrawerForm />;
return (
<>
<Button type="primary" onClick={showDrawer} icon={<PlusOutlined />}>
New account
</Button>
<Drawer
title="Create a new account"
width={720}
onClose={onClose}
visible={visible}
bodyStyle={{ paddingBottom: 80 }}
extra={
<Space>
<Button onClick={onClose}>Cancel</Button>
<Button onClick={onClose} type="primary">
Submit
</Button>
</Space>
}
>
<Form layout="vertical" hideRequiredMark>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="name"
label="Name"
rules={[{ required: true, message: 'Please enter user name' }]}
>
<Input placeholder="Please enter user name" />
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="url"
label="Url"
rules={[{ required: true, message: 'Please enter url' }]}
>
<Input
style={{ width: '100%' }}
addonBefore="http://"
addonAfter=".com"
placeholder="Please enter url"
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="owner"
label="Owner"
rules={[{ required: true, message: 'Please select an owner' }]}
>
<Select placeholder="Please select an owner">
<Option value="xiao">Xiaoxiao Fu</Option>
<Option value="mao">Maomao Zhou</Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="type"
label="Type"
rules={[{ required: true, message: 'Please choose the type' }]}
>
<Select placeholder="Please choose the type">
<Option value="private">Private</Option>
<Option value="public">Public</Option>
</Select>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={12}>
<Form.Item
name="approver"
label="Approver"
rules={[{ required: true, message: 'Please choose the approver' }]}
>
<Select placeholder="Please choose the approver">
<Option value="jack">Jack Ma</Option>
<Option value="tom">Tom Liu</Option>
</Select>
</Form.Item>
</Col>
<Col span={12}>
<Form.Item
name="dateTime"
label="DateTime"
rules={[{ required: true, message: 'Please choose the dateTime' }]}
>
<DatePicker.RangePicker
style={{ width: '100%' }}
getPopupContainer={trigger => trigger.parentElement}
/>
</Form.Item>
</Col>
</Row>
<Row gutter={16}>
<Col span={24}>
<Form.Item
name="description"
label="Description"
rules={[
{
required: true,
message: 'please enter url description',
},
]}
>
<Input.TextArea rows={4} placeholder="please enter url description" />
</Form.Item>
</Col>
</Row>
</Form>
</Drawer>
</>
);
};
```
```css

View File

@ -16,65 +16,54 @@ Open a new drawer on top of an existing drawer to handle multi branch tasks.
```jsx
import { Drawer, Button } from 'antd';
class App extends React.Component {
state = { visible: false, childrenDrawer: false };
export default () => {
const [visible, setVisible] = React.useState(false);
const [childrenDrawer, setChildrenDrawer] = React.useState(false);
showDrawer = () => {
this.setState({
visible: true,
});
const showDrawer = () => {
setVisible(true);
};
onClose = () => {
this.setState({
visible: false,
});
const onClose = () => {
setVisible(false);
};
showChildrenDrawer = () => {
this.setState({
childrenDrawer: true,
});
const showChildrenDrawer = () => {
setChildrenDrawer(true);
};
onChildrenDrawerClose = () => {
this.setState({
childrenDrawer: false,
});
const onChildrenDrawerClose = () => {
setChildrenDrawer(false);
};
render() {
return (
<>
<Button type="primary" onClick={this.showDrawer}>
Open drawer
return (
<>
<Button type="primary" onClick={showDrawer}>
Open drawer
</Button>
<Drawer
title="Multi-level drawer"
width={520}
closable={false}
onClose={onClose}
visible={visible}
>
<Button type="primary" onClick={showChildrenDrawer}>
Two-level drawer
</Button>
<Drawer
title="Multi-level drawer"
width={520}
title="Two-level Drawer"
width={320}
closable={false}
onClose={this.onClose}
visible={this.state.visible}
onClose={onChildrenDrawerClose}
visible={childrenDrawer}
>
<Button type="primary" onClick={this.showChildrenDrawer}>
Two-level drawer
</Button>
<Drawer
title="Two-level Drawer"
width={320}
closable={false}
onClose={this.onChildrenDrawerClose}
visible={this.state.childrenDrawer}
>
This is two-level drawer
</Drawer>
This is two-level drawer
</Drawer>
</>
);
}
}
export default App;
</Drawer>
</>
);
};
```
<style>

View File

@ -16,58 +16,48 @@ The Drawer can appear from any edge of the screen.
```jsx
import { Drawer, Button, Radio, Space } from 'antd';
class App extends React.Component {
state = { visible: false, placement: 'left' };
export default () => {
const [visible, setVisible] = React.useState(false);
const [placement, setPlacement] = React.useState('left');
showDrawer = () => {
this.setState({
visible: true,
});
const showDrawer = () => {
setVisible(true);
};
onClose = () => {
this.setState({
visible: false,
});
const onClose = () => {
setVisible(false);
};
onChange = e => {
this.setState({
placement: e.target.value,
});
const onChange = e => {
setPlacement(e.target.value);
};
render() {
const { placement, visible } = this.state;
return (
<>
<Space>
<Radio.Group value={placement} onChange={this.onChange}>
<Radio value="top">top</Radio>
<Radio value="right">right</Radio>
<Radio value="bottom">bottom</Radio>
<Radio value="left">left</Radio>
</Radio.Group>
<Button type="primary" onClick={this.showDrawer}>
Open
</Button>
</Space>
<Drawer
title="Basic Drawer"
placement={placement}
closable={false}
onClose={this.onClose}
visible={visible}
key={placement}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</>
);
}
}
export default App;
return (
<>
<Space>
<Radio.Group value={placement} onChange={onChange}>
<Radio value="top">top</Radio>
<Radio value="right">right</Radio>
<Radio value="bottom">bottom</Radio>
<Radio value="left">left</Radio>
</Radio.Group>
<Button type="primary" onClick={showDrawer}>
Open
</Button>
</Space>
<Drawer
title="Basic Drawer"
placement={placement}
closable={false}
onClose={onClose}
visible={visible}
key={placement}
>
<p>Some contents...</p>
<p>Some contents...</p>
<p>Some contents...</p>
</Drawer>
</>
);
};
```

View File

@ -16,47 +16,39 @@ Render in current dom. custom container, check `getContainer`.
```jsx
import { Drawer, Button } from 'antd';
class App extends React.Component {
state = { visible: false };
export default () => {
const [visible, setVisible] = React.useState(false);
showDrawer = () => {
this.setState({
visible: true,
});
const showDrawer = () => {
setVisible(true);
};
onClose = () => {
this.setState({
visible: false,
});
const onClose = () => {
setVisible(false);
};
render() {
return (
<div className="site-drawer-render-in-current-wrapper">
Render in this
<div style={{ marginTop: 16 }}>
<Button type="primary" onClick={this.showDrawer}>
Open
</Button>
</div>
<Drawer
title="Basic Drawer"
placement="right"
closable={false}
onClose={this.onClose}
visible={this.state.visible}
getContainer={false}
style={{ position: 'absolute' }}
>
<p>Some contents...</p>
</Drawer>
return (
<div className="site-drawer-render-in-current-wrapper">
Render in this
<div style={{ marginTop: 16 }}>
<Button type="primary" onClick={showDrawer}>
Open
</Button>
</div>
);
}
}
export default App;
<Drawer
title="Basic Drawer"
placement="right"
closable={false}
onClose={onClose}
visible={visible}
getContainer={false}
style={{ position: 'absolute' }}
>
<p>Some contents...</p>
</Drawer>
</div>
);
};
```
```css

View File

@ -23,151 +23,137 @@ const DescriptionItem = ({ title, content }) => (
</div>
);
class App extends React.Component {
state = { visible: false };
export default () => {
const [visible, setVisible] = React.useState(false);
showDrawer = () => {
this.setState({
visible: true,
});
const showDrawer = () => {
setVisible(true);
};
onClose = () => {
this.setState({
visible: false,
});
const onClose = () => {
setVisible(false);
};
render() {
return (
<>
<List
dataSource={[
{
name: 'Lily',
},
{
name: 'Lily',
},
]}
bordered
renderItem={item => (
<List.Item
key={item.id}
actions={[
<a onClick={this.showDrawer} key={`a-${item.id}`}>
View Profile
</a>,
]}
>
<List.Item.Meta
avatar={
<Avatar src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png" />
}
title={<a href="https://ant.design/index-cn">{item.name}</a>}
description="Progresser XTech"
/>
</List.Item>
)}
/>
<Drawer
width={640}
placement="right"
closable={false}
onClose={this.onClose}
visible={this.state.visible}
>
<p className="site-description-item-profile-p" style={{ marginBottom: 24 }}>
User Profile
</p>
<p className="site-description-item-profile-p">Personal</p>
<Row>
<Col span={12}>
<DescriptionItem title="Full Name" content="Lily" />
</Col>
<Col span={12}>
<DescriptionItem title="Account" content="AntDesign@example.com" />
</Col>
</Row>
<Row>
<Col span={12}>
<DescriptionItem title="City" content="HangZhou" />
</Col>
<Col span={12}>
<DescriptionItem title="Country" content="China🇨🇳" />
</Col>
</Row>
<Row>
<Col span={12}>
<DescriptionItem title="Birthday" content="February 2,1900" />
</Col>
<Col span={12}>
<DescriptionItem title="Website" content="-" />
</Col>
</Row>
<Row>
<Col span={24}>
<DescriptionItem
title="Message"
content="Make things as simple as possible but no simpler."
/>
</Col>
</Row>
<Divider />
<p className="site-description-item-profile-p">Company</p>
<Row>
<Col span={12}>
<DescriptionItem title="Position" content="Programmer" />
</Col>
<Col span={12}>
<DescriptionItem title="Responsibilities" content="Coding" />
</Col>
</Row>
<Row>
<Col span={12}>
<DescriptionItem title="Department" content="XTech" />
</Col>
<Col span={12}>
<DescriptionItem title="Supervisor" content={<a>Lin</a>} />
</Col>
</Row>
<Row>
<Col span={24}>
<DescriptionItem
title="Skills"
content="C / C + +, data structures, software engineering, operating systems, computer networks, databases, compiler theory, computer architecture, Microcomputer Principle and Interface Technology, Computer English, Java, ASP, etc."
/>
</Col>
</Row>
<Divider />
<p className="site-description-item-profile-p">Contacts</p>
<Row>
<Col span={12}>
<DescriptionItem title="Email" content="AntDesign@example.com" />
</Col>
<Col span={12}>
<DescriptionItem title="Phone Number" content="+86 181 0000 0000" />
</Col>
</Row>
<Row>
<Col span={24}>
<DescriptionItem
title="Github"
content={
<a href="http://github.com/ant-design/ant-design/">
github.com/ant-design/ant-design/
</a>
}
/>
</Col>
</Row>
</Drawer>
</>
);
}
}
export default App;
return (
<>
<List
dataSource={[
{
name: 'Lily',
},
{
name: 'Lily',
},
]}
bordered
renderItem={item => (
<List.Item
key={item.id}
actions={[
<a onClick={showDrawer} key={`a-${item.id}`}>
View Profile
</a>,
]}
>
<List.Item.Meta
avatar={
<Avatar src="https://gw.alipayobjects.com/zos/rmsportal/BiazfanxmamNRoxxVxka.png" />
}
title={<a href="https://ant.design/index-cn">{item.name}</a>}
description="Progresser XTech"
/>
</List.Item>
)}
/>
<Drawer width={640} placement="right" closable={false} onClose={onClose} visible={visible}>
<p className="site-description-item-profile-p" style={{ marginBottom: 24 }}>
User Profile
</p>
<p className="site-description-item-profile-p">Personal</p>
<Row>
<Col span={12}>
<DescriptionItem title="Full Name" content="Lily" />
</Col>
<Col span={12}>
<DescriptionItem title="Account" content="AntDesign@example.com" />
</Col>
</Row>
<Row>
<Col span={12}>
<DescriptionItem title="City" content="HangZhou" />
</Col>
<Col span={12}>
<DescriptionItem title="Country" content="China🇨🇳" />
</Col>
</Row>
<Row>
<Col span={12}>
<DescriptionItem title="Birthday" content="February 2,1900" />
</Col>
<Col span={12}>
<DescriptionItem title="Website" content="-" />
</Col>
</Row>
<Row>
<Col span={24}>
<DescriptionItem
title="Message"
content="Make things as simple as possible but no simpler."
/>
</Col>
</Row>
<Divider />
<p className="site-description-item-profile-p">Company</p>
<Row>
<Col span={12}>
<DescriptionItem title="Position" content="Programmer" />
</Col>
<Col span={12}>
<DescriptionItem title="Responsibilities" content="Coding" />
</Col>
</Row>
<Row>
<Col span={12}>
<DescriptionItem title="Department" content="XTech" />
</Col>
<Col span={12}>
<DescriptionItem title="Supervisor" content={<a>Lin</a>} />
</Col>
</Row>
<Row>
<Col span={24}>
<DescriptionItem
title="Skills"
content="C / C + +, data structures, software engineering, operating systems, computer networks, databases, compiler theory, computer architecture, Microcomputer Principle and Interface Technology, Computer English, Java, ASP, etc."
/>
</Col>
</Row>
<Divider />
<p className="site-description-item-profile-p">Contacts</p>
<Row>
<Col span={12}>
<DescriptionItem title="Email" content="AntDesign@example.com" />
</Col>
<Col span={12}>
<DescriptionItem title="Phone Number" content="+86 181 0000 0000" />
</Col>
</Row>
<Row>
<Col span={24}>
<DescriptionItem
title="Github"
content={
<a href="http://github.com/ant-design/ant-design/">
github.com/ant-design/ant-design/
</a>
}
/>
</Col>
</Row>
</Drawer>
</>
);
};
```
```css

View File

@ -27,52 +27,48 @@ const menu = (
]}
/>
);
class App extends React.Component {
state = {
loadings: [],
};
export default () => {
const [loadings, setLodings] = React.useState([]);
enterLoading = index => {
const newLoadings = [...this.state.loadings];
const enterLoading = index => {
const newLoadings = [...loadings];
newLoadings[index] = true;
this.setState({
loadings: newLoadings,
});
setLodings(newLoadings);
setTimeout(() => {
newLoadings[index] = false;
this.setState({ loadings: newLoadings });
setLodings(prevLoadings => {
const temLoadings = [...prevLoadings];
temLoadings[index] = false;
return temLoadings;
});
}, 6000);
};
render() {
const { loadings } = this.state;
return (
<Space direction="vertical">
<Dropdown.Button type="primary" loading overlay={menu}>
Submit
</Dropdown.Button>
<Dropdown.Button type="primary" size="small" loading overlay={menu}>
Submit
</Dropdown.Button>
<Dropdown.Button
type="primary"
loading={loadings[0]}
overlay={menu}
onClick={() => this.enterLoading(0)}
>
Submit
</Dropdown.Button>
<Dropdown.Button
icon={<DownOutlined />}
loading={loadings[1]}
overlay={menu}
onClick={() => this.enterLoading(1)}
>
Submit
</Dropdown.Button>
</Space>
);
}
}
export default App;
return (
<Space direction="vertical">
<Dropdown.Button type="primary" loading overlay={menu}>
Submit
</Dropdown.Button>
<Dropdown.Button type="primary" size="small" loading overlay={menu}>
Submit
</Dropdown.Button>
<Dropdown.Button
type="primary"
loading={loadings[0]}
overlay={menu}
onClick={() => enterLoading(0)}
>
Submit
</Dropdown.Button>
<Dropdown.Button
icon={<DownOutlined />}
loading={loadings[1]}
overlay={menu}
onClick={() => enterLoading(1)}
>
Submit
</Dropdown.Button>
</Space>
);
};
```

View File

@ -17,57 +17,48 @@ The default is to close the menu when you click on menu items, this feature can
import { Menu, Dropdown, Space } from 'antd';
import { DownOutlined } from '@ant-design/icons';
class OverlayVisible extends React.Component {
state = {
visible: false,
};
export default () => {
const [visible, setVisible] = React.useState(false);
handleMenuClick = e => {
const handleMenuClick = e => {
if (e.key === '3') {
this.setState({ visible: false });
setVisible(false);
}
};
handleVisibleChange = flag => {
this.setState({ visible: flag });
const handleVisibleChange = flag => {
setVisible(flag);
};
render() {
const menu = (
<Menu
onClick={this.handleMenuClick}
items={[
{
label: 'Clicking me will not close the menu.',
key: '1',
},
{
label: 'Clicking me will not close the menu also.',
key: '2',
},
{
label: 'Clicking me will close the menu.',
key: '3',
},
]}
/>
);
return (
<Dropdown
overlay={menu}
onVisibleChange={this.handleVisibleChange}
visible={this.state.visible}
>
<a onClick={e => e.preventDefault()}>
<Space>
Hover me
<DownOutlined />
</Space>
</a>
</Dropdown>
);
}
}
const menu = (
<Menu
onClick={handleMenuClick}
items={[
{
label: 'Clicking me will not close the menu.',
key: '1',
},
{
label: 'Clicking me will not close the menu also.',
key: '2',
},
{
label: 'Clicking me will close the menu.',
key: '3',
},
]}
/>
);
export default () => <OverlayVisible />;
return (
<Dropdown overlay={menu} onVisibleChange={handleVisibleChange} visible={visible}>
<a onClick={e => e.preventDefault()}>
<Space>
Hover me
<DownOutlined />
</Space>
</a>
</Dropdown>
);
};
```

View File

@ -36,67 +36,60 @@ const customizeRenderEmpty = () => (
const style = { width: 200 };
class Demo extends React.Component {
state = {
customize: false,
};
export default () => {
const [customize, setCustomize] = React.useState(false);
render() {
const { customize } = this.state;
return (
<div>
<Switch
unCheckedChildren="default"
checkedChildren="customize"
checked={customize}
onChange={val => {
this.setState({ customize: val });
}}
/>
return (
<div>
<Switch
unCheckedChildren="default"
checkedChildren="customize"
checked={customize}
onChange={value => {
setCustomize(value);
}}
/>
<Divider />
<Divider />
<ConfigProvider renderEmpty={customize && customizeRenderEmpty}>
<div className="config-provider">
<h4>Select</h4>
<Select style={style} />
<ConfigProvider renderEmpty={customize && customizeRenderEmpty}>
<div className="config-provider">
<h4>Select</h4>
<Select style={style} />
<h4>TreeSelect</h4>
<TreeSelect style={style} treeData={[]} />
<h4>TreeSelect</h4>
<TreeSelect style={style} treeData={[]} />
<h4>Cascader</h4>
<Cascader style={style} options={[]} showSearch />
<h4>Cascader</h4>
<Cascader style={style} options={[]} showSearch />
<h4>Transfer</h4>
<Transfer />
<h4>Transfer</h4>
<Transfer />
<h4>Table</h4>
<Table
style={{ marginTop: 8 }}
columns={[
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
]}
/>
<h4>Table</h4>
<Table
style={{ marginTop: 8 }}
columns={[
{
title: 'Name',
dataIndex: 'name',
key: 'name',
},
{
title: 'Age',
dataIndex: 'age',
key: 'age',
},
]}
/>
<h4>List</h4>
<List />
</div>
</ConfigProvider>
</div>
);
}
}
export default Demo;
<h4>List</h4>
<List />
</div>
</ConfigProvider>
</div>
);
};
```
<style>

View File

@ -30,90 +30,87 @@ const colCounts = {};
colCounts[i] = value;
});
class App extends React.Component {
state = {
export default () => {
const [state, setState] = React.useState({
gutterKey: 1,
vgutterKey: 1,
colCountKey: 2,
});
const onGutterChange = gutterKey => {
setState({ ...state, gutterKey });
};
onGutterChange = gutterKey => {
this.setState({ gutterKey });
const onVGutterChange = vgutterKey => {
setState({ ...state, vgutterKey });
};
onVGutterChange = vgutterKey => {
this.setState({ vgutterKey });
const onColCountChange = colCountKey => {
setState({ ...state, colCountKey });
};
onColCountChange = colCountKey => {
this.setState({ colCountKey });
};
render() {
const { gutterKey, vgutterKey, colCountKey } = this.state;
const cols = [];
const colCount = colCounts[colCountKey];
let colCode = '';
for (let i = 0; i < colCount; i++) {
cols.push(
<Col key={i.toString()} span={24 / colCount}>
<div>Column</div>
</Col>,
);
colCode += ` <Col span={${24 / colCount}} />\n`;
}
return (
<>
<span>Horizontal Gutter (px): </span>
<div style={{ width: '50%' }}>
<Slider
min={0}
max={Object.keys(gutters).length - 1}
value={gutterKey}
onChange={this.onGutterChange}
marks={gutters}
step={null}
tipFormatter={value => gutters[value]}
/>
</div>
<span>Vertical Gutter (px): </span>
<div style={{ width: '50%' }}>
<Slider
min={0}
max={Object.keys(vgutters).length - 1}
value={vgutterKey}
onChange={this.onVGutterChange}
marks={vgutters}
step={null}
tipFormatter={value => vgutters[value]}
/>
</div>
<span>Column Count:</span>
<div style={{ width: '50%', marginBottom: 48 }}>
<Slider
min={0}
max={Object.keys(colCounts).length - 1}
value={colCountKey}
onChange={this.onColCountChange}
marks={colCounts}
step={null}
tipFormatter={value => colCounts[value]}
/>
</div>
<Row gutter={[gutters[gutterKey], vgutters[vgutterKey]]}>
{cols}
{cols}
</Row>
Another Row:
<Row gutter={[gutters[gutterKey], vgutters[vgutterKey]]}>{cols}</Row>
<pre className="demo-code">{`<Row gutter={[${gutters[gutterKey]}, ${vgutters[vgutterKey]}]}>\n${colCode}\n${colCode}</Row>`}</pre>
<pre className="demo-code">{`<Row gutter={[${gutters[gutterKey]}, ${vgutters[vgutterKey]}]}>\n${colCode}</Row>`}</pre>
</>
const { gutterKey, vgutterKey, colCountKey } = state;
const cols = [];
const colCount = colCounts[colCountKey];
let colCode = '';
for (let i = 0; i < colCount; i++) {
cols.push(
<Col key={i.toString()} span={24 / colCount}>
<div>Column</div>
</Col>,
);
colCode += ` <Col span={${24 / colCount}} />\n`;
}
}
export default App;
return (
<>
<span>Horizontal Gutter (px): </span>
<div style={{ width: '50%' }}>
<Slider
min={0}
max={Object.keys(gutters).length - 1}
value={gutterKey}
onChange={onGutterChange}
marks={gutters}
step={null}
tipFormatter={value => gutters[value]}
/>
</div>
<span>Vertical Gutter (px): </span>
<div style={{ width: '50%' }}>
<Slider
min={0}
max={Object.keys(vgutters).length - 1}
value={vgutterKey}
onChange={onVGutterChange}
marks={vgutters}
step={null}
tipFormatter={value => vgutters[value]}
/>
</div>
<span>Column Count:</span>
<div style={{ width: '50%', marginBottom: 48 }}>
<Slider
min={0}
max={Object.keys(colCounts).length - 1}
value={colCountKey}
onChange={onColCountChange}
marks={colCounts}
step={null}
tipFormatter={value => colCounts[value]}
/>
</div>
<Row gutter={[gutters[gutterKey], vgutters[vgutterKey]]}>
{cols}
{cols}
</Row>
Another Row:
<Row gutter={[gutters[gutterKey], vgutters[vgutterKey]]}>{cols}</Row>
<pre className="demo-code">{`<Row gutter={[${gutters[gutterKey]}, ${vgutters[vgutterKey]}]}>\n${colCode}\n${colCode}</Row>`}</pre>
<pre className="demo-code">{`<Row gutter={[${gutters[gutterKey]}, ${vgutters[vgutterKey]}]}>\n${colCode}</Row>`}</pre>
</>
);
};
```
```css

View File

@ -16,30 +16,22 @@ Click the button to toggle between available and disabled states.
```jsx
import { InputNumber, Button } from 'antd';
class App extends React.Component {
state = {
disabled: true,
export default () => {
const [disabled, setDisabled] = React.useState(true);
const toggle = () => {
setDisabled(!disabled);
};
toggle = () => {
this.setState({
disabled: !this.state.disabled,
});
};
render() {
return (
<>
<InputNumber min={1} max={10} disabled={this.state.disabled} defaultValue={3} />
<div style={{ marginTop: 20 }}>
<Button onClick={this.toggle} type="primary">
Toggle disabled
</Button>
</div>
</>
);
}
}
export default App;
return (
<>
<InputNumber min={1} max={10} disabled={disabled} defaultValue={3} />
<div style={{ marginTop: 20 }}>
<Button onClick={toggle} type="primary">
Toggle disabled
</Button>
</div>
</>
);
};
```

View File

@ -18,37 +18,30 @@ import { Input } from 'antd';
const { TextArea } = Input;
class Demo extends React.Component {
state = {
value: '',
export default () => {
const [value, setValue] = React.useState();
// eslint-disable-next-line @typescript-eslint/no-shadow
const onChange = ({ target: { value } }) => {
setValue(value);
};
onChange = ({ target: { value } }) => {
this.setState({ value });
};
render() {
const { value } = this.state;
return (
<>
<TextArea placeholder="Autosize height based on content lines" autoSize />
<div style={{ margin: '24px 0' }} />
<TextArea
placeholder="Autosize height with minimum and maximum number of lines"
autoSize={{ minRows: 2, maxRows: 6 }}
/>
<div style={{ margin: '24px 0' }} />
<TextArea
value={value}
onChange={this.onChange}
placeholder="Controlled autosize"
autoSize={{ minRows: 3, maxRows: 5 }}
/>
</>
);
}
}
export default Demo;
return (
<>
<TextArea placeholder="Autosize height based on content lines" autoSize />
<div style={{ margin: '24px 0' }} />
<TextArea
placeholder="Autosize height with minimum and maximum number of lines"
autoSize={{ minRows: 2, maxRows: 6 }}
/>
<div style={{ margin: '24px 0' }} />
<TextArea
value={value}
onChange={onChange}
placeholder="Controlled autosize"
autoSize={{ minRows: 3, maxRows: 5 }}
/>
</>
);
};
```

View File

@ -22,28 +22,17 @@ const { TextArea } = Input;
const defaultValue =
'The autoSize property applies to textarea nodes, and only the height changes automatically. In addition, autoSize can be set to an object, specifying the minimum number of rows and the maximum number of rows. The autoSize property applies to textarea nodes, and only the height changes automatically. In addition, autoSize can be set to an object, specifying the minimum number of rows and the maximum number of rows.';
class Demo extends React.Component {
state = {
autoResize: false,
};
export default () => {
const [autoResize, setAutoResize] = React.useState(false);
render() {
const { autoResize } = this.state;
return (
<>
<Button
onClick={() => this.setState({ autoResize: !autoResize })}
style={{ marginBottom: 16 }}
>
Auto Resize: {String(autoResize)}
</Button>
<TextArea rows={4} autoSize={autoResize} defaultValue={defaultValue} />
<TextArea allowClear style={{ width: 93 }} />
</>
);
}
}
export default Demo;
return (
<>
<Button onClick={() => setAutoResize(!autoResize)} style={{ marginBottom: 16 }}>
Auto Resize: {String(autoResize)}
</Button>
<TextArea rows={4} autoSize={autoResize} defaultValue={defaultValue} />
<TextArea allowClear style={{ width: 93 }} />
</>
);
};
```

View File

@ -20,18 +20,19 @@ function formatNumber(value) {
return new Intl.NumberFormat().format(value);
}
class NumericInput extends React.Component {
onChange = e => {
const { value } = e.target;
const NumericInput = props => {
const { value, onBlur, onChange } = props;
const handleChange = e => {
const inputValue = e.target.value;
const reg = /^-?\d*(\.\d*)?$/;
if ((!isNaN(value) && reg.test(value)) || value === '' || value === '-') {
this.props.onChange(value);
if ((!isNaN(inputValue) && reg.test(inputValue)) || inputValue === '' || inputValue === '-') {
onChange(inputValue);
}
};
// '.' at the end or only '-' in the input box.
onBlur = () => {
const { value, onBlur, onChange } = this.props;
const handleBlur = () => {
let valueTemp = value;
if (value.charAt(value.length - 1) === '.' || value === '-') {
valueTemp = value.slice(0, -1);
@ -42,50 +43,33 @@ class NumericInput extends React.Component {
}
};
render() {
const { value } = this.props;
const title = value ? (
<span className="numeric-input-title">{value !== '-' ? formatNumber(value) : '-'}</span>
) : (
'Input a number'
);
return (
<Tooltip
trigger={['focus']}
title={title}
placement="topLeft"
overlayClassName="numeric-input"
>
<Input
{...this.props}
onChange={this.onChange}
onBlur={this.onBlur}
placeholder="Input a number"
maxLength={25}
/>
</Tooltip>
);
}
}
const title = value ? (
<span className="numeric-input-title">{value !== '-' ? formatNumber(value) : '-'}</span>
) : (
'Input a number'
);
return (
<Tooltip trigger={['focus']} title={title} placement="topLeft" overlayClassName="numeric-input">
<Input
{...props}
onChange={handleChange}
onBlur={handleBlur}
placeholder="Input a number"
maxLength={25}
/>
</Tooltip>
);
};
class NumericInputDemo extends React.Component {
constructor(props) {
super(props);
this.state = { value: '' };
}
export default () => {
const [value, setValue] = React.useState();
onChange = value => {
this.setState({ value });
const onChange = val => {
setValue(val);
};
render() {
return (
<NumericInput style={{ width: 120 }} value={this.state.value} onChange={this.onChange} />
);
}
}
export default () => <NumericInputDemo />;
return <NumericInput style={{ width: 120 }} value={value} onChange={onChange} />;
};
```
```css

View File

@ -1,12 +1,12 @@
import React from 'react';
import { mount } from 'enzyme';
import { AppstoreOutlined, BarsOutlined } from '@ant-design/icons';
import mountTest from '../../../tests/shared/mountTest';
import rtlTest from '../../../tests/shared/rtlTest';
import { render, fireEvent } from '../../../tests/utils';
import Segmented from '../index';
import type { SegmentedValue } from '../index';
import { render } from '../../../tests/utils';
// Make CSSMotion working without transition
jest.mock('rc-motion/lib/util/motion', () => ({
@ -16,6 +16,19 @@ jest.mock('rc-motion/lib/util/motion', () => ({
const prefixCls = 'ant-segmented';
function expectMatchChecked(container: HTMLElement, checkedList: boolean[]) {
const inputList = Array.from(
container.querySelectorAll<HTMLInputElement>(`.${prefixCls}-item-input`),
);
expect(inputList).toHaveLength(checkedList.length);
inputList.forEach((input, i) => {
const checked = checkedList[i];
expect(input.checked).toBe(checked);
});
}
describe('Segmented', () => {
mountTest(Segmented);
rtlTest(Segmented);
@ -29,26 +42,22 @@ describe('Segmented', () => {
});
it('render empty segmented', () => {
const wrapper = mount(<Segmented options={[]} />);
expect(wrapper.render()).toMatchSnapshot();
const { asFragment } = render(<Segmented options={[]} />);
expect(asFragment().firstChild).toMatchSnapshot();
});
it('render segmented ok', () => {
const wrapper = mount(
const { asFragment, container } = render(
<Segmented options={[{ label: 'Daily', value: 'Daily' }, 'Weekly', 'Monthly']} />,
);
expect(wrapper.render()).toMatchSnapshot();
expect(asFragment().firstChild).toMatchSnapshot();
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([true, false, false]);
expectMatchChecked(container, [true, false, false]);
});
it('render label with ReactNode', () => {
const wrapper = mount(
const { asFragment, container } = render(
<Segmented
options={[
{ label: 'Daily', value: 'Daily' },
@ -58,164 +67,127 @@ describe('Segmented', () => {
/>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(asFragment().firstChild).toMatchSnapshot();
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([true, false, false]);
expectMatchChecked(container, [true, false, false]);
expect(wrapper.find('#weekly').at(0).text()).toContain('Weekly');
expect(wrapper.find('h2').at(0).text()).toContain('Monthly');
expect(container.querySelector('#weekly')?.textContent).toContain('Weekly');
expect(container.querySelectorAll('h2')[0].textContent).toContain('Monthly');
});
it('render segmented with defaultValue', () => {
const wrapper = mount(
const { container } = render(
<Segmented
options={['Daily', 'Weekly', 'Monthly', 'Quarterly', 'Yearly']}
defaultValue="Quarterly"
/>,
);
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([false, false, false, true, false]);
expectMatchChecked(container, [false, false, false, true, false]);
});
it('render segmented with string options', () => {
const handleValueChange = jest.fn();
const wrapper = mount(
const { asFragment, container } = render(
<Segmented options={['Daily', 'Weekly', 'Monthly']} onChange={handleValueChange} />,
);
expect(wrapper.render()).toMatchSnapshot();
expect(asFragment().firstChild).toMatchSnapshot();
expectMatchChecked(container, [true, false, false]);
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([true, false, false]);
expect(
wrapper.find(`label.${prefixCls}-item`).at(0).hasClass(`${prefixCls}-item-selected`),
container
.querySelectorAll(`label.${prefixCls}-item`)[0]
.classList.contains(`${prefixCls}-item-selected`),
).toBeTruthy();
wrapper.find(`.${prefixCls}-item-input`).at(2).simulate('change');
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[2]);
expect(handleValueChange).toBeCalledWith('Monthly');
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([false, false, true]);
expectMatchChecked(container, [false, false, true]);
});
it('render segmented with numeric options', () => {
const handleValueChange = jest.fn();
const wrapper = mount(
const { asFragment, container } = render(
<Segmented options={[1, 2, 3, 4, 5]} onChange={value => handleValueChange(value)} />,
);
expect(wrapper.render()).toMatchSnapshot();
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([true, false, false, false, false]);
expect(asFragment().firstChild).toMatchSnapshot();
expectMatchChecked(container, [true, false, false, false, false]);
wrapper.find(`.${prefixCls}-item-input`).last().simulate('change');
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[4]);
expect(handleValueChange).toBeCalledWith(5);
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([false, false, false, false, true]);
expectMatchChecked(container, [false, false, false, false, true]);
});
it('render segmented with mixed options', () => {
const handleValueChange = jest.fn();
const wrapper = mount(
const { asFragment, container } = render(
<Segmented
options={['Daily', { label: 'Weekly', value: 'Weekly' }, 'Monthly']}
onChange={value => handleValueChange(value)}
/>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(asFragment().firstChild).toMatchSnapshot();
expectMatchChecked(container, [true, false, false]);
wrapper.find(`.${prefixCls}-item-input`).at(1).simulate('change');
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[1]);
expect(handleValueChange).toBeCalledWith('Weekly');
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([false, true, false]);
expectMatchChecked(container, [false, true, false]);
});
it('render segmented with options: disabled', () => {
const handleValueChange = jest.fn();
const wrapper = mount(
const { asFragment, container } = render(
<Segmented
options={['Daily', { label: 'Weekly', value: 'Weekly', disabled: true }, 'Monthly']}
onChange={value => handleValueChange(value)}
/>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(asFragment().firstChild).toMatchSnapshot();
expect(
wrapper.find(`label.${prefixCls}-item`).at(1).hasClass(`${prefixCls}-item-disabled`),
container
.querySelectorAll(`label.${prefixCls}-item`)[1]
.classList.contains(`${prefixCls}-item-disabled`),
).toBeTruthy();
expect(wrapper.find(`.${prefixCls}-item-input`).at(1).prop('disabled')).toBeTruthy();
expect(container.querySelectorAll(`.${prefixCls}-item-input`)[1]).toHaveAttribute('disabled');
wrapper.find(`.${prefixCls}-item-input`).at(1).simulate('change');
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[1]);
expect(handleValueChange).not.toBeCalled();
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([true, false, false]);
expectMatchChecked(container, [true, false, false]);
wrapper.find(`.${prefixCls}-item-input`).at(2).simulate('change');
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[2]);
expect(handleValueChange).toBeCalledWith('Monthly');
expect(handleValueChange).toBeCalledTimes(1);
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([false, false, true]);
expectMatchChecked(container, [false, false, true]);
});
it('render segmented: disabled', () => {
const handleValueChange = jest.fn();
const wrapper = mount(
const { asFragment, container } = render(
<Segmented
disabled
options={['Daily', 'Weekly', 'Monthly']}
onChange={value => handleValueChange(value)}
/>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(wrapper.find(`.${prefixCls}`).hasClass(`${prefixCls}-disabled`)).toBeTruthy();
expect(asFragment().firstChild).toMatchSnapshot();
expect(
container.querySelectorAll(`.${prefixCls}`)[0].classList.contains(`${prefixCls}-disabled`),
).toBeTruthy();
wrapper.find(`.${prefixCls}-item-input`).at(1).simulate('change');
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[1]);
expect(handleValueChange).not.toBeCalled();
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([true, false, false]);
expectMatchChecked(container, [true, false, false]);
wrapper.find(`.${prefixCls}-item-input`).at(2).simulate('change');
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[2]);
expect(handleValueChange).not.toBeCalled();
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([true, false, false]);
expectMatchChecked(container, [true, false, false]);
});
it('render segmented with className and other html attributes', () => {
@ -234,11 +206,11 @@ describe('Segmented', () => {
it('render segmented with ref', () => {
const ref = React.createRef<HTMLDivElement>();
const wrapper = mount(
const { container } = render(
<Segmented options={['Daily', 'Monthly', 'Weekly']} defaultValue="Weekly" ref={ref} />,
);
expect((wrapper.find(Segmented).getElement() as any).ref).toBe(ref);
expect(ref.current).toBe(container.querySelector(`.${prefixCls}`));
});
it('render segmented with controlled mode', async () => {
@ -249,115 +221,124 @@ describe('Segmented', () => {
render() {
return (
<Segmented
options={['Map', 'Transit', 'Satellite']}
value={this.state.value}
onChange={value =>
this.setState({
value,
})
}
/>
<>
<Segmented
options={['Map', 'Transit', 'Satellite']}
value={this.state.value}
onChange={value =>
this.setState({
value,
})
}
/>
<div className="value">{this.state.value}</div>
<input
className="control"
onChange={e => {
this.setState({ value: e.target.value });
}}
/>
</>
);
}
}
const wrapper = mount<typeof Demo>(<Demo />);
wrapper.find('Segmented').find(`.${prefixCls}-item-input`).at(0).simulate('change');
expect(wrapper.find(Demo).state().value).toBe('Map');
const { container } = render(<Demo />);
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[0]);
expect(container.querySelector('.value')?.textContent).toBe('Map');
wrapper.find('Segmented').find(`.${prefixCls}-item-input`).at(1).simulate('change');
expect(wrapper.find(Demo).state().value).toBe('Transit');
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[1]);
expect(container.querySelector('.value')?.textContent).toBe('Transit');
});
it('render segmented with options null/undefined', () => {
const handleValueChange = jest.fn();
const wrapper = mount(
const { asFragment, container } = render(
<Segmented
options={[null, undefined, ''] as any}
disabled
onChange={value => handleValueChange(value)}
/>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(wrapper.find(`.${prefixCls}-item-label`).map(n => n.getDOMNode().textContent)).toEqual([
'',
'',
'',
]);
expect(asFragment().firstChild).toMatchSnapshot();
expect(
Array.from(container.querySelectorAll(`.${prefixCls}-item-label`)).map(n => n.textContent),
).toEqual(['', '', '']);
});
it('render segmented with thumb', () => {
const handleValueChange = jest.fn();
const wrapper = mount(
const { asFragment, container } = render(
<Segmented
options={['Map', 'Transit', 'Satellite']}
onChange={value => handleValueChange(value)}
/>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(asFragment().firstChild).toMatchSnapshot();
expectMatchChecked(container, [true, false, false]);
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([true, false, false]);
expect(
wrapper.find(`label.${prefixCls}-item`).at(0).hasClass(`${prefixCls}-item-selected`),
container
.querySelectorAll(`label.${prefixCls}-item`)[0]
.classList.contains(`${prefixCls}-item-selected`),
).toBeTruthy();
wrapper.find(`.${prefixCls}-item-input`).at(2).simulate('change');
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[2]);
expect(handleValueChange).toBeCalledWith('Satellite');
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([false, false, true]);
expectMatchChecked(container, [false, false, true]);
// thumb appeared
expect(wrapper.find(`.${prefixCls}-thumb`).length).toBe(1);
expect(container.querySelectorAll(`.${prefixCls}-thumb`).length).toBe(1);
// change selection again
wrapper.find(`.${prefixCls}-item-input`).at(1).simulate('change');
fireEvent.click(container.querySelectorAll(`.${prefixCls}-item-input`)[1]);
expect(handleValueChange).toBeCalledWith('Transit');
expect(
wrapper
.find(`.${prefixCls}-item-input`)
.map(el => (el.getDOMNode() as HTMLInputElement).checked),
).toEqual([false, true, false]);
expectMatchChecked(container, [false, true, false]);
// thumb appeared
expect(wrapper.find(`.${prefixCls}-thumb`).length).toBe(1);
expect(container.querySelectorAll(`.${prefixCls}-thumb`).length).toBe(1);
});
it('render segmented with `block`', () => {
const wrapper = mount(<Segmented block options={['Daily', 'Weekly', 'Monthly']} />);
const { asFragment, container } = render(
<Segmented block options={['Daily', 'Weekly', 'Monthly']} />,
);
expect(wrapper.render()).toMatchSnapshot();
expect(asFragment().firstChild).toMatchSnapshot();
expect(wrapper.find(`.${prefixCls}`).at(0).hasClass(`${prefixCls}-block`)).toBeTruthy();
expect(
container.querySelectorAll(`.${prefixCls}`)[0].classList.contains(`${prefixCls}-block`),
).toBeTruthy();
});
it('render segmented with `size#small`', () => {
const wrapper = mount(<Segmented size="small" options={['Daily', 'Weekly', 'Monthly']} />);
const { asFragment, container } = render(
<Segmented size="small" options={['Daily', 'Weekly', 'Monthly']} />,
);
expect(wrapper.render()).toMatchSnapshot();
expect(asFragment().firstChild).toMatchSnapshot();
expect(wrapper.find(`.${prefixCls}`).at(0).hasClass(`${prefixCls}-sm`)).toBeTruthy();
expect(
container.querySelectorAll(`.${prefixCls}`)[0].classList.contains(`${prefixCls}-sm`),
).toBeTruthy();
});
it('render segmented with `size#large`', () => {
const wrapper = mount(<Segmented size="large" options={['Daily', 'Weekly', 'Monthly']} />);
const { asFragment, container } = render(
<Segmented size="large" options={['Daily', 'Weekly', 'Monthly']} />,
);
expect(wrapper.render()).toMatchSnapshot();
expect(asFragment().firstChild).toMatchSnapshot();
expect(wrapper.find(`.${prefixCls}`).at(0).hasClass(`${prefixCls}-lg`)).toBeTruthy();
expect(
container.querySelectorAll(`.${prefixCls}`)[0].classList.contains(`${prefixCls}-lg`),
).toBeTruthy();
});
it('render with icons', () => {
const wrapper = mount(
const { asFragment, container } = render(
<Segmented
options={[
{
@ -372,8 +353,12 @@ describe('Segmented', () => {
]}
/>,
);
expect(wrapper.render()).toMatchSnapshot();
expect(wrapper.find(`span.${prefixCls}-item-icon`).length).toBe(2);
expect(wrapper.find(`div.${prefixCls}-item-label`).at(1).contains('KanbanYes')).toBeTruthy();
expect(asFragment().firstChild).toMatchSnapshot();
expect(container.querySelectorAll(`span.${prefixCls}-item-icon`).length).toBe(2);
expect(
container
.querySelectorAll(`div.${prefixCls}-item-label`)[1]
.textContent?.includes('KanbanYes'),
).toBeTruthy();
});
});

View File

@ -214,6 +214,7 @@ Properties for row selection.
| onSelectAll | Callback executed when select/deselect all rows | function(selected, selectedRows, changeRows) | - | |
| onSelectInvert | Callback executed when row selection is inverted | function(selectedRowKeys) | - | |
| onSelectNone | Callback executed when row selection is cleared | function() | - | |
| onSelectMultiple | Callback executed when row selection is changed by pressing shift | function(selected, selectedRows, changeRows) | - | |
### scroll

View File

@ -216,6 +216,7 @@ const columns = [
| onSelectAll | 用户手动选择/取消选择所有行的回调 | function(selected, selectedRows, changeRows) | - | |
| onSelectInvert | 用户手动选择反选的回调 | function(selectedRowKeys) | - | |
| onSelectNone | 用户清空选择的回调 | function() | - | |
| onSelectMultiple | 用户使用键盘 shift 选择多行的回调 | function(selected, selectedRows, changeRows) | - | |
### scroll

View File

@ -153,11 +153,13 @@ export interface TableRowSelection<T> {
onChange?: (selectedRowKeys: Key[], selectedRows: T[]) => void;
getCheckboxProps?: (record: T) => Partial<Omit<CheckboxProps, 'checked' | 'defaultChecked'>>;
onSelect?: SelectionSelectFn<T>;
/** @deprecated This function is deprecated and should use `onChange` instead */
onSelectMultiple?: (selected: boolean, selectedRows: T[], changeRows: T[]) => void;
/** @deprecated This function is meaningless and should use `onChange` instead */
/** @deprecated This function is deprecated and should use `onChange` instead */
onSelectAll?: (selected: boolean, selectedRows: T[], changeRows: T[]) => void;
/** @deprecated This function is meaningless and should use `onChange` instead */
/** @deprecated This function is deprecated and should use `onChange` instead */
onSelectInvert?: (selectedRowKeys: Key[]) => void;
/** @deprecated This function is deprecated and should use `onChange` instead */
onSelectNone?: () => void;
selections?: INTERNAL_SELECTION_ITEM[] | boolean;
hideSelectAll?: boolean;

View File

@ -122,11 +122,11 @@ ReactDOM.render(<Articles />, mountNode);
### UI/UE 设计师
简历和作品集请投递:lindong.lld#antgroup.com
简历和作品集请投递:jiayin.liu#antgroup.com
> 注明简历来自 ant.design 官网
- 岗位级别P6/P7/P8
- 岗位级别P5/P6/P7/P8
- 岗位地点:杭州
- 岗位要求:
- 至少 3-5 年的工作经验,扎实设计功底;
@ -141,7 +141,6 @@ ReactDOM.render(<Articles />, mountNode);
- 参与 Ant Design 的打磨,将其建设成全球卓越的设计体系。
- 参与 AntV 的打磨,将其建设成全球一流的数据可视化体系。
- One More Thing ❤️
- 你们总是为世界带去美好,但总是忘却你们也需要美好。我们正在努力打造 [🍳 Kitchen一款为设计师提效的 Sketch 工具集](https://kitchen.alipay.com/)等专属设计师的产品,让设计真正变成财富。期待志同道合的你,一道给设计行业带来「微小而美好的改变」。
### 前端工程师
@ -150,21 +149,20 @@ ReactDOM.render(<Articles />, mountNode);
> 注明简历来自 ant.design 官网
- 岗位级别P6/P7/P8
- 岗位地点:杭州
- 岗位级别P5/P6/P7/P8
- 岗位地点:杭州/上海
- 岗位要求:
- 在 React 技术栈持续耕耘,情有独钟。
- 热爱开源。
- 坚持和善于用技术和工具解决其他问题。
- 丰富的中后台前端研发经验。
- 爱 🐱。
- 岗位职责:
- 负责 Ant Design 前端基础设施研发。
- 负责中后台设计/前端工具体系建设。
### ADIArtificial Design Intelligence 工程师
简历和作品集请投递:lindong.lld#alipay.com
简历和作品集请投递:jiayin.liu#antgroup.com
> 注明简历来自 ant.design 官网

View File

@ -200,7 +200,7 @@
"cheerio": "^1.0.0-rc.3",
"concurrently": "^7.0.0",
"cross-env": "^7.0.0",
"css-minimizer-webpack-plugin": "^3.2.0",
"css-minimizer-webpack-plugin": "^1.3.0",
"dekko": "^0.2.1",
"docsearch-react-fork": "^0.0.0-alpha.0",
"docsearch.js": "^2.6.3",
@ -246,7 +246,7 @@
"jsonml.js": "^0.1.0",
"less-vars-to-js": "^1.3.0",
"lz-string": "^1.4.4",
"mini-css-extract-plugin": "^2.4.5",
"mini-css-extract-plugin": "^1.6.2",
"mockdate": "^3.0.0",
"open": "^8.0.1",
"prettier": "^2.3.2",
@ -279,12 +279,11 @@
"remark-cli": "^10.0.0",
"remark-lint": "^9.0.0",
"remark-preset-lint-recommended": "^6.0.0",
"remove-files-webpack-plugin": "^1.4.5",
"remove-files-webpack-plugin": "1.4.4",
"rimraf": "^3.0.0",
"scrollama": "^3.0.0",
"semver": "^7.3.5",
"simple-git": "^3.0.0",
"string-replace-loader": "^3.0.3",
"stylelint": "^14.0.0",
"stylelint-config-prettier": "^9.0.2",
"stylelint-config-rational-order": "^0.1.2",