mirror of
https://github.com/MrXujiang/h5-Dooring.git
synced 2025-12-12 10:12:51 +00:00
refactor update folder
This commit is contained in:
parent
c81e15efaa
commit
dae99ae103
@ -7,4 +7,4 @@
|
||||
img {
|
||||
width: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
import { CarouselConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo, PropsWithChildren } from 'react';
|
||||
import { Carousel } from 'zarm';
|
||||
import styles from './index.less';
|
||||
import { CarouselConfigType } from '../DynamicEngine/schema';
|
||||
|
||||
interface CarouselTypes extends CarouselConfigType {
|
||||
isTpl: boolean;
|
||||
71
src/components/BasicShop/BasicComponents/Carousel/schema.ts
Normal file
71
src/components/BasicShop/BasicComponents/Carousel/schema.ts
Normal file
@ -0,0 +1,71 @@
|
||||
const Carousel = {
|
||||
editData: [
|
||||
{
|
||||
key: 'direction',
|
||||
name: '方向',
|
||||
type: 'Radio',
|
||||
range: [
|
||||
{
|
||||
key: 'down',
|
||||
text: '从上到下',
|
||||
},
|
||||
{
|
||||
key: 'left',
|
||||
text: '从左到右',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
key: 'swipeable',
|
||||
name: '是否可拖拽',
|
||||
type: 'Switch',
|
||||
},
|
||||
{
|
||||
key: 'autoPlay',
|
||||
name: '是否自动播放',
|
||||
type: 'Switch',
|
||||
},
|
||||
{
|
||||
key: 'imgList',
|
||||
name: '图片列表',
|
||||
type: 'DataList',
|
||||
},
|
||||
],
|
||||
config: {
|
||||
direction: 'left',
|
||||
swipeable: false,
|
||||
autoPlay: false,
|
||||
imgList: [
|
||||
{
|
||||
id: '1',
|
||||
title: '趣谈小课1',
|
||||
desc: '致力于打造优质小课程',
|
||||
link: 'xxxxx',
|
||||
imgUrl: [
|
||||
{
|
||||
uid: '001',
|
||||
name: 'image.png',
|
||||
status: 'done',
|
||||
url: 'http://io.nainor.com/uploads/1_1740bd7c3dc.png',
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
id: '2',
|
||||
title: '趣谈小课1',
|
||||
desc: '致力于打造优质小课程',
|
||||
link: 'xxxxx',
|
||||
imgUrl: [
|
||||
{
|
||||
uid: '001',
|
||||
name: 'image.png',
|
||||
status: 'done',
|
||||
url: 'http://io.nainor.com/uploads/2_1740bd8d525.png',
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
tplImg: 'http://io.nainor.com/uploads/carousal_17442e1420f.png',
|
||||
},
|
||||
};
|
||||
export default Carousel;
|
||||
21
src/components/BasicShop/BasicComponents/Footer/index.tsx
Normal file
21
src/components/BasicShop/BasicComponents/Footer/index.tsx
Normal file
@ -0,0 +1,21 @@
|
||||
import { FooterConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
const Footer = memo((props: FooterConfigType) => {
|
||||
const { bgColor, text, color, align, fontSize, height } = props;
|
||||
return (
|
||||
<footer
|
||||
style={{
|
||||
backgroundColor: bgColor,
|
||||
color,
|
||||
fontSize,
|
||||
textAlign: align,
|
||||
height,
|
||||
lineHeight: height + 'px',
|
||||
}}
|
||||
>
|
||||
{text}
|
||||
</footer>
|
||||
);
|
||||
});
|
||||
|
||||
export default Footer;
|
||||
@ -1,6 +1,6 @@
|
||||
import { Input, Cell, DateSelect, Radio, Select } from 'zarm';
|
||||
import styles from './baseForm.less';
|
||||
|
||||
import React from 'react';
|
||||
// 维护表单控件, 提高form渲染性能
|
||||
const BaseForm = {
|
||||
Text: props => {
|
||||
23
src/components/BasicShop/BasicComponents/Header/index.less
Normal file
23
src/components/BasicShop/BasicComponents/Header/index.less
Normal file
@ -0,0 +1,23 @@
|
||||
.header {
|
||||
box-sizing: content-box;
|
||||
padding: 3px 12px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
height: 50px;
|
||||
background-color: #000;
|
||||
.logo {
|
||||
margin-right: 10px;
|
||||
max-width: 160px;
|
||||
max-height: 46px;
|
||||
height: 46px;
|
||||
overflow: hidden;
|
||||
img {
|
||||
height: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
.title {
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
}
|
||||
}
|
||||
20
src/components/BasicShop/BasicComponents/Header/index.tsx
Normal file
20
src/components/BasicShop/BasicComponents/Header/index.tsx
Normal file
@ -0,0 +1,20 @@
|
||||
import { memo } from 'react';
|
||||
import styles from './index.less';
|
||||
import React from 'react';
|
||||
import { HeaderConfigType } from '@/components/DynamicEngine/schema';
|
||||
|
||||
const Header = memo((props: HeaderConfigType) => {
|
||||
const { bgColor, logo, logoText, fontSize, color } = props;
|
||||
return (
|
||||
<header className={styles.header} style={{ backgroundColor: bgColor }}>
|
||||
<div className={styles.logo}>
|
||||
<img src={logo && logo[0].url} alt={logoText} />
|
||||
</div>
|
||||
<div className={styles.title} style={{ fontSize, color }}>
|
||||
{logoText}
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
});
|
||||
|
||||
export default Header;
|
||||
42
src/components/BasicShop/BasicComponents/Icon/schema.ts
Normal file
42
src/components/BasicShop/BasicComponents/Icon/schema.ts
Normal file
@ -0,0 +1,42 @@
|
||||
export type IconTypes =
|
||||
| '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';
|
||||
12
src/components/BasicShop/BasicComponents/Image/index.tsx
Normal file
12
src/components/BasicShop/BasicComponents/Image/index.tsx
Normal file
@ -0,0 +1,12 @@
|
||||
import { ImageConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
const Image = memo((props: ImageConfigType) => {
|
||||
const { imgUrl, round = 0 } = props;
|
||||
return (
|
||||
<div style={{ borderRadius: round, width: '100%', textAlign: 'center', overflow: 'hidden' }}>
|
||||
<img src={imgUrl && imgUrl[0].url} alt="" style={{ width: '100%' }} />
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default Image;
|
||||
19
src/components/BasicShop/BasicComponents/List/index.less
Normal file
19
src/components/BasicShop/BasicComponents/List/index.less
Normal file
@ -0,0 +1,19 @@
|
||||
.list {
|
||||
margin: 20px auto;
|
||||
width: 94%;
|
||||
.sourceList {
|
||||
.sourceItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 16px;
|
||||
.imgWrap {
|
||||
}
|
||||
.content {
|
||||
margin-left: 12px;
|
||||
.tit {
|
||||
line-height: 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
51
src/components/BasicShop/BasicComponents/List/index.tsx
Normal file
51
src/components/BasicShop/BasicComponents/List/index.tsx
Normal file
@ -0,0 +1,51 @@
|
||||
import { ListConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import styles from './index.less';
|
||||
const List = memo((props: ListConfigType) => {
|
||||
const { round, sourceData, imgSize, fontSize, color } = props;
|
||||
return (
|
||||
<div className={styles.list}>
|
||||
<div className={styles.sourceList}>
|
||||
{sourceData.map((item, i) => {
|
||||
return (
|
||||
<div className={styles.sourceItem} key={i}>
|
||||
<div className={styles.imgWrap}>
|
||||
<img
|
||||
src={
|
||||
item.imgUrl[0]
|
||||
? item.imgUrl[0].url
|
||||
: 'http://io.nainor.com/uploads/01_173e15d3493.png'
|
||||
}
|
||||
alt={item.desc}
|
||||
style={{
|
||||
width: imgSize,
|
||||
height: imgSize,
|
||||
objectFit: 'cover',
|
||||
borderRadius: round,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles.content}>
|
||||
<a
|
||||
className={styles.tit}
|
||||
style={{ fontSize, color }}
|
||||
href={item.link ? item.link : '#'}
|
||||
>
|
||||
{item.title}
|
||||
<div
|
||||
className={styles.desc}
|
||||
style={{ fontSize: fontSize * 0.8, color: 'rgba(0,0,0, .3)' }}
|
||||
>
|
||||
{item.desc}
|
||||
</div>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default List;
|
||||
15
src/components/BasicShop/BasicComponents/LongText/index.tsx
Normal file
15
src/components/BasicShop/BasicComponents/LongText/index.tsx
Normal file
@ -0,0 +1,15 @@
|
||||
import { LongTextConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import styles from './index.less';
|
||||
const LongText = memo((props: LongTextConfigType) => {
|
||||
const { text, fontSize, color, indent, lineHeight, textAlign } = props;
|
||||
return (
|
||||
<div
|
||||
className={styles.textWrap}
|
||||
style={{ color, textIndent: indent + 'px', fontSize, lineHeight, textAlign }}
|
||||
>
|
||||
{text}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
export default LongText;
|
||||
13
src/components/BasicShop/BasicComponents/Notice/index.tsx
Normal file
13
src/components/BasicShop/BasicComponents/Notice/index.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import { NoticeBar } from 'zarm';
|
||||
import React, { memo } from 'react';
|
||||
import { NoticeConfigType } from '@/components/DynamicEngine/schema';
|
||||
const Notice = memo((props: NoticeConfigType) => {
|
||||
const { text, speed, theme, isClose = false } = props;
|
||||
return (
|
||||
<NoticeBar theme={theme === 'default' ? undefined : theme} closable={isClose} speed={speed}>
|
||||
<span style={{ color: 'inherit' }}>{text}</span>
|
||||
</NoticeBar>
|
||||
);
|
||||
});
|
||||
|
||||
export default Notice;
|
||||
14
src/components/BasicShop/BasicComponents/Qrcode/index.tsx
Normal file
14
src/components/BasicShop/BasicComponents/Qrcode/index.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
import { QRCodeConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
|
||||
const Qrcode = memo((props: QRCodeConfigType) => {
|
||||
const { qrcode, text, color, fontSize = 14 } = props;
|
||||
return (
|
||||
<div style={{ width: '240px', margin: '16px auto' }}>
|
||||
<img src={qrcode && qrcode[0].url} alt={text} style={{ width: '100%' }} />
|
||||
<div style={{ textAlign: 'center', color, fontSize, paddingTop: '8px' }}>{text}</div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default Qrcode;
|
||||
@ -24,4 +24,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,7 +1,7 @@
|
||||
import { TabConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { useEffect, useRef } from 'react';
|
||||
import { Tabs } from 'zarm';
|
||||
import styles from './index.less';
|
||||
import { TabConfigType } from '../DynamicEngine/schema';
|
||||
|
||||
const { Panel } = Tabs;
|
||||
|
||||
@ -22,7 +22,7 @@ const XTab = (props: TabConfigType) => {
|
||||
return (
|
||||
<div className={styles.tabWrap} ref={tabWrapRef}>
|
||||
<Tabs
|
||||
canSwipe
|
||||
scrollThreshold={3}
|
||||
onChange={i => {
|
||||
console.log(i);
|
||||
}}
|
||||
13
src/components/BasicShop/BasicComponents/Text/index.tsx
Normal file
13
src/components/BasicShop/BasicComponents/Text/index.tsx
Normal file
@ -0,0 +1,13 @@
|
||||
import { TextConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import styles from './index.less';
|
||||
|
||||
const Text = memo((props: TextConfigType) => {
|
||||
const { align, text, fontSize, color, lineHeight } = props;
|
||||
return (
|
||||
<div className={styles.textWrap} style={{ color, textAlign: align, fontSize, lineHeight }}>
|
||||
{text}
|
||||
</div>
|
||||
);
|
||||
});
|
||||
export default Text;
|
||||
@ -1,7 +1,7 @@
|
||||
import { VideoConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import { Player, BigPlayButton } from 'video-react';
|
||||
import './index.css';
|
||||
import { VideoConfigType } from '../DynamicEngine/schema';
|
||||
|
||||
const VideoPlayer = memo((props: VideoConfigType) => {
|
||||
const { poster, url } = props;
|
||||
@ -0,0 +1,21 @@
|
||||
import { XProgressConfigType } from '@/components/DynamicEngine/schema';
|
||||
import React, { memo } from 'react';
|
||||
import { Progress } from 'zarm';
|
||||
import styles from './index.less';
|
||||
|
||||
const XProgress = memo((props: XProgressConfigType) => {
|
||||
const { theme, size, shape, percent, strokeWidth } = props;
|
||||
return (
|
||||
<div className={styles.textWrap} style={{ textAlign: 'center' }}>
|
||||
<Progress
|
||||
shape={shape}
|
||||
size={size}
|
||||
percent={percent}
|
||||
theme={theme}
|
||||
strokeWidth={strokeWidth}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
|
||||
export default XProgress;
|
||||
@ -3,20 +3,22 @@ import Loading from '../LoadingCp';
|
||||
import { useMemo, memo, FC } from 'react';
|
||||
import React from 'react';
|
||||
import { AllTemplateType } from './schema';
|
||||
const needList = ['Tab', 'Carousel', 'Upload', 'Video', 'Icon', 'Chart'];
|
||||
|
||||
const DynamicFunc = (type: AllTemplateType) =>
|
||||
export type componentsType = 'media' | 'base' | 'visible';
|
||||
|
||||
const DynamicFunc = (type: AllTemplateType, componentsType: componentsType) =>
|
||||
dynamic({
|
||||
loader: async function() {
|
||||
let Component: FC<{ isTpl: boolean }>;
|
||||
if (needList.includes(type)) {
|
||||
const { default: Graph } = await import(`@/components/${type}`);
|
||||
if (componentsType === 'base') {
|
||||
const { default: Graph } = await import(`@/components/BasicShop/BasicComponents/${type}`);
|
||||
Component = Graph;
|
||||
} else if (componentsType === 'media') {
|
||||
const { default: Graph } = await import(`@/components/BasicShop/MediaComponents/${type}`);
|
||||
Component = Graph;
|
||||
} else {
|
||||
const Components = ((await import(`@/components/DynamicEngine/components`)) as unknown) as {
|
||||
[key: string]: FC;
|
||||
};
|
||||
Component = Components[type];
|
||||
const { default: Graph } = await import(`@/components/BasicShop/VisualComponents/${type}`);
|
||||
Component = Graph;
|
||||
}
|
||||
|
||||
return (props: DynamicType) => {
|
||||
@ -35,14 +37,15 @@ type DynamicType = {
|
||||
isTpl: boolean;
|
||||
config: { [key: string]: any };
|
||||
type: AllTemplateType;
|
||||
componentsType: componentsType;
|
||||
};
|
||||
const DynamicEngine = memo((props: DynamicType) => {
|
||||
const { type, config, isTpl } = props;
|
||||
const { type, config, isTpl, componentsType } = props;
|
||||
const Dynamic = useMemo(() => {
|
||||
return (DynamicFunc(type) as unknown) as FC<DynamicType>;
|
||||
return (DynamicFunc(type, componentsType) as unknown) as FC<DynamicType>;
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [type, config]);
|
||||
return <Dynamic type={type} config={config} isTpl={isTpl} />;
|
||||
return <Dynamic type={type} config={config} isTpl={isTpl} componentsType={componentsType} />;
|
||||
});
|
||||
|
||||
export default DynamicEngine;
|
||||
|
||||
@ -1,8 +1,8 @@
|
||||
import { useState, useEffect, memo } from 'react';
|
||||
import classnames from 'classnames';
|
||||
import Icon from '../Icon/';
|
||||
import Icon from '../../BasicShop/BasicComponents/Icon';
|
||||
import styles from './index.less';
|
||||
import { IconTypes } from '../DynamicEngine/schema';
|
||||
import { IconTypes } from '../../DynamicEngine/schema';
|
||||
import React from 'react';
|
||||
|
||||
interface CardPickerType {
|
||||
0
src/components/PanelComponents/Color/index.less
Normal file
0
src/components/PanelComponents/Color/index.less
Normal file
@ -3,10 +3,12 @@ import { SketchPicker, ColorResult } from 'react-color';
|
||||
import { rgba2Obj } from '@/utils/tool';
|
||||
// import styles from './index.less'
|
||||
|
||||
export type ColorConfigType = string;
|
||||
|
||||
//value 初始值传来,onchange item给的回调
|
||||
interface ColorProps {
|
||||
value?: string;
|
||||
id?: string;
|
||||
onChange?: (v: string) => void;
|
||||
value?: ColorConfigType;
|
||||
onChange?: (v: ColorConfigType) => void;
|
||||
}
|
||||
|
||||
class colorPicker extends React.Component<ColorProps> {
|
||||
@ -1,7 +1,7 @@
|
||||
import React, { memo, useEffect, FC } from 'react';
|
||||
import { Form, Select, Input, Modal } from 'antd';
|
||||
import Upload from '@/components/Upload';
|
||||
import { BasicDataSource } from '../DynamicEngine/schema';
|
||||
import Upload from '../Upload';
|
||||
import { BasicDataSource } from '../../DynamicEngine/schema';
|
||||
import { Store } from 'antd/lib/form/interface';
|
||||
|
||||
// import styles from './index.less';
|
||||
@ -39,4 +39,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -18,7 +18,7 @@ import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||
import EditorModal from './editorModal';
|
||||
import { uuid } from '@/utils/tool';
|
||||
import styles from './index.less';
|
||||
import { BasicDataSource } from '../DynamicEngine/schema';
|
||||
import { BasicDataSource } from '../../DynamicEngine/schema';
|
||||
|
||||
type ListItemProps = DndItemProps & {
|
||||
isDragging: boolean;
|
||||
@ -31,9 +31,6 @@ function ListItem(props: ListItemProps) {
|
||||
const {
|
||||
title,
|
||||
desc,
|
||||
link,
|
||||
imgUrl,
|
||||
type,
|
||||
onDel,
|
||||
onEdit,
|
||||
// 这些 props 由 React DnD注入,参考`collect`函数定义
|
||||
@ -73,7 +70,6 @@ type DndItemProps = BasicDataSource & {
|
||||
onDel: Function;
|
||||
onEdit: Function;
|
||||
key: number;
|
||||
id: string;
|
||||
find: Function;
|
||||
move: Function;
|
||||
type?: number;
|
||||
@ -7,7 +7,7 @@ import Color from '../Color';
|
||||
import CardPicker from '../CardPicker';
|
||||
import Table from '../Table';
|
||||
import { Store } from 'antd/lib/form/interface';
|
||||
import { BasicRangeType, IconSchema } from '../DynamicEngine/schema';
|
||||
import { BasicRangeType, IconSchema } from '../../DynamicEngine/schema';
|
||||
// import styles from './index.less';
|
||||
const normFile = (e: any) => {
|
||||
console.log('Upload event:', e);
|
||||
@ -8,4 +8,4 @@
|
||||
cursor: pointer;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2,7 +2,7 @@ import React, { memo, useState, useEffect } from 'react';
|
||||
import { Input, Button, Popconfirm } from 'antd';
|
||||
import { MinusCircleOutlined } from '@ant-design/icons';
|
||||
import styles from './index.less';
|
||||
import { TabConfigType } from '../DynamicEngine/schema';
|
||||
import { TabConfigType } from '../../DynamicEngine/schema';
|
||||
|
||||
type MultiTextProps = {
|
||||
onChange?: (v: TabConfigType['tabs']) => void;
|
||||
@ -1,9 +1,10 @@
|
||||
import React, { useContext, useState, useEffect, useRef, memo } from 'react';
|
||||
import React, { useContext, useState, useEffect, useRef, memo, RefObject } from 'react';
|
||||
import { Table, Input, Button, Popconfirm, Form, Modal } from 'antd';
|
||||
// 下方样式主要为全局样式,暂时不可删
|
||||
import styles from './index.less';
|
||||
import { ColumnsType } from 'antd/lib/table';
|
||||
|
||||
const EditableContext = React.createContext<any>();
|
||||
const EditableContext = React.createContext<any>(null);
|
||||
|
||||
interface Item {
|
||||
key: string;
|
||||
@ -32,7 +33,7 @@ interface EditableCellProps {
|
||||
editable: boolean;
|
||||
children: React.ReactNode;
|
||||
dataIndex: string;
|
||||
record: Item;
|
||||
record: any;
|
||||
handleSave: (record: Item) => void;
|
||||
}
|
||||
|
||||
@ -46,12 +47,12 @@ const EditableCell: React.FC<EditableCellProps> = ({
|
||||
...restProps
|
||||
}) => {
|
||||
const [editing, setEditing] = useState(false);
|
||||
const inputRef = useRef();
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const form = useContext(EditableContext);
|
||||
|
||||
useEffect(() => {
|
||||
if (editing) {
|
||||
inputRef.current.focus();
|
||||
inputRef.current?.focus();
|
||||
}
|
||||
}, [editing]);
|
||||
|
||||
@ -60,10 +61,9 @@ const EditableCell: React.FC<EditableCellProps> = ({
|
||||
form.setFieldsValue({ [dataIndex]: record[dataIndex] });
|
||||
};
|
||||
|
||||
const save = async e => {
|
||||
const save = async () => {
|
||||
try {
|
||||
const values = await form.validateFields();
|
||||
|
||||
toggleEdit();
|
||||
handleSave({ ...record, ...values });
|
||||
} catch (errInfo) {
|
||||
@ -85,7 +85,11 @@ const EditableCell: React.FC<EditableCellProps> = ({
|
||||
},
|
||||
]}
|
||||
>
|
||||
<Input ref={inputRef} onPressEnter={save} onBlur={save} />
|
||||
<Input
|
||||
ref={(inputRef as unknown) as () => RefObject<HTMLInputElement>}
|
||||
onPressEnter={save}
|
||||
onBlur={save}
|
||||
/>
|
||||
</Form.Item>
|
||||
) : (
|
||||
<div className="editable-cell-value-wrap" style={{ paddingRight: 24 }} onClick={toggleEdit}>
|
||||
@ -97,8 +101,19 @@ const EditableCell: React.FC<EditableCellProps> = ({
|
||||
return <td {...restProps}>{childNode}</td>;
|
||||
};
|
||||
|
||||
class EditableTable extends React.Component {
|
||||
constructor(props) {
|
||||
class EditableTable extends React.Component<any, any> {
|
||||
columns: (
|
||||
| { title: string; dataIndex: string; width: string; editable: boolean; render?: undefined }
|
||||
| {
|
||||
title: string;
|
||||
dataIndex: string;
|
||||
render: (text: string, record: any) => JSX.Element | null;
|
||||
width?: undefined;
|
||||
editable?: undefined;
|
||||
}
|
||||
)[];
|
||||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.columns = [
|
||||
{
|
||||
@ -119,13 +134,13 @@ class EditableTable extends React.Component {
|
||||
render: (text: string, record) =>
|
||||
this.state.dataSource.length >= 1 ? (
|
||||
<Popconfirm title="Sure to delete?" onConfirm={() => this.handleDelete(record.key)}>
|
||||
<a>删除</a>
|
||||
<span>删除</span>
|
||||
</Popconfirm>
|
||||
) : null,
|
||||
},
|
||||
];
|
||||
|
||||
const dataSource = props.data.map((item, i: number) => ({ key: i + '', ...item }));
|
||||
const dataSource = props.data.map((item: any, i: number) => ({ key: i + '', ...item }));
|
||||
|
||||
this.state = {
|
||||
dataSource: dataSource,
|
||||
@ -156,7 +171,7 @@ class EditableTable extends React.Component {
|
||||
this.props.onChange && this.props.onChange(newDataSource);
|
||||
};
|
||||
|
||||
handleSave = row => {
|
||||
handleSave = (row: any) => {
|
||||
const newData = [...this.state.dataSource];
|
||||
const index = newData.findIndex(item => row.key === item.key);
|
||||
const item = newData[index];
|
||||
@ -174,14 +189,14 @@ class EditableTable extends React.Component {
|
||||
});
|
||||
};
|
||||
|
||||
handleOk = e => {
|
||||
handleOk = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||
console.log(e);
|
||||
this.setState({
|
||||
visible: false,
|
||||
});
|
||||
};
|
||||
|
||||
handleCancel = e => {
|
||||
handleCancel = (e: React.MouseEvent<HTMLElement, MouseEvent>) => {
|
||||
console.log(e);
|
||||
this.setState({
|
||||
visible: false,
|
||||
@ -196,7 +211,7 @@ class EditableTable extends React.Component {
|
||||
cell: EditableCell,
|
||||
},
|
||||
};
|
||||
const columns = this.columns.map(col => {
|
||||
const columns: ColumnsType<any> = this.columns.map(col => {
|
||||
if (!col.editable) {
|
||||
return col;
|
||||
}
|
||||
@ -6,4 +6,4 @@
|
||||
:global(.ant-upload-select-picture-card .ant-upload-text) {
|
||||
margin-top: 8px;
|
||||
color: #666;
|
||||
}
|
||||
}
|
||||
@ -14,7 +14,7 @@ library.push(
|
||||
text: (
|
||||
<div>
|
||||
<a href="https://github.com/MrXujiang">@徐小夕</a>
|
||||
<a href="https://github.com/yehuozhili/learnsinglespa">@yehuozhili</a>
|
||||
<a href="https://github.com/yehuozhili">@yehuozhili</a>
|
||||
</div>
|
||||
),
|
||||
useReg: /(.*?)作者是谁(.*?)/,
|
||||
|
||||
@ -13,7 +13,7 @@ import SourceBox from './SourceBox';
|
||||
import TargetBox from './TargetBox';
|
||||
import Calibration from 'components/Calibration';
|
||||
import DynamicEngine from 'components/DynamicEngine';
|
||||
import FormEditor from 'components/FormEditor';
|
||||
import FormEditor from 'components/PanelComponents/FormEditor';
|
||||
import template from 'components/DynamicEngine/template';
|
||||
import mediaTpl from 'components/DynamicEngine/mediaTpl';
|
||||
import graphTpl from 'components/DynamicEngine/graphTpl';
|
||||
@ -137,21 +137,36 @@ const Container = props => {
|
||||
<TabPane tab={generateHeader('base', '基础组件')} key="1">
|
||||
{template.map((value, i) => (
|
||||
<TargetBox item={value} key={i} canvasId={canvasId}>
|
||||
<DynamicEngine {...value} config={schema[value.type].config} isTpl={true} />
|
||||
<DynamicEngine
|
||||
{...value}
|
||||
config={schema[value.type].config}
|
||||
componentsType="base"
|
||||
isTpl={true}
|
||||
/>
|
||||
</TargetBox>
|
||||
))}
|
||||
</TabPane>
|
||||
<TabPane tab={generateHeader('media', '媒体组件')} key="2">
|
||||
{mediaTpl.map((value, i) => (
|
||||
<TargetBox item={value} key={i} canvasId={canvasId}>
|
||||
<DynamicEngine {...value} config={schema[value.type].config} isTpl={true} />
|
||||
<DynamicEngine
|
||||
{...value}
|
||||
config={schema[value.type].config}
|
||||
componentsType="media"
|
||||
isTpl={true}
|
||||
/>
|
||||
</TargetBox>
|
||||
))}
|
||||
</TabPane>
|
||||
<TabPane tab={generateHeader('visible', '可视化组件')} key="3">
|
||||
{graphTpl.map((value, i) => (
|
||||
<TargetBox item={value} key={i} canvasId={canvasId}>
|
||||
<DynamicEngine {...value} config={schema[value.type].config} isTpl={true} />
|
||||
<DynamicEngine
|
||||
{...value}
|
||||
config={schema[value.type].config}
|
||||
componentsType="visible"
|
||||
isTpl={true}
|
||||
/>
|
||||
</TargetBox>
|
||||
))}
|
||||
</TabPane>
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user