feat: add drag handle for table row component
This commit is contained in:
parent
bf2ea2a6e1
commit
5cbbfcf428
@ -32,6 +32,7 @@
|
|||||||
"marked": "^4.0.12",
|
"marked": "^4.0.12",
|
||||||
"react-beautiful-dnd": "^13.1.0",
|
"react-beautiful-dnd": "^13.1.0",
|
||||||
"react-big-calendar": "^0.38.7",
|
"react-big-calendar": "^0.38.7",
|
||||||
|
"react-drag-listview": "^0.1.9",
|
||||||
"react-helmet": "^6.1.0",
|
"react-helmet": "^6.1.0",
|
||||||
"react-i18next": "^11.15.1",
|
"react-i18next": "^11.15.1",
|
||||||
"react-image-lightbox": "^5.1.4",
|
"react-image-lightbox": "^5.1.4",
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import { MenuOutlined } from '@ant-design/icons';
|
||||||
import { css } from '@emotion/css';
|
import { css } from '@emotion/css';
|
||||||
import { ArrayField, Field } from '@formily/core';
|
import { ArrayField, Field } from '@formily/core';
|
||||||
import { observer, RecursionField, Schema, useField, useFieldSchema } from '@formily/react';
|
import { observer, RecursionField, Schema, useField, useFieldSchema } from '@formily/react';
|
||||||
import { Table, TableColumnProps } from 'antd';
|
import { Table, TableColumnProps } from 'antd';
|
||||||
import cls from 'classnames';
|
import { default as classNames, default as cls } from 'classnames';
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
|
import ReactDragListView from 'react-drag-listview';
|
||||||
import { DndContext } from '../..';
|
import { DndContext } from '../..';
|
||||||
import { RecordIndexProvider, RecordProvider, useRequest, useSchemaInitializer } from '../../../';
|
import { RecordIndexProvider, RecordProvider, useRequest, useSchemaInitializer } from '../../../';
|
||||||
|
|
||||||
@ -82,6 +84,9 @@ export const components = {
|
|||||||
</DndContext>
|
</DndContext>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
row: (props) => {
|
||||||
|
return <tr draggable {...props} />;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -99,10 +104,30 @@ const useDefDataSource = (options, props) => {
|
|||||||
}, options);
|
}, options);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const SortHandle = () => {
|
||||||
|
return <MenuOutlined className={'drag-handle'} style={{ cursor: 'grab' }} />;
|
||||||
|
};
|
||||||
|
|
||||||
|
const TableIndex = (props) => {
|
||||||
|
const { index } = props;
|
||||||
|
return (
|
||||||
|
<div className={classNames('nb-table-index')} style={{ padding: '0 8px 0 16px' }}>
|
||||||
|
{index + 1}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
export const TableArray: React.FC<any> = observer((props) => {
|
export const TableArray: React.FC<any> = observer((props) => {
|
||||||
const field = useField<ArrayField>();
|
const field = useField<ArrayField>();
|
||||||
const columns = useTableColumns();
|
const columns = useTableColumns();
|
||||||
const { useSelectedRowKeys = useDef, useDataSource = useDefDataSource, onChange, ...others } = props;
|
const {
|
||||||
|
dragSort = false,
|
||||||
|
showIndex = true,
|
||||||
|
useSelectedRowKeys = useDef,
|
||||||
|
useDataSource = useDefDataSource,
|
||||||
|
onChange,
|
||||||
|
...others
|
||||||
|
} = props;
|
||||||
const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys();
|
const [selectedRowKeys, setSelectedRowKeys] = useSelectedRowKeys();
|
||||||
useDataSource({
|
useDataSource({
|
||||||
onSuccess(data) {
|
onSuccess(data) {
|
||||||
@ -117,6 +142,74 @@ export const TableArray: React.FC<any> = observer((props) => {
|
|||||||
onChange(selectedRowKeys: any[]) {
|
onChange(selectedRowKeys: any[]) {
|
||||||
setSelectedRowKeys(selectedRowKeys);
|
setSelectedRowKeys(selectedRowKeys);
|
||||||
},
|
},
|
||||||
|
renderCell: (checked, record, index, originNode) => {
|
||||||
|
const current = props?.pagination?.current;
|
||||||
|
const pageSize = props?.pagination?.pageSize || 20;
|
||||||
|
if (current) {
|
||||||
|
index = index + (current - 1) * pageSize;
|
||||||
|
}
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
checked ? 'checked' : null,
|
||||||
|
css`
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
padding-right: 8px;
|
||||||
|
.nb-table-index {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
&:not(.checked) {
|
||||||
|
.nb-table-index {
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
&:hover {
|
||||||
|
.nb-table-index {
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
.nb-origin-node {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
checked ? 'checked' : null,
|
||||||
|
css`
|
||||||
|
position: relative;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
`,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{dragSort && <SortHandle />}
|
||||||
|
{showIndex && <TableIndex index={index} />}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={classNames(
|
||||||
|
'nb-origin-node',
|
||||||
|
checked ? 'checked' : null,
|
||||||
|
css`
|
||||||
|
position: absolute;
|
||||||
|
right: 50%;
|
||||||
|
transform: translateX(50%);
|
||||||
|
&:not(.checked) {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
{originNode}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
},
|
||||||
...props.rowSelection,
|
...props.rowSelection,
|
||||||
}
|
}
|
||||||
: undefined,
|
: undefined,
|
||||||
@ -128,6 +221,16 @@ export const TableArray: React.FC<any> = observer((props) => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<ReactDragListView
|
||||||
|
handleSelector={'.drag-handle'}
|
||||||
|
onDragEnd={(fromIndex, toIndex) => {
|
||||||
|
console.log('ReactDragListView', fromIndex, toIndex);
|
||||||
|
field.move(fromIndex, toIndex);
|
||||||
|
}}
|
||||||
|
lineClassName={css`
|
||||||
|
border-bottom: 2px solid rgba(241, 139, 98, 0.6) !important;
|
||||||
|
`}
|
||||||
|
>
|
||||||
<Table
|
<Table
|
||||||
rowKey={defaultRowKey}
|
rowKey={defaultRowKey}
|
||||||
{...others}
|
{...others}
|
||||||
@ -136,6 +239,7 @@ export const TableArray: React.FC<any> = observer((props) => {
|
|||||||
columns={columns}
|
columns={columns}
|
||||||
dataSource={field?.value?.slice?.()}
|
dataSource={field?.value?.slice?.()}
|
||||||
/>
|
/>
|
||||||
|
</ReactDragListView>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -181,8 +181,7 @@ export const TableRecordActionInitializers = (props: any) => {
|
|||||||
],
|
],
|
||||||
},
|
},
|
||||||
]}
|
]}
|
||||||
>
|
component={MenuOutlined}
|
||||||
<MenuOutlined />
|
/>
|
||||||
</SchemaInitializer.Button>
|
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
@ -28,6 +28,7 @@ SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => {
|
|||||||
items = [],
|
items = [],
|
||||||
insertPosition = 'beforeEnd',
|
insertPosition = 'beforeEnd',
|
||||||
dropdown,
|
dropdown,
|
||||||
|
component,
|
||||||
style,
|
style,
|
||||||
...others
|
...others
|
||||||
} = props;
|
} = props;
|
||||||
@ -123,6 +124,9 @@ SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => {
|
|||||||
{...dropdown}
|
{...dropdown}
|
||||||
overlay={menu}
|
overlay={menu}
|
||||||
>
|
>
|
||||||
|
{component ? (
|
||||||
|
React.createElement(component)
|
||||||
|
) : (
|
||||||
<Button
|
<Button
|
||||||
{...others}
|
{...others}
|
||||||
type={'dashed'}
|
type={'dashed'}
|
||||||
@ -134,6 +138,7 @@ SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => {
|
|||||||
>
|
>
|
||||||
{compile(props.children || props.title)}
|
{compile(props.children || props.title)}
|
||||||
</Button>
|
</Button>
|
||||||
|
)}
|
||||||
</Dropdown>
|
</Dropdown>
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
@ -7,6 +7,7 @@ export interface SchemaInitializerButtonProps extends ButtonProps {
|
|||||||
insertPosition?: 'beforeBegin' | 'afterBegin' | 'beforeEnd' | 'afterEnd';
|
insertPosition?: 'beforeBegin' | 'afterBegin' | 'beforeEnd' | 'afterEnd';
|
||||||
items?: SchemaInitializerItemOptions[];
|
items?: SchemaInitializerItemOptions[];
|
||||||
dropdown?: DropDownProps;
|
dropdown?: DropDownProps;
|
||||||
|
component?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type SchemaInitializerItemOptions = ItemGroupOptions | SubMenuOptions | ItemOptions | DividerOptions;
|
export type SchemaInitializerItemOptions = ItemGroupOptions | SubMenuOptions | ItemOptions | DividerOptions;
|
||||||
|
37
yarn.lock
37
yarn.lock
@ -4636,6 +4636,14 @@ babel-preset-jest@^26.6.2:
|
|||||||
babel-plugin-jest-hoist "^26.6.2"
|
babel-plugin-jest-hoist "^26.6.2"
|
||||||
babel-preset-current-node-syntax "^1.0.0"
|
babel-preset-current-node-syntax "^1.0.0"
|
||||||
|
|
||||||
|
babel-runtime@^6.26.0:
|
||||||
|
version "6.26.0"
|
||||||
|
resolved "https://registry.npmjs.org/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe"
|
||||||
|
integrity sha1-llxwWGaOgrVde/4E/yM3vItWR/4=
|
||||||
|
dependencies:
|
||||||
|
core-js "^2.4.0"
|
||||||
|
regenerator-runtime "^0.11.0"
|
||||||
|
|
||||||
bail@^1.0.0:
|
bail@^1.0.0:
|
||||||
version "1.0.5"
|
version "1.0.5"
|
||||||
resolved "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776"
|
resolved "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz#b6fa133404a392cbc1f8c4bf63f5953351e7a776"
|
||||||
@ -5769,6 +5777,11 @@ core-js@3.8.2:
|
|||||||
resolved "https://registry.npmjs.org/core-js/-/core-js-3.8.2.tgz#0a1fd6709246da9ca8eff5bb0cbd15fba9ac7044"
|
resolved "https://registry.npmjs.org/core-js/-/core-js-3.8.2.tgz#0a1fd6709246da9ca8eff5bb0cbd15fba9ac7044"
|
||||||
integrity sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A==
|
integrity sha512-FfApuSRgrR6G5s58casCBd9M2k+4ikuu4wbW6pJyYU7bd9zvFc9qf7vr5xmrZOhT9nn+8uwlH1oRR9jTnFoA3A==
|
||||||
|
|
||||||
|
core-js@^2.4.0:
|
||||||
|
version "2.6.12"
|
||||||
|
resolved "https://registry.npmjs.org/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec"
|
||||||
|
integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ==
|
||||||
|
|
||||||
core-util-is@1.0.2:
|
core-util-is@1.0.2:
|
||||||
version "1.0.2"
|
version "1.0.2"
|
||||||
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
|
||||||
@ -13127,6 +13140,15 @@ prop-types@^15.5.7, prop-types@^15.6.2, prop-types@^15.7.2:
|
|||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
react-is "^16.8.1"
|
react-is "^16.8.1"
|
||||||
|
|
||||||
|
prop-types@^15.5.8:
|
||||||
|
version "15.8.1"
|
||||||
|
resolved "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz#67d87bf1a694f48435cf332c24af10214a3140b5"
|
||||||
|
integrity sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==
|
||||||
|
dependencies:
|
||||||
|
loose-envify "^1.4.0"
|
||||||
|
object-assign "^4.1.1"
|
||||||
|
react-is "^16.13.1"
|
||||||
|
|
||||||
property-information@^5.0.0, property-information@^5.3.0, property-information@^5.5.0:
|
property-information@^5.0.0, property-information@^5.3.0, property-information@^5.5.0:
|
||||||
version "5.6.0"
|
version "5.6.0"
|
||||||
resolved "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69"
|
resolved "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz#61675545fb23002f245c6540ec46077d4da3ed69"
|
||||||
@ -13787,6 +13809,14 @@ react-dom@17.x, react-dom@^17.0.1:
|
|||||||
object-assign "^4.1.1"
|
object-assign "^4.1.1"
|
||||||
scheduler "^0.20.2"
|
scheduler "^0.20.2"
|
||||||
|
|
||||||
|
react-drag-listview@^0.1.9:
|
||||||
|
version "0.1.9"
|
||||||
|
resolved "https://registry.npmjs.org/react-drag-listview/-/react-drag-listview-0.1.9.tgz#6732849c50f1de088775c1f287017615544cec3d"
|
||||||
|
integrity sha512-/OsYevKtCUlw4FhJIfZPH7INHEmyl89sSC5COzonHW5Z2c8rHg4DNYFnUxOyqH+65o7sHweL13oaf6wr7dFvPA==
|
||||||
|
dependencies:
|
||||||
|
babel-runtime "^6.26.0"
|
||||||
|
prop-types "^15.5.8"
|
||||||
|
|
||||||
react-fast-compare@^3.1.1:
|
react-fast-compare@^3.1.1:
|
||||||
version "3.2.0"
|
version "3.2.0"
|
||||||
resolved "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
resolved "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
|
||||||
@ -13819,7 +13849,7 @@ react-image-lightbox@^5.1.4:
|
|||||||
prop-types "^15.7.2"
|
prop-types "^15.7.2"
|
||||||
react-modal "^3.11.1"
|
react-modal "^3.11.1"
|
||||||
|
|
||||||
react-is@^16.12.0, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4:
|
react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4:
|
||||||
version "16.13.1"
|
version "16.13.1"
|
||||||
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
resolved "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
|
||||||
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
|
||||||
@ -14220,6 +14250,11 @@ regenerator-runtime@0.13.5:
|
|||||||
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"
|
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697"
|
||||||
integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
|
integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA==
|
||||||
|
|
||||||
|
regenerator-runtime@^0.11.0:
|
||||||
|
version "0.11.1"
|
||||||
|
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9"
|
||||||
|
integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg==
|
||||||
|
|
||||||
regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7:
|
regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7:
|
||||||
version "0.13.9"
|
version "0.13.9"
|
||||||
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
resolved "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
|
||||||
|
Loading…
Reference in New Issue
Block a user