node tree of all components

This commit is contained in:
chenos 2021-07-13 00:31:38 +08:00
parent 6f54ee3d4e
commit e50267d64c
23 changed files with 391 additions and 68 deletions

View File

@ -11,6 +11,62 @@ group:
# Action - 操作 # Action - 操作
## 组件节点树
<pre lang="tsx">
////////// 单节点 //////////
// 常规按钮操作
<Action/>
// 内链
<Action.Link/>
// 外链
<Action.URL/>
////////// 弹出层相关操作 //////////
// 对话框
<Action title={'按钮标题'}>
<Action.Modal title={'对话框标题'}>
// 添加其他节点
</Action.Modal>
</Action>
// 抽屉
<Action title={'按钮标题'}>
<Action.Drawer title={'抽屉标题'}>
// 添加其他节点
</Action.Drawer>
</Action>
// 气泡
<Action title={'按钮标题'}>
<Action.Popover title={'气泡标题'}>
// 添加其他节点
</Action.Popover>
</Action>
// 指定容器
<Action title={'按钮标题'}>
<Action.Container>
// 添加其他节点
</Action.Container>
</Action>
////////// 操作分组 //////////
// 下拉操作
<Action.Dropdown>
<Action/>
<Action title={'按钮标题'}>
<Action.Modal title={'对话框标题'}>
// 添加其他节点
</Action.Modal>
</Action>
</Action.Dropdown>
</pre>
操作有三类: 操作有三类:
- 常规操作Action - 常规操作Action

View File

@ -11,12 +11,29 @@ group:
# AddNew - 新增 # AddNew - 新增
包括两部分 ## 组件节点树
- AddNew.BlockItem 新增区块项 <pre lang="tsx">
- AddNew.FormItem 新增表单项 // 简单场景,只支持上下拖拽布局
<DragAndDrop>
// 常规区块
<AddNew.BlockItem/>
// 或表单控件
<AddNew.BlockItem/>
</DragAndDrop>
支持常规布局也支持 Grid 布局 // 栅格布局,支持行列等复杂的拖拽操作
<Grid>
<Grid.Row>
<Grid.Col>
// 常规区块
<AddNew.BlockItem/>
// 或表单控件
<AddNew.BlockItem/>
</Grid.Col>
</Grid.Row>
</Grid>
</pre>
## 代码演示 ## 代码演示

View File

