mirror of
https://github.com/smartxworks/sunmao-ui.git
synced 2024-12-03 09:09:52 +08:00
Merge pull request #529 from smartxworks/feat/arco-widget
support for automatic generation of `rowKey` or setting from columns
This commit is contained in:
commit
0ea1a9edbd
@ -21,7 +21,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
"typings": "tsc --emitDeclarationOnly",
|
"typings": "tsc --emitDeclarationOnly",
|
||||||
"build": "tsup src/index.ts --format cjs,esm,iife --legacy-output --inject ./react-import.js --clean --no-splitting --sourcemap",
|
"build": "tsup src/index.ts src/widgets/index.ts --format cjs,esm,iife --legacy-output --inject ./react-import.js --clean --no-splitting --sourcemap",
|
||||||
"serve": "vite preview",
|
"serve": "vite preview",
|
||||||
"lint": "eslint ./src --ext .ts --ext .tsx",
|
"lint": "eslint ./src --ext .ts --ext .tsx",
|
||||||
"fix-lint": "eslint --fix ./src --ext .ts --ext .tsx",
|
"fix-lint": "eslint --fix ./src --ext .ts --ext .tsx",
|
||||||
|
@ -74,6 +74,14 @@ const rowClickStyle = css`
|
|||||||
|
|
||||||
export const exampleProperties: Static<typeof TablePropsSpec> = {
|
export const exampleProperties: Static<typeof TablePropsSpec> = {
|
||||||
columns: [
|
columns: [
|
||||||
|
{
|
||||||
|
title: 'Key',
|
||||||
|
dataIndex: 'key',
|
||||||
|
type: 'text',
|
||||||
|
displayValue: '',
|
||||||
|
filter: false,
|
||||||
|
componentSlotIndex: 0,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: 'Name',
|
title: 'Name',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
@ -107,11 +115,12 @@ export const exampleProperties: Static<typeof TablePropsSpec> = {
|
|||||||
data: Array(13)
|
data: Array(13)
|
||||||
.fill('')
|
.fill('')
|
||||||
.map((_, index) => ({
|
.map((_, index) => ({
|
||||||
key: `key ${index}`,
|
key: index,
|
||||||
name: `${Math.random() > 0.5 ? 'Kevin Sandra' : 'Naomi Cook'}${index}`,
|
name: `${Math.random() > 0.5 ? 'Kevin Sandra' : 'Naomi Cook'}${index}`,
|
||||||
link: `link${Math.random() > 0.5 ? '-A' : '-B'}`,
|
link: `link${Math.random() > 0.5 ? '-A' : '-B'}`,
|
||||||
salary: Math.floor(Math.random() * 1000),
|
salary: Math.floor(Math.random() * 1000),
|
||||||
})),
|
})),
|
||||||
|
rowKey: 'key',
|
||||||
checkCrossPage: true,
|
checkCrossPage: true,
|
||||||
pagination: {
|
pagination: {
|
||||||
enablePagination: true,
|
enablePagination: true,
|
||||||
@ -172,8 +181,15 @@ export const Table = implementRuntimeComponent({
|
|||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const ref = useRef<TableInstance | null>(null);
|
const ref = useRef<TableInstance | null>(null);
|
||||||
const { pagination, rowClick, useDefaultFilter, useDefaultSort, data, ...cProps } =
|
const {
|
||||||
getComponentProps(props);
|
pagination,
|
||||||
|
rowKey,
|
||||||
|
rowClick,
|
||||||
|
useDefaultFilter,
|
||||||
|
useDefaultSort,
|
||||||
|
data,
|
||||||
|
...cProps
|
||||||
|
} = getComponentProps(props);
|
||||||
|
|
||||||
const {
|
const {
|
||||||
pageSize,
|
pageSize,
|
||||||
@ -186,6 +202,7 @@ export const Table = implementRuntimeComponent({
|
|||||||
} = pagination;
|
} = pagination;
|
||||||
|
|
||||||
const rowSelectionType = rowSelectionTypeMap[cProps.rowSelectionType];
|
const rowSelectionType = rowSelectionTypeMap[cProps.rowSelectionType];
|
||||||
|
const currentChecked = useRef<(string | number)[]>([]);
|
||||||
|
|
||||||
const [currentPage, setCurrentPage] = useStateValue<number>(
|
const [currentPage, setCurrentPage] = useStateValue<number>(
|
||||||
defaultCurrent ?? 1,
|
defaultCurrent ?? 1,
|
||||||
@ -196,6 +213,7 @@ export const Table = implementRuntimeComponent({
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
mergeState({ pageSize });
|
mergeState({ pageSize });
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const [sortRule, setSortRule] = useState<SortRule | null>(null);
|
const [sortRule, setSortRule] = useState<SortRule | null>(null);
|
||||||
@ -236,9 +254,29 @@ export const Table = implementRuntimeComponent({
|
|||||||
// Otherwise it will automatically paginate on the front end based on the current page
|
// Otherwise it will automatically paginate on the front end based on the current page
|
||||||
return sortedData?.slice(0, pageSize);
|
return sortedData?.slice(0, pageSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sortedData;
|
return sortedData;
|
||||||
}, [pageSize, sortedData, enablePagination, useCustomPagination]);
|
}, [pageSize, sortedData, enablePagination, useCustomPagination]);
|
||||||
|
|
||||||
|
// reset state when data changed
|
||||||
|
useEffect(() => {
|
||||||
|
if (!currentPageData.length) {
|
||||||
|
mergeState({
|
||||||
|
selectedRowKeys: [],
|
||||||
|
selectedRows: [],
|
||||||
|
sortRule: {},
|
||||||
|
filterRule: undefined,
|
||||||
|
currentPage: undefined,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeState({
|
||||||
|
selectedRows: currentPageData.filter(d =>
|
||||||
|
currentChecked.current.includes(d[rowKey])
|
||||||
|
),
|
||||||
|
});
|
||||||
|
}, [currentPageData, mergeState, rowKey]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setColumns(
|
setColumns(
|
||||||
cProps.columns!.map((column, i) => {
|
cProps.columns!.map((column, i) => {
|
||||||
@ -466,6 +504,7 @@ export const Table = implementRuntimeComponent({
|
|||||||
return (
|
return (
|
||||||
<BaseTable
|
<BaseTable
|
||||||
ref={ref}
|
ref={ref}
|
||||||
|
rowKey={rowKey}
|
||||||
className={css`
|
className={css`
|
||||||
${customStyle?.content}
|
${customStyle?.content}
|
||||||
${rowClick ? rowClickStyle : ''}
|
${rowClick ? rowClickStyle : ''}
|
||||||
@ -503,6 +542,7 @@ export const Table = implementRuntimeComponent({
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
onChange(selectedRowKeys, selectedRows) {
|
onChange(selectedRowKeys, selectedRows) {
|
||||||
|
currentChecked.current = selectedRowKeys;
|
||||||
mergeState({
|
mergeState({
|
||||||
selectedRowKeys: selectedRowKeys as string[],
|
selectedRowKeys: selectedRowKeys as string[],
|
||||||
selectedRows,
|
selectedRows,
|
||||||
|
1
packages/arco-lib/src/constants/widgets.ts
Normal file
1
packages/arco-lib/src/constants/widgets.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const ARCO_V1_VERSION = 'arco/v1';
|
@ -301,6 +301,13 @@ export const TablePropsSpec = Type.Object({
|
|||||||
},
|
},
|
||||||
weight: 0,
|
weight: 0,
|
||||||
}),
|
}),
|
||||||
|
rowKey: Type.Any({
|
||||||
|
title: 'RowKey',
|
||||||
|
category: Category.Columns,
|
||||||
|
widget: 'arco/v1/primaryKey',
|
||||||
|
description:
|
||||||
|
'This optional is used to select a unique key for any given row from columns.',
|
||||||
|
}),
|
||||||
tableLayoutFixed: Type.Boolean({
|
tableLayoutFixed: Type.Boolean({
|
||||||
title: 'Layout Fixed',
|
title: 'Layout Fixed',
|
||||||
description:
|
description:
|
||||||
|
49
packages/arco-lib/src/widgets/TablePrimaryKeyWidget.tsx
Normal file
49
packages/arco-lib/src/widgets/TablePrimaryKeyWidget.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { WidgetProps, implementWidget } from '@sunmao-ui/editor-sdk';
|
||||||
|
import { ColumnSpec } from '../generated/types/Table';
|
||||||
|
import { Static } from '@sinclair/typebox';
|
||||||
|
import { Select } from '@arco-design/web-react';
|
||||||
|
import { ARCO_V1_VERSION } from '../constants/widgets';
|
||||||
|
|
||||||
|
type TablePrimaryKeyWidget = 'arco/v1/primaryKey';
|
||||||
|
|
||||||
|
declare module '@sunmao-ui/editor-sdk' {
|
||||||
|
interface WidgetOptionsMap {
|
||||||
|
'arco/v1/primaryKey': Record<string, unknown>;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export const TablePrimaryKeyWidget: React.FC<
|
||||||
|
WidgetProps<TablePrimaryKeyWidget, string>
|
||||||
|
> = props => {
|
||||||
|
const { value, onChange, component } = props;
|
||||||
|
const { properties } = component;
|
||||||
|
const columns = properties.columns as Static<typeof ColumnSpec>[];
|
||||||
|
|
||||||
|
const keys = columns.map(c => c.dataIndex);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Select
|
||||||
|
value={value}
|
||||||
|
defaultValue="auto"
|
||||||
|
onChange={value => {
|
||||||
|
onChange(value);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{keys.map(key => {
|
||||||
|
return (
|
||||||
|
<Select.Option key={key} value={key}>
|
||||||
|
{key}
|
||||||
|
</Select.Option>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</Select>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default implementWidget<TablePrimaryKeyWidget>({
|
||||||
|
version: ARCO_V1_VERSION,
|
||||||
|
metadata: {
|
||||||
|
name: 'primaryKey',
|
||||||
|
},
|
||||||
|
})(TablePrimaryKeyWidget);
|
3
packages/arco-lib/src/widgets/index.ts
Normal file
3
packages/arco-lib/src/widgets/index.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
import TablePrimaryKeyWidget from './TablePrimaryKeyWidget';
|
||||||
|
|
||||||
|
export const widgets = [TablePrimaryKeyWidget];
|
@ -3,6 +3,7 @@ import ReactDOM from 'react-dom';
|
|||||||
import { RegistryInterface } from '@sunmao-ui/runtime';
|
import { RegistryInterface } from '@sunmao-ui/runtime';
|
||||||
import { sunmaoChakraUILib } from '@sunmao-ui/chakra-ui-lib';
|
import { sunmaoChakraUILib } from '@sunmao-ui/chakra-ui-lib';
|
||||||
import { widgets as chakraWidgets } from '@sunmao-ui/chakra-ui-lib/dist/esm/widgets/index';
|
import { widgets as chakraWidgets } from '@sunmao-ui/chakra-ui-lib/dist/esm/widgets/index';
|
||||||
|
import { widgets as arcoWidgets } from '@sunmao-ui/arco-lib/dist/esm/widgets/index';
|
||||||
import { ArcoDesignLib } from '@sunmao-ui/arco-lib';
|
import { ArcoDesignLib } from '@sunmao-ui/arco-lib';
|
||||||
import { initSunmaoUIEditor } from './init';
|
import { initSunmaoUIEditor } from './init';
|
||||||
import { LocalStorageManager } from './LocalStorageManager';
|
import { LocalStorageManager } from './LocalStorageManager';
|
||||||
@ -17,7 +18,7 @@ type Options = Partial<{
|
|||||||
|
|
||||||
const lsManager = new LocalStorageManager();
|
const lsManager = new LocalStorageManager();
|
||||||
const { Editor, registry } = initSunmaoUIEditor({
|
const { Editor, registry } = initSunmaoUIEditor({
|
||||||
widgets: [...chakraWidgets],
|
widgets: [...chakraWidgets, ...arcoWidgets],
|
||||||
storageHandler: {
|
storageHandler: {
|
||||||
onSaveApp(app) {
|
onSaveApp(app) {
|
||||||
lsManager.saveAppInLS(app);
|
lsManager.saveAppInLS(app);
|
||||||
|
3
packages/editor/types/widgets.d.ts
vendored
3
packages/editor/types/widgets.d.ts
vendored
@ -1,3 +1,6 @@
|
|||||||
declare module '@sunmao-ui/chakra-ui-lib/dist/esm/widgets/index' {
|
declare module '@sunmao-ui/chakra-ui-lib/dist/esm/widgets/index' {
|
||||||
export * from '@sunmao-ui/chakra-ui-lib/lib/widgets/index';
|
export * from '@sunmao-ui/chakra-ui-lib/lib/widgets/index';
|
||||||
}
|
}
|
||||||
|
declare module '@sunmao-ui/arco-lib/dist/esm/widgets/index' {
|
||||||
|
export * from '@sunmao-ui/arco-lib/lib/widgets/index';
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user