diff --git a/packages/client/src/schema-component/antd/grid/demos/demo2.tsx b/packages/client/src/schema-component/antd/grid/demos/demo2.tsx new file mode 100644 index 000000000..99ec6eafa --- /dev/null +++ b/packages/client/src/schema-component/antd/grid/demos/demo2.tsx @@ -0,0 +1,209 @@ +import { ISchema, observer, Schema, useFieldSchema } from '@formily/react'; +import { uid } from '@formily/shared'; +import { + Form, + FormItem, + Grid, + Input, + Markdown, + SchemaComponent, + SchemaComponentProvider, + SchemaInitializer, + useDesignable +} from '@nocobase/client'; +import { Switch } from 'antd'; +import React from 'react'; + +const schema: ISchema = { + type: 'void', + name: 'grid1', + 'x-decorator': 'Form', + 'x-component': 'Grid', + 'x-item-initializer': 'AddGridFormItem', + 'x-uid': uid(), + properties: { + row1: { + type: 'void', + 'x-component': 'Grid.Row', + 'x-uid': uid(), + properties: { + col11: { + type: 'void', + 'x-component': 'Grid.Col', + properties: { + name: { + type: 'string', + title: 'Name', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + 'x-collection-field': 'posts.name', + }, + title: { + type: 'string', + title: 'Title', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + 'x-collection-field': 'posts.title', + }, + }, + }, + col12: { + type: 'void', + 'x-component': 'Grid.Col', + properties: { + intro: { + type: 'string', + title: 'Intro', + 'x-decorator': 'FormItem', + 'x-component': 'Input', + }, + }, + }, + }, + }, + }, +}; + +const useFormItemInitializerFields = () => { + return [ + { + key: 'name', + title: 'Name', + component: InitializeFormItem, + schema: { + type: 'string', + title: 'Name', + 'x-component': 'Input', + 'x-decorator': 'FormItem', + 'x-collection-field': 'posts.name', + }, + }, + { + key: 'title', + title: 'Title', + component: InitializeFormItem, + schema: { + type: 'string', + title: 'Title', + 'x-component': 'Input', + 'x-decorator': 'FormItem', + 'x-collection-field': 'posts.title', + }, + }, + ]; +}; + +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 AddGridFormItem = observer((props: any) => { + return ( + + Configure fields + + ); +}); + +const useCurrentFieldSchema = (path: string) => { + const fieldSchema = useFieldSchema(); + const { remove } = useDesignable(); + const findFieldSchema = (schema: Schema) => { + return schema.reduceProperties((buf, s) => { + if (s['x-collection-field'] === path) { + return s; + } + const child = findFieldSchema(s); + if (child) { + return child; + } + return buf; + }); + }; + const schema = findFieldSchema(fieldSchema); + return { + schema, + exists: !!schema, + remove() { + schema && + remove(schema, { + removeEmptyParents: true, + }); + }, + }; +}; + +const InitializeFormItem = (props) => { + const { title, schema, insert } = props; + const { exists, remove } = useCurrentFieldSchema(schema['x-collection-field']); + return ( + { + if (exists) { + return remove(); + } + insert({ + ...schema, + }); + }} + > +
+ {title} +
+
+ ); +}; + +const InitializeTextFormItem = (props) => { + const { title, insert } = props; + return ( + { + insert({ + type: 'void', + 'x-component': 'Markdown.Void', + 'x-decorator': 'FormItem', + // 'x-editable': false, + }); + }} + > + {title} + + ); +}; + +export default function App() { + return ( + + + + ); +} diff --git a/packages/client/src/schema-component/antd/grid/demos/demo3.tsx b/packages/client/src/schema-component/antd/grid/demos/demo3.tsx new file mode 100644 index 000000000..103140156 --- /dev/null +++ b/packages/client/src/schema-component/antd/grid/demos/demo3.tsx @@ -0,0 +1,149 @@ +import { FormOutlined, TableOutlined } from '@ant-design/icons'; +import { ISchema, observer } from '@formily/react'; +import { uid } from '@formily/shared'; +import { + CardItem, + Form, + Grid, + Markdown, + SchemaComponent, + SchemaComponentProvider, + SchemaInitializer, + VoidTable +} from '@nocobase/client'; +import React from 'react'; + +const schema: ISchema = { + type: 'void', + name: 'grid1', + 'x-component': 'Grid', + 'x-item-initializer': 'AddGridBlockItem', + 'x-uid': uid(), + properties: { + row1: { + type: 'void', + 'x-component': 'Grid.Row', + 'x-uid': uid(), + }, + }, +}; + +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 AddGridBlockItem = observer((props: any) => { + return ( + + Add block + + ); +}); + +const TableBlockInitializerItem = (props) => { + const { insert } = props; + return ( + } + onClick={(info) => { + insert({ + type: 'void', + 'x-component': 'VoidTable', + 'x-decorator': 'CardItem', + }); + }} + items={[ + { + type: 'itemGroup', + title: 'select a data source', + children: [ + { + key: 'users', + title: 'Users', + }, + { + key: 'posts', + title: 'Posts', + }, + ], + }, + ]} + > + Table + + ); +}; + +const FormBlockInitializerItem = (props) => { + const { insert } = props; + return ( + } + onClick={(info) => { + insert({ + type: 'void', + 'x-component': 'Form', + 'x-decorator': 'CardItem', + }); + }} + items={[ + { + type: 'itemGroup', + title: 'select a data source', + children: [ + { + key: 'users', + title: 'Users', + }, + { + key: 'posts', + title: 'Posts', + }, + ], + }, + ]} + > + Form + + ); +}; + +export default function App() { + return ( + + + + ); +} diff --git a/packages/client/src/schema-component/antd/grid/index.md b/packages/client/src/schema-component/antd/grid/index.md index 0331d13ba..750ec3bd5 100644 --- a/packages/client/src/schema-component/antd/grid/index.md +++ b/packages/client/src/schema-component/antd/grid/index.md @@ -5,6 +5,10 @@ group: path: /schema-components --- -# Grid 待定 +# Grid + + + + diff --git a/packages/client/src/schema-component/antd/grid/index.tsx b/packages/client/src/schema-component/antd/grid/index.tsx index 4c4066023..107601a52 100644 --- a/packages/client/src/schema-component/antd/grid/index.tsx +++ b/packages/client/src/schema-component/antd/grid/index.tsx @@ -4,6 +4,7 @@ import { observer, RecursionField, Schema, useField, useFieldSchema } from '@for import { uid } from '@formily/shared'; import cls from 'classnames'; import React, { useState } from 'react'; +import { useComponent } from '../..'; import { DndContext } from '../../common/dnd-context'; const ColDivider = (props) => { @@ -65,6 +66,7 @@ const RowDivider = (props) => { export const Grid: any = observer((props) => { const field = useField(); const fieldSchema = useFieldSchema(); + const ItemInitializer = useComponent(fieldSchema['x-item-initializer']); const addr = field.address.toString(); const wrapSchema = (schema: Schema) => { const row = new Schema({ @@ -97,6 +99,7 @@ export const Grid: any = observer((props) => { ); })} +
{ItemInitializer && }
); }); diff --git a/packages/client/src/schema-initializer/demos/demo1.tsx b/packages/client/src/schema-initializer/demos/demo1.tsx index a1e51c3fa..86a95390e 100644 --- a/packages/client/src/schema-initializer/demos/demo1.tsx +++ b/packages/client/src/schema-initializer/demos/demo1.tsx @@ -13,7 +13,7 @@ const Hello = observer((props) => { ); }); -const InitializerButton = observer((props: any) => { +const AddBlockButton = observer((props: any) => { return ( schema} @@ -34,7 +34,7 @@ const InitializerButton = observer((props: any) => { }, ]} > - Create block + Add block ); }); @@ -94,7 +94,7 @@ const FormBlockInitializerItem = (props) => { export default function App() { return ( - + { +const AddActionButton = observer((props: any) => { return ( { { title: 'Create', key: 'create', - component: 'ActionInitializerItem', + component: InitializeAction, schema: { title: 'Create', 'x-action': 'posts:create', @@ -36,7 +36,7 @@ const ActionInitializerButton = observer((props: any) => { title: 'Update', 'x-action': 'posts:update', }, - component: 'ActionInitializerItem', + component: InitializeAction, }, ], }, @@ -65,7 +65,7 @@ const useCurrentActionSchema = (action: string) => { }; }; -const ActionInitializerItem = (props) => { +const InitializeAction = (props) => { const { title, schema, insert } = props; const { exists, remove } = useCurrentActionSchema(schema['x-action']); return ( @@ -90,13 +90,13 @@ const ActionInitializerItem = (props) => { export default function App() { return ( - + diff --git a/packages/client/src/schema-initializer/demos/demo3.tsx b/packages/client/src/schema-initializer/demos/demo3.tsx index fd89ecfa3..4e14ee1ee 100644 --- a/packages/client/src/schema-initializer/demos/demo3.tsx +++ b/packages/client/src/schema-initializer/demos/demo3.tsx @@ -16,7 +16,7 @@ const useFormItemInitializerFields = () => { { key: 'name', title: 'Name', - component: 'FormItemInitializer', + component: InitializeFormItem, schema: { type: 'string', title: 'Name', @@ -28,7 +28,7 @@ const useFormItemInitializerFields = () => { { key: 'title', title: 'Title', - component: 'FormItemInitializer', + component: InitializeFormItem, schema: { type: 'string', title: 'Title', @@ -40,7 +40,7 @@ const useFormItemInitializerFields = () => { ]; }; -const FormItemInitializerButton = observer((props: any) => { +const AddFormItemButton = observer((props: any) => { return ( schema} @@ -55,7 +55,7 @@ const FormItemInitializerButton = observer((props: any) => { }, { title: 'Add text', - component: 'AddTextFormItemInitializer', + component: InitializeTextFormItem, }, ]} > @@ -89,7 +89,7 @@ const useCurrentFieldSchema = (path: string) => { }; }; -const FormItemInitializer = (props) => { +const InitializeFormItem = (props) => { const { title, schema, insert } = props; const { exists, remove } = useCurrentFieldSchema(schema['x-collection-field']); return ( @@ -110,7 +110,7 @@ const FormItemInitializer = (props) => { ); }; -const AddTextFormItemInitializer = (props) => { +const InitializeTextFormItem = (props) => { const { title, insert } = props; return ( { return (
{props.children} - +
); }; export default function App() { return ( - + { 'x-collection-field': 'posts.name', 'x-component': 'Input', }, - component: ColumnInitializer, + component: ColumnInitializerItem, }, { key: 'title', @@ -32,13 +32,13 @@ const useTableColumnInitializerFields = () => { 'x-collection-field': 'posts.title', 'x-component': 'Input', }, - component: ColumnInitializer, + component: ColumnInitializerItem, }, ]; return fields; }; -export const InitializerButton = observer((props: any) => { +export const AddTableColumn = observer((props: any) => { return ( schema} @@ -80,7 +80,7 @@ const useCurrentColumnSchema = (path: string) => { }; }; -export const ColumnInitializer = (props) => { +export const ColumnInitializerItem = (props) => { const { title, schema, insert } = props; const { exists, remove } = useCurrentColumnSchema(schema['x-collection-field']); return ( @@ -120,7 +120,7 @@ const schema = { { id: 3, name: 'Name3' }, ], 'x-component': 'ArrayTable', - 'x-column-initializer': 'InitializerButton', + 'x-column-initializer': 'AddTableColumn', 'x-component-props': { rowKey: 'id', }, @@ -145,7 +145,7 @@ const schema = { export default function App() { return ( - + );