🆕 添加右键菜单,支持删除和复制组件 🆕 添加帮助引导

This commit is contained in:
xujiang 2020-11-05 23:35:18 +08:00
parent a7132c2c99
commit 68eedbd245
14 changed files with 212 additions and 47 deletions

View File

@ -34,6 +34,10 @@ export default defineConfig({
path: '/ide',
component: '../pages/ide',
},
{
path: '/help',
component: '../pages/help',
},
{
path: '/login',
component: '../pages/login',

View File

@ -70,6 +70,7 @@
"react": "^16.12.0",
"react-codemirror2": "^7.2.1",
"react-color": "^2.18.1",
"react-contexify": "^4.1.1",
"react-dnd": "^11.1.3",
"react-dnd-html5-backend": "^11.1.3",
"react-dom": "^16.12.0",

BIN
src/assets/1.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
src/assets/2.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 62 KiB

BIN
src/assets/3.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 144 KiB

BIN
src/assets/4.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
src/assets/5.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

BIN
src/assets/6.png Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

View File

@ -2,13 +2,14 @@ import React, { memo, useCallback, useContext, useEffect, useMemo, useState } fr
import { useDrop } from 'react-dnd';
import Draggable, { DraggableData, DraggableEvent } from 'react-draggable';
import GridLayout, { ItemCallback } from 'react-grid-layout';
import { Tooltip } from 'antd';
import { connect } from 'dva';
import DynamicEngine from 'components/DynamicEngine';
import styles from './index.less';
import { uuid } from '@/utils/tool';
import { Dispatch } from 'umi';
import { StateWithHistory } from 'redux-undo';
import { Menu, Item, MenuProvider } from 'react-contexify';
import 'react-contexify/dist/ReactContexify.min.css';
import { dooringContext } from '@/layouts';
interface SourceBoxProps {
pstate: { pointData: { id: string; item: any; point: any; isMenu?: any }[]; curPoint: any };
@ -148,6 +149,43 @@ const SourceBox = memo((props: SourceBoxProps) => {
}))
);
};
const handleContextMenuDel = () => {
if (pstate.curPoint) {
dispatch({
type: 'editorModal/delPointData',
payload: { id: pstate.curPoint.id },
});
}
};
const handleContextMenuCopy = () => {
if (pstate.curPoint) {
dispatch({
type: 'editorModal/copyPointData',
payload: { id: pstate.curPoint.id },
});
}
};
const onConTextClick = (type: string) => {
if (type === 'del') {
handleContextMenuDel();
} else if (type === 'copy') {
handleContextMenuCopy();
}
};
const MyAwesomeMenu = useCallback(
() => (
<Menu id="menu_id">
<Item onClick={() => onConTextClick('copy')}></Item>
<Item onClick={() => onConTextClick('del')}></Item>
</Menu>
),
[onConTextClick],
);
useEffect(() => {
let { width, height } = document.getElementById(canvasId)!.getBoundingClientRect();
console.log(width, height);
@ -176,57 +214,59 @@ const SourceBox = memo((props: SourceBoxProps) => {
}}
>
<div className={styles.canvasBox}>
<div
style={{
transform: `scale(${scaleNum})`,
position: 'relative',
width: '100%',
height: '100%',
}}
>
<MenuProvider id="menu_id">
<div
id={canvasId}
className={styles.canvas}
style={{
opacity,
transform: `scale(${scaleNum})`,
position: 'relative',
width: '100%',
height: '100%',
}}
ref={drop}
>
{pointData.length > 0 ? (
<GridLayout
className={styles.layout}
cols={24}
rowHeight={2}
width={canvasRect[0] || 0}
margin={[0, 0]}
onDragStop={dragStop}
onDragStart={onDragStart}
onResizeStop={onResizeStop}
>
{pointData.map(value => (
<div
className={value.isMenu ? styles.selected : styles.dragItem}
key={value.id}
data-grid={value.point}
>
<DynamicEngine {...value.item} isTpl={false} />
{/* <div
className={styles.tooltip}
style={{ display: value.isMenu ? 'block' : 'none' }}
<div
id={canvasId}
className={styles.canvas}
style={{
opacity,
}}
ref={drop}
>
{pointData.length > 0 ? (
<GridLayout
className={styles.layout}
cols={24}
rowHeight={2}
width={canvasRect[0] || 0}
margin={[0, 0]}
onDragStop={dragStop}
onDragStart={onDragStart}
onResizeStop={onResizeStop}
>
{pointData.map(value => (
<div
className={value.isMenu ? styles.selected : styles.dragItem}
key={value.id}
data-grid={value.point}
>
<div className="tooltipRow1">
<a></a>
</div>
<div className="tooltipRow2">
<a></a>
</div>
</div> */}
</div>
))}
</GridLayout>
) : null}
<DynamicEngine {...value.item} isTpl={false} />
{/* <div
className={styles.tooltip}
style={{ display: value.isMenu ? 'block' : 'none' }}
>
<div className="tooltipRow1">
<a></a>
</div>
<div className="tooltipRow2">
<a></a>
</div>
</div> */}
</div>
))}
</GridLayout>
) : null}
</div>
</div>
</div>
</MenuProvider>
</div>
</Draggable>
);
@ -356,7 +396,12 @@ const SourceBox = memo((props: SourceBoxProps) => {
clonePointData,
]);
return <>{render}</>;
return (
<>
{render}
<MyAwesomeMenu />
</>
);
});
export default connect((state: StateWithHistory<any>) => ({

View File

@ -142,6 +142,10 @@ const HeaderComponent = memo((props: HeaderComponentProps) => {
});
};
const toHelp = () => {
window.open('/help');
};
const toBack = () => {
history.push('/');
};
@ -262,6 +266,15 @@ const HeaderComponent = memo((props: HeaderComponentProps) => {
<Button type="link" onClick={toPreview} disabled={!pointData.length}>
</Button>
<Button
type="link"
style={{ marginRight: '9px' }}
onClick={toHelp}
disabled={!pointData.length}
title="使用帮助"
>
</Button>
</div>
<div className={styles.btnArea}>
<Select

View File

@ -6,6 +6,7 @@
* @LastEditors: dragon
* @LastEditTime: 2020-10-08 16:12:26
*/
import { uuid } from '@/utils/tool';
const pointData = localStorage.getItem('userData') || '[]';
function overSave(name, data) {
@ -43,6 +44,22 @@ export default {
curPoint: payload,
};
},
copyPointData(state, { payload }) {
const { id } = payload;
const pointData = [];
state.pointData.forEach(item => {
pointData.push({ ...item });
if (item.id === id) {
pointData.push({ ...item, id: uuid(6, 10) });
}
});
overSave('userData', pointData);
return {
...state,
pointData,
};
},
delPointData(state, { payload }) {
const { id } = payload;
const pointData = state.pointData.filter(item => item.id !== id);

23
src/pages/help/index.less Normal file
View File

@ -0,0 +1,23 @@
.helpWrap {
width: 880px;
height: 100vh;
overflow: auto;
margin: 0 auto;
padding-top: 20px;
background-color: #fff;
h2 {
text-align: center;
}
.helpItem {
border-bottom: 1px dashed #ccc;
margin-bottom: 20px;
h3 {
margin-bottom: 10px;
}
.imgWrap {
img {
width: 100%;
}
}
}
}

54
src/pages/help/index.tsx Normal file
View File

@ -0,0 +1,54 @@
import React from 'react';
import A from '@/assets/1.png';
import B from '@/assets/2.png';
import C from '@/assets/3.png';
import D from '@/assets/4.png';
import E from '@/assets/5.png';
import F from '@/assets/6.png';
import styles from './index.less';
const Help = () => {
return (
<div className={styles.helpWrap}>
<h2>H5-Dooring使用指南</h2>
<div className={styles.helpItem}>
<h3>1. </h3>
<div className={styles.imgWrap}>
<img src={A} alt="H5编辑器, H5制作, H5设计" />
</div>
</div>
<div className={styles.helpItem}>
<h3>2. </h3>
<div className={styles.imgWrap}>
<img src={B} alt="H5编辑器, H5制作, H5设计" />
</div>
</div>
<div className={styles.helpItem}>
<h3>3. 使</h3>
<div className={styles.imgWrap}>
<img src={C} alt="H5编辑器, H5制作, H5设计" />
</div>
</div>
<div className={styles.helpItem}>
<h3>4. </h3>
<div className={styles.imgWrap}>
<img src={D} alt="H5编辑器, H5制作, H5设计" />
</div>
</div>
<div className={styles.helpItem}>
<h3>5. 使</h3>
<div className={styles.imgWrap}>
<img src={E} alt="H5编辑器, H5制作, H5设计" />
</div>
</div>
<div className={styles.helpItem}>
<h3>6. , </h3>
<div className={styles.imgWrap}>
<img src={F} alt="H5编辑器, H5制作, H5设计" />
</div>
</div>
</div>
);
};
export default Help;

View File

@ -11791,6 +11791,14 @@ react-color@^2.18.1:
reactcss "^1.2.0"
tinycolor2 "^1.4.1"
react-contexify@^4.1.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/react-contexify/-/react-contexify-4.1.1.tgz#f5eba1ad82a923c033c91d0abcea1da0a71ebaa1"
integrity sha512-WJeRI4ohHEOmNiH0xb62a/eV+5ae168FB7H6pfbeEVJkf0UN7D5H99l6b89poc2LHKN1gOimFjREyY8quGVsXA==
dependencies:
classnames "^2.2.6"
prop-types "^15.6.2"
react-dnd-html5-backend@^11.1.3:
version "11.1.3"
resolved "https://registry.yarnpkg.com/react-dnd-html5-backend/-/react-dnd-html5-backend-11.1.3.tgz#2749f04f416ec230ea193f5c1fbea2de7dffb8f7"