Merge remote-tracking branch 'origin/main'

# Conflicts:
#	src/components/LexicalEditor/Index.jsx
2.0/email-builder
Lei OT 11 months ago
commit b3f50ecb90

@ -27,6 +27,7 @@ import ListMaxIndentLevelPlugin from "./plugins/ListMaxIndentLevelPlugin";
import CodeHighlightPlugin from "./plugins/CodeHighlightPlugin"; import CodeHighlightPlugin from "./plugins/CodeHighlightPlugin";
import AutoLinkPlugin from "./plugins/AutoLinkPlugin"; import AutoLinkPlugin from "./plugins/AutoLinkPlugin";
import TabFocusPlugin from './plugins/TabFocusPlugin'; import TabFocusPlugin from './plugins/TabFocusPlugin';
import EditorRefPlugin from './plugins/EditorRefPlugin'
import ImagesPlugin from './plugins/ImagesPlugin'; import ImagesPlugin from './plugins/ImagesPlugin';
import InlineImagePlugin from './plugins/InlineImagePlugin'; import InlineImagePlugin from './plugins/InlineImagePlugin';
import { ImageNode } from './nodes/ImageNode'; import { ImageNode } from './nodes/ImageNode';
@ -133,7 +134,7 @@ function MyOnChangePlugin({ onChange }) {
}, [editor, onChange]); }, [editor, onChange]);
return null; return null;
} }
export default function Editor({ isRichText, onChange, initialValue, ...props }) { export default function Editor({ isRichText, editorRef, onChange, initialValue, ...props }) {
return ( return (
<LexicalComposer initialConfig={editorConfig}> <LexicalComposer initialConfig={editorConfig}>
<div className='editor-container'> <div className='editor-container'>
@ -158,6 +159,7 @@ export default function Editor({ isRichText, onChange, initialValue, ...props })
<TabFocusPlugin /> <TabFocusPlugin />
<TabIndentationPlugin /> <TabIndentationPlugin />
<HorizontalRulePlugin /> <HorizontalRulePlugin />
<EditorRefPlugin editorRef={editorRef} />
<ImagesPlugin /> <ImagesPlugin />
<InlineImagePlugin /> <InlineImagePlugin />
<MyOnChangePlugin onChange={onChange}/> <MyOnChangePlugin onChange={onChange}/>

@ -0,0 +1,24 @@
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import { useEffect } from 'react'
/**
*
* Use this plugin to access the editor instance outside of the
* LexicalComposer. This can help with things like buttons or other
* UI components that need to update or read EditorState but need to
* be positioned outside the LexicalComposer in the React tree.
*/
export default function EditorRefPlugin({ editorRef }) {
const [editor] = useLexicalComposerContext()
useEffect(() => {
if (typeof editorRef === 'function') {
editorRef(editor)
} else if (typeof editorRef === 'object') {
editorRef.current = editor
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [editor])
return null
}

@ -143,7 +143,11 @@ function DesktopApp() {
items: [ items: [
{ {
label: <Link to="/account/profile">个人资料</Link>, label: <Link to="/account/profile">个人资料</Link>,
key: '1', key: 'profile',
},
{
label: <Link to="/account/snippet-list">图文集管理</Link>,
key: 'snippet-list',
}, },
{ type: 'divider' }, { type: 'divider' },
{ label: <ReloadPrompt force />, key: 'reload' }, { label: <ReloadPrompt force />, key: 'reload' },
@ -152,7 +156,7 @@ function DesktopApp() {
{ type: 'divider' }, { type: 'divider' },
{ {
label: <Link to="/p/dingding/logout">退出</Link>, label: <Link to="/p/dingding/logout">退出</Link>,
key: '3', key: 'logout',
}, },
], ],
}} }}

@ -6,11 +6,15 @@ import { copy, isNotEmpty, isEmpty } from '@/utils/commons'
import { WhatsAppOutlined } from '@ant-design/icons' import { WhatsAppOutlined } from '@ant-design/icons'
import { Row, Col, Tag, List, Form, Input, Button, Space } from 'antd' import { Row, Col, Tag, List, Form, Input, Button, Space } from 'antd'
import dayjs from 'dayjs' import dayjs from 'dayjs'
import { useCallback, useEffect, useState } from 'react' import { useCallback, useEffect, useState, useRef } from 'react'
import { Link } from 'react-router-dom' import { Link } from 'react-router-dom'
import LexicalEditor from '@/components/LexicalEditor'
import {$generateNodesFromDOM} from '@lexical/html'
function SnippetList() { function SnippetList() {
const [form] = Form.useForm() const [form] = Form.useForm()
const editorRef = useRef(null)
const [editorContent, setEditorContent] = useState('initialContent')
return ( return (
<> <>
@ -34,10 +38,18 @@ function SnippetList() {
<Input placeholder='placeholder' /> <Input placeholder='placeholder' />
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>
<Button type='primary'>搜索</Button> <Button type='primary' onClick={() => {
console.info(editorRef.current)
const editorStateJSONString = '{"root":{"children":[{"children":[{"detail":0,"format":0,"mode":"normal","style":"","text":"We are ","type":"text","version":1},{"detail":0,"format":1,"mode":"normal","style":"","text":"expert in customizing, and best-rated in delivering personalized Asia exploration","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":", ensured by ","type":"text","version":1},{"detail":0,"format":1,"mode":"normal","style":"","text":"our company-managed local services across Asia","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":". The proof is our over ","type":"text","version":1},{"detail":0,"format":1,"mode":"normal","style":"","text":"10,000 reviews with 98.8% 5-star ratings","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":" on the most reputable platforms like ","type":"text","version":1},{"detail":0,"format":1,"mode":"normal","style":"","text":"TripAdvisor and Trustpilot","type":"text","version":1},{"detail":0,"format":0,"mode":"normal","style":"","text":".","type":"text","version":1}],"direction":"ltr","format":"start","indent":0,"type":"paragraph","version":1,"textFormat":0,"textStyle":""}],"direction":"ltr","format":"","indent":0,"type":"root","version":1}}'
const editorState = editorRef.current.parseEditorState(editorStateJSONString);
editorRef.current.setEditorState(editorState)
}}>搜索</Button>
</Form.Item> </Form.Item>
<Form.Item> <Form.Item>
<Button>新增</Button> <Button onClick={() => {
console.info(JSON.stringify(editorRef.current.getEditorState()))
}}>新增</Button>
</Form.Item> </Form.Item>
</Form> </Form>
<Row gutter={16}> <Row gutter={16}>
@ -52,7 +64,10 @@ function SnippetList() {
'Highlights Travel Family Loyalty Club', 'Highlights Travel Family Loyalty Club',
]} ]}
renderItem={(item) => ( renderItem={(item) => (
<List.Item className='hover:bg-stone-50'> <List.Item className='hover:bg-stone-50' onClick={(e) => {
console.info(item)
setEditorContent('<strong>' + item + '</strong>')
}}>
<Row gutter={16} className='w-full'> <Row gutter={16} className='w-full'>
<Col span={16}> <Col span={16}>
<Tag color='magenta'>类型</Tag> <Tag color='magenta'>类型</Tag>
@ -70,8 +85,10 @@ function SnippetList() {
<pre className='whitespace-pre-wrap break-words'> <pre className='whitespace-pre-wrap break-words'>
<p>Discover China with the <strong>award-winning</strong> and <strong>best-rated</strong> tour company for <strong>personalized travel in China</strong>. Honored as <strong>China's Leading Tour Operator</strong> by the <strong>World Travel Awards</strong>, we boast <strong>10,000+ reviews</strong> and a remarkable <strong>98.8% 5-star rating</strong>. Our expertise in customizing personalized China explorations is backed by our company-managed local services across China. Explore and kickstart your personalized travel experience with just a click!</p> <p>Discover China with the <strong>award-winning</strong> and <strong>best-rated</strong> tour company for <strong>personalized travel in China</strong>. Honored as <strong>China's Leading Tour Operator</strong> by the <strong>World Travel Awards</strong>, we boast <strong>10,000+ reviews</strong> and a remarkable <strong>98.8% 5-star rating</strong>. Our expertise in customizing personalized China explorations is backed by our company-managed local services across China. Explore and kickstart your personalized travel experience with just a click!</p>
</pre> </pre>
<LexicalEditor {...{ isRichText: true, editorRef }} onChange={() => {console.info('onChange')}} initialValue={editorContent} />
</Col> </Col>
</Row> </Row>
</Space> </Space>
</> </>
) )

Loading…
Cancel
Save