feat(client/demos): custom field item initializer

This commit is contained in:
chenos 2022-12-22 21:26:32 +08:00
parent d2275455be
commit faa7d819a1
3 changed files with 132 additions and 14 deletions

View File

@ -0,0 +1,126 @@
import { FormLayout } from '@formily/antd';
import { ISchema } from '@formily/react';
import { uid } from '@formily/shared';
import {
CardItem,
CollectionManagerProvider,
CollectionProvider,
FormItem,
Grid,
Input,
InputNumber,
Markdown,
SchemaComponent,
SchemaComponentProvider,
SchemaInitializer,
SchemaInitializerProvider,
useCollectionManager
} from '@nocobase/client';
import cloneDeep from 'lodash/cloneDeep';
import React from 'react';
const collection: any = {
name: 'posts',
fields: [],
};
const schema: ISchema = {
type: 'object',
properties: {
grid: {
type: 'void',
'x-component': 'Grid',
'x-initializer': 'AddFieldButton',
'x-uid': uid(),
properties: {},
},
},
};
const gridRowColWrap = (schema: ISchema) => {
return {
type: 'void',
'x-component': 'Grid.Row',
properties: {
[uid()]: {
type: 'void',
'x-component': 'Grid.Col',
properties: {
[schema.name || uid()]: schema,
},
},
},
};
};
const FormItemInitializer = (props) => {
const { item, insert } = props;
const { getInterface } = useCollectionManager();
return (
<SchemaInitializer.Item
onClick={() => {
const interfaceOptions = getInterface(item.fieldInterface);
if (!interfaceOptions) {
return;
}
const name = `f_${uid()}`;
const options = cloneDeep(interfaceOptions.default);
options.name = name;
options.uiSchema.title = name;
collection.fields.push(options);
insert({
name,
'x-component': 'CollectionField',
'x-collection-field': `posts.${name}`,
'x-component-props': {},
'x-decorator': 'FormItem',
'x-designer': 'FormItem.Designer',
});
}}
/>
);
};
export const AddFieldButton = (props: any) => {
const { insertPosition = 'beforeEnd', component } = props;
return (
<SchemaInitializer.Button
wrap={gridRowColWrap}
insertPosition={insertPosition}
items={[
{
key: 'media',
type: 'itemGroup',
title: 'Field interfaces',
children: [
{
key: 'singleText',
type: 'item',
title: 'Single text',
fieldInterface: 'input',
component: FormItemInitializer,
},
],
},
]}
component={component}
title={component ? undefined : 'Add Field'}
/>
);
};
export default function App() {
return (
<SchemaComponentProvider components={{ Grid, CardItem, Markdown, InputNumber, FormItem, Input }}>
<SchemaInitializerProvider initializers={{ AddFieldButton }}>
<CollectionManagerProvider>
<CollectionProvider collection={collection}>
<FormLayout layout={'vertical'}>
<SchemaComponent schema={schema} />
</FormLayout>
</CollectionProvider>
</CollectionManagerProvider>
</SchemaInitializerProvider>
</SchemaComponentProvider>
);
}

View File

@ -143,3 +143,7 @@ resource 需要与 `<RecordProvider/>` 搭配使用,用于提供当前数据
<code src="./demos/demo3.tsx"/> <code src="./demos/demo3.tsx"/>
<code src="./demos/demo4.tsx"/> <code src="./demos/demo4.tsx"/>
## Initializer
<code src="./demos/demo5.tsx"/>

View File

@ -1,9 +1,7 @@
import { ISchema, observer, useFieldSchema } from '@formily/react'; import { ISchema } from '@formily/react';
import { uid } from '@formily/shared'; import { uid } from '@formily/shared';
import { import {
CardItem, CardItem, Grid,
DragHandler,
Grid,
Markdown, Markdown,
SchemaComponent, SchemaComponent,
SchemaComponentProvider, SchemaComponentProvider,
@ -55,16 +53,6 @@ export const AddBlockButton = (props: any) => {
); );
}; };
const Block = observer((props) => {
const fieldSchema = useFieldSchema();
return (
<div style={{ marginBottom: 20, padding: '0 20px', height: 50, lineHeight: '50px', background: '#f1f1f1' }}>
Block {fieldSchema.title}
<DragHandler />
</div>
);
});
const schema: ISchema = { const schema: ISchema = {
type: 'object', type: 'object',
properties: { properties: {