@ -11,7 +11,15 @@ group:
# Cascader - 级联选择 # Cascader - 级联选择
## 省市区级联 ## 组件节点树
<pre lang="tsx">
<Cascader/>
</pre>
## 代码演示
### 省市区级联
```tsx ```tsx
/** /**

View File

@ -11,6 +11,15 @@ group:
# Checkbox - 多选框 # Checkbox - 多选框
## 组件节点树
<pre lang="tsx">
// 勾选
<Checkbox/>
// 多选框
<Checkbox.Group/>
</pre>
## 代码演示 ## 代码演示
### 勾选 ### 勾选

View File

@ -11,6 +11,16 @@ group:
# ColorSelect - 颜色选择器 # ColorSelect - 颜色选择器
## 组件节点树
<pre lang="tsx">
<ColorSelect/>
</pre>
## 代码演示
### 颜色选择器
```tsx ```tsx
/** /**
* title: 颜色选择器 * title: 颜色选择器

View File

@ -11,6 +11,14 @@ group:
# DatabaseField - 数据表字段 # DatabaseField - 数据表字段
## 组件节点树
<pre lang="tsx">
<DatabaseField/>
</pre>
## 代码演示
```tsx ```tsx
import React from 'react'; import React from 'react';
import { createForm } from '@formily/core'; import { createForm } from '@formily/core';

View File

@ -11,6 +11,12 @@ group:
# DatePicker - 日期选择器 # DatePicker - 日期选择器
## 组件节点树
<pre lang="tsx">
<DatePicker/>
</pre>
## 代码演示 ## 代码演示
### 日期选择器 ### 日期选择器

View File

@ -9,6 +9,23 @@ group:
path: /client/schemas path: /client/schemas
--- ---
# Filter - 筛选器
## 组件节点树
<pre lang="tsx">
<Filter>
<Filter.Column title={'字段1'} operations={[]}>
<Input/>
</Filter.Column>
<Filter.Column title={'字段2'}>
<Input/>
</Filter.Column>
</Filter>
</pre>
## 代码演示
<!-- <Filter> <!-- <Filter>
<Filter.Column title={'字段1'} operations={[]}> <Filter.Column title={'字段1'} operations={[]}>
<Input/> <Input/>

View File

@ -11,6 +11,16 @@ group:
# Form - 表单 # Form - 表单
## 组件节点树
<pre lang="tsx">
<Form>
<Input/>
<Select/>
// 添加其他节点
</Form>
</pre>
## 代码演示 ## 代码演示
### 常规表单 ### 常规表单

View File

@ -13,6 +13,21 @@ group:
基于行Row和列Col来定义区块Block的外部框架。 基于行Row和列Col来定义区块Block的外部框架。
## 组件节点树
<pre lang="tsx">
<Grid>
<Grid.Row>
<Grid.Col>
// 添加其他节点
</Grid.Col>
<Grid.Col>
// 添加其他节点
</Grid.Col>
</Grid.Row>
</Grid>
</pre>
## 列宽说明 ## 列宽说明
最大支持四列,如果要支持越多列,需要处理的比例也越多。 最大支持四列,如果要支持越多列,需要处理的比例也越多。

View File

@ -11,6 +11,14 @@ group:
# IconPicker - 图标选择器 # IconPicker - 图标选择器
## 节点树
<pre lang="tsx">
<IconPicker/>
</pre>
## 代码演示
```tsx ```tsx
/** /**
* title: 图标 * title: 图标

View File

@ -11,6 +11,14 @@ group:
# InputNumber - 数字框 # InputNumber - 数字框
## 节点树
<pre lang="tsx">
<InputNumber/>
</pre>
## 代码演示
### 数字框 ### 数字框
```tsx ```tsx

View File

@ -13,6 +13,13 @@ group:
输入框是非常常用的控件,参数可以组合成许多字段,如单行文本、多行文本、手机号、邮箱、网址等。 输入框是非常常用的控件,参数可以组合成许多字段,如单行文本、多行文本、手机号、邮箱、网址等。
## 节点树
<pre lang="tsx">
<Input/>
<Input.TextArea/>
</pre>
## 代码演示 ## 代码演示
### 单行文本 ### 单行文本

View File

@ -11,6 +11,12 @@ group:
# Markdown 编辑器 # Markdown 编辑器
## 节点树
<pre lang="tsx">
<Markdown/>
</pre>
## 代码演示 ## 代码演示
### Markdown 编辑器 ### Markdown 编辑器

View File

@ -13,6 +13,36 @@ group:
需要 antd v4.16+ 支持,在此之前的 Menu.Item 不支持 Fragment 包裹。 需要 antd v4.16+ 支持,在此之前的 Menu.Item 不支持 Fragment 包裹。
## 组件树
<pre lang="tsx">
<Menu>
// 菜单分组
<Menu.ItemGroup>
<Menu.Item/>
</Menu.ItemGroup>
// 子菜单
<Menu.SubMenu>
<Menu.Item/>
</Menu.SubMenu>
// 菜单项
<Menu.Item/>
// 分割线
<Menu.Divider/>
// 其他一些基于 Menu.Item 的延伸
// 外链
<Menu.URL/>
// 内链
<Menu.Link/>
// 操作,用法与 Action 相同
<Menu.Action/>
// 新增菜单项
<Menu.AddNew/>
</Menu>
</pre>
## 代码演示 ## 代码演示
### 横向菜单 ### 横向菜单

View File

@ -52,8 +52,6 @@ import ReactDOM from 'react-dom';
import { useMount } from 'ahooks'; import { useMount } from 'ahooks';
import { useDesignable, SchemaRenderer } from '..'; import { useDesignable, SchemaRenderer } from '..';
import { Router } from 'react-router'; import { Router } from 'react-router';
import { useLifecycle } from 'beautiful-react-hooks';
import { Action, useDefaultAction } from '../action'; import { Action, useDefaultAction } from '../action';
export type MenuType = React.FC<MenuProps & { hideSubMenu?: boolean }> & { export type MenuType = React.FC<MenuProps & { hideSubMenu?: boolean }> & {
@ -67,30 +65,18 @@ export type MenuType = React.FC<MenuProps & { hideSubMenu?: boolean }> & {
Url?: React.FC<MenuItemProps & { url: string }>; Url?: React.FC<MenuItemProps & { url: string }>;
}; };
export const MenuContainerContext = createContext({
sideMenuRef: null,
});
export const MenuContext = createContext({ export const MenuContext = createContext({
mode: null, mode: null,
designableBar: null, designableBar: null,
}); });
function Blank() {
return null;
}
function useDesignableBar() { function useDesignableBar() {
const { designableBar } = useContext(MenuContext); const { designableBar } = useContext(MenuContext);
const options = useContext(SchemaOptionsContext); const options = useContext(SchemaOptionsContext);
const DesignableBar = designableBar const DesignableBar = designableBar
? get(options.components, designableBar) ? get(options.components, designableBar)
: null; : null;
return DesignableBar || (() => null);
return {
DesignableBar: DesignableBar || Blank,
};
} }
export const Menu: MenuType = observer((props: any) => { export const Menu: MenuType = observer((props: any) => {
@ -103,7 +89,6 @@ export const Menu: MenuType = observer((props: any) => {
...others ...others
} = props; } = props;
let defaultSelectedKey = defaultSelectedKeys ? defaultSelectedKeys[0] : null; let defaultSelectedKey = defaultSelectedKeys ? defaultSelectedKeys[0] : null;
// const schema = useFieldSchema();
const { schema, schema: designableSchema, refresh } = useDesignable(); const { schema, schema: designableSchema, refresh } = useDesignable();
const designableBar = schema['x-designable-bar']; const designableBar = schema['x-designable-bar'];
const history = useHistory(); const history = useHistory();
@ -183,7 +168,7 @@ export const Menu: MenuType = observer((props: any) => {
renderSideMenu(defaultSelectedKey); renderSideMenu(defaultSelectedKey);
}); });
const isEmpty = !Object.keys(designableSchema.properties || {}).length; const isEmpty = !Object.keys(designableSchema.properties || {}).length;
console.log({ designableSchema }) console.log({ designableSchema });
return ( return (
<MenuContext.Provider <MenuContext.Provider
value={{ value={{
@ -235,9 +220,7 @@ export const Menu: MenuType = observer((props: any) => {
}); });
const AddNewAction = () => { const AddNewAction = () => {
const fieldSchema = useFieldSchema();
const { schema, insertBefore } = useDesignable(); const { schema, insertBefore } = useDesignable();
console.log('AddNewAction', schema, fieldSchema);
return ( return (
<Dropdown <Dropdown
overlayStyle={{ overlayStyle={{
@ -254,13 +237,22 @@ const AddNewAction = () => {
key: uid(), key: uid(),
'x-component': 'Menu.Item', 'x-component': 'Menu.Item',
}); });
console.log('s.s.s.s.s.s', s) console.log('s.s.s.s.s.s', s);
}} }}
style={{ minWidth: 150 }} style={{ minWidth: 150 }}
> >
<MenuOutlined /> <MenuOutlined />
</AntdMenu.Item> </AntdMenu.Item>
<AntdMenu.Item> <AntdMenu.Item
onClick={() => {
const s = insertBefore({
type: 'void',
key: uid(),
title: uid(),
'x-component': 'Menu.SubMenu',
});
}}
>
<GroupOutlined /> <GroupOutlined />
</AntdMenu.Item> </AntdMenu.Item>
<AntdMenu.Item> <AntdMenu.Item>
@ -286,9 +278,8 @@ Menu.AddNew = observer((props) => {
}); });
Menu.Url = observer((props) => { Menu.Url = observer((props) => {
const field = useField(); const DesignableBar = useDesignableBar();
const schema = useFieldSchema(); const { schema } = useDesignable();
const { DesignableBar } = useDesignableBar();
return ( return (
<AntdMenu.Item <AntdMenu.Item
{...props} {...props}
@ -300,7 +291,7 @@ Menu.Url = observer((props) => {
}} }}
icon={props.icon ? <Icon type={props.icon as string} /> : undefined} icon={props.icon ? <Icon type={props.icon as string} /> : undefined}
> >
{field.title} {schema.title}
<DesignableBar /> <DesignableBar />
</AntdMenu.Item> </AntdMenu.Item>
); );
@ -308,9 +299,8 @@ Menu.Url = observer((props) => {
Menu.Link = observer((props) => { Menu.Link = observer((props) => {
const history = useHistory(); const history = useHistory();
const field = useField(); const DesignableBar = useDesignableBar();
const schema = useFieldSchema(); const { schema } = useDesignable();
const { DesignableBar } = useDesignableBar();
return ( return (
<AntdMenu.Item <AntdMenu.Item
{...props} {...props}
@ -322,7 +312,7 @@ Menu.Link = observer((props) => {
}} }}
icon={props.icon ? <Icon type={props.icon as string} /> : undefined} icon={props.icon ? <Icon type={props.icon as string} /> : undefined}
> >
{field.title} {schema.title}
<DesignableBar /> <DesignableBar />
</AntdMenu.Item> </AntdMenu.Item>
); );
@ -331,9 +321,8 @@ Menu.Link = observer((props) => {
Menu.Item = observer((props: any) => { Menu.Item = observer((props: any) => {
const { useAction = useDefaultAction, ...others } = props; const { useAction = useDefaultAction, ...others } = props;
const { run } = useAction(); const { run } = useAction();
const field = useField(); const DesignableBar = useDesignableBar();
const schema = useFieldSchema(); const { schema } = useDesignable();
const { DesignableBar } = useDesignableBar();
return ( return (
<AntdMenu.Item <AntdMenu.Item
{...others} {...others}
@ -346,7 +335,7 @@ Menu.Item = observer((props: any) => {
key={schema.name} key={schema.name}
icon={props.icon ? <Icon type={props.icon as string} /> : undefined} icon={props.icon ? <Icon type={props.icon as string} /> : undefined}
> >
{field.title} {schema.title}
<DesignableBar /> <DesignableBar />
</AntdMenu.Item> </AntdMenu.Item>
); );
@ -354,8 +343,8 @@ Menu.Item = observer((props: any) => {
Menu.Action = observer((props: any) => { Menu.Action = observer((props: any) => {
const { icon, ...others } = props; const { icon, ...others } = props;
const schema = useFieldSchema(); // const DesignableBar = useDesignableBar();
const { DesignableBar } = useDesignableBar(); const { schema } = useDesignable();
return ( return (
<Action <Action
// @ts-ignore // @ts-ignore
@ -365,15 +354,12 @@ Menu.Action = observer((props: any) => {
ButtonComponent={AntdMenu.Item} ButtonComponent={AntdMenu.Item}
{...others} {...others}
/> />
// <Action {...others}/>
// <DesignableBar />
// </AntdMenu.Item>
); );
}); });
Menu.SubMenu = observer((props) => { Menu.SubMenu = observer((props) => {
const { DesignableBar } = useDesignableBar(); const DesignableBar = useDesignableBar();
const schema = useFieldSchema(); const { schema } = useDesignable();
const { mode } = useContext(MenuContext); const { mode } = useContext(MenuContext);
return mode === 'mix' ? ( return mode === 'mix' ? (
<Menu.Item {...props} /> <Menu.Item {...props} />
@ -411,15 +397,10 @@ Menu.SubMenu = observer((props) => {
Menu.Divider = observer(AntdMenu.Divider); Menu.Divider = observer(AntdMenu.Divider);
function useDesigner() {
const field = useField();
}
Menu.DesignableBar = (props) => { Menu.DesignableBar = (props) => {
const field = useField(); const field = useField();
const fieldSchema = useFieldSchema();
const [visible, setVisible] = useState(false); const [visible, setVisible] = useState(false);
const { schema, remove, refresh, insertAfter } = useDesignable(); const { schema, remove, refresh, insertAfter, appendChild } = useDesignable();
return ( return (
<div className={cls('designable-bar', { active: visible })}> <div className={cls('designable-bar', { active: visible })}>
<div <div
@ -443,29 +424,52 @@ Menu.DesignableBar = (props) => {
<AntdMenu.Item <AntdMenu.Item
onClick={() => { onClick={() => {
const title = uid(); const title = uid();
field.title = title;
field.componentProps['icon'] = 'DeleteOutlined'; field.componentProps['icon'] = 'DeleteOutlined';
schema['x-component-props'] = schema['x-component-props'] =
schema['x-component-props'] || {}; schema['x-component-props'] || {};
schema['x-component-props']['icon'] = 'DeleteOutlined'; schema['x-component-props']['icon'] = 'DeleteOutlined';
schema.title = title; schema.title = title;
fieldSchema.title = title;
fieldSchema['x-component-props'] =
fieldSchema['x-component-props'] || {};
fieldSchema['x-component-props']['icon'] = 'DeleteOutlined';
refresh(); refresh();
}} }}
> >
</AntdMenu.Item> </AntdMenu.Item>
<AntdMenu.Item onClick={() => { <AntdMenu.Item
const s = insertAfter({ onClick={() => {
type: 'void', const s = insertAfter({
key: uid(), type: 'void',
title: uid(), key: uid(),
'x-component': 'Menu.SubMenu', title: uid(),
}); 'x-component': 'Menu.SubMenu',
}}></AntdMenu.Item> });
}}
>
</AntdMenu.Item>
<AntdMenu.Item
onClick={() => {
const s = insertAfter({
type: 'void',
key: uid(),
title: uid(),
'x-component': 'Menu.Item',
});
}}
>
</AntdMenu.Item>
<AntdMenu.Item
onClick={() => {
const s = appendChild({
type: 'void',
key: uid(),
title: uid(),
'x-component': 'Menu.Item',
});
}}
>
</AntdMenu.Item>
<AntdMenu.Item <AntdMenu.Item
onClick={() => { onClick={() => {
Modal.confirm({ Modal.confirm({

View File

@ -11,6 +11,13 @@ group:
# Password - 密码 # Password - 密码
## 节点树
<pre lang="tsx">
// 单选框
<Password/>
</pre>
## 代码演示 ## 代码演示
### 密码框 ### 密码框

View File

@ -11,6 +11,15 @@ group:
# Radio - 单选框 # Radio - 单选框
## 节点树
<pre lang="tsx">
// 单选框
<Radio/>
// 单选框分组
<Radio.Group/>
</pre>
## 代码演示 ## 代码演示
### 单选框 ### 单选框

View File

@ -11,6 +11,31 @@ group:
# Select - 选择器 # Select - 选择器
## 节点树
<pre lang="tsx">
// 常规选择器
<Select/>
// 选项值为对象类型
<Select.Object>
// 抽屉选择器
<Select.Drawer>
// 可选项
<Select.Options>
<Form>
<Table>
<Action/>
</Table>
</Form>
</Select.Options>
// 选中项详情
<Select.OptionTag>
<Form>
// 添加其他节点
</Form>
</Select.OptionTag>
</Select.Drawer>
</pre>
## Select ## Select

View File

@ -11,10 +11,48 @@ group:
# Table - 表格 # Table - 表格
- 远程数据、远程分页、远程过滤 ## 组件节点树
- 远程数据、本地分页、远程过滤
- 远程数据、本地分页、本地过滤
- 本地数据、本地分页、本地过滤
<pre lang="tsx">
<Table>
// 顶部操作栏
<Table.ActionBar align={'top'}>
<Action title={'筛选'}>
<Action.Popover>
<Form>
// 此处省略 Filter 节点细节
<Filter/>
<Action/>
</Form>
</Action.Popover>
</Action>
<Action align={'right'} title={'删除'}/>
</Table.ActionBar>
// 底部操作栏
<Table.ActionBar align={'bottom'}>
<Table.Pagination/>
</Table.ActionBar>
// 表格列
<Table.Column title={'拖拽排序'}>
<Table.SortHandle/>
</Table.Column>
<Table.Column title={'序号'}>
<Table.Index/>
</Table.Column>
<Table.Column title={'字段1'}>
<Input/>
</Table.Column>
<Table.Column title={'字段2'}>
<Select/>
</Table.Column>
<Table.Column title={'操作'}>
<Action/>
<Action/>
<Action/>
</Table.Column>
</Table>
</pre>
## 代码演示
<code src="./demos/demo1.tsx"/> <code src="./demos/demo1.tsx"/>

View File

@ -11,6 +11,19 @@ group:
# Tabs - 标签页 # Tabs - 标签页
## 组件节点树
<pre lang="tsx">
<Tabs>
<Tabs.TabPane title={'标签 1'}>
// 添加其他节点
</Tabs.TabPane>
<Tabs.TabPane title={'标签 2'}>
// 添加其他节点
</Tabs.TabPane>
</Tabs>
</pre>
## 代码演示 ## 代码演示
### 基本使用 ### 基本使用

View File

@ -11,6 +11,12 @@ group:
# TimePicker - 时间选择器 # TimePicker - 时间选择器
## 节点树
<pre lang="tsx">
<TimePicker/>
</pre>
## 代码演示 ## 代码演示
### 日期选择器 ### 日期选择器

View File

@ -11,6 +11,12 @@ group:
# Upload - 上传 # Upload - 上传
## 节点树
<pre lang="tsx">
<Upload/>
</pre>
## 代码演示 ## 代码演示
### 上传 ### 上传