feat(client): improve schema Initializer
This commit is contained in:
parent
4baded4702
commit
6990347013
@ -1,15 +1,21 @@
|
||||
import { observer, Schema } from '@formily/react';
|
||||
import { ISchema, observer } from '@formily/react';
|
||||
import { useDesignable } from '@nocobase/client';
|
||||
import { Button, Dropdown, Menu } from 'antd';
|
||||
import React, { createContext, useContext, useState } from 'react';
|
||||
import {
|
||||
SchemaInitializerButtonProps,
|
||||
SchemaInitializerItemComponent,
|
||||
SchemaInitializerItemOptions,
|
||||
SchemaInitializerItemProps
|
||||
} from './types';
|
||||
|
||||
const defaultWrap = (s: Schema) => s;
|
||||
const defaultWrap = (s: ISchema) => s;
|
||||
|
||||
export const SchemaInitializerItemContext = createContext(null);
|
||||
|
||||
export const SchemaInitializer = () => null;
|
||||
|
||||
SchemaInitializer.Button = observer((props: any) => {
|
||||
SchemaInitializer.Button = observer((props: SchemaInitializerButtonProps) => {
|
||||
const { wrap = defaultWrap, items = [], insertPosition, dropdown, ...others } = props;
|
||||
const { insertAdjacent, findComponent } = useDesignable();
|
||||
const [visible, setVisible] = useState(false);
|
||||
@ -20,7 +26,7 @@ SchemaInitializer.Button = observer((props: any) => {
|
||||
if (item.type === 'divider') {
|
||||
return <Menu.Divider key={`item-${indexA}`} />;
|
||||
}
|
||||
if (item.component) {
|
||||
if (item.type === 'item' && item.component) {
|
||||
const Component = findComponent(item.component);
|
||||
return (
|
||||
Component && (
|
||||
@ -37,6 +43,7 @@ SchemaInitializer.Button = observer((props: any) => {
|
||||
>
|
||||
<Component
|
||||
{...item}
|
||||
item={item}
|
||||
insert={(schema) => {
|
||||
insertAdjacent(insertPosition, wrap(schema));
|
||||
}}
|
||||
@ -68,6 +75,7 @@ SchemaInitializer.Button = observer((props: any) => {
|
||||
>
|
||||
<Component
|
||||
{...child}
|
||||
item={child}
|
||||
insert={(schema) => {
|
||||
insertAdjacent(insertPosition, wrap(schema));
|
||||
}}
|
||||
@ -97,18 +105,22 @@ SchemaInitializer.Button = observer((props: any) => {
|
||||
);
|
||||
});
|
||||
|
||||
SchemaInitializer.Item = (props) => {
|
||||
const { items = [], children, icon, onClick, ...others } = props;
|
||||
SchemaInitializer.Item = (props: SchemaInitializerItemProps) => {
|
||||
const { index, info } = useContext(SchemaInitializerItemContext);
|
||||
const { items = [], children = info?.title, icon, onClick, ...others } = props;
|
||||
if (items?.length > 0) {
|
||||
const renderMenuItem = (items) => {
|
||||
const renderMenuItem = (items: SchemaInitializerItemOptions[]) => {
|
||||
if (!items?.length) {
|
||||
return null;
|
||||
}
|
||||
return items.map((item, indexA) => {
|
||||
if (item.type === 'divider') {
|
||||
return <Menu.Divider key={`divider-${indexA}`} />;
|
||||
}
|
||||
if (item.type === 'itemGroup') {
|
||||
return (
|
||||
<Menu.ItemGroup eventKey={indexA} key={indexA} title={item.title}>
|
||||
// @ts-ignore
|
||||
<Menu.ItemGroup eventKey={`item-group-${indexA}`} key={`item-group-${indexA}`} title={item.title}>
|
||||
{renderMenuItem(item.children)}
|
||||
</Menu.ItemGroup>
|
||||
);
|
||||
@ -116,13 +128,19 @@ SchemaInitializer.Item = (props) => {
|
||||
if (item.type === 'subMenu') {
|
||||
return (
|
||||
// @ts-ignore
|
||||
<Menu.SubMenu eventKey={indexA} key={indexA} title={item.title}>
|
||||
<Menu.SubMenu eventKey={`sub-menu-${indexA}`} key={`sub-menu-${indexA}`} title={item.title}>
|
||||
{renderMenuItem(item.children)}
|
||||
</Menu.SubMenu>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Menu.Item eventKey={item.key} key={item.key} onClick={onClick}>
|
||||
<Menu.Item
|
||||
eventKey={item.key}
|
||||
key={item.key}
|
||||
onClick={(info) => {
|
||||
onClick({ ...info, item });
|
||||
}}
|
||||
>
|
||||
{item.title}
|
||||
</Menu.Item>
|
||||
);
|
||||
@ -136,8 +154,19 @@ SchemaInitializer.Item = (props) => {
|
||||
);
|
||||
}
|
||||
return (
|
||||
<Menu.Item eventKey={info.key || index} icon={icon} onClick={onClick} {...others}>
|
||||
<Menu.Item
|
||||
eventKey={index}
|
||||
icon={icon}
|
||||
onClick={(opts) => {
|
||||
onClick({ ...opts, item: info });
|
||||
}}
|
||||
{...others}
|
||||
>
|
||||
{children}
|
||||
</Menu.Item>
|
||||
);
|
||||
};
|
||||
|
||||
SchemaInitializer.itemWrap = (component?: SchemaInitializerItemComponent) => {
|
||||
return component;
|
||||
};
|
||||
|
@ -20,13 +20,16 @@ const AddBlockButton = observer((props: any) => {
|
||||
insertPosition={'beforeBegin'}
|
||||
items={[
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: 'Data blocks',
|
||||
children: [
|
||||
{
|
||||
type: 'item',
|
||||
title: 'Table',
|
||||
component: TableBlockInitializerItem,
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
title: 'Form',
|
||||
component: FormBlockInitializerItem,
|
||||
},
|
||||
@ -39,58 +42,56 @@ const AddBlockButton = observer((props: any) => {
|
||||
);
|
||||
});
|
||||
|
||||
const TableBlockInitializerItem = (props) => {
|
||||
const TableBlockInitializerItem = SchemaInitializer.itemWrap((props) => {
|
||||
const { insert } = props;
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
icon={<TableOutlined />}
|
||||
onClick={(info) => {
|
||||
console.log({ info });
|
||||
insert({
|
||||
type: 'void',
|
||||
title: info.key,
|
||||
'x-component': 'Hello',
|
||||
});
|
||||
}}
|
||||
items={[
|
||||
const items: any = [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: 'select a data source',
|
||||
children: [
|
||||
{
|
||||
key: 'users',
|
||||
type: 'item',
|
||||
title: 'Users',
|
||||
},
|
||||
{
|
||||
key: 'posts',
|
||||
type: 'item',
|
||||
title: 'Posts',
|
||||
},
|
||||
],
|
||||
},
|
||||
]}
|
||||
>
|
||||
Table
|
||||
</SchemaInitializer.Item>
|
||||
];
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
icon={<TableOutlined />}
|
||||
items={items}
|
||||
onClick={({ item }) => {
|
||||
// 如果有 items 时,onClick 里会返回点击的 item
|
||||
// TODO: 实际情况,这里还需要补充更完整的初始化逻辑
|
||||
insert({
|
||||
type: 'void',
|
||||
title: item.title,
|
||||
'x-component': 'Hello',
|
||||
});
|
||||
}}
|
||||
/>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
const FormBlockInitializerItem = (props) => {
|
||||
const FormBlockInitializerItem = SchemaInitializer.itemWrap((props) => {
|
||||
const { insert } = props;
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
icon={<FormOutlined />}
|
||||
onClick={(info) => {
|
||||
onClick={() => {
|
||||
insert({
|
||||
type: 'void',
|
||||
title: 'form',
|
||||
title: 'Form',
|
||||
'x-component': 'Hello',
|
||||
});
|
||||
}}
|
||||
>
|
||||
Form
|
||||
</SchemaInitializer.Item>
|
||||
/>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
|
@ -17,11 +17,12 @@ const AddActionButton = observer((props: any) => {
|
||||
style={{ marginLeft: 8 }}
|
||||
items={[
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: 'Enable actions',
|
||||
children: [
|
||||
{
|
||||
type: 'item',
|
||||
title: 'Create',
|
||||
key: 'create',
|
||||
component: InitializeAction,
|
||||
schema: {
|
||||
title: 'Create',
|
||||
@ -30,13 +31,13 @@ const AddActionButton = observer((props: any) => {
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
title: 'Update',
|
||||
key: 'update',
|
||||
component: InitializeAction,
|
||||
schema: {
|
||||
title: 'Update',
|
||||
'x-action': 'posts:update',
|
||||
},
|
||||
component: InitializeAction,
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -65,28 +66,28 @@ const useCurrentActionSchema = (action: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
const InitializeAction = (props) => {
|
||||
const { title, schema, insert } = props;
|
||||
const { exists, remove } = useCurrentActionSchema(schema['x-action']);
|
||||
const InitializeAction = SchemaInitializer.itemWrap((props) => {
|
||||
const { item, insert } = props;
|
||||
const { exists, remove } = useCurrentActionSchema(item.schema['x-action']);
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
onClick={(info) => {
|
||||
onClick={() => {
|
||||
if (exists) {
|
||||
return remove();
|
||||
}
|
||||
insert({
|
||||
type: 'void',
|
||||
'x-component': 'Action',
|
||||
...schema,
|
||||
...item.schema,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
{title} <Switch size={'small'} checked={exists} />
|
||||
{item.title} <Switch size={'small'} checked={exists} />
|
||||
</div>
|
||||
</SchemaInitializer.Item>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
export default function App() {
|
||||
return (
|
||||
@ -96,11 +97,15 @@ export default function App() {
|
||||
type: 'void',
|
||||
name: 'page',
|
||||
'x-component': 'ActionBar',
|
||||
// 指定初始化的按钮组件,
|
||||
// Table、Form、Details、Calendar、Kanban 等等不同区块
|
||||
// 可以根据情况组装自己的 initializer
|
||||
'x-action-initializer': 'AddActionButton',
|
||||
properties: {
|
||||
action1: {
|
||||
type: 'void',
|
||||
title: 'Update',
|
||||
// 使用 x-action 来标记 action schema
|
||||
'x-action': 'posts:update',
|
||||
'x-component': 'Action',
|
||||
},
|
||||
|
@ -6,6 +6,7 @@ import {
|
||||
SchemaComponent,
|
||||
SchemaComponentProvider,
|
||||
SchemaInitializer,
|
||||
SchemaInitializerItemOptions,
|
||||
useDesignable
|
||||
} from '@nocobase/client';
|
||||
import { Input, Switch } from 'antd';
|
||||
@ -14,7 +15,7 @@ import React from 'react';
|
||||
const useFormItemInitializerFields = () => {
|
||||
return [
|
||||
{
|
||||
key: 'name',
|
||||
type: 'item',
|
||||
title: 'Name',
|
||||
component: InitializeFormItem,
|
||||
schema: {
|
||||
@ -26,7 +27,7 @@ const useFormItemInitializerFields = () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
key: 'title',
|
||||
type: 'item',
|
||||
title: 'Title',
|
||||
component: InitializeFormItem,
|
||||
schema: {
|
||||
@ -37,7 +38,7 @@ const useFormItemInitializerFields = () => {
|
||||
'x-collection-field': 'posts.title',
|
||||
},
|
||||
},
|
||||
];
|
||||
] as SchemaInitializerItemOptions[];
|
||||
};
|
||||
|
||||
const AddFormItemButton = observer((props: any) => {
|
||||
@ -47,6 +48,7 @@ const AddFormItemButton = observer((props: any) => {
|
||||
insertPosition={'beforeEnd'}
|
||||
items={[
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: 'Display fields',
|
||||
children: useFormItemInitializerFields(),
|
||||
},
|
||||
@ -54,6 +56,7 @@ const AddFormItemButton = observer((props: any) => {
|
||||
type: 'divider',
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
title: 'Add text',
|
||||
component: InitializeTextFormItem,
|
||||
},
|
||||
@ -89,9 +92,9 @@ const useCurrentFieldSchema = (path: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
const InitializeFormItem = (props) => {
|
||||
const { title, schema, insert } = props;
|
||||
const { exists, remove } = useCurrentFieldSchema(schema['x-collection-field']);
|
||||
const InitializeFormItem = SchemaInitializer.itemWrap((props) => {
|
||||
const { item, insert } = props;
|
||||
const { exists, remove } = useCurrentFieldSchema(item.schema['x-collection-field']);
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
onClick={() => {
|
||||
@ -99,22 +102,22 @@ const InitializeFormItem = (props) => {
|
||||
return remove();
|
||||
}
|
||||
insert({
|
||||
...schema,
|
||||
...item.schema,
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
{title} <Switch size={'small'} checked={exists} />
|
||||
{item.title} <Switch size={'small'} checked={exists} />
|
||||
</div>
|
||||
</SchemaInitializer.Item>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
const InitializeTextFormItem = (props) => {
|
||||
const { title, insert } = props;
|
||||
const InitializeTextFormItem = SchemaInitializer.itemWrap((props) => {
|
||||
const { insert } = props;
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
onClick={(info) => {
|
||||
onClick={() => {
|
||||
insert({
|
||||
type: 'void',
|
||||
'x-component': 'Markdown.Void',
|
||||
@ -122,11 +125,9 @@ const InitializeTextFormItem = (props) => {
|
||||
// 'x-editable': false,
|
||||
});
|
||||
}}
|
||||
>
|
||||
{title}
|
||||
</SchemaInitializer.Item>
|
||||
/>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
const Page = (props) => {
|
||||
return (
|
||||
|
@ -5,15 +5,16 @@ import {
|
||||
SchemaComponent,
|
||||
SchemaComponentProvider,
|
||||
SchemaInitializer,
|
||||
SchemaInitializerItemOptions,
|
||||
useDesignable
|
||||
} from '@nocobase/client';
|
||||
import { Switch } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
const useTableColumnInitializerFields = () => {
|
||||
const fields = [
|
||||
const fields: SchemaInitializerItemOptions[] = [
|
||||
{
|
||||
key: 'name',
|
||||
type: 'item',
|
||||
title: 'Name',
|
||||
schema: {
|
||||
type: 'string',
|
||||
@ -24,7 +25,7 @@ const useTableColumnInitializerFields = () => {
|
||||
component: ColumnInitializerItem,
|
||||
},
|
||||
{
|
||||
key: 'title',
|
||||
type: 'item',
|
||||
title: 'Title',
|
||||
schema: {
|
||||
type: 'string',
|
||||
@ -45,6 +46,7 @@ export const AddTableColumn = observer((props: any) => {
|
||||
insertPosition={'beforeEnd'}
|
||||
items={[
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: 'Display fields',
|
||||
children: useTableColumnInitializerFields(),
|
||||
},
|
||||
@ -80,9 +82,9 @@ const useCurrentColumnSchema = (path: string) => {
|
||||
};
|
||||
};
|
||||
|
||||
export const ColumnInitializerItem = (props) => {
|
||||
const { title, schema, insert } = props;
|
||||
const { exists, remove } = useCurrentColumnSchema(schema['x-collection-field']);
|
||||
export const ColumnInitializerItem = SchemaInitializer.itemWrap((props) => {
|
||||
const { item, insert } = props;
|
||||
const { exists, remove } = useCurrentColumnSchema(item.schema['x-collection-field']);
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
onClick={() => {
|
||||
@ -91,23 +93,23 @@ export const ColumnInitializerItem = (props) => {
|
||||
}
|
||||
insert({
|
||||
type: 'void',
|
||||
title: schema.name,
|
||||
title: item.schema.name,
|
||||
'x-component': 'ArrayTable.Column',
|
||||
properties: {
|
||||
[schema.name]: {
|
||||
[item.schema.name]: {
|
||||
'x-read-pretty': true,
|
||||
...schema,
|
||||
...item.schema,
|
||||
},
|
||||
},
|
||||
});
|
||||
}}
|
||||
>
|
||||
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
|
||||
{title} <Switch size={'small'} checked={exists} />
|
||||
{item.title} <Switch size={'small'} checked={exists} />
|
||||
</div>
|
||||
</SchemaInitializer.Item>
|
||||
);
|
||||
};
|
||||
});
|
||||
|
||||
const schema = {
|
||||
type: 'object',
|
||||
|
@ -7,7 +7,25 @@ group:
|
||||
|
||||
# SchemaInitializer
|
||||
|
||||
用于配置各种 schema 的初始化
|
||||
用于各种 schema 的初始化。新增的 schema 可以插入到某个已有 schema 节点的任意位置,包括:
|
||||
|
||||
```ts
|
||||
{
|
||||
properties: {
|
||||
// beforeBegin 在当前节点的前面插入
|
||||
node1: {
|
||||
properties: {
|
||||
// afterBegin 在当前节点的第一个子节点前面插入
|
||||
// ...
|
||||
// beforeEnd 在当前节点的最后一个子节点后面
|
||||
},
|
||||
},
|
||||
// afterEnd 在当前节点的后面
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
SchemaInitializer 的核心包括 `<SchemaInitializer.Button/>` 和 `<SchemaInitializer.Item/>` 两个组件。`<SchemaInitializer.Button/>` 是用于创建 Schema 的 Dropdown 按钮,按钮有上下文,表示新增的 schema 要插入的位置,可以通过 `insertPosition` 属性来指定插入的具体位置。下拉菜单里的为 `<SchemaInitializer.Item/>`,用于自定义各种 schema 的初始化逻辑,schema 可以是区块、字段、操作等。
|
||||
|
||||
## SchemaInitializer.Button
|
||||
|
||||
@ -16,13 +34,16 @@ group:
|
||||
```tsx | pure
|
||||
const items = [
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: 'Data blocks',
|
||||
children: [
|
||||
{
|
||||
type: 'item',
|
||||
title: 'Table',
|
||||
component: 'TableBlockInitializerItem',
|
||||
},
|
||||
{
|
||||
type: 'item',
|
||||
title: 'Form',
|
||||
component: 'FormBlockInitializerItem',
|
||||
},
|
||||
@ -51,8 +72,9 @@ const useFormItemInitializerFields = () => {
|
||||
const { fields } = useCollection();
|
||||
return fields.map(field => {
|
||||
return {
|
||||
key: field.name,
|
||||
component: 'FormItemInitializerItem'
|
||||
type: 'item',
|
||||
component: 'FormItemInitializerItem',
|
||||
schema: {}, // TODO, 例如从 field.uiSchema 里获取
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -77,43 +99,38 @@ export const AddFieldButton = () => {
|
||||
|
||||
## SchemaInitializer.Item
|
||||
|
||||
扩展项
|
||||
用于自定义各种 schema 的初始化逻辑,配合 `SchemaInitializer.itemWrap()` 可获得更好的类型提示。
|
||||
|
||||
`<SchemaInitializer.Button/>` 的下拉菜单项,items 属性里 type 为 item 的 component):
|
||||
|
||||
```ts
|
||||
{
|
||||
type: 'item',
|
||||
title: 'Table',
|
||||
component: 'TableBlockInitializerItem',
|
||||
}
|
||||
```
|
||||
|
||||
例子如下:
|
||||
|
||||
```tsx | pure
|
||||
const TableBlockInitializerItem = (props) => {
|
||||
const TableBlockInitializerItem = SchemaInitializer.itemWrap((props) => {
|
||||
const { insert } = props;
|
||||
return (
|
||||
<SchemaInitializer.Item
|
||||
icon={<TableOutlined />}
|
||||
onClick={(info) => {
|
||||
console.log({ info });
|
||||
onClick={() => {
|
||||
// 插入的 schema,在这里补充更完整的逻辑
|
||||
insert({
|
||||
type: 'void',
|
||||
title: info.key,
|
||||
'x-component': 'Hello',
|
||||
'x-component': 'Table',
|
||||
});
|
||||
}}
|
||||
items={[
|
||||
{
|
||||
type: 'itemGroup',
|
||||
title: 'select a data source',
|
||||
children: [
|
||||
{
|
||||
key: 'users',
|
||||
title: 'Users',
|
||||
},
|
||||
{
|
||||
key: 'posts',
|
||||
title: 'Posts',
|
||||
},
|
||||
],
|
||||
},
|
||||
]}
|
||||
>
|
||||
Table
|
||||
</SchemaInitializer.Item>
|
||||
);
|
||||
};
|
||||
});
|
||||
```
|
||||
|
||||
## Examples
|
||||
|
@ -1 +1,3 @@
|
||||
export * from './SchemaInitializer';
|
||||
export * from './types';
|
||||
|
||||
|
57
packages/client/src/schema-initializer/types.ts
Normal file
57
packages/client/src/schema-initializer/types.ts
Normal file
@ -0,0 +1,57 @@
|
||||
import { ISchema } from '@formily/react';
|
||||
import { ButtonProps, DropDownProps, MenuItemProps } from 'antd';
|
||||
|
||||
export interface SchemaInitializerButtonProps extends ButtonProps {
|
||||
wrap?: (s: ISchema) => ISchema;
|
||||
insertPosition?: 'beforeBegin' | 'afterBegin' | 'beforeEnd' | 'afterEnd';
|
||||
items?: SchemaInitializerItemOptions[];
|
||||
dropdown?: DropDownProps;
|
||||
}
|
||||
|
||||
export type SchemaInitializerItemOptions = ItemGroupOptions | SubMenuOptions | ItemOptions | DividerOptions;
|
||||
|
||||
interface ItemCommonOptions {
|
||||
title?: any;
|
||||
}
|
||||
|
||||
interface ItemGroupOptions extends ItemCommonOptions {
|
||||
type: 'itemGroup';
|
||||
children?: SchemaInitializerItemOptions[];
|
||||
}
|
||||
|
||||
interface SubMenuOptions extends ItemCommonOptions {
|
||||
type: 'subMenu';
|
||||
children?: SchemaInitializerItemOptions[];
|
||||
}
|
||||
|
||||
interface ItemOptions extends ItemCommonOptions {
|
||||
type: 'item';
|
||||
component?: any;
|
||||
schema?: ISchema;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface DividerOptions {
|
||||
type: 'divider';
|
||||
}
|
||||
|
||||
export type SchemaInitializerItemComponent = (props?: SchemaInitializerItemComponentProps) => any;
|
||||
|
||||
interface SchemaInitializerItemComponentProps {
|
||||
insert?: (s: ISchema) => void;
|
||||
item?: ItemOptions;
|
||||
}
|
||||
|
||||
export interface SchemaInitializerItemProps extends Omit<MenuItemProps, 'onClick'> {
|
||||
items?: SchemaInitializerItemOptions[];
|
||||
onClick?: MenuClickEventHandler;
|
||||
}
|
||||
|
||||
type MenuClickEventHandler = (info: MenuInfo) => void;
|
||||
|
||||
interface MenuInfo {
|
||||
// key: string;
|
||||
// keyPath: string[];
|
||||
item: ItemOptions;
|
||||
domEvent: React.MouseEvent<HTMLElement> | React.KeyboardEvent<HTMLElement>;
|
||||
}
|
Loading…
Reference in New Issue
Block a user