mirror of
https://github.com/MrXujiang/h5-Dooring.git
synced 2025-12-11 17:32:50 +00:00
🆕 添加富文本组件 💄 优化首页样式
This commit is contained in:
parent
17ba811b3c
commit
c86501388a
@ -62,6 +62,7 @@
|
||||
"antd": "^4.7.0",
|
||||
"antd-img-crop": "^3.10.0",
|
||||
"axios": "^0.19.2",
|
||||
"braft-editor": "^2.3.9",
|
||||
"chatbot-antd": "^0.6.0",
|
||||
"codemirror": "^5.57.0",
|
||||
"dom-to-image": "^2.6.0",
|
||||
|
||||
BIN
src/assets/richText.png
Normal file
BIN
src/assets/richText.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 22 KiB |
17
src/components/BasicShop/BasicComponents/RichText/index.less
Normal file
17
src/components/BasicShop/BasicComponents/RichText/index.less
Normal file
@ -0,0 +1,17 @@
|
||||
.richTextWrap {
|
||||
:global(p) {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
:global(img) {
|
||||
max-width: 100%;
|
||||
text-align: center;
|
||||
}
|
||||
:global(blockquote) {
|
||||
margin: 0 0 10px;
|
||||
padding: 12px 20px;
|
||||
background-color: #f1f2f3;
|
||||
border-left: 5px solid #ccc;
|
||||
color: #666;
|
||||
font-style: italic;
|
||||
}
|
||||
}
|
||||
30
src/components/BasicShop/BasicComponents/RichText/index.tsx
Normal file
30
src/components/BasicShop/BasicComponents/RichText/index.tsx
Normal file
@ -0,0 +1,30 @@
|
||||
import React, { memo, useState } from 'react';
|
||||
import styles from './index.less';
|
||||
import { IButtonConfig } from './schema';
|
||||
import logo from '@/assets/richText.png';
|
||||
|
||||
interface IProps extends IButtonConfig {
|
||||
isTpl: boolean;
|
||||
}
|
||||
|
||||
const XButton = memo((props: IProps) => {
|
||||
const { isTpl, borderColor, borderWidth, round, padding, content } = props;
|
||||
|
||||
return isTpl ? (
|
||||
<div>
|
||||
<img style={{ width: '100%' }} src={logo} alt=""></img>
|
||||
</div>
|
||||
) : (
|
||||
<div
|
||||
className={styles.richTextWrap}
|
||||
style={{
|
||||
border: `${borderWidth}px solid ${borderColor}`,
|
||||
borderRadius: round + 'px',
|
||||
padding: padding + 'px',
|
||||
}}
|
||||
>
|
||||
<div dangerouslySetInnerHTML={{ __html: content }}></div>
|
||||
</div>
|
||||
);
|
||||
});
|
||||
export default XButton;
|
||||
64
src/components/BasicShop/BasicComponents/RichText/schema.ts
Normal file
64
src/components/BasicShop/BasicComponents/RichText/schema.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import {
|
||||
IColorConfigType,
|
||||
INumberConfigType,
|
||||
ITextConfigType,
|
||||
TColorDefaultType,
|
||||
TNumberDefaultType,
|
||||
TTextDefaultType,
|
||||
IRichTextConfigType,
|
||||
TRichTextDefaultType,
|
||||
} from '@/components/PanelComponents/FormEditor/types';
|
||||
|
||||
export type TButtonEditData = Array<
|
||||
ITextConfigType | IColorConfigType | INumberConfigType | IRichTextConfigType
|
||||
>;
|
||||
|
||||
export interface IButtonConfig {
|
||||
round: TNumberDefaultType;
|
||||
borderWidth: TNumberDefaultType;
|
||||
padding: TNumberDefaultType;
|
||||
borderColor: TColorDefaultType;
|
||||
content: TRichTextDefaultType;
|
||||
}
|
||||
|
||||
export interface IButtonSchema {
|
||||
editData: TButtonEditData;
|
||||
config: IButtonConfig;
|
||||
}
|
||||
const Button: IButtonSchema = {
|
||||
editData: [
|
||||
{
|
||||
key: 'round',
|
||||
name: '边框圆角',
|
||||
type: 'Number',
|
||||
},
|
||||
{
|
||||
key: 'borderWidth',
|
||||
name: '边框宽度',
|
||||
type: 'Number',
|
||||
},
|
||||
{
|
||||
key: 'borderColor',
|
||||
name: '边框颜色',
|
||||
type: 'Color',
|
||||
},
|
||||
{
|
||||
key: 'padding',
|
||||
name: '内边距',
|
||||
type: 'Number',
|
||||
},
|
||||
{
|
||||
key: 'content',
|
||||
name: '内容',
|
||||
type: 'RichText',
|
||||
},
|
||||
],
|
||||
config: {
|
||||
round: 0,
|
||||
borderWidth: 0,
|
||||
borderColor: 'rgba(255,255,255,1)',
|
||||
padding: 0,
|
||||
content: '',
|
||||
},
|
||||
};
|
||||
export default Button;
|
||||
@ -0,0 +1,6 @@
|
||||
const template = {
|
||||
type: 'RichText',
|
||||
h: 120,
|
||||
displayName: '富文本组件',
|
||||
};
|
||||
export default template;
|
||||
@ -11,6 +11,7 @@ import Notice from './Notice/schema';
|
||||
import Qrcode from './Qrcode/schema';
|
||||
import Tab from './Tab/schema';
|
||||
import Text from './Text/schema';
|
||||
import RichText from './RichText/schema';
|
||||
|
||||
const basicSchema = {
|
||||
Carousel,
|
||||
@ -26,5 +27,6 @@ const basicSchema = {
|
||||
Qrcode,
|
||||
Tab,
|
||||
Text,
|
||||
RichText,
|
||||
};
|
||||
export default basicSchema;
|
||||
|
||||
@ -11,6 +11,7 @@ import Qrcode from './Qrcode/template';
|
||||
import Tab from './Tab/template';
|
||||
import Text from './Text/template';
|
||||
import WhiteTpl from './WhiteTpl/template';
|
||||
import RichText from './RichText/template';
|
||||
|
||||
const basicTemplate = [
|
||||
Carousel,
|
||||
@ -26,6 +27,7 @@ const basicTemplate = [
|
||||
Tab,
|
||||
Text,
|
||||
WhiteTpl,
|
||||
RichText,
|
||||
];
|
||||
const BasicTemplate = basicTemplate.map(v => {
|
||||
return { ...v, category: 'base' };
|
||||
|
||||
@ -8,6 +8,7 @@ import CardPicker from '../CardPicker';
|
||||
import Table from '../Table';
|
||||
import Pos from '../Pos';
|
||||
import { Store } from 'antd/lib/form/interface';
|
||||
import RichText from '../XEditor';
|
||||
import FormItems from '../FormItems';
|
||||
// import styles from './index.less';
|
||||
const normFile = (e: any) => {
|
||||
@ -158,6 +159,11 @@ const FormEditor = (props: FormEditorProps) => {
|
||||
<FormItems data={item.data} rightPannelRef={rightPannelRef} />
|
||||
</Form.Item>
|
||||
)}
|
||||
{item.type === 'RichText' && (
|
||||
<Form.Item label={item.name} name={item.key} noStyle={true}>
|
||||
<RichText />
|
||||
</Form.Item>
|
||||
)}
|
||||
</React.Fragment>
|
||||
);
|
||||
})}
|
||||
|
||||
4
src/components/PanelComponents/XEditor/index.less
Normal file
4
src/components/PanelComponents/XEditor/index.less
Normal file
@ -0,0 +1,4 @@
|
||||
.avatarUploader > :global(.ant-upload) {
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
}
|
||||
94
src/components/PanelComponents/XEditor/index.tsx
Normal file
94
src/components/PanelComponents/XEditor/index.tsx
Normal file
@ -0,0 +1,94 @@
|
||||
import React, { useState, useEffect, memo } from 'react';
|
||||
import req from '@/utils/req';
|
||||
import BraftEditor from 'braft-editor';
|
||||
import 'braft-editor/dist/index.css';
|
||||
import styles from './index.less';
|
||||
|
||||
const controls = [
|
||||
{
|
||||
key: 'bold',
|
||||
text: <b>加粗</b>,
|
||||
},
|
||||
'undo',
|
||||
'redo',
|
||||
'emoji',
|
||||
'list-ul',
|
||||
'list-ol',
|
||||
'blockquote',
|
||||
'text-align',
|
||||
'font-size',
|
||||
'line-height',
|
||||
'letter-spacing',
|
||||
'text-color',
|
||||
'italic',
|
||||
'underline',
|
||||
'link',
|
||||
'media',
|
||||
];
|
||||
|
||||
export default memo(function XEditor(props: any) {
|
||||
const [editorState, setEditorState] = useState(BraftEditor.createEditorState());
|
||||
|
||||
const { value, onChange } = props;
|
||||
|
||||
const myUploadFn = param => {
|
||||
const fd = new FormData();
|
||||
fd.append('file', param.file);
|
||||
|
||||
req
|
||||
.post('xxxx', fd, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
onUploadProgress: function(event) {
|
||||
// 上传进度发生变化时调用param.progress
|
||||
console.log((event.loaded / event.total) * 100);
|
||||
param.progress((event.loaded / event.total) * 100);
|
||||
},
|
||||
})
|
||||
.then(res => {
|
||||
console.log(res);
|
||||
// 上传成功后调用param.success并传入上传后的文件地址
|
||||
param.success({
|
||||
url: res.url,
|
||||
meta: {
|
||||
id: Date.now(),
|
||||
title: res.filename,
|
||||
alt: '趣谈前端',
|
||||
},
|
||||
});
|
||||
})
|
||||
.catch(err => {
|
||||
param.error({
|
||||
msg: '上传失败.',
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
const submitContent = () => {
|
||||
const htmlContent = editorState.toHTML();
|
||||
onChange && onChange(htmlContent);
|
||||
};
|
||||
|
||||
const handleEditorChange = editorState => {
|
||||
setEditorState(editorState);
|
||||
if (onChange) {
|
||||
const htmlContent = editorState.toHTML();
|
||||
onChange(htmlContent);
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
const htmlContent = value || '';
|
||||
setEditorState(BraftEditor.createEditorState(htmlContent));
|
||||
}, []);
|
||||
return (
|
||||
<BraftEditor
|
||||
value={editorState}
|
||||
controls={controls}
|
||||
onChange={handleEditorChange}
|
||||
onSave={submitContent}
|
||||
media={{ uploadFn: myUploadFn }}
|
||||
/>
|
||||
);
|
||||
});
|
||||
@ -5,7 +5,7 @@ import styles from './index.less';
|
||||
///这组件写的有问题 popover会重定位
|
||||
const content = (
|
||||
<div className={styles.imgWrap}>
|
||||
<img src="http://io.nainor.com/uploads/WechatIMG2_1742b586c3d.jpeg" alt="sponsorship" />
|
||||
<img src="http://49.234.61.19/uploads/WechatIMG2_1742b586c3d.jpeg" alt="sponsorship" />
|
||||
</div>
|
||||
);
|
||||
|
||||
|
||||
@ -53,7 +53,7 @@
|
||||
.footer {
|
||||
margin-top: 50px;
|
||||
text-align: center;
|
||||
font-size: 50px;
|
||||
font-size: 15px;
|
||||
p {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
import React from 'react';
|
||||
import { Tabs, message, Button } from 'antd';
|
||||
import { Tabs, message } from 'antd';
|
||||
import { history } from 'umi';
|
||||
import {
|
||||
MobileOutlined,
|
||||
ConsoleSqlOutlined,
|
||||
GithubOutlined,
|
||||
CodeOutlined,
|
||||
IdcardOutlined,
|
||||
} from '@ant-design/icons';
|
||||
import Zan from '@/components/Zan';
|
||||
import styles from './index.less';
|
||||
|
||||
const { TabPane } = Tabs;
|
||||
@ -90,21 +90,30 @@ const Home = () => {
|
||||
</div>
|
||||
</div>
|
||||
<footer className={styles.footer}>
|
||||
<div>
|
||||
<a href="https://github.com/MrXujiang/h5-Dooring">
|
||||
<GithubOutlined />
|
||||
</a>
|
||||
<p>
|
||||
Welcome to H5-Dooring
|
||||
<span role="img" aria-label="welcome">
|
||||
👋
|
||||
</span>
|
||||
</p>
|
||||
<p>
|
||||
<Button type="primary">
|
||||
<a href="https://www.oschina.net/p/h5-dooring">为dooring投票</a>
|
||||
</Button>
|
||||
</p>
|
||||
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
||||
<div style={{ marginTop: '30px' }}>
|
||||
<Zan />
|
||||
</div>
|
||||
<div style={{ width: '160px', marginLeft: '60px', marginTop: '32px' }}>
|
||||
<a
|
||||
href="http://49.234.61.19/h5?tid=B73349B8&isTpl=1"
|
||||
style={{ marginRight: '24px' }}
|
||||
target="_blank"
|
||||
>
|
||||
商务合作
|
||||
</a>
|
||||
<a href="http://49.234.61.19/h5?tid=7B4008F7&isTpl=1" target="_blank">
|
||||
友情链接
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
||||
<div style={{ width: '360px', marginLeft: '60px', marginTop: '32px' }}>
|
||||
<span style={{ marginRight: '24px' }}>更多产品: </span>
|
||||
<a href="http://49.234.61.19/qt" style={{ marginRight: '24px' }} target="_blank">
|
||||
趣图-在线gif动图制作平台
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
</div>
|
||||
|
||||
72
yarn.lock
72
yarn.lock
@ -3978,6 +3978,39 @@ braces@^3.0.1, braces@~3.0.2:
|
||||
dependencies:
|
||||
fill-range "^7.0.1"
|
||||
|
||||
braft-convert@^2.3.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/braft-convert/-/braft-convert-2.3.0.tgz#27d5905136c334903d083b7a2352a72045627888"
|
||||
integrity sha512-5km+dLHk8iYDv2iEYDrDQ2ld/ZoUx66QLql0qdm5PqZEcNXc8dBHGLORfzeu3iMw1jLeAiHxtdY5+ypuIhczVg==
|
||||
dependencies:
|
||||
draft-convert "^2.0.0"
|
||||
draft-js "^0.10.3"
|
||||
|
||||
braft-editor@^2.3.9:
|
||||
version "2.3.9"
|
||||
resolved "https://registry.yarnpkg.com/braft-editor/-/braft-editor-2.3.9.tgz#fd2b8e23ea71191016579a1ed8231d16ad8f5b4a"
|
||||
integrity sha512-mqdPk/zI2dhFK8tW/A4Qj/AkkARLh5L/niNw+iif5wFqb6zh15rMlrShgz1nWO/QXyAKr8XtDgxiBbR0zWwtRg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.0.0"
|
||||
braft-convert "^2.3.0"
|
||||
braft-finder "^0.0.19"
|
||||
braft-utils "^3.0.8"
|
||||
draft-convert "^2.0.0"
|
||||
draft-js "^0.10.3"
|
||||
draft-js-multidecorators "^1.0.0"
|
||||
draftjs-utils "^0.9.4"
|
||||
immutable "~3.7.4"
|
||||
|
||||
braft-finder@^0.0.19:
|
||||
version "0.0.19"
|
||||
resolved "https://registry.yarnpkg.com/braft-finder/-/braft-finder-0.0.19.tgz#c324d82526ed3476a93de86cc9b407f4e188bc8d"
|
||||
integrity sha512-0kzI6/KbomJJhYX1hpjn4edCKhblyUyWdUrsgBmOrwy0vrj+pPkm69+Uf8Uj6KGAULM6LF0ooC++p7fqUGgFHw==
|
||||
|
||||
braft-utils@^3.0.8:
|
||||
version "3.0.12"
|
||||
resolved "https://registry.yarnpkg.com/braft-utils/-/braft-utils-3.0.12.tgz#2b755ce1d8397d96b627b6767f74d07f25729d85"
|
||||
integrity sha512-O2cKysURNC4HSEMKgNmQ2RluwcrxvYrztlEmyPN5SzktiNX3vaLFQoo0Ez3PlIhvjaGrIBSIT2Oyh2N6mn6TFg==
|
||||
|
||||
brorand@^1.0.1:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f"
|
||||
@ -5618,6 +5651,36 @@ dotenv@8.2.0:
|
||||
resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-8.2.0.tgz#97e619259ada750eea3e4ea3e26bceea5424b16a"
|
||||
integrity sha512-8sJ78ElpbDJBHNeBzUbUVLsqKdccaa/BXF1uPTw3GrvQTBgrQrtObr2mUrE38vzYd8cEv+m/JBfDLioYcfXoaw==
|
||||
|
||||
draft-convert@^2.0.0:
|
||||
version "2.1.10"
|
||||
resolved "https://registry.yarnpkg.com/draft-convert/-/draft-convert-2.1.10.tgz#07552f0aadff7ac01c8619d769210d4ea8fcab77"
|
||||
integrity sha512-PRdcjBqFUfEb2jlPM+bOyyCNlTzGaHdyhvKsw5nur6Dj1YclmuAiTwJ8yTsEa95YI9kwzbO5ccZ/+tYj/LlS0A==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.5.5"
|
||||
immutable "~3.7.4"
|
||||
invariant "^2.2.1"
|
||||
|
||||
draft-js-multidecorators@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/draft-js-multidecorators/-/draft-js-multidecorators-1.0.0.tgz#6c4be8d7b78dd2b966ee51ee6cc179b9b535e612"
|
||||
integrity sha1-bEvo17eN0rlm7lHubMF5ubU15hI=
|
||||
dependencies:
|
||||
immutable "*"
|
||||
|
||||
draft-js@^0.10.3:
|
||||
version "0.10.5"
|
||||
resolved "https://registry.yarnpkg.com/draft-js/-/draft-js-0.10.5.tgz#bfa9beb018fe0533dbb08d6675c371a6b08fa742"
|
||||
integrity sha512-LE6jSCV9nkPhfVX2ggcRLA4FKs6zWq9ceuO/88BpXdNCS7mjRTgs0NsV6piUCJX9YxMsB9An33wnkMmU2sD2Zg==
|
||||
dependencies:
|
||||
fbjs "^0.8.15"
|
||||
immutable "~3.7.4"
|
||||
object-assign "^4.1.0"
|
||||
|
||||
draftjs-utils@^0.9.4:
|
||||
version "0.9.4"
|
||||
resolved "https://registry.yarnpkg.com/draftjs-utils/-/draftjs-utils-0.9.4.tgz#976c61aa133dbbbfedd65ae1dd6627d7b98c6f08"
|
||||
integrity sha512-KYjABSbGpJrwrwmxVj5UhfV37MF/p0QRxKIyL+/+QOaJ8J9z1FBKxkblThbpR0nJi9lxPQWGg+gh+v0dAsSCCg==
|
||||
|
||||
duplexer3@^0.1.4:
|
||||
version "0.1.4"
|
||||
resolved "https://registry.yarnpkg.com/duplexer3/-/duplexer3-0.1.4.tgz#ee01dd1cac0ed3cbc7fdbea37dc0a8f1ce002ce2"
|
||||
@ -6486,7 +6549,7 @@ fb-watchman@^2.0.0:
|
||||
dependencies:
|
||||
bser "2.1.1"
|
||||
|
||||
fbjs@^0.8.0, fbjs@^0.8.3, fbjs@^0.8.9:
|
||||
fbjs@^0.8.0, fbjs@^0.8.15, fbjs@^0.8.3, fbjs@^0.8.9:
|
||||
version "0.8.17"
|
||||
resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.17.tgz#c4d598ead6949112653d6588b01a5cdcd9f90fdd"
|
||||
integrity sha1-xNWY6taUkRJlPWWIsBpc3Nn5D90=
|
||||
@ -7415,11 +7478,16 @@ immer@^7.0.5:
|
||||
resolved "https://registry.yarnpkg.com/immer/-/immer-7.0.9.tgz#28e7552c21d39dd76feccd2b800b7bc86ee4a62e"
|
||||
integrity sha512-Vs/gxoM4DqNAYR7pugIxi0Xc8XAun/uy7AQu4fLLqaTBHxjOP9pJ266Q9MWA/ly4z6rAFZbvViOtihxUZ7O28A==
|
||||
|
||||
immutable@^3.8.1:
|
||||
immutable@*, immutable@^3.8.1:
|
||||
version "3.8.2"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.2.tgz#c2439951455bb39913daf281376f1530e104adf3"
|
||||
integrity sha1-wkOZUUVbs5kT2vKBN28VMOEErfM=
|
||||
|
||||
immutable@~3.7.4:
|
||||
version "3.7.6"
|
||||
resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.7.6.tgz#13b4d3cb12befa15482a26fe1b2ebae640071e4b"
|
||||
integrity sha1-E7TTyxK++hVIKib+Gy665kAHHks=
|
||||
|
||||
import-cwd@^2.0.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/import-cwd/-/import-cwd-2.1.0.tgz#aa6cf36e722761285cb371ec6519f53e2435b0a9"
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user