parent
71ea3834da
commit
152495d379
@ -0,0 +1,50 @@ |
||||
// Nie 2023/2/8 元素添加迭代递归渲染 |
||||
|
||||
import {useEffect, useState} from "react"; |
||||
import css from './index.module.scss'; |
||||
import {defaultStore} from "@/store/index.js"; |
||||
|
||||
export default function Atom(props) { |
||||
const AtomList = props.AtomList; |
||||
const [boxState, setBoxState] = useState(new Array(AtomList.length).fill(false)); |
||||
// 打开关闭标签 |
||||
function handleChangeBoxState(index){ |
||||
const temporaryState = new Array(boxState.length).fill(false); |
||||
if(!boxState[index]){ |
||||
temporaryState[index] = true; |
||||
} |
||||
setBoxState(temporaryState) |
||||
} |
||||
// 添加元素 |
||||
function handleAddElement(item){ |
||||
defaultStore.setNewElementIdentify(item.identify) |
||||
} |
||||
useEffect(() => { |
||||
if(props.state){ |
||||
setBoxState(new Array(boxState.length).fill(false)) |
||||
} |
||||
}, [props.state]) |
||||
return AtomList.map((item, index) => { |
||||
if (item.children && Array.isArray(item.children)) { |
||||
return <div key={index} className={css.atomBox}> |
||||
<div className={css.atomTitle} onClick={() => handleChangeBoxState(index)}>{item.name}</div> |
||||
<div className={boxState[index] ? [css.atomSon, css.atomBoxOpen].join(' ') : css.atomSon}> |
||||
<div className={css.atomDescribe}>{item.describe}</div> |
||||
<div>{Atom({AtomList: item.children, state: boxState[index]})}</div> |
||||
</div> |
||||
</div> |
||||
} else { |
||||
return <div key={index} className={css.atomBox}> |
||||
<div className={css.atomTitle}> |
||||
<div className={css.text} onClick={() => handleChangeBoxState(index)}>{item.name}</div> |
||||
<div className={css.cmd}> |
||||
<div onClick={() => handleAddElement(item)}>+</div> |
||||
</div> |
||||
</div> |
||||
<div className={boxState[index] ? [css.atomSon, css.atomBoxOpen].join(' ') : css.atomSon}> |
||||
<div className={css.atomDescribe}>{item.describe}</div> |
||||
</div> |
||||
</div> |
||||
} |
||||
}) |
||||
} |
@ -0,0 +1,84 @@ |
||||
@import '@/assets/default.scss'; |
||||
|
||||
$open: open; |
||||
$close: close; |
||||
|
||||
.atomBox { |
||||
position: relative; |
||||
margin: 0.5rem 0; |
||||
padding-left: 0.5rem; |
||||
|
||||
|
||||
.atomTitle { |
||||
@include font-serif; |
||||
font-weight: 600; |
||||
cursor: pointer; |
||||
display: flex; |
||||
|
||||
& > div.text { |
||||
position: relative; |
||||
white-space: nowrap; |
||||
flex: 1; |
||||
} |
||||
|
||||
& > div.cmd { |
||||
position: relative; |
||||
flex-shrink: 0; |
||||
width: 40px; |
||||
@include font-mono; |
||||
font-size: 30px; |
||||
} |
||||
} |
||||
|
||||
.atomSon { |
||||
position: relative; |
||||
overflow: hidden; |
||||
//padding: 1rem 0; |
||||
box-sizing: border-box; |
||||
max-height: 0; |
||||
animation: close linear 300ms; |
||||
|
||||
& > div.atomDescribe { |
||||
position: relative; |
||||
white-space: nowrap; |
||||
font-size: 14px; |
||||
padding-left: 1.2rem; |
||||
color: #666; |
||||
|
||||
&:before { |
||||
content: ""; |
||||
position: absolute; |
||||
left: 0.7rem; |
||||
width: 0.3rem; |
||||
height: 100%; |
||||
background: #1a1a1a; |
||||
} |
||||
} |
||||
} |
||||
|
||||
.atomBoxOpen { |
||||
animation: open ease-in-out 300ms forwards; |
||||
|
||||
&:hover { |
||||
overflow: overlay; |
||||
} |
||||
} |
||||
} |
||||
|
||||
@keyframes open { |
||||
from { |
||||
max-height: 0; |
||||
} |
||||
to { |
||||
max-height: 300px; |
||||
} |
||||
} |
||||
|
||||
@keyframes close { |
||||
to { |
||||
max-height: 0; |
||||
} |
||||
from { |
||||
max-height: 300px; |
||||
} |
||||
} |
@ -1,4 +1,7 @@ |
||||
import icon from '../assets/react.svg' |
||||
|
||||
|
||||
|
||||
export const config = { |
||||
projectName:'西安升帮联创技术服务有限公司', |
||||
icon, |
||||
|
@ -0,0 +1,230 @@ |
||||
// 从元素模板中获取指定元素
|
||||
export function getTargetElement(identify, AtomTemplate){ |
||||
let element = null; |
||||
for(let i in AtomTemplate){ |
||||
if(AtomTemplate[i].identify == identify){ |
||||
element = AtomTemplate[i]; |
||||
break |
||||
}else if(Array.isArray(AtomTemplate[i].children)){ |
||||
const s = getTargetElement(identify, AtomTemplate[i].children); |
||||
if(s) element = s |
||||
} |
||||
} |
||||
return element |
||||
} |
||||
|
||||
|
||||
// 框架基础属性
|
||||
const style1 = [ |
||||
'background', |
||||
'backdrop-filter', |
||||
'position', |
||||
'top', |
||||
'bottom', |
||||
'left', |
||||
'right', |
||||
'width', |
||||
'height', |
||||
'margin', |
||||
'padding', |
||||
'border', |
||||
'border-radius', |
||||
'href',// 跳转
|
||||
'overflow', |
||||
'全剧中', |
||||
] |
||||
// 文字属性
|
||||
const style2 = [ |
||||
'color', 'font-size', 'font-weight', '是否换行', '下划线', '首行缩进', 'line-height', 'text-align' |
||||
] |
||||
|
||||
|
||||
// 元素原型
|
||||
export class NE { |
||||
constructor() { |
||||
return [ |
||||
{ |
||||
name: '框架',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "此类元素为页面提供骨架",// 描述
|
||||
identify: 'frame',// 标识
|
||||
config: {}, |
||||
depth: '', |
||||
children: [ |
||||
{ |
||||
name: '单元素结构',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "此结构仅可容纳一个子元素",// 描述
|
||||
identify: 'singleFrame',// 标识
|
||||
config: { |
||||
childrenLength: 1, |
||||
childrenType: 'element', |
||||
middle: '中间件', |
||||
style: [...style1], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
childElement: [] |
||||
}, { |
||||
name: '横向多元素结构',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "此结构可在横向上排列多个子元素",// 描述
|
||||
identify: 'transverseFrame',// 标识
|
||||
config: { |
||||
childrenLength: 'n', |
||||
childrenType: 'element', |
||||
middle: '中间件', |
||||
style: [...style1, 'flex'], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
childElement: [] |
||||
}, { |
||||
name: '纵向多元素结构',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "此结构可在纵向上排列多个子元素",// 描述
|
||||
identify: 'longitudinalFrame',// 标识
|
||||
config: { |
||||
childrenLength: 'n', |
||||
childrenType: 'element', |
||||
middle: '中间件', |
||||
style: [...style1, 'flex'], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
childElement: [] |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
name: '内元素',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "",// 描述
|
||||
identify: 'innerElement',// 标识
|
||||
config: {}, |
||||
depth: '', |
||||
children: [ |
||||
{ |
||||
name: '行内文本',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "",// 描述
|
||||
identify: 'span',// 标识
|
||||
config: { |
||||
childrenType: 'text', |
||||
middle: '中间件', |
||||
style: [...style2], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
}, { |
||||
name: '块文本',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "",// 描述
|
||||
identify: 'blockText',// 标识
|
||||
config: { |
||||
childrenType: 'text', |
||||
middle: '中间件', |
||||
style: [...style2, 'flex'], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
}, { |
||||
name: '图像',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "",// 描述
|
||||
identify: 'image',// 标识
|
||||
config: { |
||||
childrenType: 'images', |
||||
middle: '中间件', |
||||
style: [...style1, 'flex'], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
}, { |
||||
name: '视频',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "",// 描述
|
||||
identify: 'video',// 标识
|
||||
config: { |
||||
childrenType: 'video', |
||||
middle: '中间件', |
||||
style: [...style2, 'flex'], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
} |
||||
] |
||||
}, |
||||
{ |
||||
name: '输入元素',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "信息录入元素",// 描述
|
||||
identify: 'input',// 标识
|
||||
config: {}, |
||||
depth: '', |
||||
children: [ |
||||
{ |
||||
name: '基本输入',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "单行文本输入",// 描述
|
||||
identify: 'input-text',// 标识
|
||||
config: { |
||||
childrenType: 'text', |
||||
middle: '中间件', |
||||
style: [...style2], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
}, { |
||||
name: '块输入',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "多行文本输入",// 描述
|
||||
identify: 'input-textarea',// 标识
|
||||
config: { |
||||
childrenType: 'text', |
||||
middle: '中间件', |
||||
style: [...style2, 'flex'], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
}, { |
||||
name: '代码块',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "等宽字体的代码多行输入",// 描述
|
||||
identify: 'input-code',// 标识
|
||||
config: { |
||||
childrenType: 'text', |
||||
middle: '中间件', |
||||
style: [...style1, 'flex'], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
}, { |
||||
name: '等待开发',// 元素名称
|
||||
// dir:true,// 是否为叶子节点
|
||||
describe: "可拓展的输入选项",// 描述
|
||||
identify: 'nomal',// 标识
|
||||
config: { |
||||
childrenType: 'text', |
||||
middle: '中间件', |
||||
style: [...style2, 'flex'], |
||||
styleLimit: {}, |
||||
event: {} |
||||
}, |
||||
depth: '', |
||||
} |
||||
] |
||||
}, |
||||
]; |
||||
} |
||||
} |
Loading…
Reference in new issue