此为默认的 Toolbar 组件,其内部会自动根据 Schema 的 x-settings
、x-initializer
渲染 SchemaSettings
、SchemaInitializer
和 Drag
组件。
Toolbar 具体的渲染规则为:当有 x-toolbar
会渲染对应的组件;当无 x-toolbar
但是有 x-settings
、x-initializer
会渲染默认的 SchemaToolbar
组件。
1interface SchemaToolbarProps {
2 title?: string;
3 draggable?: boolean;
4 initializer?: string | false;
5 settings?: string | false;
6 /**
7 * @default true
8 */
9 showBorder?: boolean;
10 showBackground?: boolean;
11}
详细解释
title
:左上角的标题draggable
:是否可以拖拽,默认为 true
initializer
:SchemaInitializer
的默认值,当 schema 里没有 x-initializer
时,会使用此值;当为 false
时,不会渲染 SchemaInitializer
settings
:SchemaSettings
的默认值,当 schema 里没有 x-settings
时,会使用此值;当为 false
时,不会渲染 SchemaSettings
showBorder
:边框是否变为橘色showBackground
:背景是否变为橘色示例
未指定 x-toolbar
时会渲染默认的 SchemaToolbar
这个组件。
1import { useFieldSchema } from '@tachybase/schema';
2import {
3 Application,
4 CardItem,
5 Grid,
6 Plugin,
7 SchemaComponent,
8 SchemaInitializer,
9 SchemaInitializerItem,
10 SchemaSettings,
11 useSchemaInitializer,
12 useSchemaInitializerItem,
13} from '@tachybase/client';
14import React from 'react';
15
16const mySettings = new SchemaSettings({
17 name: 'mySettings',
18 items: [
19 {
20 name: 'remove',
21 type: 'remove',
22 componentProps: {
23 removeParentsIfNoChildren: true,
24 },
25 },
26 ],
27});
28
29const myInitializer = new SchemaInitializer({
30 name: 'MyInitializer',
31 title: 'Button Text',
32 wrap: Grid.wrap,
33 items: [
34 {
35 name: 'demo1',
36 title: 'Demo1',
37 Component: () => {
38 const itemConfig = useSchemaInitializerItem();
39 const { insert } = useSchemaInitializer();
40 const handleClick = () => {
41 insert({
42 type: 'void',
43 'x-settings': 'mySettings',
44 'x-decorator': 'CardItem',
45 'x-component': 'Hello',
46 });
47 };
48 return <SchemaInitializerItem title={itemConfig.title} onClick={handleClick}></SchemaInitializerItem>;
49 },
50 },
51 ],
52});
53
54const Hello = () => {
55 const schema = useFieldSchema();
56 return <h1>Hello, world! {schema.name}</h1>;
57};
58
59const hello1 = Grid.wrap({
60 type: 'void',
61 // 仅指定了 `x-settings` 但是没有 `x-toolbar`,会使用默认的 `SchemaToolbar` 组件
62 'x-settings': 'mySettings',
63 'x-decorator': 'CardItem',
64 'x-component': 'Hello',
65});
66
67const HelloPage = () => {
68 return (
69 <div>
70 <SchemaComponent
71 schema={{
72 name: 'root',
73 type: 'void',
74 'x-component': 'Grid',
75 'x-initializer': 'MyInitializer',
76 properties: {
77 hello1,
78 },
79 }}
80 />
81 </div>
82 );
83};
84
85class PluginHello extends Plugin {
86 async load() {
87 this.app.addComponents({ Grid, CardItem, Hello });
88 this.app.schemaSettingsManager.add(mySettings);
89 this.app.schemaInitializerManager.add(myInitializer);
90 this.router.add('hello', {
91 path: '/',
92 Component: HelloPage,
93 });
94 }
95}
96
97const app = new Application({
98 router: {
99 type: 'memory',
100 },
101 designable: true,
102 plugins: [PluginHello],
103});
104
105export default app.getRootComponent();
自定义 Toolbar 组件。
1import { useFieldSchema } from '@tachybase/schema';
2import {
3 Application,
4 CardItem,
5 Grid,
6 Plugin,
7 SchemaComponent,
8 SchemaInitializer,
9 SchemaInitializerItem,
10 SchemaSettings,
11 SchemaToolbar,
12 useSchemaInitializer,
13 useSchemaInitializerItem,
14} from '@tachybase/client';
15import React from 'react';
16
17const mySettings = new SchemaSettings({
18 name: 'mySettings',
19 items: [
20 {
21 name: 'remove',
22 type: 'remove',
23 componentProps: {
24 removeParentsIfNoChildren: true,
25 },
26 },
27 ],
28});
29
30const MyToolbar = () => {
31 return <SchemaToolbar showBackground title='Test' />
32}
33
34const myInitializer = new SchemaInitializer({
35 name: 'MyInitializer',
36 title: 'Button Text',
37 wrap: Grid.wrap,
38 items: [
39 {
40 name: 'demo1',
41 title: 'Demo1',
42 Component: () => {
43 const itemConfig = useSchemaInitializerItem();
44 // 调用插入功能
45 const { insert } = useSchemaInitializer();
46 const handleClick = () => {
47 insert({
48 type: 'void',
49 // 使用自定义的 Toolbar 组件
50 'x-toolbar': 'MyToolbar',
51 'x-settings': 'mySettings',
52 'x-decorator': 'CardItem',
53 'x-component': 'Hello',
54 });
55 };
56 return <SchemaInitializerItem title={itemConfig.title} onClick={handleClick}></SchemaInitializerItem>;
57 },
58 },
59 ],
60});
61
62const Hello = () => {
63 const schema = useFieldSchema();
64 return <h1>Hello, world! {schema.name}</h1>;
65};
66
67const hello1 = Grid.wrap({
68 type: 'void',
69 // 使用自定义的 Toolbar 组件
70 'x-toolbar': 'MyToolbar',
71 'x-settings': 'mySettings',
72 'x-decorator': 'CardItem',
73 'x-component': 'Hello',
74});
75
76const HelloPage = () => {
77 return (
78 <div>
79 <SchemaComponent
80 schema={{
81 name: 'root',
82 type: 'void',
83 'x-component': 'Grid',
84 'x-initializer': 'MyInitializer',
85 properties: {
86 hello1,
87 },
88 }}
89 />
90 </div>
91 );
92};
93
94class PluginHello extends Plugin {
95 async load() {
96 this.app.addComponents({ Grid, CardItem, Hello, MyToolbar });
97 this.app.schemaSettingsManager.add(mySettings);
98 this.app.schemaInitializerManager.add(myInitializer);
99 this.router.add('hello', {
100 path: '/',
101 Component: HelloPage,
102 });
103 }
104}
105
106const app = new Application({
107 router: {
108 type: 'memory',
109 },
110 designable: true,
111 plugins: [PluginHello],
112});
113
114export default app.getRootComponent();
用于渲染 SchemaToolbar
。
1const useSchemaToolbarRender: (fieldSchema: ISchema) => {
2 render(props?: SchemaToolbarProps): React.JSX.Element;
3 exists: boolean;
4}
前面示例中 'x-decorator': 'CardItem'
中组件 CardItem
里面就调用了 useSchemaToolbarRender()
进行渲染。内置的组件还有:BlockItem
、CardItem
、Action
、FormItem
。
render()
支持二次覆盖组件属性。
1const MyDecorator = () => {
2 const filedSchema = useFieldSchema();
3 const { render } = useSchemaToolbarRender(filedSchema); // 从 Schema 中读取 Toolbar 组件
4
5 return <Card>{ render() }</Card>
6}
1import { Card } from 'antd';
2import { useFieldSchema } from '@tachybase/schema';
3import {
4 Application,
5 CardItem,
6 Grid,
7 Plugin,
8 SchemaComponent,
9 SchemaInitializer,
10 SchemaInitializerItem,
11 SchemaSettings,
12 SchemaToolbar,
13 useSchemaInitializer,
14 useSchemaInitializerItem,
15 useSchemaToolbarRender
16} from '@tachybase/client';
17import React from 'react';
18
19const mySettings = new SchemaSettings({
20 name: 'mySettings',
21 items: [
22 {
23 name: 'remove',
24 type: 'remove',
25 componentProps: {
26 removeParentsIfNoChildren: true,
27 },
28 },
29 ],
30});
31
32const MyToolbar = (props) => {
33 return <SchemaToolbar showBackground title='Test' {...props} />
34}
35
36// 自定义包装器
37const MyDecorator = ({children}) => {
38 const filedSchema = useFieldSchema();
39 // 使用 `useSchemaToolbarRender()` 获取并渲染内容
40 const { render } = useSchemaToolbarRender(filedSchema);
41 return <Card style={{ marginBottom: 10 }}>{ render({ draggable: false }) }{children}</Card>
42}
43
44const myInitializer = new SchemaInitializer({
45 name: 'MyInitializer',
46 title: 'Button Text',
47 wrap: Grid.wrap,
48 items: [
49 {
50 name: 'demo1',
51 title: 'Demo1',
52 Component: () => {
53 const itemConfig = useSchemaInitializerItem();
54 // 调用插入功能
55 const { insert } = useSchemaInitializer();
56 const handleClick = () => {
57 insert({
58 type: 'void',
59 // 使用自定义的 Toolbar 组件
60 'x-toolbar': 'MyToolbar',
61 'x-settings': 'mySettings',
62 'x-decorator': 'MyDecorator',
63 'x-component': 'Hello',
64 });
65 };
66 return <SchemaInitializerItem title={itemConfig.title} onClick={handleClick}></SchemaInitializerItem>;
67 },
68 },
69 ],
70});
71
72const Hello = () => {
73 const schema = useFieldSchema();
74 return <h1>Hello, world! {schema.name}</h1>;
75};
76
77const hello1 = Grid.wrap({
78 type: 'void',
79 // 使用自定义的 Toolbar 组件
80 'x-toolbar': 'MyToolbar',
81 'x-settings': 'mySettings',
82 'x-decorator': 'MyDecorator',
83 'x-component': 'Hello',
84});
85
86const HelloPage = () => {
87 return (
88 <div>
89 <SchemaComponent
90 schema={{
91 name: 'root',
92 type: 'void',
93 'x-component': 'Grid',
94 'x-initializer': 'MyInitializer',
95 properties: {
96 hello1,
97 },
98 }}
99 />
100 </div>
101 );
102};
103
104class PluginHello extends Plugin {
105 async load() {
106 this.app.addComponents({ Grid, CardItem, Hello, MyToolbar, MyDecorator });
107 this.app.schemaSettingsManager.add(mySettings);
108 this.app.schemaInitializerManager.add(myInitializer);
109 this.router.add('hello', {
110 path: '/',
111 Component: HelloPage,
112 });
113 }
114}
115
116const app = new Application({
117 router: {
118 type: 'memory',
119 },
120 designable: true,
121 plugins: [PluginHello],
122});
123
124export default app.getRootComponent();