This component provides a configuration to all React components underneath itself via the context API. In the render tree all components will have access to the provided config.
import React from 'react';
import { ConfigProvider } from 'antd';
// ...
const Demo: React.FC = () => (
<ConfigProvider direction="rtl">
<App />
</ConfigProvider>
);
export default Demo;
Some components use dynamic style to support wave effect. You can config csp
prop if Content Security Policy (CSP) is enabled:
<ConfigProvider csp={{ nonce: 'YourNonceCode' }}>
<Button>My Button</Button>
</ConfigProvider>
import React, { useState } from 'react';
import { EllipsisOutlined } from '@ant-design/icons';
import type {
ConfigProviderProps,
RadioChangeEvent,
TableProps,
TourProps,
UploadFile,
} from 'antd';
import {
Button,
Calendar,
ConfigProvider,
DatePicker,
Divider,
Form,
Image,
Input,
InputNumber,
Modal,
Pagination,
Popconfirm,
QRCode,
Radio,
Select,
Space,
Table,
theme,
TimePicker,
Tour,
Transfer,
Upload,
} from 'antd';
import enUS from 'antd/locale/en_US';
import zhCN from 'antd/locale/zh_CN';
import dayjs from 'dayjs';
import 'dayjs/locale/zh-cn';
type Locale = ConfigProviderProps['locale'];
dayjs.locale('en');
const { Option } = Select;
const { RangePicker } = DatePicker;
const columns: TableProps['columns'] = [
{
title: 'Name',
dataIndex: 'name',
filters: [{ text: 'filter1', value: 'filter1' }],
},
{
title: 'Age',
dataIndex: 'age',
},
];
const Page: React.FC = () => {
const { token } = theme.useToken();
const [open, setOpen] = useState(false);
const [tourOpen, setTourOpen] = useState(false);
const tourRefs = React.useRef<HTMLElement[]>([]);
const showModal = () => {
setOpen(true);
};
const hideModal = () => {
setOpen(false);
};
const info = () => {
Modal.info({
title: 'some info',
content: 'some info',
});
};
const confirm = () => {
Modal.confirm({
title: 'some info',
content: 'some info',
});
};
const steps: TourProps['steps'] = [
{
title: 'Upload File',
description: 'Put your files here.',
target: () => tourRefs.current[0],
},
{
title: 'Save',
description: 'Save your changes.',
target: () => tourRefs.current[1],
},
{
title: 'Other Actions',
description: 'Click to see other actions.',
target: () => tourRefs.current[2],
},
];
const fileList: UploadFile[] = [
{
uid: '-1',
name: 'image.png',
status: 'done',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-2',
percent: 50,
name: 'image.png',
status: 'uploading',
url: 'https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png',
},
{
uid: '-3',
name: 'image.png',
status: 'error',
},
];
return (
<Space
direction="vertical"
size={[0, 16]}
style={{ width: '100%', paddingTop: 16, borderTop: `1px solid ${token.colorBorder}` }}
>
<Pagination defaultCurrent={1} total={50} showSizeChanger />
<Space wrap>
<Select showSearch style={{ width: 200 }}>
<Option value="jack">jack</Option>
<Option value="lucy">lucy</Option>
</Select>
<DatePicker />
<TimePicker />
<RangePicker />
</Space>
<Space wrap>
<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>
</Space>
<Transfer dataSource={[]} showSearch targetKeys={[]} />
<div style={{ width: 320, border: `1px solid ${token.colorBorder}`, borderRadius: 8 }}>
<Calendar fullscreen={false} value={dayjs()} />
</div>
<Form name="basic" autoComplete="off" labelCol={{ sm: { span: 4 } }} wrapperCol={{ span: 6 }}>
<Form.Item label="Username" name="username" rules={[{ required: true }]}>
<Input width={200} />
</Form.Item>
<Form.Item
label="Age"
name="age"
rules={[{ type: 'number', min: 0, max: 99 }]}
initialValue={100}
>
<InputNumber width={200} />
</Form.Item>
<Form.Item wrapperCol={{ offset: 2, span: 6 }}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
<Table dataSource={[]} columns={columns} />
<Modal title="Locale Modal" open={open} onCancel={hideModal}>
<p>Locale Modal</p>
</Modal>
<Space wrap size={80}>
<QRCode
value="https://ant.design/"
status="expired"
onRefresh={() => console.log('refresh')}
/>
<Image
width={160}
src="https://zos.alipayobjects.com/rmsportal/jkjgkEfvpUPVyRjUImniVslZfWPnJuuZ.png"
/>
</Space>
<Upload listType="picture-card" fileList={fileList} />
<Divider orientation="left">Tour</Divider>
<Button type="primary" onClick={() => setTourOpen(true)}>
Begin Tour
</Button>
<Space>
<Button
ref={(node) => {
node && tourRefs.current.splice(0, 0, node);
}}
>
{' '}
Upload
</Button>
<Button
ref={(node) => {
node && tourRefs.current.splice(1, 0, node);
}}
type="primary"
>
Save
</Button>
<Button
ref={(node) => {
node && tourRefs.current.splice(2, 0, node);
}}
icon={<EllipsisOutlined />}
/>
</Space>
<Tour open={tourOpen} steps={steps} onClose={() => setTourOpen(false)} />
</Space>
);
};
const App: React.FC = () => {
const [locale, setLocal] = useState<Locale>(enUS);
const changeLocale = (e: RadioChangeEvent) => {
const localeValue = e.target.value;
setLocal(localeValue);
if (!localeValue) {
dayjs.locale('en');
} else {
dayjs.locale('zh-cn');
}
};
return (
<>
<div style={{ marginBottom: 16 }}>
<span style={{ marginInlineEnd: 16 }}>Change locale of components:</span>
<Radio.Group value={locale} onChange={changeLocale}>
<Radio.Button key="en" value={enUS}>
English
</Radio.Button>
<Radio.Button key="cn" value={zhCN}>
中文
</Radio.Button>
</Radio.Group>
</div>
<ConfigProvider locale={locale}>
<Page />
</ConfigProvider>
</>
);
};
export default App;
import React, { useState } from 'react';
import {
DownloadOutlined,
LeftOutlined,
MinusOutlined,
PlusOutlined,
RightOutlined,
SearchOutlined as SearchIcon,
SmileOutlined,
} from '@ant-design/icons';
import type { ConfigProviderProps, RadioChangeEvent } from 'antd';
import {
Badge,
Button,
Cascader,
Col,
ConfigProvider,
Divider,
Input,
InputNumber,
Modal,
Pagination,
Radio,
Rate,
Row,
Select,
Space,
Steps,
Switch,
Tree,
TreeSelect,
} from 'antd';
type DirectionType = ConfigProviderProps['direction'];
const InputGroup = Input.Group;
const ButtonGroup = Button.Group;
const { Option } = Select;
const { TreeNode } = Tree;
const { Search } = Input;
const cascaderOptions = [
{
value: 'tehran',
label: 'تهران',
children: [
{
value: 'tehran-c',
label: 'تهران',
children: [
{
value: 'saadat-abad',
label: 'سعادت آیاد',
},
],
},
],
},
{
value: 'ardabil',
label: 'اردبیل',
children: [
{
value: 'ardabil-c',
label: 'اردبیل',
children: [
{
value: 'primadar',
label: 'پیرمادر',
},
],
},
],
},
{
value: 'gilan',
label: 'گیلان',
children: [
{
value: 'rasht',
label: 'رشت',
children: [
{
value: 'district-3',
label: 'منطقه ۳',
},
],
},
],
},
];
type Placement = 'bottomLeft' | 'bottomRight' | 'topLeft' | 'topRight';
const Page: React.FC<{ placement: Placement }> = ({ placement }) => {
const [currentStep, setCurrentStep] = useState(0);
const [modalOpen, setModalOpen] = useState(false);
const [badgeCount, setBadgeCount] = useState(5);
const [showBadge, setShowBadge] = useState(true);
const selectBefore = (
<Select defaultValue="Http://" style={{ width: 90 }}>
<Option value="Http://">Http://</Option>
<Option value="Https://">Https://</Option>
</Select>
);
const selectAfter = (
<Select defaultValue=".com" style={{ width: 80 }}>
<Option value=".com">.com</Option>
<Option value=".jp">.jp</Option>
<Option value=".cn">.cn</Option>
<Option value=".org">.org</Option>
</Select>
);
// ==== Cascader ====
const cascaderFilter = (inputValue: string, path: { label: string }[]) =>
path.some((option) => option.label.toLowerCase().includes(inputValue.toLowerCase()));
const onCascaderChange = (value: any) => {
console.log(value);
};
// ==== End Cascader ====
// ==== Modal ====
const showModal = () => {
setModalOpen(true);
};
const handleOk = (e: React.MouseEvent<HTMLElement>) => {
console.log(e);
setModalOpen(false);
};
const handleCancel = (e: React.MouseEvent<HTMLElement>) => {
console.log(e);
setModalOpen(false);
};
// ==== End Modal ====
const onStepsChange = (newCurrentStep: number) => {
console.log('onChange:', newCurrentStep);
setCurrentStep(newCurrentStep);
};
// ==== Badge ====
const increaseBadge = () => {
setBadgeCount(badgeCount + 1);
};
const declineBadge = () => {
setBadgeCount((prev) => (prev - 1 < 0 ? 0 : prev - 1));
};
const onChangeBadge = (checked: boolean) => {
setShowBadge(checked);
};
// ==== End Badge ====
return (
<div className="direction-components">
<Row>
<Col span={24}>
<Divider orientation="left">Cascader example</Divider>
<Cascader
suffixIcon={<SearchIcon />}
options={cascaderOptions}
onChange={onCascaderChange}
placeholder="یک مورد انتخاب کنید"
placement={placement}
/>
With search:
<Cascader
suffixIcon={<SmileOutlined />}
options={cascaderOptions}
onChange={onCascaderChange}
placeholder="Select an item"
placement={placement}
showSearch={{ filter: cascaderFilter }}
/>
</Col>
</Row>
<br />
<Row>
<Col span={12}>
<Divider orientation="left">Switch example</Divider>
<Switch defaultChecked />
<Switch loading defaultChecked />
<Switch size="small" loading />
</Col>
<Col span={12}>
<Divider orientation="left">Radio Group example</Divider>
<Radio.Group defaultValue="c" buttonStyle="solid">
<Radio.Button value="a">تهران</Radio.Button>
<Radio.Button value="b" disabled>
اصفهان
</Radio.Button>
<Radio.Button value="c">فارس</Radio.Button>
<Radio.Button value="d">خوزستان</Radio.Button>
</Radio.Group>
</Col>
</Row>
<br />
<Row>
<Col span={12}>
<Divider orientation="left">Button example</Divider>
<div className="button-demo">
<Button type="primary" icon={<DownloadOutlined />} />
<Button type="primary" shape="circle" icon={<DownloadOutlined />} />
<Button type="primary" shape="round" icon={<DownloadOutlined />} />
<Button type="primary" shape="round" icon={<DownloadOutlined />}>
Download
</Button>
<Button type="primary" icon={<DownloadOutlined />}>
Download
</Button>
<br />
<Button.Group>
<Button type="primary">
<LeftOutlined />
Backward
</Button>
<Button type="primary">
Forward
<RightOutlined />
</Button>
</Button.Group>
<Button type="primary" loading>
Loading
</Button>
<Button type="primary" size="small" loading>
Loading
</Button>
</div>
</Col>
<Col span={12}>
<Divider orientation="left">Tree example</Divider>
<Tree
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: '#1677ff' }}>sss</span>} key="0-0-1-0" />
</TreeNode>
</TreeNode>
</Tree>
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Input (Input Group) example</Divider>
<InputGroup size="large">
<Row gutter={8}>
<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>
<Space wrap>
<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">
<Option value="jack">Jack</Option>
<Option value="سعید">سعید</Option>
<Option value="tom">Tom</Option>
</Select>
</Space>
</Col>
<Col span={12}>
<Divider orientation="left">TreeSelect example</Divider>
<TreeSelect
showSearch
style={{ width: '100%' }}
dropdownStyle={{ maxHeight: 400, overflow: 'auto' }}
placeholder="Please select"
allowClear
treeDefaultExpandAll
>
<TreeNode title="parent 1" key="0-1">
<TreeNode title="parent 1-0" key="0-1-1">
<TreeNode title="my leaf" key="random" />
<TreeNode title="your leaf" key="random1" />
</TreeNode>
<TreeNode title="parent 1-1" key="random2">
<TreeNode title={<b style={{ color: '#08c' }}>sss</b>} key="random3" />
</TreeNode>
</TreeNode>
</TreeSelect>
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Modal example</Divider>
<Button type="primary" onClick={showModal}>
Open Modal
</Button>
<Modal title="پنچره ساده" open={modalOpen} onOk={handleOk} onCancel={handleCancel}>
<p>نگاشتههای خود را اینجا قراردهید</p>
<p>نگاشتههای خود را اینجا قراردهید</p>
<p>نگاشتههای خود را اینجا قراردهید</p>
</Modal>
</Col>
</Row>
<br />
<Row>
<Col span={24}>
<Divider orientation="left">Steps example</Divider>
<Steps
progressDot
current={currentStep}
items={[
{
title: 'Finished',
description: 'This is a description.',
},
{
title: 'In Progress',
description: 'This is a description.',
},
{
title: 'Waiting',
description: 'This is a description.',
},
]}
/>
<br />
<Steps
current={currentStep}
onChange={onStepsChange}
items={[
{
title: 'Step 1',
description: 'This is a description.',
},
{
title: 'Step 2',
description: 'This is a description.',
},
{
title: 'Step 3',
description: 'This is a description.',
},
]}
/>
</Col>
</Row>
<br />
<Row>
<Col span={12}>
<Divider orientation="left">Rate example</Divider>
<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" target="_blank" rel="noreferrer">
rc-rate
</a>{' '}
implement rtl support.
</Col>
<Col span={12}>
<Divider orientation="left">Badge example</Divider>
<Badge count={badgeCount}>
<a href="#" className="head-example" />
</Badge>
<ButtonGroup>
<Button onClick={declineBadge}>
<MinusOutlined />
</Button>
<Button onClick={increaseBadge}>
<PlusOutlined />
</Button>
</ButtonGroup>
<div style={{ marginTop: 12 }}>
<Badge dot={showBadge}>
<a href="#" className="head-example" />
</Badge>
<Switch onChange={onChangeBadge} checked={showBadge} />
</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>
);
};
const App: React.FC = () => {
const [direction, setDirection] = useState<DirectionType>('ltr');
const [placement, setPlacement] = useState<Placement>('bottomLeft');
const changeDirection = (e: RadioChangeEvent) => {
const directionValue = e.target.value;
setDirection(directionValue);
setPlacement(directionValue === 'rtl' ? 'bottomRight' : 'bottomLeft');
};
return (
<>
<div style={{ marginBottom: 16 }}>
<span style={{ marginInlineEnd: 16 }}>Change direction of components:</span>
<Radio.Group defaultValue="ltr" onChange={changeDirection}>
<Radio.Button key="ltr" value="ltr">
LTR
</Radio.Button>
<Radio.Button key="rtl" value="rtl">
RTL
</Radio.Button>
</Radio.Group>
</div>
<ConfigProvider direction={direction}>
<Page placement={placement} />
</ConfigProvider>
</>
);
};
export default App;
import React, { useState } from 'react';
import {
Button,
Card,
ConfigProvider,
DatePicker,
Divider,
Input,
Radio,
Select,
Space,
Table,
Tabs,
} from 'antd';
import type { ConfigProviderProps } from 'antd';
type SizeType = ConfigProviderProps['componentSize'];
const App: React.FC = () => {
const [componentSize, setComponentSize] = useState<SizeType>('small');
return (
<>
<Radio.Group
value={componentSize}
onChange={(e) => {
setComponentSize(e.target.value);
}}
>
<Radio.Button value="small">Small</Radio.Button>
<Radio.Button value="middle">Middle</Radio.Button>
<Radio.Button value="large">Large</Radio.Button>
</Radio.Group>
<Divider />
<ConfigProvider componentSize={componentSize}>
<Space size={[0, 16]} style={{ width: '100%' }} direction="vertical">
<Input />
<Tabs
defaultActiveKey="1"
items={[
{
label: 'Tab 1',
key: '1',
children: 'Content of Tab Pane 1',
},
{
label: 'Tab 2',
key: '2',
children: 'Content of Tab Pane 2',
},
{
label: 'Tab 3',
key: '3',
children: 'Content of Tab Pane 3',
},
]}
/>
<Input.Search allowClear />
<Input.TextArea allowClear />
<Select defaultValue="demo" options={[{ value: 'demo' }]} />
<DatePicker />
<DatePicker.RangePicker />
<Button>Button</Button>
<Card title="Card">
<Table
columns={[
{ title: 'Name', dataIndex: 'name' },
{ title: 'Age', dataIndex: 'age' },
]}
dataSource={[
{ key: '1', name: 'John Brown', age: 32 },
{ key: '2', name: 'Jim Green', age: 42 },
{ key: '3', name: 'Joe Black', age: 32 },
]}
/>
</Card>
</Space>
</ConfigProvider>
</>
);
};
export default App;
import React from 'react';
import {
Button,
ColorPicker,
ConfigProvider,
Divider,
Form,
Input,
InputNumber,
Space,
Switch,
} from 'antd';
import type { ColorPickerProps, GetProp } from 'antd';
type Color = Extract<GetProp<ColorPickerProps, 'value'>, { cleared: any }>;
type ThemeData = {
borderRadius: number;
colorPrimary: string;
Button?: {
colorPrimary: string;
algorithm?: boolean;
};
};
const defaultData: ThemeData = {
borderRadius: 6,
colorPrimary: '#1677ff',
Button: {
colorPrimary: '#00B96B',
},
};
export default () => {
const [form] = Form.useForm();
const [data, setData] = React.useState<ThemeData>(defaultData);
return (
<div>
<ConfigProvider
theme={{
token: {
colorPrimary: data.colorPrimary,
borderRadius: data.borderRadius,
},
components: {
Button: {
colorPrimary: data.Button?.colorPrimary,
algorithm: data.Button?.algorithm,
},
},
}}
>
<Space>
<Input />
<Button type="primary">Button</Button>
</Space>
</ConfigProvider>
<Divider />
<Form
form={form}
onValuesChange={(_, allValues) => {
setData({
...allValues,
});
}}
name="theme"
initialValues={defaultData}
labelCol={{ span: 4 }}
wrapperCol={{ span: 20 }}
>
<Form.Item
name="colorPrimary"
label="Primary Color"
trigger="onChangeComplete"
getValueFromEvent={(color: Color) => color.toHexString()}
>
<ColorPicker />
</Form.Item>
<Form.Item name="borderRadius" label="Border Radius">
<InputNumber />
</Form.Item>
<Form.Item label="Button">
<Form.Item name={['Button', 'algorithm']} valuePropName="checked" label="algorithm">
<Switch />
</Form.Item>
<Form.Item
name={['Button', 'colorPrimary']}
label="Primary Color"
trigger="onChangeComplete"
getValueFromEvent={(color: Color) => color.toHexString()}
>
<ColorPicker />
</Form.Item>
</Form.Item>
<Form.Item name="submit" wrapperCol={{ offset: 4, span: 20 }}>
<Button type="primary">Submit</Button>
</Form.Item>
</Form>
</div>
);
};
import React from 'react';
import { HappyProvider } from '@ant-design/happy-work-theme';
import { Button, ConfigProvider, Space } from 'antd';
import type { ConfigProviderProps, GetProp } from 'antd';
type WaveConfig = GetProp<ConfigProviderProps, 'wave'>;
// Prepare effect holder
const createHolder = (node: HTMLElement) => {
const { borderWidth } = getComputedStyle(node);
const borderWidthNum = parseInt(borderWidth, 10);
const div = document.createElement('div');
div.style.position = 'absolute';
div.style.inset = `-${borderWidthNum}px`;
div.style.borderRadius = 'inherit';
div.style.background = 'transparent';
div.style.zIndex = '999';
div.style.pointerEvents = 'none';
div.style.overflow = 'hidden';
node.appendChild(div);
return div;
};
const createDot = (holder: HTMLElement, color: string, left: number, top: number, size = 0) => {
const dot = document.createElement('div');
dot.style.position = 'absolute';
dot.style.left = `${left}px`;
dot.style.top = `${top}px`;
dot.style.width = `${size}px`;
dot.style.height = `${size}px`;
dot.style.borderRadius = '50%';
dot.style.background = color;
dot.style.transform = 'translate(-50%, -50%)';
dot.style.transition = 'all 1s ease-out';
holder.appendChild(dot);
return dot;
};
// Inset Effect
const showInsetEffect: WaveConfig['showEffect'] = (node, { event, component }) => {
if (component !== 'Button') {
return;
}
const holder = createHolder(node);
const rect = holder.getBoundingClientRect();
const left = event.clientX - rect.left;
const top = event.clientY - rect.top;
const dot = createDot(holder, 'rgba(255, 255, 255, 0.65)', left, top);
// Motion
requestAnimationFrame(() => {
dot.ontransitionend = () => {
holder.remove();
};
dot.style.width = '200px';
dot.style.height = '200px';
dot.style.opacity = '0';
});
};
// Shake Effect
const showShakeEffect: WaveConfig['showEffect'] = (node, { component }) => {
if (component !== 'Button') {
return;
}
const seq = [0, -15, 15, -5, 5, 0];
const itv = 10;
let steps = 0;
function loop() {
cancelAnimationFrame((node as any).effectTimeout);
(node as any).effectTimeout = requestAnimationFrame(() => {
const currentStep = Math.floor(steps / itv);
const current = seq[currentStep];
const next = seq[currentStep + 1];
if (!next) {
node.style.transform = '';
node.style.transition = '';
return;
}
// Trans from current to next by itv
const angle = current + ((next - current) / itv) * (steps % itv);
node.style.transform = `rotate(${angle}deg)`;
node.style.transition = 'none';
steps += 1;
loop();
});
}
loop();
};
// Component
const Wrapper = ({ name, ...wave }: WaveConfig & { name: string }) => (
<ConfigProvider wave={wave}>
<Button type="primary">{name}</Button>
</ConfigProvider>
);
const App = () => (
<Space style={{ padding: 24 }} size="large">
<Wrapper name="Disabled" disabled />
<Wrapper name="Default" />
<Wrapper name="Inset" showEffect={showInsetEffect} />
<Wrapper name="Shake" showEffect={showShakeEffect} />
<HappyProvider>
<Button type="primary">Happy Work</Button>
</HappyProvider>
</Space>
);
export default App;
import React, { useContext, useLayoutEffect } from 'react';
import { StyleProvider } from '@ant-design/cssinjs';
import { ExclamationCircleFilled } from '@ant-design/icons';
import { App, Button, ConfigProvider, message, Modal, notification, Space } from 'antd';
const Demo: React.FC = () => {
const { locale, theme } = useContext(ConfigProvider.ConfigContext);
useLayoutEffect(() => {
ConfigProvider.config({
holderRender: (children) => (
<StyleProvider hashPriority="high">
<ConfigProvider prefixCls="static" iconPrefixCls="icon" locale={locale} theme={theme}>
<App message={{ maxCount: 1 }} notification={{ maxCount: 1 }}>
{children}
</App>
</ConfigProvider>
</StyleProvider>
),
});
}, [locale, theme]);
return (
<div>
<Space>
<Button
type="primary"
onClick={() => {
message.info('This is a normal message');
}}
>
message
</Button>
<Button
type="primary"
onClick={() => {
notification.open({
message: 'Notification Title',
description:
'This is the content of the notification. This is the content of the notification. This is the content of the notification.',
});
}}
>
notification
</Button>
<Button
type="primary"
onClick={() => {
Modal.confirm({
title: 'Do you want to delete these items?',
icon: <ExclamationCircleFilled />,
content: 'Some descriptions',
});
}}
>
Modal
</Button>
</Space>
</div>
);
};
export default Demo;
import React, { useState } from 'react';
import { SmileOutlined } from '@ant-design/icons';
import { Button, Checkbox, ConfigProvider, Radio, Select } from 'antd';
// Ant Design site use `es` module for view
// but do not replace related lib `lib` with `es`
// which do not show correct in site.
// We may need do convert in site also.
const App: React.FC = () => {
const [prefixCls, setPrefixCls] = useState('light');
return (
<>
<Button
style={{ marginBottom: 12 }}
type="primary"
onClick={() => setPrefixCls(prefixCls === 'light' ? 'dark' : 'light')}
>
toggle prefixCls
</Button>
<br />
<ConfigProvider prefixCls={prefixCls} iconPrefixCls="bamboo">
<SmileOutlined />
<Select style={{ width: 120 }} />
<Radio>test</Radio>
<Checkbox>test</Checkbox>
</ConfigProvider>
</>
);
};
export default App;
import React, { useState } from 'react';
import { Checkbox, ConfigProvider, Divider, Form, Input, Radio, Space } from 'antd';
import type { ConfigProviderProps } from 'antd';
type SizeType = ConfigProviderProps['componentSize'];
const ConfigDisplay = () => {
const { componentDisabled, componentSize } = ConfigProvider.useConfig();
return (
<>
<Form.Item label="componentSize value">
<Input value={componentSize} />
</Form.Item>
<Form.Item label="componentDisabled value">
<Input value={String(componentDisabled)} disabled={componentDisabled} />
</Form.Item>
</>
);
};
const App: React.FC = () => {
const [componentSize, setComponentSize] = useState<SizeType>('small');
const [disabled, setDisabled] = useState<boolean>(true);
return (
<div>
<Space>
<Radio.Group
value={componentSize}
onChange={(e) => {
setComponentSize(e.target.value);
}}
>
<Radio.Button value="small">Small</Radio.Button>
<Radio.Button value="middle">Middle</Radio.Button>
<Radio.Button value="large">Large</Radio.Button>
</Radio.Group>
<Checkbox checked={disabled} onChange={(e) => setDisabled(e.target.checked)}>
Form disabled
</Checkbox>
</Space>
<Divider />
<ConfigProvider componentSize={componentSize}>
<div className="example">
<Form disabled={disabled}>
<ConfigDisplay />
</Form>
</div>
</ConfigProvider>
</div>
);
};
export default App;
import React from 'react';
import { Alert, ConfigProvider, Input, Typography } from 'antd';
const App: React.FC = () => (
<>
<Typography.Title level={4}>Open single page to check the console</Typography.Title>
<ConfigProvider warning={{ strict: false }}>
<Alert closeText="deprecated" />
<Input.Group />
</ConfigProvider>
</>
);
export default App;
Property | Description | Type | Default | Version |
---|---|---|---|---|
componentDisabled | Config antd component disabled |
boolean | - | 4.21.0 |
componentSize | Config antd component size | small | middle | large |
- | |
csp | Set Content Security Policy config | { nonce: string } | - | |
direction | Set direction of layout. See demo | ltr | rtl |
ltr |
|
getPopupContainer | To set the container of the popup element. The default is to create a div element in body |
function(triggerNode) | () => document.body | |
getTargetContainer | Config Affix, Anchor scroll target container | () => HTMLElement | () => window | 4.2.0 |
iconPrefixCls | Set icon prefix className | string | anticon |
4.11.0 |
locale | Language package setting, you can find the packages in antd/locale | object | - | |
popupMatchSelectWidth | Determine whether the dropdown menu and the select input are the same width. Default set min-width same as input. Will ignore when value less than select width. false will disable virtual scroll |
boolean | number | - | 5.5.0 |
popupOverflow | Select like component popup logic. Can set to show in viewport or follow window scroll | ‘viewport’ | ‘scroll’ |
‘viewport’ | 5.5.0 |
prefixCls | Set prefix className | string | ant |
|
renderEmpty | Set empty content of components. Ref Empty | function(componentName: string): ReactNode | - | |
theme | Set theme, ref Customize Theme | Theme | - | 5.0.0 |
variant | Set variant of data entry components | outlined | filled | borderless |
- | 5.19.0 |
virtual | Disable virtual scroll when set to false |
boolean | - | 4.3.0 |
warning | Config warning level, when strict is false , it will aggregate deprecated information into a single message |
{ strict: boolean } | - | 5.10.0 |
Setting Modal
、Message
、Notification
static config. Not work on hooks.
ConfigProvider.config({
// 5.13.0+
holderRender: (children) => (
<ConfigProvider
prefixCls="ant"
iconPrefixCls="anticon"
theme={{ token: { colorPrimary: 'red' } }}
>
{children}
</ConfigProvider>
),
});
5.3.0+
Available since 5.2.0
. Get the value of the parent Provider
. Such as DisabledContextProvider
, SizeContextProvider
.
const {
componentDisabled, // 5.3.0+
componentSize, // 5.3.0+
} = ConfigProvider.useConfig();
Property | Description | Type | Default | Version |
---|---|---|---|---|
componentDisabled | antd component disabled state | boolean | - | 5.3.0 |
componentSize | antd component size state | small | middle | large |
- | 5.3.0 |
Property | Description | Type | Default | Version |
---|---|---|---|---|
alert | Set Alert common props | { className?: string, style?: React.CSSProperties, closeIcon?: React.ReactNode } | - | 5.7.0, closeIcon: 5.14.0 |
anchor | Set Anchor common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
avatar | Set Avatar common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
badge | Set Badge common props | { className?: string, style?: React.CSSProperties, classNames?: BadgeProps[“classNames”], styles?: BadgeProps[“styles”] } | - | 5.7.0 |
breadcrumb | Set Breadcrumb common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
button | Set Button common props | { className?: string, style?: React.CSSProperties, classNames?: ButtonProps[“classNames”], styles?: ButtonProps[“styles”], autoInsertSpace?: boolean } | - | 5.6.0, autoInsertSpace: 5.17.0 |
card | Set Card common props | { className?: string, style?: React.CSSProperties, classNames?: CardProps[“classNames”], styles?: CardProps[“styles”] } | - | 5.7.0, classNames and styles : 5.14.0 |
calendar | Set Calendar common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
carousel | Set Carousel common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
cascader | Set Cascader common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
checkbox | Set Checkbox common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
collapse | Set Collapse common props | { className?: string, style?: React.CSSProperties, expandIcon?: (props) => ReactNode } | - | 5.7.0, expandIcon: 5.15.0 |
colorPicker | Set ColorPicker common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
datePicker | Set datePicker common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
rangePicker | Set rangePicker common props | { className?: string, style?: React.CSSProperties } | - | 5.11.0 |
descriptions | Set Descriptions common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
divider | Set Divider common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
drawer | Set Drawer common props | { className?: string, style?: React.CSSProperties, classNames?: DrawerProps[“classNames”], styles?: DrawerProps[“styles”], closeIcon?: ReactNode } | - | 5.7.0, classNames and styles : 5.10.0, closeIcon : 5.14.0 |
dropdown | Set Dropdown common props | { className?: string, style?: React.CSSProperties } | - | 5.11.0 |
empty | Set Empty common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
flex | Set Flex common props | { className?: string, style?: React.CSSProperties, vertical?: boolean } | - | 5.10.0 |
floatButtonGroup | Set FloatButton.Group common props | { closeIcon?: React.ReactNode } | - | 5.16.0 |
form | Set Form common props | { className?: string, style?: React.CSSProperties, validateMessages?: ValidateMessages, requiredMark?: boolean | optional , scrollToFirstError?: boolean | Options } |
- | requiredMark: 4.8.0; colon: 4.18.0; scrollToFirstError: 5.2.0; className: 5.7.0; style: 5.7.0 |
image | Set Image common props | { className?: string, style?: React.CSSProperties, preview?: { closeIcon?: React.ReactNode } } | - | 5.7.0, closeIcon: 5.14.0 |
input | Set Input common props | { autoComplete?: string, className?: string, style?: React.CSSProperties, allowClear?: boolean | { clearIcon?: ReactNode } } | - | 4.2.0, allowClear: 5.15.0 |
textArea | Set TextArea common props | { autoComplete?: string, className?: string, style?: React.CSSProperties, allowClear?: boolean | { clearIcon?: ReactNode } } | - | 5.15.0 |
layout | Set Layout common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
list | Set List common props | { className?: string, style?: React.CSSProperties, item?:{ classNames: ListItemProps[“classNames”], styles: ListItemProps[“styles”] } } | - | 5.7.0 |
menu | Set Menu common props | { className?: string, style?: React.CSSProperties, expandIcon?: ReactNode | props => ReactNode } | - | 5.7.0, expandIcon: 5.15.0 |
mentions | Set Mentions common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
message | Set Message common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
modal | Set Modal common props | { className?: string, style?: React.CSSProperties, classNames?: ModalProps[“classNames”], styles?: ModalProps[“styles”], closeIcon?: React.ReactNode } | - | 5.7.0, classNames and styles : 5.10.0, closeIcon : 5.14.0 |
notification | Set Notification common props | { className?: string, style?: React.CSSProperties, closeIcon?: React.ReactNode } | - | 5.7.0, closeIcon : 5.14.0 |
pagination | Set Pagination common props | { showSizeChanger?: boolean, className?: string, style?: React.CSSProperties } | - | 5.7.0 |
progress | Set Progress common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
radio | Set Radio common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
rate | Set Rate common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
result | Set Result common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
skeleton | Set Skeleton common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
segmented | Set Segmented common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
select | Set Select common props | { className?: string, showSearch?: boolean, style?: React.CSSProperties } | - | 5.7.0 |
slider | Set Slider common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
switch | Set Switch common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
space | Set Space common props, ref Space | { size: small | middle | large | number , className?: string, style?: React.CSSProperties, classNames?: SpaceProps[“classNames”], styles?: SpaceProps[“styles”] } |
- | 5.6.0 |
splitter | Set Splitter common props | { className?: string, style?: React.CSSProperties } | - | 5.21.0 |
spin | Set Spin common props | { className?: string, style?: React.CSSProperties, indicator?: React.ReactElement } | - | 5.7.0, indicator: 5.20.0 |
statistic | Set Statistic common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
steps | Set Steps common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
table | Set Table common props | { className?: string, style?: React.CSSProperties, expandable?: { expandIcon?: props => React.ReactNode } } | - | 5.7.0, expandable: 5.14.0 |
tabs | Set Tabs common props | { className?: string, style?: React.CSSProperties, indicator?: { size?: GetIndicatorSize, align?: start | center | end }, moreIcon?: ReactNode, addIcon?: ReactNode, removeIcon?: ReactNode } |
- | 5.7.0, moreIcon and addIcon : 5.14.0, removeIcon : 5.15.0 |
tag | Set Tag common props | { className?: string, style?: React.CSSProperties, closeIcon?: React.ReactNode } | - | 5.7.0, closeIcon: 5.14.0 |
timeline | Set Timeline common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
timePicker | Set TimePicker common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
tour | Set Tour common props | { closeIcon?: React.ReactNode } | - | 5.14.0 |
transfer | Set Transfer common props | { className?: string, style?: React.CSSProperties, selectionsIcon?: React.ReactNode } | - | 5.7.0, selectionsIcon: 5.14.0 |
tree | Set Tree common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
typography | Set Typography common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
upload | Set Upload common props | { className?: string, style?: React.CSSProperties } | - | 5.7.0 |
wave | Config wave effect | { disabled?: boolean, showEffect?: (node: HTMLElement, info: { className, token, component }) => void } | - | 5.8.0 |
See FAQ Date-related-components-locale-is-not-working?
getPopupContainer
?Related issue: https://github.com/ant-design/ant-design/issues/19974
When you config getPopupContainer
to parentNode globally, Modal will throw error of triggerNode is undefined
because it did not have a triggerNode. You can try the fix below.
<ConfigProvider
- getPopupContainer={triggerNode => triggerNode.parentNode}
+ getPopupContainer={node => {
+ if (node) {
+ return node.parentNode;
+ }
+ return document.body;
+ }}
>
<App />
</ConfigProvider>
prefixCls
and theme
) affect ReactNode inside message.info
, notification.open
, Modal.confirm
?antd will dynamic create React instance by ReactDOM.render
when call message methods. Whose context is different with origin code located context. We recommend useMessage
, useNotification
and useModal
which , the methods came from message/notification/Modal
has been deprecated in 5.x.
Related issue: #39045
In production mode of Vite, default exports from cjs file should be used like this: enUS.default
. So you can directly import locale from es/
directory like import enUS from 'antd/es/locale/en_US'
to make dev and production have the same behavior.
prefixCls
priority(The former is covered by the latter)ConfigProvider.config({ prefixCls: 'prefix-1' })
ConfigProvider.config({ holderRender: (children) => <ConfigProvider prefixCls="prefix-2">{children}</ConfigProvider> })
message.config({ prefixCls: 'prefix-3' })