chore(🆙): upgrade devDeps (#29418)

* chore(🆙): upgrade devDeps

* prettier code

* fix dnd demo

* fix react-dnd demo

* fix npm start and demo tsx compile

* fix snapshot
This commit is contained in:
afc163 2021-02-23 10:45:11 +08:00 committed by GitHub
parent 1c8a88b2d7
commit 76434a15df
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
36 changed files with 233 additions and 227 deletions

View File

@ -5,7 +5,7 @@ module.exports = {
'plugin:jest/recommended', 'plugin:jest/recommended',
'plugin:react/recommended', 'plugin:react/recommended',
'plugin:import/typescript', 'plugin:import/typescript',
'prettier/react', 'plugin:markdown/recommended',
], ],
env: { env: {
browser: true, browser: true,
@ -20,7 +20,7 @@ module.exports = {
}, },
}, },
parser: '@typescript-eslint/parser', parser: '@typescript-eslint/parser',
plugins: ['markdown', 'react', 'babel', 'jest', '@typescript-eslint', 'react-hooks', 'unicorn'], plugins: ['react', 'babel', 'jest', '@typescript-eslint', 'react-hooks', 'unicorn', 'markdown'],
// https://github.com/typescript-eslint/typescript-eslint/issues/46#issuecomment-470486034 // https://github.com/typescript-eslint/typescript-eslint/issues/46#issuecomment-470486034
overrides: [ overrides: [
{ {
@ -32,7 +32,28 @@ module.exports = {
}, },
}, },
{ {
files: ['*.md'], // In v2, explicitly apply eslint-plugin-markdown's `markdown`
// processor on any Markdown files you want to lint.
files: ['components/*/demo/*.md'],
processor: 'markdown/markdown',
},
{
// In v2, configuration for fenced code blocks is separate from the
// containing Markdown file. Each code block has a virtual filename
// appended to the Markdown file's path.
files: [
'components/*/demo/*.md/*.ts',
'components/*/demo/*.md/*.tsx',
'components/*/demo/*.md/*.js',
'components/*/demo/*.md/*.jsx',
],
// Configuration for fenced code blocks goes with the override for
// the code block's virtual filename, for example:
parserOptions: {
ecmaFeatures: {
impliedStrict: true,
},
},
globals: { globals: {
React: true, React: true,
ReactDOM: true, ReactDOM: true,
@ -44,10 +65,12 @@ module.exports = {
'no-plusplus': 0, 'no-plusplus': 0,
'eol-last': 0, 'eol-last': 0,
'no-script-url': 0, 'no-script-url': 0,
'default-case': 0,
'prefer-rest-params': 0, 'prefer-rest-params': 0,
'react/no-access-state-in-setstate': 0, 'react/no-access-state-in-setstate': 0,
'react/destructuring-assignment': 0, 'react/destructuring-assignment': 0,
'react/no-multi-comp': 0, 'react/no-multi-comp': 0,
'react/no-array-index-key': 0,
'jsx-a11y/href-no-hash': 0, 'jsx-a11y/href-no-hash': 0,
'import/no-extraneous-dependencies': 0, 'import/no-extraneous-dependencies': 0,
'jsx-a11y/control-has-associated-label': 0, 'jsx-a11y/control-has-associated-label': 0,

View File

@ -18,9 +18,7 @@ import { Anchor } from 'antd';
const { Link } = Anchor; const { Link } = Anchor;
const getCurrentAnchor = () => { const getCurrentAnchor = () => '#components-anchor-demo-static';
return '#components-anchor-demo-static';
};
ReactDOM.render( ReactDOM.render(
<Anchor affix={false} getCurrentAnchor={getCurrentAnchor}> <Anchor affix={false} getCurrentAnchor={getCurrentAnchor}>

View File

@ -17,11 +17,9 @@ Basic Usage, set data source of autocomplete with `options` property.
import React, { useState } from 'react'; import React, { useState } from 'react';
import { AutoComplete } from 'antd'; import { AutoComplete } from 'antd';
const mockVal = (str: string, repeat: number = 1) => { const mockVal = (str: string, repeat: number = 1) => ({
return { value: str.repeat(repeat),
value: str.repeat(repeat), });
};
};
const Complete: React.FC = () => { const Complete: React.FC = () => {
const [value, setValue] = useState(''); const [value, setValue] = useState('');
const [options, setOptions] = useState<{ value: string }[]>([]); const [options, setOptions] = useState<{ value: string }[]>([]);

View File

@ -17,40 +17,36 @@ Demonstration of [Lookup Patterns: Certain Category](https://ant.design/docs/spe
import { Input, AutoComplete } from 'antd'; import { Input, AutoComplete } from 'antd';
import { UserOutlined } from '@ant-design/icons'; import { UserOutlined } from '@ant-design/icons';
const renderTitle = (title: string) => { const renderTitle = (title: string) => (
return ( <span>
<span> {title}
{title} <a
<a style={{ float: 'right' }}
style={{ float: 'right' }} href="https://www.google.com/search?q=antd"
href="https://www.google.com/search?q=antd" target="_blank"
target="_blank" rel="noopener noreferrer"
rel="noopener noreferrer" >
> more
more </a>
</a> </span>
</span> );
);
};
const renderItem = (title: string, count: number) => { const renderItem = (title: string, count: number) => ({
return { value: title,
value: title, label: (
label: ( <div
<div style={{
style={{ display: 'flex',
display: 'flex', justifyContent: 'space-between',
justifyContent: 'space-between', }}
}} >
> {title}
{title} <span>
<span> <UserOutlined /> {count}
<UserOutlined /> {count} </span>
</span> </div>
</div> ),
), });
};
};
const options = [ const options = [
{ {

View File

@ -22,8 +22,8 @@ function getRandomInt(max: number, min: number = 0) {
return Math.floor(Math.random() * (max - min + 1)) + min; // eslint-disable-line no-mixed-operators return Math.floor(Math.random() * (max - min + 1)) + min; // eslint-disable-line no-mixed-operators
} }
const searchResult = (query: string) => { const searchResult = (query: string) =>
return new Array(getRandomInt(5)) new Array(getRandomInt(5))
.join('.') .join('.')
.split('.') .split('.')
.map((_, idx) => { .map((_, idx) => {
@ -52,7 +52,6 @@ const searchResult = (query: string) => {
), ),
}; };
}); });
};
const Complete: React.FC = () => { const Complete: React.FC = () => {
const [options, setOptions] = useState<SelectProps<object>['options']>([]); const [options, setOptions] = useState<SelectProps<object>['options']>([]);

View File

@ -17,44 +17,40 @@ Avatar group display.
import { Avatar, Divider, Tooltip } from 'antd'; import { Avatar, Divider, Tooltip } from 'antd';
import { UserOutlined, AntDesignOutlined } from '@ant-design/icons'; import { UserOutlined, AntDesignOutlined } from '@ant-design/icons';
class Demo extends React.Component { const Demo = () => (
render() { <>
return ( <Avatar.Group>
<> <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
<Avatar.Group> <Avatar style={{ backgroundColor: '#f56a00' }}>K</Avatar>
<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" /> <Tooltip title="Ant User" placement="top">
<Avatar style={{ backgroundColor: '#f56a00' }}>K</Avatar> <Avatar style={{ backgroundColor: '#87d068' }} icon={<UserOutlined />} />
<Tooltip title="Ant User" placement="top"> </Tooltip>
<Avatar style={{ backgroundColor: '#87d068' }} icon={<UserOutlined />} /> <Avatar style={{ backgroundColor: '#1890ff' }} icon={<AntDesignOutlined />} />
</Tooltip> </Avatar.Group>
<Avatar style={{ backgroundColor: '#1890ff' }} icon={<AntDesignOutlined />} /> <Divider />
</Avatar.Group> <Avatar.Group maxCount={2} maxStyle={{ color: '#f56a00', backgroundColor: '#fde3cf' }}>
<Divider /> <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
<Avatar.Group maxCount={2} maxStyle={{ color: '#f56a00', backgroundColor: '#fde3cf' }}> <Avatar style={{ backgroundColor: '#f56a00' }}>K</Avatar>
<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" /> <Tooltip title="Ant User" placement="top">
<Avatar style={{ backgroundColor: '#f56a00' }}>K</Avatar> <Avatar style={{ backgroundColor: '#87d068' }} icon={<UserOutlined />} />
<Tooltip title="Ant User" placement="top"> </Tooltip>
<Avatar style={{ backgroundColor: '#87d068' }} icon={<UserOutlined />} /> <Avatar style={{ backgroundColor: '#1890ff' }} icon={<AntDesignOutlined />} />
</Tooltip> </Avatar.Group>
<Avatar style={{ backgroundColor: '#1890ff' }} icon={<AntDesignOutlined />} /> <Divider />
</Avatar.Group> <Avatar.Group
<Divider /> maxCount={2}
<Avatar.Group size="large"
maxCount={2} maxStyle={{ color: '#f56a00', backgroundColor: '#fde3cf' }}
size="large" >
maxStyle={{ color: '#f56a00', backgroundColor: '#fde3cf' }} <Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" />
> <Avatar style={{ backgroundColor: '#f56a00' }}>K</Avatar>
<Avatar src="https://zos.alipayobjects.com/rmsportal/ODTLcjxAfvqbxHnVXCYX.png" /> <Tooltip title="Ant User" placement="top">
<Avatar style={{ backgroundColor: '#f56a00' }}>K</Avatar> <Avatar style={{ backgroundColor: '#87d068' }} icon={<UserOutlined />} />
<Tooltip title="Ant User" placement="top"> </Tooltip>
<Avatar style={{ backgroundColor: '#87d068' }} icon={<UserOutlined />} /> <Avatar style={{ backgroundColor: '#1890ff' }} icon={<AntDesignOutlined />} />
</Tooltip> </Avatar.Group>
<Avatar style={{ backgroundColor: '#1890ff' }} icon={<AntDesignOutlined />} /> </>
</Avatar.Group> );
</>
);
}
}
ReactDOM.render(<Demo />, mountNode); ReactDOM.render(<Demo />, mountNode);
``` ```

View File

@ -235,7 +235,7 @@ const ConfigProvider: React.FC<ConfigProviderProps> & {
); );
}; };
/** @private internal usage. do not use in your production */ /** @private internal Usage. do not use in your production */
ConfigProvider.ConfigContext = ConfigContext; ConfigProvider.ConfigContext = ConfigContext;
ConfigProvider.SizeContext = SizeContext; ConfigProvider.SizeContext = SizeContext;
ConfigProvider.config = setGlobalConfig; ConfigProvider.config = setGlobalConfig;

View File

@ -28,11 +28,7 @@ const App: React.FC = () => {
setVisible(false); setVisible(false);
}; };
return ( return (
<ConfigProvider <ConfigProvider getPopupContainer={() => domRef.current!}>
getPopupContainer={() => {
return domRef.current!;
}}
>
<div ref={domRef} className="site-drawer-render-in-current-wrapper"> <div ref={domRef} className="site-drawer-render-in-current-wrapper">
<Button type="primary" onClick={showDrawer}> <Button type="primary" onClick={showDrawer}>
Open Open

View File

@ -11,9 +11,9 @@ const EMPTY_LIST: React.ReactNode[] = [];
export interface ErrorListProps { export interface ErrorListProps {
errors?: React.ReactNode[]; errors?: React.ReactNode[];
/** @private Internal usage. Do not use in your production */ /** @private Internal Usage. Do not use in your production */
help?: React.ReactNode; help?: React.ReactNode;
/** @private Internal usage. Do not use in your production */ /** @private Internal Usage. Do not use in your production */
onDomErrorVisibleChange?: (visible: boolean) => void; onDomErrorVisibleChange?: (visible: boolean) => void;
} }

View File

@ -17,7 +17,7 @@ interface FormItemInputMiscProps {
hasFeedback?: boolean; hasFeedback?: boolean;
validateStatus?: ValidateStatus; validateStatus?: ValidateStatus;
onDomErrorVisibleChange: (visible: boolean) => void; onDomErrorVisibleChange: (visible: boolean) => void;
/** @private Internal usage, do not use in any of your production. */ /** @private Internal Usage, do not use in any of your production. */
_internalItemRender?: { _internalItemRender?: {
mark: string; mark: string;
render: ( render: (

View File

@ -43,7 +43,6 @@ const Demo = () => {
return; return;
case 'other': case 'other':
form.setFieldsValue({ note: 'Hi there!' }); form.setFieldsValue({ note: 'Hi there!' });
return;
} }
}; };
@ -82,13 +81,13 @@ const Demo = () => {
noStyle noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender} shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
> >
{({ getFieldValue }) => { {({ getFieldValue }) =>
return getFieldValue('gender') === 'other' ? ( getFieldValue('gender') === 'other' ? (
<Form.Item name="customizeGender" label="Customize Gender" rules={[{ required: true }]}> <Form.Item name="customizeGender" label="Customize Gender" rules={[{ required: true }]}>
<Input /> <Input />
</Form.Item> </Form.Item>
) : null; ) : null
}} }
</Form.Item> </Form.Item>
<Form.Item {...tailLayout}> <Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit"> <Button type="primary" htmlType="submit">

View File

@ -40,7 +40,6 @@ class Demo extends React.Component {
return; return;
case 'other': case 'other':
this.formRef.current!.setFieldsValue({ note: 'Hi there!' }); this.formRef.current!.setFieldsValue({ note: 'Hi there!' });
return;
} }
}; };
@ -80,8 +79,8 @@ class Demo extends React.Component {
noStyle noStyle
shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender} shouldUpdate={(prevValues, currentValues) => prevValues.gender !== currentValues.gender}
> >
{({ getFieldValue }) => { {({ getFieldValue }) =>
return getFieldValue('gender') === 'other' ? ( getFieldValue('gender') === 'other' ? (
<Form.Item <Form.Item
name="customizeGender" name="customizeGender"
label="Customize Gender" label="Customize Gender"
@ -89,8 +88,8 @@ class Demo extends React.Component {
> >
<Input /> <Input />
</Form.Item> </Form.Item>
) : null; ) : null
}} }
</Form.Item> </Form.Item>
<Form.Item {...tailLayout}> <Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit"> <Button type="primary" htmlType="submit">

View File

@ -92,7 +92,7 @@ const Demo = () => {
if (value.number > 0) { if (value.number > 0) {
return Promise.resolve(); return Promise.resolve();
} }
return Promise.reject('Price must be greater than zero!'); return Promise.reject(new Error('Price must be greater than zero!'));
}; };
return ( return (

View File

@ -31,10 +31,10 @@ const Demo = () => {
}} }}
> >
<Form.Item noStyle dependencies={['debug1']}> <Form.Item noStyle dependencies={['debug1']}>
{() => { {
return acc++; () => acc++
// return <pre>{JSON.stringify(form.getFieldsValue(), null, 2)}</pre>; // return <pre>{JSON.stringify(form.getFieldsValue(), null, 2)}</pre>;
}} }
</Form.Item> </Form.Item>
<Form.Item label="debug1" name="debug1"> <Form.Item label="debug1" name="debug1">
<Input /> <Input />

View File

@ -34,26 +34,24 @@ interface CustomizedFormProps {
fields: FieldData[]; fields: FieldData[];
} }
const CustomizedForm: React.FC<CustomizedFormProps> = ({ onChange, fields }) => { const CustomizedForm: React.FC<CustomizedFormProps> = ({ onChange, fields }) => (
return ( <Form
<Form name="global_state"
name="global_state" layout="inline"
layout="inline" fields={fields}
fields={fields} onFieldsChange={(_, allFields) => {
onFieldsChange={(_, allFields) => { onChange(allFields);
onChange(allFields); }}
}} >
<Form.Item
name="username"
label="Username"
rules={[{ required: true, message: 'Username is required!' }]}
> >
<Form.Item <Input />
name="username" </Form.Item>
label="Username" </Form>
rules={[{ required: true, message: 'Username is required!' }]} );
>
<Input />
</Form.Item>
</Form>
);
};
const Demo = () => { const Demo = () => {
const [fields, setFields] = useState<FieldData[]>([{ name: ['username'], value: 'Ant Design' }]); const [fields, setFields] = useState<FieldData[]>([{ name: ['username'], value: 'Ant Design' }]);

View File

@ -49,7 +49,7 @@ const HorizontalLoginForm = () => {
placeholder="Password" placeholder="Password"
/> />
</Form.Item> </Form.Item>
<Form.Item shouldUpdate={true}> <Form.Item shouldUpdate>
{() => ( {() => (
<Button <Button
type="primary" type="primary"

View File

@ -21,6 +21,7 @@ const layout = {
wrapperCol: { span: 16 }, wrapperCol: { span: 16 },
}; };
/* eslint-disable no-template-curly-in-string */
const validateMessages = { const validateMessages = {
required: '${label} is required!', required: '${label} is required!',
types: { types: {
@ -31,6 +32,7 @@ const validateMessages = {
range: '${label} must be between ${min} and ${max}', range: '${label} must be between ${min} and ${max}',
}, },
}; };
/* eslint-enable no-template-curly-in-string */
const Demo = () => { const Demo = () => {
const onFinish = (values: any) => { const onFinish = (values: any) => {

View File

@ -178,7 +178,7 @@ const RegistrationForm = () => {
if (!value || getFieldValue('password') === value) { if (!value || getFieldValue('password') === value) {
return Promise.resolve(); return Promise.resolve();
} }
return Promise.reject('The two passwords that you entered do not match!'); return Promise.reject(new Error('The two passwords that you entered do not match!'));
}, },
}), }),
]} ]}
@ -252,7 +252,7 @@ const RegistrationForm = () => {
rules={[ rules={[
{ {
validator: (_, value) => validator: (_, value) =>
value ? Promise.resolve() : Promise.reject('Should accept agreement'), value ? Promise.resolve() : Promise.reject(new Error('Should accept agreement')),
}, },
]} ]}
{...tailFormItemLayout} {...tailFormItemLayout}

View File

@ -24,8 +24,8 @@ const FormLayoutDemo = () => {
const [form] = Form.useForm(); const [form] = Form.useForm();
const [requiredMark, setRequiredMarkType] = useState<RequiredMark>('optional'); const [requiredMark, setRequiredMarkType] = useState<RequiredMark>('optional');
const onRequiredTypeChange = ({ requiredMark }: { requiredMark: RequiredMark }) => { const onRequiredTypeChange = ({ requiredMarkValue }: { requiredMarkValue: RequiredMark }) => {
setRequiredMarkType(requiredMark); setRequiredMarkType(requiredMarkValue);
}; };
return ( return (
@ -39,7 +39,7 @@ const FormLayoutDemo = () => {
<Form.Item label="Required Mark" name="requiredMark"> <Form.Item label="Required Mark" name="requiredMark">
<Radio.Group> <Radio.Group>
<Radio.Button value="optional">Optional</Radio.Button> <Radio.Button value="optional">Optional</Radio.Button>
<Radio.Button value={true}>Required</Radio.Button> <Radio.Button value>Required</Radio.Button>
<Radio.Button value={false}>Hidden</Radio.Button> <Radio.Button value={false}>Hidden</Radio.Button>
</Radio.Group> </Radio.Group>
</Form.Item> </Form.Item>

View File

@ -56,8 +56,8 @@ const Demo = () => {
{...formItemLayout} {...formItemLayout}
onFinish={onFinish} onFinish={onFinish}
initialValues={{ initialValues={{
['input-number']: 3, 'input-number': 3,
['checkbox-group']: ['A', 'B'], 'checkbox-group': ['A', 'B'],
rate: 3.5, rate: 3.5,
}} }}
> >

View File

@ -45,7 +45,7 @@ interface ClearableInputProps extends BasicProps {
} }
class ClearableLabeledInput extends React.Component<ClearableInputProps> { class ClearableLabeledInput extends React.Component<ClearableInputProps> {
/** @private Do not use out of this class. We do not promise this is always keep. */ /** @private Do Not use out of this class. We do not promise this is always keep. */
private containerRef = React.createRef<HTMLSpanElement>(); private containerRef = React.createRef<HTMLSpanElement>();
onInputMouseUp: React.MouseEventHandler = e => { onInputMouseUp: React.MouseEventHandler = e => {

View File

@ -32,7 +32,7 @@ cover: https://gw.alipayobjects.com/zos/alicdn/5FrZKStG_/List.svg
| locale | 默认文案设置,目前包括空数据文案 | object | {emptyText: `暂无数据`} | | | locale | 默认文案设置,目前包括空数据文案 | object | {emptyText: `暂无数据`} | |
| pagination | 对应的 `pagination` 配置, 设置 false 不显示 | boolean \| object | false | | | pagination | 对应的 `pagination` 配置, 设置 false 不显示 | boolean \| object | false | |
| renderItem | 当使用 dataSource 时,可以用 `renderItem` 自定义渲染列表项 | (item) => ReactNode | - | | | renderItem | 当使用 dataSource 时,可以用 `renderItem` 自定义渲染列表项 | (item) => ReactNode | - | |
| rowKey | 当 `renderItem` 自定义渲染列表项有效时,自定义每一行的 `key` 的获取方式 | ((item: T) => string) | `list-item-${index}` | | | rowKey | 当 `renderItem` 自定义渲染列表项有效时,自定义每一行的 `key` 的获取方式 | ((item: T) => string) | `list-item-${index}` | |
| size | list 的尺寸 | `default` \| `large` \| `small` | `default` | | | size | list 的尺寸 | `default` \| `large` \| `small` | `default` | |
| split | 是否展示分割线 | boolean | true | | | split | 是否展示分割线 | boolean | true | |

View File

@ -252,7 +252,7 @@ export interface MessageApi extends MessageInstance {
useMessage(): [MessageInstance, React.ReactElement]; useMessage(): [MessageInstance, React.ReactElement];
} }
/** @private test only function. Not work on production */ /** @private test Only function. Not work on production */
export const getInstance = () => (process.env.NODE_ENV === 'test' ? messageInstance : null); export const getInstance = () => (process.env.NODE_ENV === 'test' ? messageInstance : null);
export default api as MessageApi; export default api as MessageApi;

View File

@ -282,7 +282,7 @@ export interface NotificationApi extends NotificationInstance {
useNotification: () => [NotificationInstance, React.ReactElement]; useNotification: () => [NotificationInstance, React.ReactElement];
} }
/** @private test only function. Not work on production */ /** @private test Only function. Not work on production */
export const getInstance = async (cacheKey: string) => export const getInstance = async (cacheKey: string) =>
process.env.NODE_ENV === 'test' ? notificationInstance[cacheKey] : null; process.env.NODE_ENV === 'test' ? notificationInstance[cacheKey] : null;

View File

@ -155,9 +155,9 @@
&-fade-enter, &-fade-enter,
&-fade-appear { &-fade-appear {
opacity: 0;
.notification-fade-effect(); .notification-fade-effect();
opacity: 0;
animation-play-state: paused; animation-play-state: paused;
} }

View File

@ -236,10 +236,9 @@ function Table<RecordType extends object = any>(props: TableProps<RecordType>) {
}; };
/** /**
* Controlled state in `columns` is not a good idea that makes too many code (1000+ line?) to * Controlled state in `columns` is not a good idea that makes too many code (1000+ line?) to read
* read state out and then put it back to title render. Move these code into `hooks` but still * state out and then put it back to title render. Move these code into `hooks` but still too
* too complex. We should provides Table props like `sorter` & `filter` to handle control in next * complex. We should provides Table props like `sorter` & `filter` to handle control in next big version.
* big version.
*/ */
// ============================ Sorter ============================= // ============================ Sorter =============================

View File

@ -333,8 +333,8 @@ describe('Table.pagination', () => {
}); });
/** /**
* `pagination` is not designed to accept `true` value, but in practice, many people assign * `pagination` is not designed to accept `true` value, but in practice, many people assign `true`
* `true` to `pagination`, since they misunderstand that `pagination` can accept a boolean value. * to `pagination`, since they misunderstand that `pagination` can accept a boolean value.
*/ */
it('Accepts pagination as true', () => { it('Accepts pagination as true', () => {
const wrapper = mount(createTable({ pagination: true })); const wrapper = mount(createTable({ pagination: true }));

View File

@ -16,38 +16,42 @@ By using custom components, we can integrate table with react-dnd to implement d
```jsx ```jsx
import React, { useState, useCallback, useRef } from 'react'; import React, { useState, useCallback, useRef } from 'react';
import { Table } from 'antd'; import { Table } from 'antd';
import { DndProvider, useDrag, useDrop, createDndContext } from 'react-dnd'; import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend'; import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper'; import update from 'immutability-helper';
const RNDContext = createDndContext(HTML5Backend);
const type = 'DragableBodyRow'; const type = 'DragableBodyRow';
const DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) => { const DragableBodyRow = ({ index, moveRow, className, style, ...restProps }) => {
const ref = React.useRef(); const ref = React.useRef();
const [{ isOver, dropClassName }, drop] = useDrop({ const [{ isOver, dropClassName }, drop] = useDrop(
accept: type, () => ({
collect: monitor => { accept: type,
const { index: dragIndex } = monitor.getItem() || {}; collect: monitor => {
if (dragIndex === index) { const { index: dragIndex } = monitor.getItem() || {};
return {}; if (dragIndex === index) {
} return {};
return { }
isOver: monitor.isOver(), return {
dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward', isOver: monitor.isOver(),
}; dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',
}, };
drop: item => { },
moveRow(item.index, index); drop: item => {
}, moveRow(item.index, index);
}); },
const [, drag] = useDrag({
item: { type, index },
collect: monitor => ({
isDragging: monitor.isDragging(),
}), }),
}); [index],
);
const [, drag] = useDrag(
() => ({
item: { type, index },
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
}),
[],
);
drop(drag(ref)); drop(drag(ref));
return ( return (
<tr <tr
@ -120,10 +124,8 @@ const DragSortingTable: React.FC = () => {
[data], [data],
); );
const manager = useRef(RNDContext);
return ( return (
<DndProvider manager={manager.current.dragDropManager}> <DndProvider backend={HTML5Backend}>
<Table <Table
columns={columns} columns={columns}
dataSource={data} dataSource={data}

View File

@ -67,22 +67,22 @@ const Demo = () => {
const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]); const [selectedKeys, setSelectedKeys] = useState<React.Key[]>([]);
const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true); const [autoExpandParent, setAutoExpandParent] = useState<boolean>(true);
const onExpand = (expandedKeys: React.Key[]) => { const onExpand = (expandedKeysValue: React.Key[]) => {
console.log('onExpand', expandedKeys); console.log('onExpand', expandedKeysValue);
// if not set autoExpandParent to false, if children expanded, parent can not collapse. // if not set autoExpandParent to false, if children expanded, parent can not collapse.
// or, you can remove all expanded children keys. // or, you can remove all expanded children keys.
setExpandedKeys(expandedKeys); setExpandedKeys(expandedKeysValue);
setAutoExpandParent(false); setAutoExpandParent(false);
}; };
const onCheck = (checkedKeys: React.Key[]) => { const onCheck = (checkedKeysValue: React.Key[]) => {
console.log('onCheck', checkedKeys); console.log('onCheck', checkedKeysValue);
setCheckedKeys(checkedKeys); setCheckedKeys(checkedKeysValue);
}; };
const onSelect = (selectedKeys: React.Key[], info: any) => { const onSelect = (selectedKeysValue: React.Key[], info: any) => {
console.log('onSelect', info); console.log('onSelect', info);
setSelectedKeys(selectedKeys); setSelectedKeys(selectedKeysValue);
}; };
return ( return (

View File

@ -38,7 +38,8 @@ function updateTreeData(list: DataNode[], key: React.Key, children: DataNode[]):
...node, ...node,
children, children,
}; };
} else if (node.children) { }
if (node.children) {
return { return {
...node, ...node,
children: updateTreeData(node.children, key, children), children: updateTreeData(node.children, key, children),

View File

@ -98,11 +98,7 @@ const Demo: React.FC<{}> = () => {
}; };
const onSetShowLine = (checked: boolean) => { const onSetShowLine = (checked: boolean) => {
if (checked) { setShowLine(checked ? { showLeafIcon } : false);
showLeafIcon ? setShowLine(checked) : setShowLine({ showLeafIcon });
} else {
setShowLine(checked);
}
}; };
return ( return (

View File

@ -719,7 +719,7 @@ exports[`renders ./components/upload/demo/drag-sorting.md correctly 1`] = `
</svg> </svg>
</span> </span>
<span> <span>
Click to Upload Click to Upload
</span> </span>
</button> </button>
</span> </span>

View File

@ -16,40 +16,44 @@ By using `itemRender`, we can integrate upload with react-dnd to implement drag
```jsx ```jsx
import React, { useState, useCallback, useRef } from 'react'; import React, { useState, useCallback, useRef } from 'react';
import { Upload, Button, Tooltip } from 'antd'; import { Upload, Button, Tooltip } from 'antd';
import { DndProvider, useDrag, useDrop, createDndContext } from 'react-dnd'; import { DndProvider, useDrag, useDrop } from 'react-dnd';
import { HTML5Backend } from 'react-dnd-html5-backend'; import { HTML5Backend } from 'react-dnd-html5-backend';
import update from 'immutability-helper'; import update from 'immutability-helper';
import { UploadOutlined } from '@ant-design/icons'; import { UploadOutlined } from '@ant-design/icons';
const RNDContext = createDndContext(HTML5Backend);
const type = 'DragableUploadList'; const type = 'DragableUploadList';
const DragableUploadListItem = ({ originNode, moveRow, file, fileList }) => { const DragableUploadListItem = ({ originNode, moveRow, file, fileList }) => {
const ref = React.useRef(); const ref = React.useRef();
const index = fileList.indexOf(file); const index = fileList.indexOf(file);
const [{ isOver, dropClassName }, drop] = useDrop({ const [{ isOver, dropClassName }, drop] = useDrop(
accept: type, () => ({
collect: monitor => { accept: type,
const { index: dragIndex } = monitor.getItem() || {}; collect: monitor => {
if (dragIndex === index) { const { index: dragIndex } = monitor.getItem() || {};
return {}; if (dragIndex === index) {
} return {};
return { }
isOver: monitor.isOver(), return {
dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward', isOver: monitor.isOver(),
}; dropClassName: dragIndex < index ? ' drop-over-downward' : ' drop-over-upward',
}, };
drop: item => { },
moveRow(item.index, index); drop: item => {
}, moveRow(item.index, index);
}); },
const [, drag] = useDrag({
item: { type, index },
collect: monitor => ({
isDragging: monitor.isDragging(),
}), }),
}); [index],
);
const [, drag] = useDrag(
() => ({
item: { type, index },
collect: monitor => ({
isDragging: monitor.isDragging(),
}),
}),
[],
);
drop(drag(ref)); drop(drag(ref));
const errorNode = ( const errorNode = (
<Tooltip title="Upload Error" getPopupContainer={() => document.body}> <Tooltip title="Upload Error" getPopupContainer={() => document.body}>
@ -115,14 +119,12 @@ const DragSortingUpload: React.FC = () => {
[fileList], [fileList],
); );
const manager = useRef(RNDContext);
const onChange = ({ fileList: newFileList }) => { const onChange = ({ fileList: newFileList }) => {
setFileList(newFileList); setFileList(newFileList);
}; };
return ( return (
<DndProvider manager={manager.current.dragDropManager}> <DndProvider backend={HTML5Backend}>
<Upload <Upload
action="https://www.mocky.io/v2/5cc8019d300000980a055e76" action="https://www.mocky.io/v2/5cc8019d300000980a055e76"
fileList={fileList} fileList={fileList}
@ -136,9 +138,7 @@ const DragSortingUpload: React.FC = () => {
/> />
)} )}
> >
<Button> <Button icon={<UploadOutlined />}>Click to Upload</Button>
<UploadOutlined /> Click to Upload
</Button>
</Upload> </Upload>
</DndProvider> </DndProvider>
); );

View File

@ -69,7 +69,7 @@
"dist:esbuild": "ESBUILD=true npm run dist", "dist:esbuild": "ESBUILD=true npm run dist",
"lint": "npm run tsc && npm run lint:script && npm run lint:demo && npm run lint:style && npm run lint:deps && npm run lint:md", "lint": "npm run tsc && npm run lint:script && npm run lint:demo && npm run lint:style && npm run lint:deps && npm run lint:md",
"lint-fix": "npm run lint-fix:script && npm run lint-fix:demo && npm run lint-fix:style", "lint-fix": "npm run lint-fix:script && npm run lint-fix:demo && npm run lint-fix:style",
"lint-fix:demo": "eslint-tinker ./components/*/demo/*.md", "lint-fix:demo": "npm run lint:demo -- --fix",
"lint-fix:script": "npm run lint:script -- --fix", "lint-fix:script": "npm run lint:script -- --fix",
"lint-fix:style": "npm run lint:style -- --fix", "lint-fix:style": "npm run lint:style -- --fix",
"lint:demo": "eslint components/*/demo/*.md", "lint:demo": "eslint components/*/demo/*.md",
@ -188,7 +188,7 @@
"bundlesize": "^0.18.0", "bundlesize": "^0.18.0",
"chalk": "^4.0.0", "chalk": "^4.0.0",
"cheerio": "^1.0.0-rc.3", "cheerio": "^1.0.0-rc.3",
"concurrently": "^5.0.2", "concurrently": "^6.0.0",
"cross-env": "^7.0.0", "cross-env": "^7.0.0",
"css-minimizer-webpack-plugin": "^1.1.1", "css-minimizer-webpack-plugin": "^1.1.1",
"css-split-webpack-plugin": "^0.2.6", "css-split-webpack-plugin": "^0.2.6",
@ -200,16 +200,15 @@
"esbuild-loader": "^2.7.0", "esbuild-loader": "^2.7.0",
"eslint": "^7.9.0", "eslint": "^7.9.0",
"eslint-config-airbnb": "^18.0.0", "eslint-config-airbnb": "^18.0.0",
"eslint-config-prettier": "^7.0.0", "eslint-config-prettier": "^8.0.0",
"eslint-plugin-babel": "^5.3.0", "eslint-plugin-babel": "^5.3.0",
"eslint-plugin-import": "^2.21.1", "eslint-plugin-import": "^2.21.1",
"eslint-plugin-jest": "^24.0.1", "eslint-plugin-jest": "^24.0.1",
"eslint-plugin-jsx-a11y": "^6.2.1", "eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-markdown": "^1.0.0", "eslint-plugin-markdown": "^2.0.0",
"eslint-plugin-react": "^7.20.6", "eslint-plugin-react": "^7.20.6",
"eslint-plugin-react-hooks": "^4.1.2", "eslint-plugin-react-hooks": "^4.1.2",
"eslint-plugin-unicorn": "^27.0.0", "eslint-plugin-unicorn": "^28.0.2",
"eslint-tinker": "^0.5.0",
"fetch-jsonp": "^1.1.3", "fetch-jsonp": "^1.1.3",
"fs-extra": "^9.0.0", "fs-extra": "^9.0.0",
"full-icu": "^1.3.0", "full-icu": "^1.3.0",
@ -247,8 +246,8 @@
"react": "^17.0.1", "react": "^17.0.1",
"react-color": "^2.17.3", "react-color": "^2.17.3",
"react-copy-to-clipboard": "^5.0.1", "react-copy-to-clipboard": "^5.0.1",
"react-dnd": "^11.1.1", "react-dnd": "^13.0.0",
"react-dnd-html5-backend": "^11.1.1", "react-dnd-html5-backend": "^12.1.0",
"react-dom": "^17.0.1", "react-dom": "^17.0.1",
"react-draggable": "^4.4.3", "react-draggable": "^4.4.3",
"react-github-button": "^0.1.11", "react-github-button": "^0.1.11",

View File

@ -1,3 +1,4 @@
/* eslint no-console: 0 */
const chalk = require('chalk'); const chalk = require('chalk');
const fs = require('fs'); const fs = require('fs');
const { join } = require('path'); const { join } = require('path');

View File

@ -76,7 +76,11 @@ module.exports = {
// Resolve use react hook fail when yarn link or npm link // Resolve use react hook fail when yarn link or npm link
// https://github.com/webpack/webpack/issues/8607#issuecomment-453068938 // https://github.com/webpack/webpack/issues/8607#issuecomment-453068938
config.resolve.alias = { ...config.resolve.alias, react: require.resolve('react') }; config.resolve.alias = {
...config.resolve.alias,
'react/jsx-runtime': require.resolve('react/jsx-runtime'),
react: require.resolve('react'),
};
} else if (process.env.ESBUILD) { } else if (process.env.ESBUILD) {
// use esbuild // use esbuild
config.plugins.push(new ESBuildPlugin()); config.plugins.push(new ESBuildPlugin());