feat: 封装 LexicalEditorInput

2.0/email-builder
Jimmy Liow 11 months ago
parent 78266378ff
commit a0b30071c0

@ -88,9 +88,6 @@ function LexicalDefaultValuePlugin({ value = "" }= {}) {
if (clear) {
root.clear();
}
console.log('default value:');
console.log(value);
console.log(isEmpty(value))
const p = $createParagraphNode();
const _p = nodes.filter(n => n).forEach((n) => {

@ -0,0 +1,27 @@
import LexicalEditor from '@/components/LexicalEditor'
const LexicalEditorInput = (props) => {
const { id, value = {}, onChange } = props
const triggerChange = (changedValue) => {
onChange?.({
...value,
...changedValue,
})
}
return (
<LexicalEditor
id={id}
{...{ isRichText: true }}
onChange={(val) => {
triggerChange({
html: val.html,
})
}}
initialValue={value}
/>
)
}
export default LexicalEditorInput

@ -1,94 +1,190 @@
import { Conditional } from '@/components/Conditional'
import useAuthStore from '@/stores/AuthStore'
import useFormStore from '@/stores/FormStore'
import { useOrderStore } from '@/stores/OrderStore'
import { copy, isNotEmpty, isEmpty } from '@/utils/commons'
import { WhatsAppOutlined } from '@ant-design/icons'
import { Row, Col, Tag, List, Form, Input, Button, Space } from 'antd'
import dayjs from 'dayjs'
import { useCallback, useEffect, useState, useRef } from 'react'
import { Link } from 'react-router-dom'
import { Row, Col, Tag, List, Form, Input, Button, Space, Modal } from 'antd'
import { useState, useRef } from 'react'
import LexicalEditor from '@/components/LexicalEditor'
import {$generateNodesFromDOM} from '@lexical/html'
import LexicalEditorInput from './LexicalEditorInput'
function SnippetList() {
const [form] = Form.useForm()
const [snippetForm] = Form.useForm()
const editorRef = useRef(null)
const [editorContent, setEditorContent] = useState('initialContent')
const [isSnippetModalOpen, setSnippetModalOpen] = useState(false)
const [editorContent, setEditorContent] = useState("<p>Discover the best of the world with one of the <strong>best-rated tour companies for personalized travel</strong>. With over <strong>10,000+ reviews and a 98.8% 5-star rating</strong>, we focus on streamlining your planning and ensuring joyful travels. Whether it's a milestone celebration or a relaxing getaway, let us help create your beautiful journey.</p>")
const onSnippetFinish = (values) => {
console.log('onSnippetFinish:', values)
// console.info(JSON.stringify(editorRef.current.getEditorState()))
}
const onSnippetFailed = (error) => {
console.log('Failed:', error)
// form.resetFields()
}
return (
<>
<Space direction='vertical' size='large' style={{ width: '100%' }}>
<Form
layout={'inline'}
form={form}
initialValues={{
layout: 'inline',
}}>
<Form.Item label='所有者'>
<Input placeholder='placeholder' />
</Form.Item>
<Form.Item label='类别'>
<Input placeholder='placeholder' />
<Modal
centered
okButtonProps={{
autoFocus: true,
htmlType: 'submit',
}}
width={800}
zIndex={996}
title={'图文'}
open={isSnippetModalOpen} onCancel={() => setSnippetModalOpen(false)}
destroyOnClose
forceRender
modalRender={(dom) => (
<Form
name='snippetForm'
form={snippetForm}
layout='vertical'
className='max-w-4xl'
onFinish={onSnippetFinish}
onFinishFailed={onSnippetFailed}
autoComplete='off'
>
{dom}
</Form>
)}
>
<Form.Item name='snippetId' className='hidden' ><Input /></Form.Item>
<Form.Item
label='标题'
name='title'
rules={[
{
required: true,
message: 'title required',
},
]}
>
<Input />
</Form.Item>
<Form.Item label='状态'>
<Input placeholder='placeholder' />
<Form.Item
label='内容'
name='content'
rules={[
{
required: true,
message: 'content required',
},
]}
>
{/* <LexicalEditor
{...{ isRichText: true, editorRef }}
onChange={() => {
console.info('onChange')
}}
initialValue={editorContent}
/> */}
<LexicalEditorInput />
</Form.Item>
<Form.Item label='标题'>
<Input placeholder='placeholder' />
</Form.Item>
<Form.Item>
<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}}'
</Modal>
const editorState = editorRef.current.parseEditorState(editorStateJSONString);
editorRef.current.setEditorState(editorState)
}}>搜索</Button>
</Form.Item>
<Form.Item>
<Button onClick={() => {
console.info(JSON.stringify(editorRef.current.getEditorState()))
}}>新增</Button>
</Form.Item>
</Form>
<Row gutter={16}>
<Col span={8}>
<List
bordered
dataSource={[
'问客人发帖',
'婚礼团upsale',
'泰国相关',
'日本暑期预警',
'Highlights Travel Family Loyalty Club',
]}
renderItem={(item) => (
<List.Item className='hover:bg-stone-50' onClick={(e) => {
console.info(item)
setEditorContent('<strong>' + item + '</strong>')
<Space direction='vertical' size='large' style={{ width: '100%' }}>
<Form
layout={'inline'}
form={form}
initialValues={{
layout: 'inline',
}}>
<Form.Item label='所有者'>
<Input placeholder='placeholder' />
</Form.Item>
<Form.Item label='类别'>
<Input placeholder='placeholder' />
</Form.Item>
<Form.Item label='状态'>
<Input placeholder='placeholder' />
</Form.Item>
<Form.Item label='标题'>
<Input placeholder='placeholder' />
</Form.Item>
<Form.Item>
<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>
<Button
onClick={() => {
// snippetForm.setFieldsValue({
// title: 'Title....',
// content: editorContent
// })
setSnippetModalOpen(true)
}}>
<Row gutter={16} className='w-full'>
<Col span={16}>
<Tag color='magenta'>类型</Tag>
{item}
</Col>
<Col span={8}>
<div className='text-end'>王静</div>
</Col>
</Row>
</List.Item>
)}
/>
</Col>
<Col span={16} className='border-solid border rounded border-gray-300'>
<pre className='whitespace-pre-wrap break-words'>
新增
</Button>
</Form.Item>
</Form>
<Row gutter={16}>
<Col span={8}>
<List
bordered
dataSource={[
'问客人发帖',
'婚礼团upsale',
'泰国相关',
'日本暑期预警',
'Highlights Travel Family Loyalty Club',
]}
renderItem={(item) => (
<List.Item
className='hover:bg-stone-50'
onClick={(e) => {
console.info(item)
setEditorContent('<strong>' + item + '</strong>')
}}>
<Row gutter={16} className='w-full'>
<Col span={16}>
<Tag color='magenta'>类型</Tag>
{item}
</Col>
<Col span={8}>
<div className='text-end'>王静</div>
</Col>
</Row>
</List.Item>
)}
/>
</Col>
<Col
span={16}>
<Space
direction="vertical"
size="middle"
style={{
display: 'flex',
}}
>
<div
className='border-solid border rounded border-gray-300'>
<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>
</pre>
<LexicalEditor {...{ isRichText: true, editorRef }} onChange={() => {console.info('onChange')}} initialValue={editorContent} />
</Col>
</Row>
</div>
</Space>
</Col>
</Row>
</Space>
</>
)

Loading…
Cancel
Save