mirror of
https://github.com/idrawjs/idraw
synced 2026-05-24 01:58:27 +00:00
feat: add header of idraw design
This commit is contained in:
parent
026052d93a
commit
f834f010e0
22 changed files with 482 additions and 55 deletions
3
.vscode/settings.json
vendored
3
.vscode/settings.json
vendored
|
|
@ -10,5 +10,8 @@
|
|||
},
|
||||
"[json]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
},
|
||||
"[less]": {
|
||||
"editor.defaultFormatter": "esbenp.prettier-vscode"
|
||||
}
|
||||
}
|
||||
148
packages/design/dev/data.ts
Normal file
148
packages/design/dev/data.ts
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
import type { DesignData } from '../src';
|
||||
|
||||
const data: DesignData = {
|
||||
components: [
|
||||
{
|
||||
uuid: 'demo-xxx-001',
|
||||
type: 'component',
|
||||
name: 'demo',
|
||||
x: 50,
|
||||
y: 50,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#1f1f1f',
|
||||
children: [
|
||||
{
|
||||
uuid: 'group-001-0014',
|
||||
type: 'circle',
|
||||
x: -40,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#f44336'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'group-001-0015',
|
||||
type: 'circle',
|
||||
x: -20,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#ff9800'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'group-001-0016',
|
||||
type: 'circle',
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#ffc106'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'group-001-0017',
|
||||
type: 'circle',
|
||||
x: 20,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#cddc39'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'group-001-0018',
|
||||
type: 'circle',
|
||||
x: 40,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#4caf50'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'demo-xxx-002',
|
||||
type: 'component',
|
||||
name: 'demo',
|
||||
x: 50,
|
||||
y: 50,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#f0f0f0',
|
||||
children: [
|
||||
{
|
||||
uuid: 'group-001-0014',
|
||||
type: 'circle',
|
||||
x: -40,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#f44336'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'group-001-0015',
|
||||
type: 'circle',
|
||||
x: -20,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#ff9800'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'group-001-0016',
|
||||
type: 'circle',
|
||||
x: 0,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#ffc106'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'group-001-0017',
|
||||
type: 'circle',
|
||||
x: 20,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#cddc39'
|
||||
}
|
||||
},
|
||||
{
|
||||
uuid: 'group-001-0018',
|
||||
type: 'circle',
|
||||
x: 40,
|
||||
y: 0,
|
||||
w: 100,
|
||||
h: 100,
|
||||
desc: {
|
||||
bgColor: '#4caf50'
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
],
|
||||
modules: [],
|
||||
pages: []
|
||||
};
|
||||
|
||||
export default data;
|
||||
|
|
@ -1,8 +1,26 @@
|
|||
import React from 'react';
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { createRoot } from 'react-dom/client';
|
||||
import { Design } from '../src/index';
|
||||
|
||||
const dom = document.querySelector('#lab') as HTMLDivElement;
|
||||
const root = createRoot(dom);
|
||||
|
||||
root.render(<Design />);
|
||||
const App = () => {
|
||||
// const style = { margin: 0, padding: 0 }
|
||||
// const [width, setWidth] = useState<number>(window.innerWidth);
|
||||
// const [height, setHeight] = useState<number>(window.innerHeight);
|
||||
// useEffect(() => {
|
||||
// window.addEventListener('resize', () => {
|
||||
// setWidth(window.innerWidth);
|
||||
// setHeight(window.innerHeight);
|
||||
// });
|
||||
// }, []);
|
||||
|
||||
const style = { margin: 40 };
|
||||
const width = 1000;
|
||||
const height = 600;
|
||||
|
||||
return <Design width={width} height={height} style={style} />;
|
||||
};
|
||||
|
||||
root.render(<App />);
|
||||
|
|
|
|||
24
packages/design/src/context.ts
Normal file
24
packages/design/src/context.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { createContext } from 'react';
|
||||
import { DesignData } from './types';
|
||||
|
||||
export interface DesignContext {
|
||||
data: DesignData;
|
||||
}
|
||||
|
||||
export function createDesignData(): DesignData {
|
||||
return {
|
||||
components: [],
|
||||
modules: [],
|
||||
pages: []
|
||||
};
|
||||
}
|
||||
|
||||
export function createDesignContextValue(opts?: { data?: DesignData }): DesignContext {
|
||||
return {
|
||||
data: opts?.data || createDesignData()
|
||||
};
|
||||
}
|
||||
|
||||
const Context = createContext<DesignContext>(createDesignContextValue());
|
||||
|
||||
export const Provider = Context.Provider;
|
||||
|
|
@ -1,11 +1,19 @@
|
|||
@import "../../css/variable.less";
|
||||
@import '../../css/variable.less';
|
||||
|
||||
@mod-name: ~'@{prefix}-icon';
|
||||
|
||||
.@{mod-name} {
|
||||
display: flex;
|
||||
text-align: center;
|
||||
font-size: 16;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
font-size: 16;
|
||||
}
|
||||
color: inherit;
|
||||
font-style: normal;
|
||||
line-height: 0;
|
||||
text-align: center;
|
||||
text-transform: none;
|
||||
|
||||
svg {
|
||||
justify-content: center;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,3 +6,4 @@
|
|||
@import "./modules/header.less";
|
||||
@import "./modules/sketch.less";
|
||||
@import "./modules/toolbar.less";
|
||||
@import "./modules/panel-layer.less";
|
||||
|
|
|
|||
|
|
@ -1 +1,16 @@
|
|||
@import "../variable.less";
|
||||
@import '../variable.less';
|
||||
|
||||
@mod-header: ~'@{prefix}-mod-header';
|
||||
|
||||
.@{mod-header} {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
height: 100%;
|
||||
box-sizing: border-box;
|
||||
padding: 0 20px;
|
||||
|
||||
.@{mod-header}-theme-switch {
|
||||
display: flex;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
23
packages/design/src/css/modules/panel-layer.less
Normal file
23
packages/design/src/css/modules/panel-layer.less
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
@import "../variable.less";
|
||||
|
||||
@mod-panel-layer: ~'@{prefix}-mod-panel-layer';
|
||||
|
||||
.@{mod-panel-layer} {
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
display: flex;
|
||||
flex-flow: column;
|
||||
|
||||
.@{mod-panel-layer}-header {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
.@{mod-panel-layer}-content {
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.@{mod-panel-layer}-footer {
|
||||
height: 40px;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -2,7 +2,10 @@
|
|||
|
||||
@mod-sketch: ~'@{prefix}-mod-sketch';
|
||||
|
||||
// @mod-sketch-header-height: 36px;
|
||||
|
||||
.@{mod-sketch} {
|
||||
display: flex;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
box-shadow: 0 0 0 1px #0000001a,0px 0px .5px #0000002e, 0px 3px 8px #0000001a, 0px 1px 3px #0000001a;
|
||||
|
|
@ -15,4 +18,20 @@
|
|||
min-width: 400px;
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.@{mod-sketch}-header {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
// height: @mod-sketch-header-height;
|
||||
}
|
||||
|
||||
.@{mod-sketch}-content {
|
||||
position: absolute;
|
||||
// top: @mod-sketch-header-height;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
}
|
||||
}
|
||||
17
packages/design/src/icons/dark.tsx
Normal file
17
packages/design/src/icons/dark.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { iconClassName } from './util';
|
||||
import type { IconProps } from './util';
|
||||
|
||||
const Dark = (props: IconProps) => {
|
||||
const { className, style } = props;
|
||||
return (
|
||||
<span className={classnames([iconClassName, className])} style={style}>
|
||||
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor">
|
||||
<path d="M516.266667 938.666667h-38.4c-234.666667-21.333333-405.333333-230.4-384-465.066667 17.066667-204.8 179.2-366.933333 384-384 17.066667 0 34.133333 8.533333 42.666666 21.333333 8.533333 12.8 8.533333 34.133333-4.266666 46.933334-85.333333 115.2-59.733333 273.066667 55.466666 358.4 89.6 68.266667 213.333333 68.266667 302.933334 0 12.8-8.533333 29.866667-12.8 46.933333-4.266667 12.8 8.533333 21.333333 25.6 21.333333 42.666667-8.533333 115.2-64 217.6-153.6 290.133333-81.066667 59.733333-174.933333 93.866667-273.066666 93.866667zM396.8 187.733333c-123.733333 42.666667-213.333333 153.6-221.866667 290.133334-17.066667 187.733333 119.466667 354.133333 307.2 371.2 89.6 8.533333 179.2-17.066667 247.466667-76.8 46.933333-38.4 81.066667-89.6 102.4-145.066667-106.666667 38.4-226.133333 21.333333-320-46.933333-119.466667-93.866667-166.4-251.733333-115.2-392.533334z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default Dark;
|
||||
17
packages/design/src/icons/light.tsx
Normal file
17
packages/design/src/icons/light.tsx
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { iconClassName } from './util';
|
||||
import type { IconProps } from './util';
|
||||
|
||||
const Light = (props: IconProps) => {
|
||||
const { className, style } = props;
|
||||
return (
|
||||
<span className={classnames([iconClassName, className])} style={style}>
|
||||
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor">
|
||||
<path d="M512 768c-141.376 0-256-114.624-256-256s114.624-256 256-256 256 114.624 256 256-114.624 256-256 256z m0-85.333333a170.666667 170.666667 0 1 0 0-341.333334 170.666667 170.666667 0 0 0 0 341.333334zM469.333333 85.333333a42.666667 42.666667 0 1 1 85.333334 0v85.333334a42.666667 42.666667 0 1 1-85.333334 0V85.333333z m0 768a42.666667 42.666667 0 1 1 85.333334 0v85.333334a42.666667 42.666667 0 1 1-85.333334 0v-85.333334zM85.333333 554.666667a42.666667 42.666667 0 1 1 0-85.333334h85.333334a42.666667 42.666667 0 1 1 0 85.333334H85.333333z m768 0a42.666667 42.666667 0 1 1 0-85.333334h85.333334a42.666667 42.666667 0 1 1 0 85.333334h-85.333334zM161.834667 222.165333a42.666667 42.666667 0 0 1 60.330666-60.330666l64 64a42.666667 42.666667 0 0 1-60.330666 60.330666l-64-64z m576 576a42.666667 42.666667 0 0 1 60.330666-60.330666l64 64a42.666667 42.666667 0 0 1-60.330666 60.330666l-64-64z m-515.669334 64a42.666667 42.666667 0 0 1-60.330666-60.330666l64-64a42.666667 42.666667 0 0 1 60.330666 60.330666l-64 64z m576-576a42.666667 42.666667 0 0 1-60.330666-60.330666l64-64a42.666667 42.666667 0 0 1 60.330666 60.330666l-64 64z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default Light;
|
||||
20
packages/design/src/icons/more.tsx
Normal file
20
packages/design/src/icons/more.tsx
Normal file
|
|
@ -0,0 +1,20 @@
|
|||
import React from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { iconClassName } from './util';
|
||||
import type { IconProps } from './util';
|
||||
|
||||
const More = (props: IconProps) => {
|
||||
const { className, style } = props;
|
||||
return (
|
||||
<span className={classnames([iconClassName, className])} style={style}>
|
||||
<svg viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" width="1em" height="1em" fill="currentColor">
|
||||
<path d="M512 42.666667a469.333333 469.333333 0 1 0 469.333333 469.333333A469.333333 469.333333 0 0 0 512 42.666667z m0 864a394.666667 394.666667 0 1 1 394.666667-394.666667 395.146667 395.146667 0 0 1-394.666667 394.666667z"></path>
|
||||
<path d="M304.906667 512m-66.666667 0a66.666667 66.666667 0 1 0 133.333333 0 66.666667 66.666667 0 1 0-133.333333 0Z"></path>
|
||||
<path d="M512 512m-66.666667 0a66.666667 66.666667 0 1 0 133.333334 0 66.666667 66.666667 0 1 0-133.333334 0Z"></path>
|
||||
<path d="M719.093333 512m-66.666666 0a66.666667 66.666667 0 1 0 133.333333 0 66.666667 66.666667 0 1 0-133.333333 0Z"></path>
|
||||
</svg>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
||||
export default More;
|
||||
|
|
@ -1,25 +1,31 @@
|
|||
import React, { useEffect, useState } from 'react';
|
||||
import { Sketch } from './modules';
|
||||
import type { SketchProps } from './modules';
|
||||
import { Provider, createDesignContextValue } from './context';
|
||||
import type { DesignContext } from './context';
|
||||
import type { DesignData } from './types';
|
||||
import './css/index.less';
|
||||
|
||||
export const Design = () => {
|
||||
const [width, setWidth] = useState<number>(1000);
|
||||
const [height, setHeight] = useState<number>(600);
|
||||
export type DesignProps = SketchProps & {
|
||||
data?: DesignData;
|
||||
locale?: string; // TODO
|
||||
};
|
||||
|
||||
// const [width, setWidth] = useState<number>(window.innerWidth);
|
||||
// const [height, setHeight] = useState<number>(window.innerHeight);
|
||||
// useEffect(() => {
|
||||
// window.addEventListener('resize', () => {
|
||||
// const width = window.innerWidth;
|
||||
// const height = window.innerHeight;
|
||||
// setWidth(width);
|
||||
// setHeight(height);
|
||||
// });
|
||||
// }, []);
|
||||
export const Design = (props: DesignProps) => {
|
||||
const { width = 1000, height = 600, style, className, data } = props;
|
||||
const [contextValue, setContextValue] = useState<DesignContext>(createDesignContextValue({ data }));
|
||||
|
||||
useEffect(() => {
|
||||
if (data) {
|
||||
setContextValue({ ...contextValue, ...{ data } });
|
||||
}
|
||||
}, [data]);
|
||||
|
||||
return (
|
||||
<div style={{ position: 'fixed', left: 0, right: 0, width, height }}>
|
||||
<Sketch width={width} height={height} />
|
||||
</div>
|
||||
<Provider value={contextValue}>
|
||||
<Sketch width={width} height={height} style={style} className={className} />
|
||||
</Provider>
|
||||
);
|
||||
};
|
||||
|
||||
export * from './types';
|
||||
|
|
|
|||
|
|
@ -2,9 +2,8 @@ import React from 'react';
|
|||
import type { CSSProperties } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { createPrefixName } from '../../css';
|
||||
import './index.less';
|
||||
|
||||
const modName = 'mod-sketch';
|
||||
const modName = 'mod-xxx';
|
||||
|
||||
const prefixName = createPrefixName(modName);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,31 @@
|
|||
import React from 'react';
|
||||
import type { CSSProperties } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Switch from 'antd/es/switch';
|
||||
import { createPrefixName } from '../../css';
|
||||
import IconDark from '../../icons/dark';
|
||||
import IconLight from '../../icons/light';
|
||||
|
||||
const modName = 'mod-header';
|
||||
|
||||
const prefixName = createPrefixName(modName);
|
||||
|
||||
export interface ModProps {
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
}
|
||||
|
||||
export const Header = (props: ModProps) => {
|
||||
const { className, style } = props;
|
||||
return (
|
||||
<div style={style} className={classnames(prefixName(), className)}>
|
||||
<span>Header</span>
|
||||
<Switch
|
||||
className={prefixName('theme', 'switch')}
|
||||
checkedChildren={<IconLight style={{ height: '100%' }} />}
|
||||
unCheckedChildren={<IconDark style={{ height: '100%' }} />}
|
||||
defaultChecked
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
24
packages/design/src/modules/panel-layer/index.tsx
Normal file
24
packages/design/src/modules/panel-layer/index.tsx
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import React from 'react';
|
||||
import type { CSSProperties } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import { createPrefixName } from '../../css';
|
||||
|
||||
const modName = 'mod-panel-layer';
|
||||
|
||||
const prefixName = createPrefixName(modName);
|
||||
|
||||
export interface PanelLayerProps {
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
}
|
||||
|
||||
export const PanelLayer = (props: PanelLayerProps) => {
|
||||
const { className, style } = props;
|
||||
return (
|
||||
<div style={style} className={classnames(prefixName(), className)}>
|
||||
<div className={prefixName('header')}>header</div>
|
||||
<div className={prefixName('content')}>Panel Layer</div>
|
||||
<div className={prefixName('footer')}>footer</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
|
@ -5,8 +5,11 @@ import { calcElementsContextSize } from '@idraw/util';
|
|||
import Drawer from 'antd/es/drawer';
|
||||
import { getData } from '../../data';
|
||||
import { Toolbar } from '../toolbar';
|
||||
import { PanelLayer } from '../panel-layer';
|
||||
import { Header } from '../header';
|
||||
import type { CSSProperties } from 'react';
|
||||
import { createPrefixName } from '../../css';
|
||||
import { HEADER_HEIGHT } from './layout';
|
||||
|
||||
const modName = 'mod-sketch';
|
||||
const siderWidth = 200;
|
||||
|
|
@ -24,18 +27,19 @@ export const Sketch = (props: SketchProps) => {
|
|||
const ref = useRef<HTMLDivElement>(null);
|
||||
const refCore = useRef<Core | null>(null);
|
||||
const refLeftDOM = useRef<HTMLDivElement | null>(null);
|
||||
const refRighttDOM = useRef<HTMLDivElement | null>(null);
|
||||
const { className, style, width, height } = props;
|
||||
const data = getData();
|
||||
const devicePixelRatio = window.devicePixelRatio;
|
||||
|
||||
const [openLayer, setOpenLayer] = useState<boolean>(false);
|
||||
const [openSetting, setOpenSetting] = useState<boolean>(false);
|
||||
const [openLeftSider, setOpenLeftSider] = useState<boolean>(false);
|
||||
const [openRightSider, setOpenRightSider] = useState<boolean>(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (ref?.current) {
|
||||
const options = {
|
||||
width,
|
||||
height,
|
||||
height: height - HEADER_HEIGHT,
|
||||
devicePixelRatio
|
||||
};
|
||||
const core = new Core(ref.current, options);
|
||||
|
|
@ -55,40 +59,48 @@ export const Sketch = (props: SketchProps) => {
|
|||
const contextSize = calcElementsContextSize(data.elements, { viewWidth: width, viewHeight: height });
|
||||
core.resize({
|
||||
width,
|
||||
height,
|
||||
height: height - HEADER_HEIGHT,
|
||||
devicePixelRatio,
|
||||
...contextSize
|
||||
});
|
||||
}, [height, width]);
|
||||
|
||||
return (
|
||||
<div className={classnames(prefixName(), className)} style={style}>
|
||||
<div ref={ref}></div>
|
||||
<div className={classnames(prefixName(), className)} style={{ ...style, ...{ width, height, padding: 0 } }}>
|
||||
<div className={prefixName('header')} style={{ height: HEADER_HEIGHT }}>
|
||||
<Header />
|
||||
</div>
|
||||
<div ref={ref} className={prefixName('content')} style={{ top: HEADER_HEIGHT }}></div>
|
||||
<div ref={refLeftDOM}></div>
|
||||
<div ref={refRighttDOM}></div>
|
||||
<Toolbar
|
||||
className={prefixName('toolbar-position')}
|
||||
openLayer={openLayer}
|
||||
openSetting={openSetting}
|
||||
openLeftSider={openLeftSider}
|
||||
openRightSider={openRightSider}
|
||||
onClickToggleLayer={() => {
|
||||
setOpenLayer(openLayer ? false : true);
|
||||
setOpenLeftSider(openLeftSider ? false : true);
|
||||
}}
|
||||
onClickToggleSetting={() => {
|
||||
setOpenSetting(openSetting ? false : true);
|
||||
setOpenRightSider(openRightSider ? false : true);
|
||||
}}
|
||||
/>
|
||||
<div ref={refLeftDOM}></div>
|
||||
<Drawer
|
||||
title="left Drawer"
|
||||
// title="left Drawer"
|
||||
placement="left"
|
||||
closable={false}
|
||||
onClose={() => {
|
||||
console.log('on close left');
|
||||
setOpenLayer(false);
|
||||
setOpenLeftSider(false);
|
||||
}}
|
||||
mask={false}
|
||||
open={openLayer}
|
||||
open={openLeftSider}
|
||||
getContainer={() => {
|
||||
return refLeftDOM.current as HTMLDivElement;
|
||||
}}
|
||||
width={siderWidth}
|
||||
bodyStyle={{
|
||||
padding: 0
|
||||
}}
|
||||
rootStyle={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
|
|
@ -96,21 +108,19 @@ export const Sketch = (props: SketchProps) => {
|
|||
left: 0
|
||||
}}
|
||||
>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
<p>Some contents...</p>
|
||||
<PanelLayer />
|
||||
</Drawer>
|
||||
<Drawer
|
||||
title="right Drawer"
|
||||
placement="right"
|
||||
onClose={() => {
|
||||
console.log('on close right');
|
||||
setOpenSetting(false);
|
||||
setOpenRightSider(false);
|
||||
}}
|
||||
mask={false}
|
||||
open={openSetting}
|
||||
open={openRightSider}
|
||||
getContainer={() => {
|
||||
return refLeftDOM.current as HTMLDivElement;
|
||||
return refRighttDOM.current as HTMLDivElement;
|
||||
}}
|
||||
width={siderWidth}
|
||||
rootStyle={{
|
||||
|
|
|
|||
1
packages/design/src/modules/sketch/layout.ts
Normal file
1
packages/design/src/modules/sketch/layout.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export const HEADER_HEIGHT = 36;
|
||||
|
|
@ -10,6 +10,7 @@ import IconHand from '../../icons/hand';
|
|||
import IconScale from '../../icons/scale';
|
||||
import IconLayer from '../../icons/layer';
|
||||
import IconSetting from '../../icons/setting';
|
||||
import IconMore from '../../icons/more';
|
||||
|
||||
const RadioButton = Radio.Button;
|
||||
const RadioGroup = Radio.Group;
|
||||
|
|
@ -20,21 +21,21 @@ const prefixName = createPrefixName(modName);
|
|||
export interface ToolbarProps {
|
||||
className?: string;
|
||||
style?: CSSProperties;
|
||||
openLayer: boolean;
|
||||
openSetting: boolean;
|
||||
openLeftSider: boolean;
|
||||
openRightSider: boolean;
|
||||
onClickToggleLayer?: () => void;
|
||||
onClickToggleSetting?: () => void;
|
||||
}
|
||||
|
||||
export const Toolbar = (props: ToolbarProps) => {
|
||||
const { className, style, openLayer, openSetting, onClickToggleLayer, onClickToggleSetting } = props;
|
||||
const { className, style, openLeftSider, openRightSider, onClickToggleLayer, onClickToggleSetting } = props;
|
||||
const [mode, setMode] = useState<string>('select');
|
||||
const iconStyle = { fontSize: 20 };
|
||||
|
||||
return (
|
||||
<div style={style} className={classnames(prefixName(), className)}>
|
||||
<div className={prefixName('left')}>
|
||||
<Button shape="circle" type={openLayer ? 'primary' : 'default'} icon={<IconLayer style={iconStyle} />} onClick={onClickToggleLayer} />
|
||||
<Button shape="circle" type={openLeftSider ? 'primary' : 'default'} icon={<IconLayer style={iconStyle} />} onClick={onClickToggleLayer} />
|
||||
</div>
|
||||
<RadioGroup className={classnames(prefixName('middle'), prefixName('mode-switch'))} value={mode} onChange={(e) => setMode(e.target.value)}>
|
||||
<RadioButton value="select">
|
||||
|
|
@ -49,9 +50,12 @@ export const Toolbar = (props: ToolbarProps) => {
|
|||
<RadioButton value="scale">
|
||||
<IconScale style={iconStyle} />
|
||||
</RadioButton>
|
||||
<RadioButton value="more">
|
||||
<IconMore style={iconStyle} />
|
||||
</RadioButton>
|
||||
</RadioGroup>
|
||||
<div className={prefixName('right')}>
|
||||
<Button shape="circle" type={openSetting ? 'primary' : 'default'} icon={<IconSetting style={iconStyle} />} onClick={onClickToggleSetting} />
|
||||
<Button shape="circle" type={openRightSider ? 'primary' : 'default'} icon={<IconSetting style={iconStyle} />} onClick={onClickToggleSetting} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
34
packages/design/src/types/data.ts
Normal file
34
packages/design/src/types/data.ts
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
import type { Element, ElementType, ElementSize, ElementBaseDesc } from '@idraw/types';
|
||||
|
||||
export type DesignComponent = Omit<ElementSize, 'angle'> & {
|
||||
uuid: string;
|
||||
type: 'component';
|
||||
name?: string;
|
||||
desc?: ElementBaseDesc & {
|
||||
children: Array<Element<ElementType> | DesignComponent>;
|
||||
};
|
||||
};
|
||||
|
||||
export type DesignModule = Omit<ElementSize, 'angle'> & {
|
||||
uuid: string;
|
||||
type: 'module';
|
||||
name?: string;
|
||||
desc?: ElementBaseDesc & {
|
||||
children: Array<DesignComponent>;
|
||||
};
|
||||
};
|
||||
|
||||
export type DesignPage = Omit<ElementSize, 'angle'> & {
|
||||
uuid: string;
|
||||
type: 'page';
|
||||
name?: string;
|
||||
desc: ElementBaseDesc & {
|
||||
children: Array<DesignModule>;
|
||||
};
|
||||
};
|
||||
|
||||
export interface DesignData {
|
||||
components: DesignComponent[];
|
||||
modules: DesignModule[];
|
||||
pages: DesignPage[];
|
||||
}
|
||||
1
packages/design/src/types/index.ts
Normal file
1
packages/design/src/types/index.ts
Normal file
|
|
@ -0,0 +1 @@
|
|||
export * from './data';
|
||||
|
|
@ -6,7 +6,7 @@ export interface ElementSize {
|
|||
angle?: number;
|
||||
}
|
||||
|
||||
interface ElementBaseDesc {
|
||||
export interface ElementBaseDesc {
|
||||
borderWidth?: number;
|
||||
borderColor?: string;
|
||||
borderRadius?: number;
|
||||
|
|
@ -14,13 +14,17 @@ interface ElementBaseDesc {
|
|||
shadowOffsetX?: number;
|
||||
shadowOffsetY?: number;
|
||||
shadowBlur?: number;
|
||||
}
|
||||
|
||||
interface ElementRectDesc extends ElementBaseDesc {
|
||||
color?: string;
|
||||
bgColor?: string;
|
||||
}
|
||||
|
||||
// interface ElementRectDesc extends ElementBaseDesc {
|
||||
// // color?: string;
|
||||
// // bgColor?: string;
|
||||
// }
|
||||
|
||||
type ElementRectDesc = ElementBaseDesc;
|
||||
|
||||
interface ElemenTextDesc extends ElementBaseDesc {
|
||||
text: string;
|
||||
color: string;
|
||||
|
|
|
|||
Loading…
Reference in a new issue