mirror of
https://github.com/ant-design/ant-design.git
synced 2025-06-07 17:44:35 +08:00
chore: merge master
This commit is contained in:
commit
dd1670a3b4
@ -78,6 +78,8 @@ module.exports = {
|
|||||||
'jsx-a11y/href-no-hash': 0,
|
'jsx-a11y/href-no-hash': 0,
|
||||||
'jsx-a11y/control-has-associated-label': 0,
|
'jsx-a11y/control-has-associated-label': 0,
|
||||||
'import/no-extraneous-dependencies': 0,
|
'import/no-extraneous-dependencies': 0,
|
||||||
|
'react/jsx-no-constructed-context-values': 0,
|
||||||
|
'react/no-unstable-nested-components': 0,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
@ -100,7 +102,8 @@ module.exports = {
|
|||||||
'react/no-unused-prop-types': 0,
|
'react/no-unused-prop-types': 0,
|
||||||
'react/default-props-match-prop-types': 0,
|
'react/default-props-match-prop-types': 0,
|
||||||
'react-hooks/rules-of-hooks': 2, // Checks rules of Hooks
|
'react-hooks/rules-of-hooks': 2, // Checks rules of Hooks
|
||||||
|
'react/function-component-definition': 0,
|
||||||
|
'react/no-unused-class-component-methods': 0,
|
||||||
'import/extensions': 0,
|
'import/extensions': 0,
|
||||||
'import/no-cycle': 0,
|
'import/no-cycle': 0,
|
||||||
'import/no-extraneous-dependencies': [
|
'import/no-extraneous-dependencies': [
|
||||||
|
2
.github/workflows/preview-build.yml
vendored
2
.github/workflows/preview-build.yml
vendored
@ -64,6 +64,8 @@ jobs:
|
|||||||
- name: npm run site
|
- name: npm run site
|
||||||
id: site
|
id: site
|
||||||
run: npm run site
|
run: npm run site
|
||||||
|
env:
|
||||||
|
SITE_ENV: development
|
||||||
|
|
||||||
- name: upload site artifact
|
- name: upload site artifact
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v2
|
||||||
|
@ -3,6 +3,6 @@ import UnreachableException from '../unreachableException';
|
|||||||
describe('UnreachableException', () => {
|
describe('UnreachableException', () => {
|
||||||
it('error thrown matches snapshot', () => {
|
it('error thrown matches snapshot', () => {
|
||||||
const exception = new UnreachableException('some value');
|
const exception = new UnreachableException('some value');
|
||||||
expect(exception.message).toMatchInlineSnapshot(`"unreachable case: \\"some value\\""`);
|
expect(exception.error.message).toMatchInlineSnapshot(`"unreachable case: \\"some value\\""`);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
export default class UnreachableException {
|
export default class UnreachableException {
|
||||||
|
error: Error;
|
||||||
|
|
||||||
constructor(value: never) {
|
constructor(value: never) {
|
||||||
return new Error(`unreachable case: ${JSON.stringify(value)}`);
|
this.error = new Error(`unreachable case: ${JSON.stringify(value)}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
|
import memoizeOne from 'memoize-one';
|
||||||
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
import addEventListener from 'rc-util/lib/Dom/addEventListener';
|
||||||
import Affix from '../affix';
|
import Affix from '../affix';
|
||||||
import AnchorLink from './AnchorLink';
|
import AnchorLink from './AnchorLink';
|
||||||
@ -258,7 +259,6 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState, Co
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { getPrefixCls, direction } = this.context;
|
const { getPrefixCls, direction } = this.context;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
prefixCls: customizePrefixCls,
|
prefixCls: customizePrefixCls,
|
||||||
className = '',
|
className = '',
|
||||||
@ -267,6 +267,7 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState, Co
|
|||||||
affix,
|
affix,
|
||||||
showInkInFixed,
|
showInkInFixed,
|
||||||
children,
|
children,
|
||||||
|
onClick,
|
||||||
} = this.props;
|
} = this.props;
|
||||||
const { activeLink } = this.state;
|
const { activeLink } = this.state;
|
||||||
|
|
||||||
@ -309,16 +310,16 @@ export default class Anchor extends React.Component<AnchorProps, AnchorState, Co
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const contextValue = memoizeOne((link, onClickFn) => ({
|
||||||
|
registerLink: this.registerLink,
|
||||||
|
unregisterLink: this.unregisterLink,
|
||||||
|
scrollTo: this.handleScrollTo,
|
||||||
|
activeLink: link,
|
||||||
|
onClick: onClickFn,
|
||||||
|
}))(activeLink, onClick);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AnchorContext.Provider
|
<AnchorContext.Provider value={contextValue}>
|
||||||
value={{
|
|
||||||
registerLink: this.registerLink,
|
|
||||||
unregisterLink: this.unregisterLink,
|
|
||||||
activeLink: this.state.activeLink,
|
|
||||||
scrollTo: this.handleScrollTo,
|
|
||||||
onClick: this.props.onClick,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
{!affix ? (
|
{!affix ? (
|
||||||
anchorContent
|
anchorContent
|
||||||
) : (
|
) : (
|
||||||
|
@ -55,9 +55,9 @@ const getPath = (path: string, params: any) => {
|
|||||||
return path;
|
return path;
|
||||||
};
|
};
|
||||||
|
|
||||||
const addChildPath = (paths: string[], childPath: string = '', params: any) => {
|
const addChildPath = (paths: string[], childPath: string, params: any) => {
|
||||||
const originalPaths = [...paths];
|
const originalPaths = [...paths];
|
||||||
const path = getPath(childPath, params);
|
const path = getPath(childPath || '', params);
|
||||||
if (path) {
|
if (path) {
|
||||||
originalPaths.push(path);
|
originalPaths.push(path);
|
||||||
}
|
}
|
||||||
|
@ -316,6 +316,7 @@ describe('Button', () => {
|
|||||||
it('should handle fragment as children', () => {
|
it('should handle fragment as children', () => {
|
||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Button>
|
<Button>
|
||||||
|
{/* eslint-disable-next-line react/jsx-no-useless-fragment */}
|
||||||
<>text</>
|
<>text</>
|
||||||
</Button>,
|
</Button>,
|
||||||
);
|
);
|
||||||
|
@ -32,7 +32,7 @@ const ButtonGroup: React.FC<ButtonGroupProps> = props => (
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn(new UnreachableException(size));
|
console.warn(new UnreachableException(size).error);
|
||||||
}
|
}
|
||||||
|
|
||||||
const classes = classNames(
|
const classes = classNames(
|
||||||
|
@ -3,6 +3,7 @@ import { mount } from 'enzyme';
|
|||||||
import Carousel from '..';
|
import Carousel from '..';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
|
import { sleep } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('Carousel', () => {
|
describe('Carousel', () => {
|
||||||
mountTest(Carousel);
|
mountTest(Carousel);
|
||||||
@ -65,7 +66,7 @@ describe('Carousel', () => {
|
|||||||
const spy = jest.spyOn(ref.current.innerSlider, 'autoPlay');
|
const spy = jest.spyOn(ref.current.innerSlider, 'autoPlay');
|
||||||
window.resizeTo(1000);
|
window.resizeTo(1000);
|
||||||
expect(spy).not.toHaveBeenCalled();
|
expect(spy).not.toHaveBeenCalled();
|
||||||
await new Promise(resolve => setTimeout(resolve, 500));
|
await sleep(500);
|
||||||
expect(spy).toHaveBeenCalled();
|
expect(spy).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -131,17 +131,16 @@ const InternalCheckboxGroup: React.ForwardRefRenderFunction<HTMLDivElement, Chec
|
|||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line react/jsx-no-constructed-context-values
|
||||||
const context = {
|
const context = {
|
||||||
toggleOption,
|
toggleOption,
|
||||||
value,
|
value,
|
||||||
disabled: restProps.disabled,
|
disabled: restProps.disabled,
|
||||||
name: restProps.name,
|
name: restProps.name,
|
||||||
|
|
||||||
// https://github.com/ant-design/ant-design/issues/16376
|
// https://github.com/ant-design/ant-design/issues/16376
|
||||||
registerValue,
|
registerValue,
|
||||||
cancelValue,
|
cancelValue,
|
||||||
};
|
};
|
||||||
|
|
||||||
const classString = classNames(
|
const classString = classNames(
|
||||||
groupPrefixCls,
|
groupPrefixCls,
|
||||||
{
|
{
|
||||||
|
@ -151,9 +151,13 @@ function Descriptions({
|
|||||||
|
|
||||||
// Children
|
// Children
|
||||||
const rows = getRows(children, mergedColumn);
|
const rows = getRows(children, mergedColumn);
|
||||||
|
const contextValue = React.useMemo(
|
||||||
|
() => ({ labelStyle, contentStyle }),
|
||||||
|
[labelStyle, contentStyle],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DescriptionsContext.Provider value={{ labelStyle, contentStyle }}>
|
<DescriptionsContext.Provider value={contextValue}>
|
||||||
<div
|
<div
|
||||||
className={classNames(
|
className={classNames(
|
||||||
prefixCls,
|
prefixCls,
|
||||||
|
@ -77,7 +77,7 @@ const FormItemInput: React.FC<FormItemInputProps & FormItemInputMiscProps> = pro
|
|||||||
) : null;
|
) : null;
|
||||||
|
|
||||||
// Pass to sub FormItem should not with col info
|
// Pass to sub FormItem should not with col info
|
||||||
const subFormContext = { ...formContext };
|
const subFormContext = React.useMemo(() => ({ ...formContext }), [formContext]);
|
||||||
delete subFormContext.labelCol;
|
delete subFormContext.labelCol;
|
||||||
delete subFormContext.wrapperCol;
|
delete subFormContext.wrapperCol;
|
||||||
|
|
||||||
@ -87,8 +87,9 @@ const FormItemInput: React.FC<FormItemInputProps & FormItemInputMiscProps> = pro
|
|||||||
{icon}
|
{icon}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
const formItemContext = React.useMemo(() => ({ prefixCls, status }), [prefixCls, status]);
|
||||||
const errorListDom = (
|
const errorListDom = (
|
||||||
<FormItemPrefixContext.Provider value={{ prefixCls, status }}>
|
<FormItemPrefixContext.Provider value={formItemContext}>
|
||||||
<ErrorList
|
<ErrorList
|
||||||
errors={errors}
|
errors={errors}
|
||||||
warnings={warnings}
|
warnings={warnings}
|
||||||
|
@ -37,15 +37,26 @@ const FormList: React.FC<FormListProps> = ({
|
|||||||
|
|
||||||
const { getPrefixCls } = React.useContext(ConfigContext);
|
const { getPrefixCls } = React.useContext(ConfigContext);
|
||||||
const prefixCls = getPrefixCls('form', customizePrefixCls);
|
const prefixCls = getPrefixCls('form', customizePrefixCls);
|
||||||
|
const contextValue = React.useMemo(
|
||||||
|
() => ({
|
||||||
|
prefixCls,
|
||||||
|
status: 'error' as const,
|
||||||
|
}),
|
||||||
|
[prefixCls],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<List {...props}>
|
<List {...props}>
|
||||||
{(fields, operation, meta) => (
|
{(fields, operation, meta) => (
|
||||||
<FormItemPrefixContext.Provider value={{ prefixCls, status: 'error' }}>
|
<FormItemPrefixContext.Provider value={contextValue}>
|
||||||
{children(fields, operation, {
|
{children(
|
||||||
errors: meta.errors,
|
fields.map(field => ({ ...field, fieldKey: field.key })),
|
||||||
warnings: meta.warnings,
|
operation,
|
||||||
})}
|
{
|
||||||
|
errors: meta.errors,
|
||||||
|
warnings: meta.warnings,
|
||||||
|
},
|
||||||
|
)}
|
||||||
</FormItemPrefixContext.Provider>
|
</FormItemPrefixContext.Provider>
|
||||||
)}
|
)}
|
||||||
</List>
|
</List>
|
||||||
|
@ -94,56 +94,54 @@ const Demo = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Form.Provider
|
||||||
<Form.Provider
|
onFormFinish={(name, { values, forms }) => {
|
||||||
onFormFinish={(name, { values, forms }) => {
|
if (name === 'userForm') {
|
||||||
if (name === 'userForm') {
|
const { basicForm } = forms;
|
||||||
const { basicForm } = forms;
|
const users = basicForm.getFieldValue('users') || [];
|
||||||
const users = basicForm.getFieldValue('users') || [];
|
basicForm.setFieldsValue({ users: [...users, values] });
|
||||||
basicForm.setFieldsValue({ users: [...users, values] });
|
setVisible(false);
|
||||||
setVisible(false);
|
}
|
||||||
}
|
}}
|
||||||
}}
|
>
|
||||||
>
|
<Form {...layout} name="basicForm" onFinish={onFinish}>
|
||||||
<Form {...layout} name="basicForm" onFinish={onFinish}>
|
<Form.Item name="group" label="Group Name" rules={[{ required: true }]}>
|
||||||
<Form.Item name="group" label="Group Name" rules={[{ required: true }]}>
|
<Input />
|
||||||
<Input />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item
|
||||||
<Form.Item
|
label="User List"
|
||||||
label="User List"
|
shouldUpdate={(prevValues, curValues) => prevValues.users !== curValues.users}
|
||||||
shouldUpdate={(prevValues, curValues) => prevValues.users !== curValues.users}
|
>
|
||||||
>
|
{({ getFieldValue }) => {
|
||||||
{({ getFieldValue }) => {
|
const users: UserType[] = getFieldValue('users') || [];
|
||||||
const users: UserType[] = getFieldValue('users') || [];
|
return users.length ? (
|
||||||
return users.length ? (
|
<ul>
|
||||||
<ul>
|
{users.map((user, index) => (
|
||||||
{users.map((user, index) => (
|
<li key={index} className="user">
|
||||||
<li key={index} className="user">
|
<Avatar icon={<UserOutlined />} />
|
||||||
<Avatar icon={<UserOutlined />} />
|
{user.name} - {user.age}
|
||||||
{user.name} - {user.age}
|
</li>
|
||||||
</li>
|
))}
|
||||||
))}
|
</ul>
|
||||||
</ul>
|
) : (
|
||||||
) : (
|
<Typography.Text className="ant-form-text" type="secondary">
|
||||||
<Typography.Text className="ant-form-text" type="secondary">
|
( <SmileOutlined /> No user yet. )
|
||||||
( <SmileOutlined /> No user yet. )
|
</Typography.Text>
|
||||||
</Typography.Text>
|
);
|
||||||
);
|
}}
|
||||||
}}
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item {...tailLayout}>
|
||||||
<Form.Item {...tailLayout}>
|
<Button htmlType="submit" type="primary">
|
||||||
<Button htmlType="submit" type="primary">
|
Submit
|
||||||
Submit
|
</Button>
|
||||||
</Button>
|
<Button htmlType="button" style={{ margin: '0 8px' }} onClick={showUserModal}>
|
||||||
<Button htmlType="button" style={{ margin: '0 8px' }} onClick={showUserModal}>
|
Add User
|
||||||
Add User
|
</Button>
|
||||||
</Button>
|
</Form.Item>
|
||||||
</Form.Item>
|
</Form>
|
||||||
</Form>
|
|
||||||
|
|
||||||
<ModalForm visible={visible} onCancel={hideUserModal} />
|
<ModalForm visible={visible} onCancel={hideUserModal} />
|
||||||
</Form.Provider>
|
</Form.Provider>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -43,32 +43,30 @@ const FormLayoutDemo = () => {
|
|||||||
: null;
|
: null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Form
|
||||||
<Form
|
{...formItemLayout}
|
||||||
{...formItemLayout}
|
layout={formLayout}
|
||||||
layout={formLayout}
|
form={form}
|
||||||
form={form}
|
initialValues={{ layout: formLayout }}
|
||||||
initialValues={{ layout: formLayout }}
|
onValuesChange={onFormLayoutChange}
|
||||||
onValuesChange={onFormLayoutChange}
|
>
|
||||||
>
|
<Form.Item label="Form Layout" name="layout">
|
||||||
<Form.Item label="Form Layout" name="layout">
|
<Radio.Group value={formLayout}>
|
||||||
<Radio.Group value={formLayout}>
|
<Radio.Button value="horizontal">Horizontal</Radio.Button>
|
||||||
<Radio.Button value="horizontal">Horizontal</Radio.Button>
|
<Radio.Button value="vertical">Vertical</Radio.Button>
|
||||||
<Radio.Button value="vertical">Vertical</Radio.Button>
|
<Radio.Button value="inline">Inline</Radio.Button>
|
||||||
<Radio.Button value="inline">Inline</Radio.Button>
|
</Radio.Group>
|
||||||
</Radio.Group>
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="Field A">
|
||||||
<Form.Item label="Field A">
|
<Input placeholder="input placeholder" />
|
||||||
<Input placeholder="input placeholder" />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="Field B">
|
||||||
<Form.Item label="Field B">
|
<Input placeholder="input placeholder" />
|
||||||
<Input placeholder="input placeholder" />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item {...buttonItemLayout}>
|
||||||
<Form.Item {...buttonItemLayout}>
|
<Button type="primary">Submit</Button>
|
||||||
<Button type="primary">Submit</Button>
|
</Form.Item>
|
||||||
</Form.Item>
|
</Form>
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -36,67 +36,65 @@ const FormSizeDemo = () => {
|
|||||||
setComponentSize(size);
|
setComponentSize(size);
|
||||||
};
|
};
|
||||||
return (
|
return (
|
||||||
<>
|
<Form
|
||||||
<Form
|
labelCol={{ span: 4 }}
|
||||||
labelCol={{ span: 4 }}
|
wrapperCol={{ span: 14 }}
|
||||||
wrapperCol={{ span: 14 }}
|
layout="horizontal"
|
||||||
layout="horizontal"
|
initialValues={{ size: componentSize }}
|
||||||
initialValues={{ size: componentSize }}
|
onValuesChange={onFormLayoutChange}
|
||||||
onValuesChange={onFormLayoutChange}
|
size={componentSize as SizeType}
|
||||||
size={componentSize as SizeType}
|
>
|
||||||
>
|
<Form.Item label="Form Size" name="size">
|
||||||
<Form.Item label="Form Size" name="size">
|
<Radio.Group>
|
||||||
<Radio.Group>
|
<Radio.Button value="small">Small</Radio.Button>
|
||||||
<Radio.Button value="small">Small</Radio.Button>
|
<Radio.Button value="default">Default</Radio.Button>
|
||||||
<Radio.Button value="default">Default</Radio.Button>
|
<Radio.Button value="large">Large</Radio.Button>
|
||||||
<Radio.Button value="large">Large</Radio.Button>
|
</Radio.Group>
|
||||||
</Radio.Group>
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="Input">
|
||||||
<Form.Item label="Input">
|
<Input />
|
||||||
<Input />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="Select">
|
||||||
<Form.Item label="Select">
|
<Select>
|
||||||
<Select>
|
<Select.Option value="demo">Demo</Select.Option>
|
||||||
<Select.Option value="demo">Demo</Select.Option>
|
</Select>
|
||||||
</Select>
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="TreeSelect">
|
||||||
<Form.Item label="TreeSelect">
|
<TreeSelect
|
||||||
<TreeSelect
|
treeData={[
|
||||||
treeData={[
|
{ title: 'Light', value: 'light', children: [{ title: 'Bamboo', value: 'bamboo' }] },
|
||||||
{ title: 'Light', value: 'light', children: [{ title: 'Bamboo', value: 'bamboo' }] },
|
]}
|
||||||
]}
|
/>
|
||||||
/>
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="Cascader">
|
||||||
<Form.Item label="Cascader">
|
<Cascader
|
||||||
<Cascader
|
options={[
|
||||||
options={[
|
{
|
||||||
{
|
value: 'zhejiang',
|
||||||
value: 'zhejiang',
|
label: 'Zhejiang',
|
||||||
label: 'Zhejiang',
|
children: [
|
||||||
children: [
|
{
|
||||||
{
|
value: 'hangzhou',
|
||||||
value: 'hangzhou',
|
label: 'Hangzhou',
|
||||||
label: 'Hangzhou',
|
},
|
||||||
},
|
],
|
||||||
],
|
},
|
||||||
},
|
]}
|
||||||
]}
|
/>
|
||||||
/>
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="DatePicker">
|
||||||
<Form.Item label="DatePicker">
|
<DatePicker />
|
||||||
<DatePicker />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="InputNumber">
|
||||||
<Form.Item label="InputNumber">
|
<InputNumber />
|
||||||
<InputNumber />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="Switch" valuePropName="checked">
|
||||||
<Form.Item label="Switch" valuePropName="checked">
|
<Switch />
|
||||||
<Switch />
|
</Form.Item>
|
||||||
</Form.Item>
|
<Form.Item label="Button">
|
||||||
<Form.Item label="Button">
|
<Button>Button</Button>
|
||||||
<Button>Button</Button>
|
</Form.Item>
|
||||||
</Form.Item>
|
</Form>
|
||||||
</Form>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -214,15 +214,14 @@ const Sider = React.forwardRef<HTMLDivElement, SiderProps>(
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
const contextValue = React.useMemo(
|
||||||
<SiderContext.Provider
|
() => ({
|
||||||
value={{
|
siderCollapsed: collapsed,
|
||||||
siderCollapsed: collapsed,
|
}),
|
||||||
}}
|
[collapsed],
|
||||||
>
|
|
||||||
{renderSider()}
|
|
||||||
</SiderContext.Provider>
|
|
||||||
);
|
);
|
||||||
|
|
||||||
|
return <SiderContext.Provider value={contextValue}>{renderSider()}</SiderContext.Provider>;
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -64,19 +64,22 @@ const BasicLayout: React.FC<BasicPropsWithTagName> = props => {
|
|||||||
className,
|
className,
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
const contextValue = React.useMemo(
|
||||||
<LayoutContext.Provider
|
() => ({
|
||||||
value={{
|
siderHook: {
|
||||||
siderHook: {
|
addSider: (id: string) => {
|
||||||
addSider: (id: string) => {
|
setSiders(prev => [...prev, id]);
|
||||||
setSiders(prev => [...prev, id]);
|
|
||||||
},
|
|
||||||
removeSider: (id: string) => {
|
|
||||||
setSiders(prev => prev.filter(currentId => currentId !== id));
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
}}
|
removeSider: (id: string) => {
|
||||||
>
|
setSiders(prev => prev.filter(currentId => currentId !== id));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
[],
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<LayoutContext.Provider value={contextValue}>
|
||||||
<Tag className={classString} {...others}>
|
<Tag className={classString} {...others}>
|
||||||
{children}
|
{children}
|
||||||
</Tag>
|
</Tag>
|
||||||
|
@ -50,11 +50,9 @@ ReactDOM.render(
|
|||||||
grid={{ gutter: 16, column: 4 }}
|
grid={{ gutter: 16, column: 4 }}
|
||||||
dataSource={data}
|
dataSource={data}
|
||||||
renderItem={item => (
|
renderItem={item => (
|
||||||
<>
|
<List.Item>
|
||||||
<List.Item>
|
<Card title={item.title}>Card content</Card>
|
||||||
<Card title={item.title}>Card content</Card>
|
</List.Item>
|
||||||
</List.Item>
|
|
||||||
</>
|
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
<List grid={{ gutter: 16, column: 4 }} dataSource={data} renderItem={() => <ListItem />} />
|
<List grid={{ gutter: 16, column: 4 }} dataSource={data} renderItem={() => <ListItem />} />
|
||||||
|
@ -256,9 +256,13 @@ function List<T>({
|
|||||||
}
|
}
|
||||||
|
|
||||||
const paginationPosition = paginationProps.position || 'bottom';
|
const paginationPosition = paginationProps.position || 'bottom';
|
||||||
|
const contextValue = React.useMemo(
|
||||||
|
() => ({ grid, itemLayout }),
|
||||||
|
[JSON.stringify(grid), itemLayout],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<ListContext.Provider value={{ grid, itemLayout }}>
|
<ListContext.Provider value={contextValue}>
|
||||||
<div className={classString} {...rest}>
|
<div className={classString} {...rest}>
|
||||||
{(paginationPosition === 'top' || paginationPosition === 'both') && paginationContent}
|
{(paginationPosition === 'top' || paginationPosition === 'both') && paginationContent}
|
||||||
{header && <div className={`${prefixCls}-header`}>{header}</div>}
|
{header && <div className={`${prefixCls}-header`}>{header}</div>}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
|
import memoizeOne from 'memoize-one';
|
||||||
import { ValidateMessages } from 'rc-field-form/lib/interface';
|
import { ValidateMessages } from 'rc-field-form/lib/interface';
|
||||||
import devWarning from '../_util/devWarning';
|
import devWarning from '../_util/devWarning';
|
||||||
|
|
||||||
@ -79,9 +80,10 @@ export default class LocaleProvider extends React.Component<LocaleProviderProps,
|
|||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { locale, children } = this.props;
|
const { locale, children } = this.props;
|
||||||
|
const contextValue = memoizeOne(localeValue => ({
|
||||||
return (
|
...localeValue,
|
||||||
<LocaleContext.Provider value={{ ...locale, exist: true }}>{children}</LocaleContext.Provider>
|
exist: true,
|
||||||
);
|
}))(locale);
|
||||||
|
return <LocaleContext.Provider value={contextValue}>{children}</LocaleContext.Provider>;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import rtlTest from '../../../tests/shared/rtlTest';
|
|||||||
|
|
||||||
const { getMentions } = Mentions;
|
const { getMentions } = Mentions;
|
||||||
|
|
||||||
function simulateInput(wrapper, text = '', keyEvent) {
|
function simulateInput(wrapper, text, keyEvent) {
|
||||||
const lastChar = text[text.length - 1];
|
const lastChar = text[text.length - 1];
|
||||||
const myKeyEvent = keyEvent || {
|
const myKeyEvent = keyEvent || {
|
||||||
which: lastChar.charCodeAt(0),
|
which: lastChar.charCodeAt(0),
|
||||||
|
@ -137,8 +137,8 @@ const Mentions = React.forwardRef<unknown, MentionProps>(InternalMentions) as Co
|
|||||||
Mentions.displayName = 'Mentions';
|
Mentions.displayName = 'Mentions';
|
||||||
Mentions.Option = Option;
|
Mentions.Option = Option;
|
||||||
|
|
||||||
Mentions.getMentions = (value: string = '', config?: MentionsConfig): MentionsEntity[] => {
|
Mentions.getMentions = (value: string = '', config: MentionsConfig = {}): MentionsEntity[] => {
|
||||||
const { prefix = '@', split = ' ' } = config || {};
|
const { prefix = '@', split = ' ' } = config;
|
||||||
const prefixList: string[] = Array.isArray(prefix) ? prefix : [prefix];
|
const prefixList: string[] = Array.isArray(prefix) ? prefix : [prefix];
|
||||||
|
|
||||||
return value
|
return value
|
||||||
|
@ -58,13 +58,16 @@ function SubMenu(props: SubMenuProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const contextValue = React.useMemo(
|
||||||
|
() => ({
|
||||||
|
...context,
|
||||||
|
firstLevel: false,
|
||||||
|
}),
|
||||||
|
[context],
|
||||||
|
);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuContext.Provider
|
<MenuContext.Provider value={contextValue}>
|
||||||
value={{
|
|
||||||
...context,
|
|
||||||
firstLevel: false,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<RcSubMenu
|
<RcSubMenu
|
||||||
{...omit(props, ['icon'])}
|
{...omit(props, ['icon'])}
|
||||||
title={titleNode}
|
title={titleNode}
|
||||||
|
@ -90,11 +90,14 @@ describe('Menu', () => {
|
|||||||
<Menu.SubMenu />
|
<Menu.SubMenu />
|
||||||
{null}
|
{null}
|
||||||
</>
|
</>
|
||||||
|
{/* eslint-disable-next-line react/jsx-no-useless-fragment */}
|
||||||
<>
|
<>
|
||||||
<Menu.Item />
|
<Menu.Item />
|
||||||
</>
|
</>
|
||||||
{undefined}
|
{undefined}
|
||||||
|
{/* eslint-disable-next-line react/jsx-no-useless-fragment */}
|
||||||
<>
|
<>
|
||||||
|
{/* eslint-disable-next-line react/jsx-no-useless-fragment */}
|
||||||
<>
|
<>
|
||||||
<Menu.Item />
|
<Menu.Item />
|
||||||
</>
|
</>
|
||||||
|
@ -3,6 +3,7 @@ import RcMenu, { ItemGroup, MenuProps as RcMenuProps } from 'rc-menu';
|
|||||||
import classNames from 'classnames';
|
import classNames from 'classnames';
|
||||||
import omit from 'rc-util/lib/omit';
|
import omit from 'rc-util/lib/omit';
|
||||||
import EllipsisOutlined from '@ant-design/icons/EllipsisOutlined';
|
import EllipsisOutlined from '@ant-design/icons/EllipsisOutlined';
|
||||||
|
import memoize from 'memoize-one';
|
||||||
import SubMenu, { SubMenuProps } from './SubMenu';
|
import SubMenu, { SubMenuProps } from './SubMenu';
|
||||||
import Item, { MenuItemProps } from './MenuItem';
|
import Item, { MenuItemProps } from './MenuItem';
|
||||||
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
import { ConfigConsumer, ConfigConsumerProps } from '../config-provider';
|
||||||
@ -81,16 +82,17 @@ class InternalMenu extends React.Component<InternalMenuProps> {
|
|||||||
const prefixCls = getPrefixCls('menu', customizePrefixCls);
|
const prefixCls = getPrefixCls('menu', customizePrefixCls);
|
||||||
const menuClassName = classNames(`${prefixCls}-${theme}`, className);
|
const menuClassName = classNames(`${prefixCls}-${theme}`, className);
|
||||||
|
|
||||||
|
// TODO: refactor menu with function component
|
||||||
|
const contextValue = memoize((cls, collapsed, the, dir) => ({
|
||||||
|
prefixCls: cls,
|
||||||
|
inlineCollapsed: collapsed || false,
|
||||||
|
antdMenuTheme: the,
|
||||||
|
direction: dir,
|
||||||
|
firstLevel: true,
|
||||||
|
}))(prefixCls, inlineCollapsed, theme, direction);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuContext.Provider
|
<MenuContext.Provider value={contextValue}>
|
||||||
value={{
|
|
||||||
prefixCls,
|
|
||||||
inlineCollapsed: inlineCollapsed || false,
|
|
||||||
antdMenuTheme: theme,
|
|
||||||
direction,
|
|
||||||
firstLevel: true,
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<RcMenu
|
<RcMenu
|
||||||
getPopupContainer={getPopupContainer}
|
getPopupContainer={getPopupContainer}
|
||||||
overflowedIndicator={<EllipsisOutlined />}
|
overflowedIndicator={<EllipsisOutlined />}
|
||||||
|
@ -47,14 +47,17 @@ class App extends React.Component {
|
|||||||
};
|
};
|
||||||
|
|
||||||
onStart = (event, uiData) => {
|
onStart = (event, uiData) => {
|
||||||
const { clientWidth, clientHeight } = window?.document?.documentElement;
|
const { clientWidth, clientHeight } = window.document.documentElement;
|
||||||
const targetRect = this.draggleRef?.current?.getBoundingClientRect();
|
const targetRect = this.draggleRef.current?.getBoundingClientRect();
|
||||||
|
if (!targetRect) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.setState({
|
this.setState({
|
||||||
bounds: {
|
bounds: {
|
||||||
left: -targetRect?.left + uiData?.x,
|
left: -targetRect.left + uiData.x,
|
||||||
right: clientWidth - (targetRect?.right - uiData?.x),
|
right: clientWidth - (targetRect.right - uiData.x),
|
||||||
top: -targetRect?.top + uiData?.y,
|
top: -targetRect.top + uiData.y,
|
||||||
bottom: clientHeight - (targetRect?.bottom - uiData?.y),
|
bottom: clientHeight - (targetRect.bottom - uiData.y),
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -27,6 +27,7 @@ const ElementsHolder = React.memo(
|
|||||||
}),
|
}),
|
||||||
[],
|
[],
|
||||||
);
|
);
|
||||||
|
// eslint-disable-next-line react/jsx-no-useless-fragment
|
||||||
return <>{elements}</>;
|
return <>{elements}</>;
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
@ -60,29 +60,27 @@ const Content = ({ children, extra }) => (
|
|||||||
);
|
);
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<>
|
<PageHeader
|
||||||
<PageHeader
|
className="site-page-header-responsive"
|
||||||
className="site-page-header-responsive"
|
onBack={() => window.history.back()}
|
||||||
onBack={() => window.history.back()}
|
title="Title"
|
||||||
title="Title"
|
subTitle="This is a subtitle"
|
||||||
subTitle="This is a subtitle"
|
extra={[
|
||||||
extra={[
|
<Button key="3">Operation</Button>,
|
||||||
<Button key="3">Operation</Button>,
|
<Button key="2">Operation</Button>,
|
||||||
<Button key="2">Operation</Button>,
|
<Button key="1" type="primary">
|
||||||
<Button key="1" type="primary">
|
Primary
|
||||||
Primary
|
</Button>,
|
||||||
</Button>,
|
]}
|
||||||
]}
|
footer={
|
||||||
footer={
|
<Tabs defaultActiveKey="1">
|
||||||
<Tabs defaultActiveKey="1">
|
<TabPane tab="Details" key="1" />
|
||||||
<TabPane tab="Details" key="1" />
|
<TabPane tab="Rule" key="2" />
|
||||||
<TabPane tab="Rule" key="2" />
|
</Tabs>
|
||||||
</Tabs>
|
}
|
||||||
}
|
>
|
||||||
>
|
<Content extra={extraContent}>{renderContent()}</Content>
|
||||||
<Content extra={extraContent}>{renderContent()}</Content>
|
</PageHeader>,
|
||||||
</PageHeader>
|
|
||||||
</>,
|
|
||||||
mountNode,
|
mountNode,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
@ -17,14 +17,12 @@ Show all configured prop.
|
|||||||
import { Pagination } from 'antd';
|
import { Pagination } from 'antd';
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<>
|
<Pagination
|
||||||
<Pagination
|
total={85}
|
||||||
total={85}
|
showSizeChanger
|
||||||
showSizeChanger
|
showQuickJumper
|
||||||
showQuickJumper
|
showTotal={total => `Total ${total} items`}
|
||||||
showTotal={total => `Total ${total} items`}
|
/>,
|
||||||
/>
|
|
||||||
</>,
|
|
||||||
mountNode,
|
mountNode,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
@ -132,7 +132,10 @@ describe('Popconfirm', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should support onConfirm to return Promise', async () => {
|
it('should support onConfirm to return Promise', async () => {
|
||||||
const confirm = () => new Promise(res => setTimeout(res, 300));
|
const confirm = () =>
|
||||||
|
new Promise(res => {
|
||||||
|
setTimeout(res, 300);
|
||||||
|
});
|
||||||
const onVisibleChange = jest.fn();
|
const onVisibleChange = jest.fn();
|
||||||
const popconfirm = mount(
|
const popconfirm = mount(
|
||||||
<Popconfirm title="code" onConfirm={confirm} onVisibleChange={onVisibleChange}>
|
<Popconfirm title="code" onConfirm={confirm} onVisibleChange={onVisibleChange}>
|
||||||
|
@ -38,19 +38,17 @@ const App = () => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<Popconfirm
|
||||||
<Popconfirm
|
title="Title"
|
||||||
title="Title"
|
visible={visible}
|
||||||
visible={visible}
|
onConfirm={handleOk}
|
||||||
onConfirm={handleOk}
|
okButtonProps={{ loading: confirmLoading }}
|
||||||
okButtonProps={{ loading: confirmLoading }}
|
onCancel={handleCancel}
|
||||||
onCancel={handleCancel}
|
>
|
||||||
>
|
<Button type="primary" onClick={showPopconfirm}>
|
||||||
<Button type="primary" onClick={showPopconfirm}>
|
Open Popconfirm with async logic
|
||||||
Open Popconfirm with async logic
|
</Button>
|
||||||
</Button>
|
</Popconfirm>
|
||||||
</Popconfirm>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -97,6 +97,7 @@ describe('Space', () => {
|
|||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Space>
|
<Space>
|
||||||
text1<span>text1</span>
|
text1<span>text1</span>
|
||||||
|
{/* eslint-disable-next-line react/jsx-no-useless-fragment */}
|
||||||
<>text3</>
|
<>text3</>
|
||||||
</Space>,
|
</Space>,
|
||||||
);
|
);
|
||||||
@ -164,6 +165,7 @@ describe('Space', () => {
|
|||||||
const wrapper = mount(
|
const wrapper = mount(
|
||||||
<Space split="-">
|
<Space split="-">
|
||||||
text1<span>text1</span>
|
text1<span>text1</span>
|
||||||
|
{/* eslint-disable-next-line react/jsx-no-useless-fragment */}
|
||||||
<>text3</>
|
<>text3</>
|
||||||
</Space>,
|
</Space>,
|
||||||
);
|
);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { mount } from 'enzyme';
|
import { mount } from 'enzyme';
|
||||||
import Spin from '..';
|
import Spin from '..';
|
||||||
|
import { sleep } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('delay spinning', () => {
|
describe('delay spinning', () => {
|
||||||
it("should render with delay when it's mounted with spinning=true and delay", () => {
|
it("should render with delay when it's mounted with spinning=true and delay", () => {
|
||||||
@ -15,7 +16,7 @@ describe('delay spinning', () => {
|
|||||||
|
|
||||||
// use await not jest.runAllTimers()
|
// use await not jest.runAllTimers()
|
||||||
// because of https://github.com/facebook/jest/issues/3465
|
// because of https://github.com/facebook/jest/issues/3465
|
||||||
await new Promise(resolve => setTimeout(resolve, 500));
|
await sleep(500);
|
||||||
wrapper.update();
|
wrapper.update();
|
||||||
|
|
||||||
expect(wrapper.find('.ant-spin').at(0).hasClass('ant-spin-spinning')).toEqual(true);
|
expect(wrapper.find('.ant-spin').at(0).hasClass('ant-spin-spinning')).toEqual(true);
|
||||||
|
@ -5,6 +5,7 @@ import focusTest from '../../../tests/shared/focusTest';
|
|||||||
import { resetWarned } from '../../_util/devWarning';
|
import { resetWarned } from '../../_util/devWarning';
|
||||||
import mountTest from '../../../tests/shared/mountTest';
|
import mountTest from '../../../tests/shared/mountTest';
|
||||||
import rtlTest from '../../../tests/shared/rtlTest';
|
import rtlTest from '../../../tests/shared/rtlTest';
|
||||||
|
import { sleep } from '../../../tests/utils';
|
||||||
|
|
||||||
describe('Switch', () => {
|
describe('Switch', () => {
|
||||||
focusTest(Switch, { refFocus: true });
|
focusTest(Switch, { refFocus: true });
|
||||||
@ -14,7 +15,7 @@ describe('Switch', () => {
|
|||||||
it('should has click wave effect', async () => {
|
it('should has click wave effect', async () => {
|
||||||
const wrapper = mount(<Switch />);
|
const wrapper = mount(<Switch />);
|
||||||
wrapper.find('.ant-switch').getDOMNode().click();
|
wrapper.find('.ant-switch').getDOMNode().click();
|
||||||
await new Promise(resolve => setTimeout(resolve, 0));
|
await sleep(0);
|
||||||
expect(wrapper.find('button').getDOMNode().getAttribute('ant-click-animating')).toBe('true');
|
expect(wrapper.find('button').getDOMNode().getAttribute('ant-click-animating')).toBe('true');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -866,6 +866,7 @@ describe('Table.filter', () => {
|
|||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
filteredValue: name,
|
filteredValue: name,
|
||||||
|
// eslint-disable-next-line react/no-unstable-nested-components
|
||||||
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm }) => (
|
filterDropdown: ({ setSelectedKeys, selectedKeys, confirm }) => (
|
||||||
<div>
|
<div>
|
||||||
<Input
|
<Input
|
||||||
@ -1266,7 +1267,7 @@ describe('Table.filter', () => {
|
|||||||
cols: [],
|
cols: [],
|
||||||
};
|
};
|
||||||
|
|
||||||
componentDidMount = () => {
|
componentDidMount() {
|
||||||
this.setState({
|
this.setState({
|
||||||
cols: [
|
cols: [
|
||||||
{
|
{
|
||||||
@ -1276,7 +1277,7 @@ describe('Table.filter', () => {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
});
|
});
|
||||||
};
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { cols } = this.state;
|
const { cols } = this.state;
|
||||||
@ -1700,38 +1701,36 @@ describe('Table.filter', () => {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
return (
|
return (
|
||||||
<>
|
<Table
|
||||||
<Table
|
columns={columns}
|
||||||
columns={columns}
|
dataSource={[
|
||||||
dataSource={[
|
{
|
||||||
{
|
key: '1',
|
||||||
key: '1',
|
name: 'John Brown',
|
||||||
name: 'John Brown',
|
age: 32,
|
||||||
age: 32,
|
address: 'New York No. 1 Lake Park',
|
||||||
address: 'New York No. 1 Lake Park',
|
},
|
||||||
},
|
{
|
||||||
{
|
key: '2',
|
||||||
key: '2',
|
name: 'Jim Green',
|
||||||
name: 'Jim Green',
|
age: 42,
|
||||||
age: 42,
|
address: 'London No. 1 Lake Park',
|
||||||
address: 'London No. 1 Lake Park',
|
},
|
||||||
},
|
{
|
||||||
{
|
key: '3',
|
||||||
key: '3',
|
name: 'Joe Black',
|
||||||
name: 'Joe Black',
|
age: 66,
|
||||||
age: 66,
|
address: 'Sidney No. 1 Lake Park',
|
||||||
address: 'Sidney No. 1 Lake Park',
|
},
|
||||||
},
|
{
|
||||||
{
|
key: '4',
|
||||||
key: '4',
|
name: 'Jim Red',
|
||||||
name: 'Jim Red',
|
age: 32,
|
||||||
age: 32,
|
address: 'London No. 2 Lake Park',
|
||||||
address: 'London No. 2 Lake Park',
|
},
|
||||||
},
|
]}
|
||||||
]}
|
onChange={this.handleChange}
|
||||||
onChange={this.handleChange}
|
/>
|
||||||
/>
|
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,9 +145,9 @@ const EditableTable = () => {
|
|||||||
const editable = isEditing(record);
|
const editable = isEditing(record);
|
||||||
return editable ? (
|
return editable ? (
|
||||||
<span>
|
<span>
|
||||||
<a href="javascript:;" onClick={() => save(record.key)} style={{ marginRight: 8 }}>
|
<Typography.Link onClick={() => save(record.key)} style={{ marginRight: 8 }}>
|
||||||
Save
|
Save
|
||||||
</a>
|
</Typography.Link>
|
||||||
<Popconfirm title="Sure to cancel?" onConfirm={cancel}>
|
<Popconfirm title="Sure to cancel?" onConfirm={cancel}>
|
||||||
<a>Cancel</a>
|
<a>Cancel</a>
|
||||||
</Popconfirm>
|
</Popconfirm>
|
||||||
|
@ -75,9 +75,9 @@ export default function usePagination(
|
|||||||
mergedPagination.current = maxPage || 1;
|
mergedPagination.current = maxPage || 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const refreshPagination = (current: number = 1, pageSize?: number) => {
|
const refreshPagination = (current?: number, pageSize?: number) => {
|
||||||
setInnerPagination({
|
setInnerPagination({
|
||||||
current,
|
current: current ?? 1,
|
||||||
pageSize: pageSize || mergedPagination.pageSize,
|
pageSize: pageSize || mergedPagination.pageSize,
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
@ -6,7 +6,7 @@ import rtlTest from '../../../tests/shared/rtlTest';
|
|||||||
|
|
||||||
const { Item } = TimeLine;
|
const { Item } = TimeLine;
|
||||||
|
|
||||||
const wrapperFactory = (timeLineProps = {}, labelItems) =>
|
const wrapperFactory = (timeLineProps = {}, labelItems = null) =>
|
||||||
mount(
|
mount(
|
||||||
<TimeLine type="editable-card" {...timeLineProps}>
|
<TimeLine type="editable-card" {...timeLineProps}>
|
||||||
<Item key="1">foo</Item>
|
<Item key="1">foo</Item>
|
||||||
|
@ -52,7 +52,10 @@ describe('Upload', () => {
|
|||||||
const data = jest.fn();
|
const data = jest.fn();
|
||||||
const props = {
|
const props = {
|
||||||
action: 'http://upload.com',
|
action: 'http://upload.com',
|
||||||
beforeUpload: () => new Promise(resolve => setTimeout(() => resolve('success'), 100)),
|
beforeUpload: () =>
|
||||||
|
new Promise(resolve => {
|
||||||
|
setTimeout(() => resolve('success'), 100);
|
||||||
|
}),
|
||||||
data,
|
data,
|
||||||
onChange: ({ file }) => {
|
onChange: ({ file }) => {
|
||||||
if (file.status !== 'uploading') {
|
if (file.status !== 'uploading') {
|
||||||
@ -103,13 +106,13 @@ describe('Upload', () => {
|
|||||||
const props = {
|
const props = {
|
||||||
action: 'http://upload.com',
|
action: 'http://upload.com',
|
||||||
beforeUpload: file =>
|
beforeUpload: file =>
|
||||||
new Promise(resolve =>
|
new Promise(resolve => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
const result = file;
|
const result = file;
|
||||||
result.name = 'test.png';
|
result.name = 'test.png';
|
||||||
resolve(result);
|
resolve(result);
|
||||||
}, 100),
|
}, 100);
|
||||||
),
|
}),
|
||||||
data,
|
data,
|
||||||
onChange: ({ file }) => {
|
onChange: ({ file }) => {
|
||||||
if (file.status !== 'uploading') {
|
if (file.status !== 'uploading') {
|
||||||
|
@ -45,11 +45,9 @@ const props = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
ReactDOM.render(
|
ReactDOM.render(
|
||||||
<>
|
<Upload {...props}>
|
||||||
<Upload {...props}>
|
<Button icon={<UploadOutlined />}>Upload</Button>
|
||||||
<Button icon={<UploadOutlined />}>Upload</Button>
|
</Upload>,
|
||||||
</Upload>
|
|
||||||
</>,
|
|
||||||
mountNode,
|
mountNode,
|
||||||
);
|
);
|
||||||
```
|
```
|
||||||
|
11
package.json
11
package.json
@ -84,9 +84,9 @@
|
|||||||
"pub": "npm run version && antd-tools run pub",
|
"pub": "npm run version && antd-tools run pub",
|
||||||
"prepublishOnly": "antd-tools run guard",
|
"prepublishOnly": "antd-tools run guard",
|
||||||
"site:theme": "npm run site:theme-dark && npm run site:theme-compact",
|
"site:theme": "npm run site:theme-dark && npm run site:theme-compact",
|
||||||
"site:theme-dark": "cross-env ESBUILD=1 ANT_THEME=dark bisheng build --ssr -c ./site/bisheng.config.js",
|
"site:theme-dark": "cross-env ESBUILD=1 ANT_THEME=dark bisheng build -c ./site/bisheng.config.js",
|
||||||
"site:theme-compact": "cross-env ESBUILD=1 ANT_THEME=compact bisheng build --ssr -c ./site/bisheng.config.js",
|
"site:theme-compact": "cross-env ESBUILD=1 ANT_THEME=compact bisheng build -c ./site/bisheng.config.js",
|
||||||
"site": "npm run site:theme && cross-env NODE_ICU_DATA=node_modules/full-icu ESBUILD=1 concurrently \"bisheng build --ssr -c ./site/bisheng.config.js\"",
|
"site": "npm run site:theme && cross-env NODE_ICU_DATA=node_modules/full-icu ESBUILD=1 bisheng build --ssr -c ./site/bisheng.config.js",
|
||||||
"sort": "npx sort-package-json",
|
"sort": "npx sort-package-json",
|
||||||
"sort-api": "antd-tools run sort-api-table",
|
"sort-api": "antd-tools run sort-api-table",
|
||||||
"start": "antd-tools run clean && cross-env NODE_ENV=development concurrently \"bisheng start -c ./site/bisheng.config.js\"",
|
"start": "antd-tools run clean && cross-env NODE_ENV=development concurrently \"bisheng start -c ./site/bisheng.config.js\"",
|
||||||
@ -119,6 +119,7 @@
|
|||||||
"classnames": "^2.2.6",
|
"classnames": "^2.2.6",
|
||||||
"copy-to-clipboard": "^3.2.0",
|
"copy-to-clipboard": "^3.2.0",
|
||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
|
"memoize-one": "^6.0.0",
|
||||||
"moment": "^2.25.3",
|
"moment": "^2.25.3",
|
||||||
"rc-cascader": "~2.2.0",
|
"rc-cascader": "~2.2.0",
|
||||||
"rc-checkbox": "~2.3.0",
|
"rc-checkbox": "~2.3.0",
|
||||||
@ -154,7 +155,7 @@
|
|||||||
"scroll-into-view-if-needed": "^2.2.25"
|
"scroll-into-view-if-needed": "^2.2.25"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ant-design/bisheng-plugin": "^3.0.0",
|
"@ant-design/bisheng-plugin": "^3.0.1",
|
||||||
"@ant-design/hitu": "^0.0.0-alpha.13",
|
"@ant-design/hitu": "^0.0.0-alpha.13",
|
||||||
"@ant-design/tools": "^14.0.0-alpha.3",
|
"@ant-design/tools": "^14.0.0-alpha.3",
|
||||||
"@docsearch/css": "^3.0.0-alpha.39",
|
"@docsearch/css": "^3.0.0-alpha.39",
|
||||||
@ -199,7 +200,7 @@
|
|||||||
"enzyme-to-json": "^3.6.0",
|
"enzyme-to-json": "^3.6.0",
|
||||||
"esbuild-loader": "^2.13.1",
|
"esbuild-loader": "^2.13.1",
|
||||||
"eslint": "^8.0.0",
|
"eslint": "^8.0.0",
|
||||||
"eslint-config-airbnb": "^18.0.0",
|
"eslint-config-airbnb": "^19.0.0",
|
||||||
"eslint-config-prettier": "^8.0.0",
|
"eslint-config-prettier": "^8.0.0",
|
||||||
"eslint-plugin-babel": "^5.3.0",
|
"eslint-plugin-babel": "^5.3.0",
|
||||||
"eslint-plugin-compat": "^4.0.0",
|
"eslint-plugin-compat": "^4.0.0",
|
||||||
|
@ -111,6 +111,13 @@ module.exports = {
|
|||||||
|
|
||||||
delete config.module.noParse;
|
delete config.module.noParse;
|
||||||
|
|
||||||
|
// Use dev mod to speed up site preview build
|
||||||
|
// This is used for CI preview build in `preview-build.yml`
|
||||||
|
if (process.env.SITE_ENV === 'development') {
|
||||||
|
console.log('Site build with development mode...');
|
||||||
|
config.mode = 'development';
|
||||||
|
}
|
||||||
|
|
||||||
if (ANT_THEME) {
|
if (ANT_THEME) {
|
||||||
config.mode = 'development';
|
config.mode = 'development';
|
||||||
config.plugins.forEach(plugin => {
|
config.plugins.forEach(plugin => {
|
||||||
@ -119,6 +126,37 @@ module.exports = {
|
|||||||
plugin.options.filename = `${ANT_THEME}.css`;
|
plugin.options.filename = `${ANT_THEME}.css`;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Remove preset target
|
||||||
|
config.module.rules.forEach(rule => {
|
||||||
|
if (rule.options?.presets?.[1]?.[0]?.includes('preset-env')) {
|
||||||
|
delete rule.options.presets[1][1];
|
||||||
|
delete rule.options.plugins;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
config.optimization.minimize = false;
|
||||||
|
delete config.optimization.minimizer;
|
||||||
|
|
||||||
|
config.externals = [
|
||||||
|
/^rc-.*/,
|
||||||
|
/^react.*/,
|
||||||
|
/^@ant-design\/.*/,
|
||||||
|
/^@babel\/.*/,
|
||||||
|
/^@algolia\/.*/,
|
||||||
|
/^@docsearch\/.*/,
|
||||||
|
/autocomplete.js/,
|
||||||
|
/docsearch.js/,
|
||||||
|
/.*\.md/,
|
||||||
|
/lodash/,
|
||||||
|
/jquery/,
|
||||||
|
/moment/,
|
||||||
|
/core-js/,
|
||||||
|
/jsonml/,
|
||||||
|
/ramda/,
|
||||||
|
/tinycolor/,
|
||||||
|
/bisheng-plugin/,
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
return config;
|
return config;
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from '@ant-design/icons';
|
import Icon from '@ant-design/icons';
|
||||||
|
|
||||||
const CodePenIcon = props => {
|
const SVGIcon = () => (
|
||||||
const SVGIcon = () => (
|
<svg viewBox="0 0 15 15" fill="currentColor">
|
||||||
<svg viewBox="0 0 15 15" fill="currentColor">
|
<path d="M14.777304,4.75062256 L7.77734505,0.0839936563 C7.60939924,-0.0279665065 7.39060662,-0.0279665065 7.22266081,0.0839936563 L0.222701813,4.75062256 C0.0836082937,4.84334851 5.66973453e-05,4.99945222 4.6875e-05,5.16662013 L4.6875e-05,9.83324903 C4.6875e-05,10.0004355 0.0836088906,10.1565596 0.222701812,10.2492466 L7.22266081,14.9158755 C7.30662908,14.9718752 7.403316,14.999875 7.50000292,14.999875 C7.59668984,14.999875 7.69337678,14.9718752 7.77734505,14.9158755 L14.777304,10.2492466 C14.9163976,10.1565206 14.9999492,10.0004169 14.999959,9.83324903 L14.999959,5.16662013 C14.9999492,4.99945222 14.9163976,4.84334851 14.777304,4.75062256 Z M7.50000292,9.23237755 L4.90139316,7.4999502 L7.50000292,5.76755409 L10.0986127,7.4999502 L7.50000292,9.23237755 Z M8,4.89905919 L8,1.43423573 L13.598561,5.16665138 L10.9999824,6.89904747 L8,4.89905919 Z M7.00000586,4.89905919 L4.00002344,6.89904747 L1.40141366,5.16665138 L7.00000586,1.43423573 L7.00000586,4.89905919 Z M3.09865372,7.4999502 L1.00004102,8.89903575 L1.00004102,6.10089589 L3.09865372,7.4999502 Z M4.00002344,8.10085292 L7.00000586,10.1008412 L7.00000586,13.5656334 L1.40141366,9.83328028 L4.00002344,8.10085292 Z M8,10.1008412 L10.9999824,8.10085292 L13.5985922,9.83328028 L8,13.5656647 L8,10.1008412 L8,10.1008412 Z M11.9013521,7.4999502 L13.9999648,6.10089589 L13.9999648,8.899067 L11.9013521,7.4999502 Z" />
|
||||||
<path d="M14.777304,4.75062256 L7.77734505,0.0839936563 C7.60939924,-0.0279665065 7.39060662,-0.0279665065 7.22266081,0.0839936563 L0.222701813,4.75062256 C0.0836082937,4.84334851 5.66973453e-05,4.99945222 4.6875e-05,5.16662013 L4.6875e-05,9.83324903 C4.6875e-05,10.0004355 0.0836088906,10.1565596 0.222701812,10.2492466 L7.22266081,14.9158755 C7.30662908,14.9718752 7.403316,14.999875 7.50000292,14.999875 C7.59668984,14.999875 7.69337678,14.9718752 7.77734505,14.9158755 L14.777304,10.2492466 C14.9163976,10.1565206 14.9999492,10.0004169 14.999959,9.83324903 L14.999959,5.16662013 C14.9999492,4.99945222 14.9163976,4.84334851 14.777304,4.75062256 Z M7.50000292,9.23237755 L4.90139316,7.4999502 L7.50000292,5.76755409 L10.0986127,7.4999502 L7.50000292,9.23237755 Z M8,4.89905919 L8,1.43423573 L13.598561,5.16665138 L10.9999824,6.89904747 L8,4.89905919 Z M7.00000586,4.89905919 L4.00002344,6.89904747 L1.40141366,5.16665138 L7.00000586,1.43423573 L7.00000586,4.89905919 Z M3.09865372,7.4999502 L1.00004102,8.89903575 L1.00004102,6.10089589 L3.09865372,7.4999502 Z M4.00002344,8.10085292 L7.00000586,10.1008412 L7.00000586,13.5656334 L1.40141366,9.83328028 L4.00002344,8.10085292 Z M8,10.1008412 L10.9999824,8.10085292 L13.5985922,9.83328028 L8,13.5656647 L8,10.1008412 L8,10.1008412 Z M11.9013521,7.4999502 L13.9999648,6.10089589 L13.9999648,8.899067 L11.9013521,7.4999502 Z" />
|
</svg>
|
||||||
</svg>
|
);
|
||||||
);
|
|
||||||
return <Icon component={SVGIcon} {...props} />;
|
const CodePenIcon = props => <Icon component={SVGIcon} {...props} />;
|
||||||
};
|
|
||||||
|
|
||||||
export default CodePenIcon;
|
export default CodePenIcon;
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from '@ant-design/icons';
|
import Icon from '@ant-design/icons';
|
||||||
|
|
||||||
const CodeSandboxIcon = props => {
|
const SVGIcon = () => (
|
||||||
const SVGIcon = () => (
|
<svg viewBox="0 0 1024 1024" fill="currentColor">
|
||||||
<svg viewBox="0 0 1024 1024" fill="currentColor">
|
<path d="M755 140.3l0.5-0.3h0.3L512 0 268.3 140h-0.3l0.8 0.4L68.6 256v512L512 1024l443.4-256V256L755 140.3z m-30 506.4v171.2L548 920.1V534.7L883.4 341v215.7l-158.4 90z m-584.4-90.6V340.8L476 534.4v385.7L300 818.5V646.7l-159.4-90.6zM511.7 280l171.1-98.3 166.3 96-336.9 194.5-337-194.6 165.7-95.7L511.7 280z" />
|
||||||
<path d="M755 140.3l0.5-0.3h0.3L512 0 268.3 140h-0.3l0.8 0.4L68.6 256v512L512 1024l443.4-256V256L755 140.3z m-30 506.4v171.2L548 920.1V534.7L883.4 341v215.7l-158.4 90z m-584.4-90.6V340.8L476 534.4v385.7L300 818.5V646.7l-159.4-90.6zM511.7 280l171.1-98.3 166.3 96-336.9 194.5-337-194.6 165.7-95.7L511.7 280z" />
|
</svg>
|
||||||
</svg>
|
);
|
||||||
);
|
|
||||||
return <Icon component={SVGIcon} {...props} />;
|
const CodeSandboxIcon = props => <Icon component={SVGIcon} {...props} />;
|
||||||
};
|
|
||||||
|
|
||||||
export default CodeSandboxIcon;
|
export default CodeSandboxIcon;
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import Icon from '@ant-design/icons';
|
import Icon from '@ant-design/icons';
|
||||||
|
|
||||||
const RiddleIcon = props => {
|
const SVGIcon = () => (
|
||||||
const SVGIcon = () => (
|
<svg viewBox="0 0 14 14" fill="currentColor">
|
||||||
<svg viewBox="0 0 14 14" fill="currentColor">
|
<path d="M13.8875145,13.1234844 C13.8687399,13.0691875 13.8499977,13.0329687 13.8312555,12.9786562 L11.3687445,8.83296875 C12.9187468,8.05754687 13.9640694,6.49009375 13.9640694,4.68728125 C13.9624994,2.09095312 11.7968694,0 9.10938728,0 L3.86404855,0 C3.04217572,0 2.37028902,0.648703125 2.37028902,1.44223437 L2.37028902,1.82090625 L0.746871676,1.82090625 C0.33593526,1.82090625 0,2.14526562 0,2.54203125 L0,13.4478437 C0,13.7540937 0.242191908,13.9879375 0.559368786,13.9879375 C0.615627746,13.9879375 0.67187052,13.9698281 0.72812948,13.9517187 L13.440615,13.9517187 C13.7578081,13.9517187 14,13.7178906 14,13.4116406 C14,13.321125 13.9624994,13.2125 13.8875145,13.1234844 Z M3.49061272,8.0394375 L3.49061272,2.9206875 L8.71719306,2.9206875 C9.74375723,2.9206875 10.5843723,3.73232812 10.5843723,4.7235 C10.5843723,5.71465625 9.76249942,6.5081875 8.71719306,6.5081875 L6.53280462,6.5081875 L6.53280462,6.52629688 C6.45781965,6.52629688 6.3828185,6.5625 6.3093711,6.59870313 C6.04843699,6.74354688 5.95469364,7.08598438 6.10467977,7.33792188 L8.3078104,11.0325469 L3.4906289,11.0325469 L3.4906289,8.0394375 L3.49061272,8.0394375 Z M1.1203237,12.8881406 L1.1203237,2.9206875 L2.3703052,2.9206875 L2.3703052,11.5545313 C2.3703052,11.8607813 2.61249711,12.0946094 2.92969017,12.0946094 L2.94843237,12.0946094 C2.98593295,12.1127188 3.04219191,12.1127188 3.09843468,12.1127188 L9.16563006,12.1127188 C9.48280694,12.1127188 9.72499884,11.878875 9.72499884,11.572625 L9.72499884,11.5364219 C9.76249942,11.3915938 9.74375723,11.2482813 9.66875607,11.1215469 L7.5593526,7.58835938 L8.6984185,7.58835938 C10.3406104,7.58835938 11.6843514,6.29095313 11.6843514,4.703875 C11.6843514,3.1168125 10.3406104,1.81939063 8.6984185,1.81939063 L3.4906289,1.81939063 L3.4906289,1.44073437 C3.4906289,1.24310937 3.65937341,1.08017187 3.86406474,1.08017187 L9.09061272,1.08017187 C11.143741,1.08017187 12.8234173,2.7019375 12.8234173,4.68578125 C12.8234173,6.21853125 11.8343538,7.5340625 10.4343538,8.05603125 C10.378111,8.07414063 10.3406104,8.09223438 10.2843514,8.11034375 C10.0234173,8.25517188 9.92967399,8.597625 10.0796763,8.8495625 L12.5062405,12.8881563 L1.12030751,12.8881563 L1.1203237,12.8881406 Z" />
|
||||||
<path d="M13.8875145,13.1234844 C13.8687399,13.0691875 13.8499977,13.0329687 13.8312555,12.9786562 L11.3687445,8.83296875 C12.9187468,8.05754687 13.9640694,6.49009375 13.9640694,4.68728125 C13.9624994,2.09095312 11.7968694,0 9.10938728,0 L3.86404855,0 C3.04217572,0 2.37028902,0.648703125 2.37028902,1.44223437 L2.37028902,1.82090625 L0.746871676,1.82090625 C0.33593526,1.82090625 0,2.14526562 0,2.54203125 L0,13.4478437 C0,13.7540937 0.242191908,13.9879375 0.559368786,13.9879375 C0.615627746,13.9879375 0.67187052,13.9698281 0.72812948,13.9517187 L13.440615,13.9517187 C13.7578081,13.9517187 14,13.7178906 14,13.4116406 C14,13.321125 13.9624994,13.2125 13.8875145,13.1234844 Z M3.49061272,8.0394375 L3.49061272,2.9206875 L8.71719306,2.9206875 C9.74375723,2.9206875 10.5843723,3.73232812 10.5843723,4.7235 C10.5843723,5.71465625 9.76249942,6.5081875 8.71719306,6.5081875 L6.53280462,6.5081875 L6.53280462,6.52629688 C6.45781965,6.52629688 6.3828185,6.5625 6.3093711,6.59870313 C6.04843699,6.74354688 5.95469364,7.08598438 6.10467977,7.33792188 L8.3078104,11.0325469 L3.4906289,11.0325469 L3.4906289,8.0394375 L3.49061272,8.0394375 Z M1.1203237,12.8881406 L1.1203237,2.9206875 L2.3703052,2.9206875 L2.3703052,11.5545313 C2.3703052,11.8607813 2.61249711,12.0946094 2.92969017,12.0946094 L2.94843237,12.0946094 C2.98593295,12.1127188 3.04219191,12.1127188 3.09843468,12.1127188 L9.16563006,12.1127188 C9.48280694,12.1127188 9.72499884,11.878875 9.72499884,11.572625 L9.72499884,11.5364219 C9.76249942,11.3915938 9.74375723,11.2482813 9.66875607,11.1215469 L7.5593526,7.58835938 L8.6984185,7.58835938 C10.3406104,7.58835938 11.6843514,6.29095313 11.6843514,4.703875 C11.6843514,3.1168125 10.3406104,1.81939063 8.6984185,1.81939063 L3.4906289,1.81939063 L3.4906289,1.44073437 C3.4906289,1.24310937 3.65937341,1.08017187 3.86406474,1.08017187 L9.09061272,1.08017187 C11.143741,1.08017187 12.8234173,2.7019375 12.8234173,4.68578125 C12.8234173,6.21853125 11.8343538,7.5340625 10.4343538,8.05603125 C10.378111,8.07414063 10.3406104,8.09223438 10.2843514,8.11034375 C10.0234173,8.25517188 9.92967399,8.597625 10.0796763,8.8495625 L12.5062405,12.8881563 L1.12030751,12.8881563 L1.1203237,12.8881406 Z" />
|
</svg>
|
||||||
</svg>
|
);
|
||||||
);
|
|
||||||
return <Icon component={SVGIcon} {...props} />;
|
const RiddleIcon = props => <Icon component={SVGIcon} {...props} />;
|
||||||
};
|
|
||||||
|
|
||||||
export default RiddleIcon;
|
export default RiddleIcon;
|
||||||
|
@ -2,14 +2,17 @@ import React from 'react';
|
|||||||
import Icon from '@ant-design/icons';
|
import Icon from '@ant-design/icons';
|
||||||
|
|
||||||
const ThemeIcon = props => {
|
const ThemeIcon = props => {
|
||||||
const SVGIcon = () => (
|
const SVGIcon = React.useCallback(
|
||||||
<svg width={21} height={21} viewBox="0 0 21 21" fill="currentColor" {...props}>
|
() => (
|
||||||
<g fillRule="evenodd">
|
<svg width={21} height={21} viewBox="0 0 21 21" fill="currentColor" {...props}>
|
||||||
<g fillRule="nonzero">
|
<g fillRule="evenodd">
|
||||||
<path d="M7.02 3.635l12.518 12.518a1.863 1.863 0 010 2.635l-1.317 1.318a1.863 1.863 0 01-2.635 0L3.068 7.588A2.795 2.795 0 117.02 3.635zm2.09 14.428a.932.932 0 110 1.864.932.932 0 010-1.864zm-.043-9.747L7.75 9.635l9.154 9.153 1.318-1.317-9.154-9.155zM3.52 12.473c.514 0 .931.417.931.931v.932h.932a.932.932 0 110 1.864h-.932v.931a.932.932 0 01-1.863 0l-.001-.931h-.93a.932.932 0 010-1.864h.93v-.932c0-.514.418-.931.933-.931zm15.374-3.727a1.398 1.398 0 110 2.795 1.398 1.398 0 010-2.795zM4.385 4.953a.932.932 0 000 1.317l2.046 2.047L7.75 7 5.703 4.953a.932.932 0 00-1.318 0zM14.701.36a.932.932 0 01.931.932v.931h.932a.932.932 0 010 1.864h-.933l.001.932a.932.932 0 11-1.863 0l-.001-.932h-.93a.932.932 0 110-1.864h.93v-.931a.932.932 0 01.933-.932z" />
|
<g fillRule="nonzero">
|
||||||
|
<path d="M7.02 3.635l12.518 12.518a1.863 1.863 0 010 2.635l-1.317 1.318a1.863 1.863 0 01-2.635 0L3.068 7.588A2.795 2.795 0 117.02 3.635zm2.09 14.428a.932.932 0 110 1.864.932.932 0 010-1.864zm-.043-9.747L7.75 9.635l9.154 9.153 1.318-1.317-9.154-9.155zM3.52 12.473c.514 0 .931.417.931.931v.932h.932a.932.932 0 110 1.864h-.932v.931a.932.932 0 01-1.863 0l-.001-.931h-.93a.932.932 0 010-1.864h.93v-.932c0-.514.418-.931.933-.931zm15.374-3.727a1.398 1.398 0 110 2.795 1.398 1.398 0 010-2.795zM4.385 4.953a.932.932 0 000 1.317l2.046 2.047L7.75 7 5.703 4.953a.932.932 0 00-1.318 0zM14.701.36a.932.932 0 01.931.932v.931h.932a.932.932 0 010 1.864h-.933l.001.932a.932.932 0 11-1.863 0l-.001-.932h-.93a.932.932 0 110-1.864h.93v-.931a.932.932 0 01.933-.932z" />
|
||||||
|
</g>
|
||||||
</g>
|
</g>
|
||||||
</g>
|
</svg>
|
||||||
</svg>
|
),
|
||||||
|
[props],
|
||||||
);
|
);
|
||||||
return <Icon component={SVGIcon} {...props} />;
|
return <Icon component={SVGIcon} {...props} />;
|
||||||
};
|
};
|
||||||
|
@ -52,7 +52,7 @@ const Home = (props: { location: any }) => {
|
|||||||
zhCN: '文章',
|
zhCN: '文章',
|
||||||
enUS: 'Articles',
|
enUS: 'Articles',
|
||||||
});
|
});
|
||||||
const { pathname, query } = path;
|
const { pathname, query = {} } = path;
|
||||||
const pathnames = pathname.split('#');
|
const pathnames = pathname.split('#');
|
||||||
if ('direction' in query) {
|
if ('direction' in query) {
|
||||||
return `${pathnames[0]}?direction=rtl#${pathnames[1]}`;
|
return `${pathnames[0]}?direction=rtl#${pathnames[1]}`;
|
||||||
|
@ -64,6 +64,7 @@ class IconDisplay extends React.PureComponent<IconDisplayProps, IconDisplayState
|
|||||||
let iconList = categories[key];
|
let iconList = categories[key];
|
||||||
if (searchKey) {
|
if (searchKey) {
|
||||||
const matchKey = searchKey
|
const matchKey = searchKey
|
||||||
|
// eslint-disable-next-line prefer-regex-literals
|
||||||
.replace(new RegExp(`^<([a-zA-Z]*)\\s/>$`, 'gi'), (_, name) => name)
|
.replace(new RegExp(`^<([a-zA-Z]*)\\s/>$`, 'gi'), (_, name) => name)
|
||||||
.replace(/(Filled|Outlined|TwoTone)$/, '')
|
.replace(/(Filled|Outlined|TwoTone)$/, '')
|
||||||
.toLowerCase();
|
.toLowerCase();
|
||||||
|
@ -35,7 +35,7 @@ class Footer extends React.Component<WrappedComponentProps & { location: any }>
|
|||||||
|
|
||||||
const getLinkHash = (path: string, hash: { zhCN: string; enUS: string }) => {
|
const getLinkHash = (path: string, hash: { zhCN: string; enUS: string }) => {
|
||||||
const pathName = getLocalizedPathname(path, isZhCN, location.query, hash);
|
const pathName = getLocalizedPathname(path, isZhCN, location.query, hash);
|
||||||
const { pathname, query } = pathName;
|
const { pathname, query = {} } = pathName;
|
||||||
const pathnames = pathname.split('#');
|
const pathnames = pathname.split('#');
|
||||||
if ('direction' in query) {
|
if ('direction' in query) {
|
||||||
return `${pathnames[0]}?direction=rtl#${pathnames[1]}`;
|
return `${pathnames[0]}?direction=rtl#${pathnames[1]}`;
|
||||||
@ -45,7 +45,7 @@ class Footer extends React.Component<WrappedComponentProps & { location: any }>
|
|||||||
|
|
||||||
const getLink = (path: string) => {
|
const getLink = (path: string) => {
|
||||||
const pathName = getLocalizedPathname(path, isZhCN, location.query);
|
const pathName = getLocalizedPathname(path, isZhCN, location.query);
|
||||||
const { pathname, query } = pathName;
|
const { pathname, query = {} } = pathName;
|
||||||
if ('direction' in query) {
|
if ('direction' in query) {
|
||||||
return `${pathname}?direction=rtl}`;
|
return `${pathname}?direction=rtl}`;
|
||||||
}
|
}
|
||||||
|
@ -118,10 +118,10 @@ export function isZhCN(pathname: string) {
|
|||||||
export function getLocalizedPathname(
|
export function getLocalizedPathname(
|
||||||
path: string,
|
path: string,
|
||||||
zhCN?: boolean,
|
zhCN?: boolean,
|
||||||
query = {},
|
query?: { [key: string]: any },
|
||||||
hash?: {
|
hash?: {
|
||||||
zhCN: string;
|
zhCN?: string;
|
||||||
enUS: string;
|
enUS?: string;
|
||||||
},
|
},
|
||||||
) {
|
) {
|
||||||
const pathname = path.startsWith('/') ? path : `/${path}`;
|
const pathname = path.startsWith('/') ? path : `/${path}`;
|
||||||
|
@ -13,6 +13,8 @@ const globalTimeout = global.setTimeout;
|
|||||||
|
|
||||||
export const sleep = async (timeout = 0) => {
|
export const sleep = async (timeout = 0) => {
|
||||||
await act(async () => {
|
await act(async () => {
|
||||||
await new Promise(resolve => globalTimeout(resolve, timeout));
|
await new Promise(resolve => {
|
||||||
|
globalTimeout(resolve, timeout);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user