From b23aeae6f1c59c4fe48de6fe08a48c621c38afe2 Mon Sep 17 00:00:00 2001 From: chenshenhai Date: Sun, 28 May 2023 21:11:17 +0800 Subject: [PATCH] feat: update component rendering for @idraw/design --- packages/design/dev/data.ts | 29 ++++---- packages/design/dev/main.tsx | 3 +- packages/design/src/context.ts | 19 +++-- packages/design/src/index.tsx | 14 ++-- .../design/src/modules/panel-layer/index.tsx | 28 +++++--- .../src/modules/panel-layer/layer-tree.tsx | 70 ++++--------------- packages/design/src/types/data.ts | 8 ++- packages/design/src/types/index.ts | 1 + packages/design/src/types/view.ts | 5 ++ packages/design/src/util/component.ts | 24 +++++++ 10 files changed, 105 insertions(+), 96 deletions(-) create mode 100644 packages/design/src/types/view.ts create mode 100644 packages/design/src/util/component.ts diff --git a/packages/design/dev/data.ts b/packages/design/dev/data.ts index fb49006..8954ed3 100644 --- a/packages/design/dev/data.ts +++ b/packages/design/dev/data.ts @@ -1,11 +1,12 @@ +import { createUUID } from '@idraw/util'; import type { DesignData } from '../src'; const data: DesignData = { components: [ { - uuid: 'demo-xxx-001', + uuid: createUUID(), type: 'component', - name: 'demo', + name: 'Button default', x: 50, y: 50, w: 100, @@ -14,7 +15,7 @@ const data: DesignData = { bgColor: '#1f1f1f', children: [ { - uuid: 'group-001-0014', + uuid: createUUID(), type: 'circle', x: -40, y: 0, @@ -25,7 +26,7 @@ const data: DesignData = { } }, { - uuid: 'group-001-0015', + uuid: createUUID(), type: 'circle', x: -20, y: 0, @@ -36,7 +37,7 @@ const data: DesignData = { } }, { - uuid: 'group-001-0016', + uuid: createUUID(), type: 'circle', x: 0, y: 0, @@ -47,7 +48,7 @@ const data: DesignData = { } }, { - uuid: 'group-001-0017', + uuid: createUUID(), type: 'circle', x: 20, y: 0, @@ -58,7 +59,7 @@ const data: DesignData = { } }, { - uuid: 'group-001-0018', + uuid: createUUID(), type: 'circle', x: 40, y: 0, @@ -72,9 +73,9 @@ const data: DesignData = { } }, { - uuid: 'demo-xxx-002', + uuid: createUUID(), type: 'component', - name: 'demo', + name: 'Button primary', x: 50, y: 50, w: 100, @@ -83,7 +84,7 @@ const data: DesignData = { bgColor: '#f0f0f0', children: [ { - uuid: 'group-001-0014', + uuid: createUUID(), type: 'circle', x: -40, y: 0, @@ -94,7 +95,7 @@ const data: DesignData = { } }, { - uuid: 'group-001-0015', + uuid: createUUID(), type: 'circle', x: -20, y: 0, @@ -105,7 +106,7 @@ const data: DesignData = { } }, { - uuid: 'group-001-0016', + uuid: createUUID(), type: 'circle', x: 0, y: 0, @@ -116,7 +117,7 @@ const data: DesignData = { } }, { - uuid: 'group-001-0017', + uuid: createUUID(), type: 'circle', x: 20, y: 0, @@ -127,7 +128,7 @@ const data: DesignData = { } }, { - uuid: 'group-001-0018', + uuid: createUUID(), type: 'circle', x: 40, y: 0, diff --git a/packages/design/dev/main.tsx b/packages/design/dev/main.tsx index 1f8cd79..8568b59 100644 --- a/packages/design/dev/main.tsx +++ b/packages/design/dev/main.tsx @@ -1,5 +1,6 @@ import React, { useState, useEffect } from 'react'; import { createRoot } from 'react-dom/client'; +import data from './data'; import { Design } from '../src/index'; const dom = document.querySelector('#lab') as HTMLDivElement; @@ -20,7 +21,7 @@ const App = () => { const width = 800; const height = 600; - return ; + return ; }; root.render(); diff --git a/packages/design/src/context.ts b/packages/design/src/context.ts index d06a9a7..9cf4b10 100644 --- a/packages/design/src/context.ts +++ b/packages/design/src/context.ts @@ -1,13 +1,16 @@ import { createContext } from 'react'; import type { Dispatch } from 'react'; +import type { Data } from '@idraw/types'; import { DesignData } from './types'; export interface DesignState { - data: DesignData; + designData: DesignData | null; + viewDrawData: Data | null; + viewDrawUUID: string | null; themeMode: 'light' | 'dark'; } -export type DesignActionType = 'updateThemeMode' | 'updateData'; +export type DesignActionType = 'updateThemeMode' | 'updateDesignData'; export type DesignAction = { type: DesignActionType; @@ -42,14 +45,14 @@ export function createDesignReducer(state: DesignState, action: DesignAction): D } }; } - case 'updateData': { - if (!action?.payload?.data) { + case 'updateDesignData': { + if (!action?.payload?.designData) { return state; } return { ...state, ...{ - data: action?.payload?.data + data: action?.payload?.designData } }; } @@ -60,8 +63,10 @@ export function createDesignReducer(state: DesignState, action: DesignAction): D export function createDesignContextState(opts?: Partial): DesignState { return { - data: opts?.data || createDesignData(), - themeMode: opts?.themeMode || 'light' + designData: opts?.designData || createDesignData(), + themeMode: opts?.themeMode || 'light', + viewDrawData: null, + viewDrawUUID: null }; } diff --git a/packages/design/src/index.tsx b/packages/design/src/index.tsx index cd9003d..e24941e 100644 --- a/packages/design/src/index.tsx +++ b/packages/design/src/index.tsx @@ -13,24 +13,24 @@ const themeName = 'theme'; const themePrefixName = createPrefixName(themeName); export type DesignProps = SketchProps & { - data?: DesignData; + designData?: DesignData; locale?: string; // TODO themeMode?: 'light' | 'dark'; }; export const Design = (props: DesignProps) => { - const { width = 1000, height = 600, style, className, data, themeMode } = props; + const { width = 1000, height = 600, style, className, designData, themeMode } = props; - const [state, dispatch] = useReducer(createDesignReducer, createDesignContextState({ data, themeMode })); + const [state, dispatch] = useReducer(createDesignReducer, createDesignContextState({ designData, themeMode })); useEffect(() => { - if (data) { + if (designData) { dispatch({ - type: 'updateData', - payload: { data } + type: 'updateDesignData', + payload: { designData } }); } - }, [data]); + }, [designData]); return ( diff --git a/packages/design/src/modules/panel-layer/index.tsx b/packages/design/src/modules/panel-layer/index.tsx index e805bf6..11c785d 100644 --- a/packages/design/src/modules/panel-layer/index.tsx +++ b/packages/design/src/modules/panel-layer/index.tsx @@ -7,27 +7,35 @@ import { prefixName } from './config'; import { LayerTree } from './layer-tree'; import FileOutlined from '@ant-design/icons/FileOutlined'; import AppstoreOutlined from '@ant-design/icons/AppstoreOutlined'; -import ProjectOutlined from '@ant-design/icons/ProjectOutlined'; +import CalculatorOutlined from '@ant-design/icons/CalculatorOutlined'; const items: TabsProps['items'] = [ { - key: '1', + key: 'page', label: , children: (
- +
) }, { - key: '2', + key: 'module', label: , - children: `Content of Tab Pane 2` + children: ( +
+ +
+ ) }, { - key: '3', - label: , - children: `Content of Tab Pane 3` + key: 'component', + label: , + children: ( +
+ +
+ ) } ]; @@ -38,11 +46,13 @@ export interface PanelLayerProps { export const PanelLayer = (props: PanelLayerProps) => { const { className, style } = props; + + const defaultTabKey = items[2].key; return (
{/*
header
*/}
- +
{/*
footer
*/}
diff --git a/packages/design/src/modules/panel-layer/layer-tree.tsx b/packages/design/src/modules/panel-layer/layer-tree.tsx index 9e10758..ca8baec 100644 --- a/packages/design/src/modules/panel-layer/layer-tree.tsx +++ b/packages/design/src/modules/panel-layer/layer-tree.tsx @@ -1,78 +1,38 @@ -import React from 'react'; -import type { CSSProperties } from 'react'; +import React, { useEffect, useContext } from 'react'; import classnames from 'classnames'; import Tree from 'antd/es/tree'; import DownOutlined from '@ant-design/icons/DownOutlined'; import { prefixName } from './config'; +import { Context } from '../../context'; +import { parseComponentViewTree } from '../../util/component'; + +import type { CSSProperties } from 'react'; import type { DataNode, TreeProps } from 'antd/es/tree'; +import type { DesignItemType } from '../../types'; const { DirectoryTree } = Tree; - -const treeData: DataNode[] = [0, 1].map((i) => { - return { - title: 'design-layer-data parent 1', - key: `${i}-0`, - children: [ - { - title: 'design-layer-data parent 1-0', - key: `${i}-0-0`, - children: [ - { - title: 'design-layer-data leaf', - key: `${i}-0-0-0` - }, - { - title: 'design-layer-data leaf', - key: `${i}-0-0-1` - }, - { - title: 'design-layer-data leaf', - key: `${i}-0-0-2` - } - ] - }, - { - title: 'design-layer-data parent 1-1', - key: `${i}-0-1`, - children: [ - { - title: 'design-layer-data leaf', - key: `${i}-0-1-0` - } - ] - }, - { - title: 'design-layer-data parent 1-2', - key: `${i}-0-2`, - children: [ - { - title: 'design-layer-data leaf', - key: `${i}-0-2-0` - }, - { - title: 'design-layer-data leaf', - key: `${i}-0-2-1` - } - ] - } - ] - }; -}); - const baseName = 'layer-tree'; export interface LayerTreeProps { className?: string; style?: CSSProperties; + type: DesignItemType; } export const LayerTree = (props: LayerTreeProps) => { - const { className, style } = props; + const { className, style, type } = props; + const { state } = useContext(Context); const onSelect: TreeProps['onSelect'] = (selectedKeys, info) => { console.log('selected', selectedKeys, info); }; + let treeData: DataNode[] = []; + + if (type === 'component') { + treeData = parseComponentViewTree(state?.designData || null); + } + return (
} icon={null} defaultExpandedKeys={['0-0-0']} onSelect={onSelect} treeData={treeData} /> diff --git a/packages/design/src/types/data.ts b/packages/design/src/types/data.ts index 634e6d4..f613900 100644 --- a/packages/design/src/types/data.ts +++ b/packages/design/src/types/data.ts @@ -1,9 +1,11 @@ import type { Element, ElementType, ElementSize, ElementBaseDesc } from '@idraw/types'; +export type DesignItemType = 'component' | 'module' | 'page'; + export type DesignComponent = Omit & { uuid: string; type: 'component'; - name?: string; + name: string; desc?: ElementBaseDesc & { children: Array | DesignComponent>; }; @@ -12,7 +14,7 @@ export type DesignComponent = Omit & { export type DesignModule = Omit & { uuid: string; type: 'module'; - name?: string; + name: string; desc?: ElementBaseDesc & { children: Array; }; @@ -21,7 +23,7 @@ export type DesignModule = Omit & { export type DesignPage = Omit & { uuid: string; type: 'page'; - name?: string; + name: string; desc: ElementBaseDesc & { children: Array; }; diff --git a/packages/design/src/types/index.ts b/packages/design/src/types/index.ts index 3707679..d90f396 100644 --- a/packages/design/src/types/index.ts +++ b/packages/design/src/types/index.ts @@ -1 +1,2 @@ export * from './data'; +export * from './view'; diff --git a/packages/design/src/types/view.ts b/packages/design/src/types/view.ts new file mode 100644 index 0000000..0a4b83b --- /dev/null +++ b/packages/design/src/types/view.ts @@ -0,0 +1,5 @@ +export interface ViewTreeNode { + title: string; + key: string; + children?: ViewTreeNode[]; +} diff --git a/packages/design/src/util/component.ts b/packages/design/src/util/component.ts new file mode 100644 index 0000000..4085a4a --- /dev/null +++ b/packages/design/src/util/component.ts @@ -0,0 +1,24 @@ +import { Data } from '@idraw/types'; +import { ViewTreeNode, DesignData, DesignComponent } from '../types'; + +export function parseComponentViewTree(designData: DesignData | null): ViewTreeNode[] { + const list: ViewTreeNode[] = []; + designData?.components?.forEach((comp: DesignComponent) => { + const children: ViewTreeNode[] = []; + if (Array.isArray(comp?.desc?.children)) { + comp?.desc?.children?.forEach((child) => { + children.push({ + key: child.uuid, + title: child.name || 'Unamed', + children: [] + }); + }); + } + list.push({ + key: comp.uuid, + title: comp.name || 'Unamed', + children + }); + }); + return list; +}