mirror of
https://github.com/MrXujiang/h5-Dooring.git
synced 2025-12-15 20:52:49 +00:00
🆕 添加icon组件库 📦 添加package.json说明日志
This commit is contained in:
parent
f4f2a2ebaa
commit
b89af1975b
23
package.json
23
package.json
@ -1,9 +1,22 @@
|
||||
{
|
||||
"name": "h5-Dooring",
|
||||
"version": "1.2.0",
|
||||
"name": "h5-dooring",
|
||||
"version": "1.3.0",
|
||||
"description": "H5-Dooring是一款功能强大,开源免费的H5可视化页面配置解决方案,致力于提供一套简单方便、专业可靠、无限可能的H5落地页最佳实践。技术栈以react为主, 后台采用nodejs开发。",
|
||||
"private": false,
|
||||
"license": "MIT",
|
||||
"author": {
|
||||
"name": "徐小夕",
|
||||
"email": "xujiang156@qq.com",
|
||||
"url": "http://io.nainor.com/h5_visible"
|
||||
},
|
||||
"keywords": [
|
||||
"h5 editor",
|
||||
"h5",
|
||||
"react",
|
||||
"antd",
|
||||
"react-dnd",
|
||||
"web visible"
|
||||
],
|
||||
"contributors": ["yehuozhili <yehuozhili@outlook.com> (https://github.com/yehuozhili))"],
|
||||
"scripts": {
|
||||
"start": "umi dev",
|
||||
"build": "umi build",
|
||||
@ -23,6 +36,7 @@
|
||||
"prettier --parser=typescript --write"
|
||||
]
|
||||
},
|
||||
"homepage": "http://io.nainor.com/h5_visible",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git+https://github.com/MrXujiang/h5-Dooring.git"
|
||||
@ -58,5 +72,6 @@
|
||||
"video-react": "^0.14.1",
|
||||
"yorkie": "^2.0.0",
|
||||
"zarm": "^2.5.1"
|
||||
}
|
||||
},
|
||||
"license": "MIT"
|
||||
}
|
||||
|
||||
38
src/components/CardPicker/index.js
Normal file
38
src/components/CardPicker/index.js
Normal file
@ -0,0 +1,38 @@
|
||||
import { useState, useEffect, memo } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Icon from '../Icon';
|
||||
import styles from './index.less';
|
||||
|
||||
export default memo(props => {
|
||||
const { type, icons, onChange } = props;
|
||||
|
||||
const [selected, setSelected] = useState(type);
|
||||
|
||||
const handlePicker = v => {
|
||||
if (onChange) {
|
||||
onChange(v);
|
||||
return;
|
||||
}
|
||||
setSelected(v);
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
setSelected(type);
|
||||
}, [type]);
|
||||
|
||||
return (
|
||||
<div className={styles.pickerWrap}>
|
||||
{icons.map((item, i) => {
|
||||
return (
|
||||
<span
|
||||
className={classnames(styles.picker, selected === item ? styles.selected : '')}
|
||||
onClick={handlePicker.bind(this, item)}
|
||||
key={i}
|
||||
>
|
||||
<Icon type={item} size={20} />
|
||||
</span>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
16
src/components/CardPicker/index.less
Normal file
16
src/components/CardPicker/index.less
Normal file
@ -0,0 +1,16 @@
|
||||
.pickerWrap {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
.picker {
|
||||
display: inline-block;
|
||||
padding: 10px;
|
||||
border: 2px solid transparent;
|
||||
cursor: pointer;
|
||||
&:hover {
|
||||
border-color: #4091f7;
|
||||
}
|
||||
&.selected {
|
||||
border-color: #4091f7;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -145,6 +145,8 @@ export default {
|
||||
key: 'imgSize',
|
||||
name: '图片大小',
|
||||
type: 'Number',
|
||||
isCrop: true,
|
||||
cropRate: 1,
|
||||
},
|
||||
{
|
||||
key: 'sourceData',
|
||||
@ -271,6 +273,8 @@ export default {
|
||||
key: 'qrcode',
|
||||
name: '二维码',
|
||||
type: 'Upload',
|
||||
isCrop: true,
|
||||
cropRate: 1,
|
||||
},
|
||||
{
|
||||
key: 'text',
|
||||
@ -364,6 +368,7 @@ export default {
|
||||
key: 'imgUrl',
|
||||
name: '上传',
|
||||
type: 'Upload',
|
||||
isCrop: false,
|
||||
},
|
||||
{
|
||||
key: 'round',
|
||||
@ -399,6 +404,8 @@ export default {
|
||||
key: 'logo',
|
||||
name: 'logo',
|
||||
type: 'Upload',
|
||||
isCrop: true,
|
||||
cropRate: 1000 / 618,
|
||||
},
|
||||
{
|
||||
key: 'logoText',
|
||||
@ -519,6 +526,79 @@ export default {
|
||||
color: 'rgba(153,153,153,1)',
|
||||
},
|
||||
},
|
||||
Icon: {
|
||||
editData: [
|
||||
{
|
||||
key: 'color',
|
||||
name: '颜色',
|
||||
type: 'Color',
|
||||
},
|
||||
{
|
||||
key: 'size',
|
||||
name: '大小',
|
||||
type: 'Number',
|
||||
},
|
||||
{
|
||||
key: 'spin',
|
||||
name: '旋转动画',
|
||||
type: 'Switch',
|
||||
},
|
||||
{
|
||||
key: 'type',
|
||||
name: '图标类型',
|
||||
type: 'CardPicker',
|
||||
icons: [
|
||||
'AccountBookTwoTone',
|
||||
'AlertTwoTone',
|
||||
'ApiTwoTone',
|
||||
'AppstoreTwoTone',
|
||||
'AudioTwoTone',
|
||||
'BankTwoTone',
|
||||
'BellTwoTone',
|
||||
'BookTwoTone',
|
||||
'BugTwoTone',
|
||||
'BuildTwoTone',
|
||||
'BulbTwoTone',
|
||||
'CalculatorTwoTone',
|
||||
'CalendarTwoTone',
|
||||
'CameraTwoTone',
|
||||
'CarTwoTone',
|
||||
'CarryOutTwoTone',
|
||||
'CiCircleTwoTone',
|
||||
'CloudTwoTone',
|
||||
'CodeTwoTone',
|
||||
'CrownTwoTone',
|
||||
'CustomerServiceTwoTone',
|
||||
'DollarCircleTwoTone',
|
||||
'EnvironmentTwoTone',
|
||||
'ExperimentTwoTone',
|
||||
'FireTwoTone',
|
||||
'GiftTwoTone',
|
||||
'InsuranceTwoTone',
|
||||
'LikeTwoTone',
|
||||
'LockTwoTone',
|
||||
'MailTwoTone',
|
||||
'MessageTwoTone',
|
||||
'PhoneTwoTone',
|
||||
'PictureTwoTone',
|
||||
'PlaySquareTwoTone',
|
||||
'RedEnvelopeTwoTone',
|
||||
'ShopTwoTone',
|
||||
'TrademarkCircleTwoTone',
|
||||
'StarTwoTone',
|
||||
'SafetyCertificateTwoTone',
|
||||
'SettingTwoTone',
|
||||
'RocketTwoTone',
|
||||
],
|
||||
},
|
||||
],
|
||||
config: {
|
||||
color: '',
|
||||
size: 36,
|
||||
spin: false,
|
||||
type: 'CarTwoTone',
|
||||
},
|
||||
},
|
||||
Video: {
|
||||
editData: [
|
||||
{
|
||||
|
||||
@ -1,40 +1,44 @@
|
||||
const template = [
|
||||
{
|
||||
type:'Text',
|
||||
h: 20
|
||||
{
|
||||
type: 'Text',
|
||||
h: 20,
|
||||
},
|
||||
{
|
||||
type:'Carousel',
|
||||
h: 82
|
||||
{
|
||||
type: 'Carousel',
|
||||
h: 82,
|
||||
},
|
||||
{
|
||||
type:'Tab',
|
||||
h: 130
|
||||
{
|
||||
type: 'Tab',
|
||||
h: 130,
|
||||
},
|
||||
{
|
||||
type:'Notice',
|
||||
h: 20
|
||||
{
|
||||
type: 'Notice',
|
||||
h: 20,
|
||||
},
|
||||
{
|
||||
type:'Qrcode',
|
||||
h: 150
|
||||
{
|
||||
type: 'Qrcode',
|
||||
h: 150,
|
||||
},
|
||||
{
|
||||
type:'Footer',
|
||||
h: 24
|
||||
{
|
||||
type: 'Icon',
|
||||
h: 23,
|
||||
},
|
||||
{
|
||||
type:'Image',
|
||||
h: 188
|
||||
{
|
||||
type: 'Image',
|
||||
h: 188,
|
||||
},
|
||||
{
|
||||
type:'Header',
|
||||
h: 28
|
||||
{
|
||||
type: 'Header',
|
||||
h: 28,
|
||||
},
|
||||
{
|
||||
type:'List',
|
||||
h: 110
|
||||
}
|
||||
]
|
||||
{
|
||||
type: 'List',
|
||||
h: 110,
|
||||
},
|
||||
{
|
||||
type: 'Footer',
|
||||
h: 24,
|
||||
},
|
||||
];
|
||||
|
||||
export default template
|
||||
export default template;
|
||||
|
||||
@ -1,17 +1,10 @@
|
||||
import React, { memo, useState, useEffect } from 'react';
|
||||
import {
|
||||
Form,
|
||||
Select,
|
||||
InputNumber,
|
||||
Input,
|
||||
Switch,
|
||||
Radio,
|
||||
Button
|
||||
} from 'antd';
|
||||
import { Form, Select, InputNumber, Input, Switch, Radio, Button } from 'antd';
|
||||
import Upload from '@/components/Upload';
|
||||
import DataList from '@/components/DataList';
|
||||
import MutiText from '@/components/MutiText';
|
||||
import Color from '@/components/Color';
|
||||
import CardPicker from '@/components/CardPicker';
|
||||
|
||||
// import styles from './index.less';
|
||||
const normFile = e => {
|
||||
@ -29,32 +22,24 @@ const formItemLayout = {
|
||||
wrapperCol: { span: 16 },
|
||||
};
|
||||
|
||||
const defaultConfig = [
|
||||
{
|
||||
"key": "tabs",
|
||||
"name": "项目类别",
|
||||
"type": "mutiText",
|
||||
"defaultValue": ["类别一", "类别二"]
|
||||
}
|
||||
]
|
||||
const FormEditor = props => {
|
||||
const { config, defaultValue, onSave, onDel, uid } = props;
|
||||
|
||||
const FormEditor = (props) => {
|
||||
const { config = defaultConfig, defaultValue, onSave, onDel, uid } = props
|
||||
const onFinish = values => {
|
||||
onSave && onSave(values)
|
||||
}
|
||||
onSave && onSave(values);
|
||||
};
|
||||
|
||||
const handleDel = () => {
|
||||
onDel && onDel(uid)
|
||||
}
|
||||
onDel && onDel(uid);
|
||||
};
|
||||
|
||||
const [form] = Form.useForm()
|
||||
const [form] = Form.useForm();
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
form.resetFields()
|
||||
}
|
||||
}, [defaultValue])
|
||||
form.resetFields();
|
||||
};
|
||||
}, [defaultValue]);
|
||||
|
||||
return (
|
||||
<Form
|
||||
@ -64,83 +49,88 @@ const FormEditor = (props) => {
|
||||
onFinish={onFinish}
|
||||
initialValues={defaultValue}
|
||||
>
|
||||
{
|
||||
config.map((item, i) => {
|
||||
return <React.Fragment key={i}>
|
||||
{
|
||||
item.type === 'Number' &&
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<InputNumber min={1} />
|
||||
</Form.Item>
|
||||
}
|
||||
{
|
||||
item.type === 'Text' &&
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
}
|
||||
{
|
||||
item.type === 'DataList' &&
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<DataList />
|
||||
</Form.Item>
|
||||
}
|
||||
{
|
||||
item.type === 'Color' &&
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<Color />
|
||||
</Form.Item>
|
||||
}
|
||||
{
|
||||
item.type === 'MutiText' &&
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<MutiText />
|
||||
</Form.Item>
|
||||
}
|
||||
{
|
||||
item.type === 'Select' &&
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<Select placeholder="请选择">
|
||||
{
|
||||
item.range.map((v, i) => {
|
||||
return <Option value={v.key} key={i}>{ v.text }</Option>
|
||||
})
|
||||
}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
}
|
||||
{
|
||||
item.type === 'Radio' &&
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<Radio.Group>
|
||||
{
|
||||
item.range.map((v, i) => {
|
||||
return <Radio value={v.key} key={i}>{ v.text }</Radio>
|
||||
})
|
||||
}
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
}
|
||||
{
|
||||
item.type === 'Switch' &&
|
||||
<Form.Item label={item.name} name={item.key} valuePropName="checked">
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
}
|
||||
{
|
||||
item.type === 'Upload' &&
|
||||
<Form.Item label={item.name} name={item.key} valuePropName="fileList" getValueFromEvent={normFile}>
|
||||
<Upload />
|
||||
</Form.Item>
|
||||
}
|
||||
{config.map((item, i) => {
|
||||
return (
|
||||
<React.Fragment key={i}>
|
||||
{item.type === 'Number' && (
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<InputNumber min={1} max={item.range && item.range[1]} />
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'Text' && (
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<Input />
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'DataList' && (
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<DataList />
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'Color' && (
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<Color />
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'MutiText' && (
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<MutiText />
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'Select' && (
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<Select placeholder="请选择">
|
||||
{item.range.map((v, i) => {
|
||||
return (
|
||||
<Option value={v.key} key={i}>
|
||||
{v.text}
|
||||
</Option>
|
||||
);
|
||||
})}
|
||||
</Select>
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'Radio' && (
|
||||
<Form.Item label={item.name} name={item.key}>
|
||||
<Radio.Group>
|
||||
{item.range.map((v, i) => {
|
||||
return (
|
||||
<Radio value={v.key} key={i}>
|
||||
{v.text}
|
||||
</Radio>
|
||||
);
|
||||
})}
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'Switch' && (
|
||||
<Form.Item label={item.name} name={item.key} valuePropName="checked">
|
||||
<Switch />
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'Upload' && (
|
||||
<Form.Item
|
||||
label={item.name}
|
||||
name={item.key}
|
||||
valuePropName="fileList"
|
||||
getValueFromEvent={normFile}
|
||||
>
|
||||
<Upload cropRate={item.cropRate} isCrop={item.isCrop} />
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'CardPicker' && (
|
||||
<Form.Item label={item.name} name={item.key} valuePropName="type">
|
||||
<CardPicker icons={item.icons} />
|
||||
</Form.Item>
|
||||
)}
|
||||
</React.Fragment>
|
||||
})
|
||||
}
|
||||
);
|
||||
})}
|
||||
<Form.Item wrapperCol={{ span: 12, offset: 6 }}>
|
||||
<Button type="primary" htmlType="submit">
|
||||
保存
|
||||
</Button>
|
||||
<Button type="danger" style={{marginLeft: '20px'}} onClick={handleDel}>
|
||||
<Button type="danger" style={{ marginLeft: '20px' }} onClick={handleDel}>
|
||||
删除
|
||||
</Button>
|
||||
</Form.Item>
|
||||
@ -148,4 +138,4 @@ const FormEditor = (props) => {
|
||||
);
|
||||
};
|
||||
|
||||
export default memo(FormEditor)
|
||||
export default memo(FormEditor);
|
||||
|
||||
20
src/components/Icon/index.js
Normal file
20
src/components/Icon/index.js
Normal file
@ -0,0 +1,20 @@
|
||||
import { memo } from 'react';
|
||||
import * as Icon from '@ant-design/icons';
|
||||
import IconImg from 'assets/icon.png';
|
||||
|
||||
const XIcon = memo(props => {
|
||||
const { color, size, type, spin, isTpl } = props;
|
||||
|
||||
const MyIcon = Icon[type];
|
||||
|
||||
return isTpl ? (
|
||||
<div style={{ textAlign: 'center' }}>
|
||||
<img style={{ verticalAlign: '-20px', width: '82px' }} src={IconImg} alt={type} />
|
||||
图标
|
||||
</div>
|
||||
) : (
|
||||
<MyIcon twoToneColor={color} style={{ fontSize: size }} spin={spin} />
|
||||
);
|
||||
});
|
||||
|
||||
export default XIcon;
|
||||
@ -20,7 +20,8 @@ const SourceBox = memo(props => {
|
||||
pointEnd = monitor.getSourceClientOffset(),
|
||||
y = pointEnd.y < top ? 0 : pointEnd.y - top,
|
||||
col = 24, // 网格列数
|
||||
cellHeight = 2;
|
||||
cellHeight = 2,
|
||||
w = item.type === 'Icon' ? 3 : col;
|
||||
// 转换成网格规则的坐标和大小
|
||||
let gridY = Math.ceil(y / cellHeight);
|
||||
dispatch({
|
||||
@ -28,7 +29,7 @@ const SourceBox = memo(props => {
|
||||
payload: {
|
||||
id: uuid(6, 10),
|
||||
item,
|
||||
point: { i: `x-${pointData.length}`, x: 0, y: gridY, w: col, h: item.h, isBounded: true },
|
||||
point: { i: `x-${pointData.length}`, x: 0, y: gridY, w, h: item.h, isBounded: true },
|
||||
},
|
||||
});
|
||||
},
|
||||
|
||||
@ -6,7 +6,7 @@ import schema from 'components/DynamicEngine/schema';
|
||||
import styles from './index.less';
|
||||
|
||||
const TargetBox = memo(props => {
|
||||
const { item, dispatch, canvasId, pointData } = props;
|
||||
const { item, dispatch, pointData } = props;
|
||||
const [{ isDragging }, drag, preview] = useDrag({
|
||||
item: {
|
||||
type: item.type,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user