Skip to content

Commit

Permalink
feat: create reusable plugin
Browse files Browse the repository at this point in the history
  • Loading branch information
sashuk committed Jul 11, 2023
1 parent 736826d commit db8f33c
Show file tree
Hide file tree
Showing 16 changed files with 311 additions and 144 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { noop } from '@toptal/picasso/utils'
import type { LexicalEditor as LexicalEditorType } from 'lexical'
import { $getRoot } from 'lexical'

import { ImageNode } from '../plugins/ImagePlugin/nodes'
import ToolbarPlugin from '../LexicalEditorToolbarPlugin'
import { RTEPluginContextProvider } from '../plugins/api'
import { CustomEmojiNode } from '../plugins/EmojiPlugin/nodes/CustomEmojiNode'
Expand All @@ -29,7 +28,6 @@ import {
HeadingsReplacementPlugin,
TriggerInitialOnChangePlugin,
FocusOnLabelClickPlugin,
ImagePlugin,
} from '../plugins'
import type { ASTType } from '../RichText'
import { useOnFocus, useTypographyClasses } from './hooks'
Expand Down Expand Up @@ -147,7 +145,6 @@ const LexicalEditor = forwardRef<HTMLDivElement, Props>(function LexicalEditor(
},
namespace: 'editor',
nodes: [
ImageNode,
CustomEmojiNode,
ListNode,
ListItemNode,
Expand Down Expand Up @@ -218,7 +215,6 @@ const LexicalEditor = forwardRef<HTMLDivElement, Props>(function LexicalEditor(
<ListPlugin />
<EmojiPlugin />
<HistoryPlugin />
<ImagePlugin />
{hiddenInputId && (
<FocusOnLabelClickPlugin hiddenInputId={hiddenInputId} />
)}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
import React, { useState } from 'react'
import { Container, Radio } from '@toptal/picasso'
import type { UploadedImage } from '@toptal/picasso-rich-text-editor'
import { ImagePlugin, RichTextEditor } from '@toptal/picasso-rich-text-editor'

import type { RichTextEditorChangeHandler } from '../types'

// Imitate file upload function that sets image URL
const onUploadSucceeded = (uploadedImage: UploadedImage) =>
new Promise<UploadedImage>(resolve => {
setTimeout(() => {
const fileUrl = `./jacqueline/128x128.jpg?originalFileName=${encodeURIComponent(
uploadedImage.file.name
)}`

resolve({ ...uploadedImage, url: fileUrl })
}, 2000)
})

// Imitate failure during upload
const onUploadFailed = () =>
new Promise<UploadedImage>((resolve, reject) => {
setTimeout(() => {
reject('Upload failed')
}, 2000)
})

const Example = () => {
const [value, setValue] = useState<string | undefined>()
const [useSuccessfulUpload, setUseSuccessfullUpload] = useState('true')

const handleChange: RichTextEditorChangeHandler = newValue =>
setValue(newValue)

return (
<>
<Container bottom='medium'>
<Radio.Group
name='onUploadCase'
onChange={(event: React.ChangeEvent<{ value: string }>) => {
setUseSuccessfullUpload(event.target.value)
}}
value={useSuccessfulUpload}
>
<Radio label='Imitate successful upload' value='true' />
<Radio label='Imitate failing upload' value='false' />
</Radio.Group>
</Container>
<RichTextEditor
id='editor'
onChange={handleChange}
placeholder='Write some cool rich text'
plugins={[
<ImagePlugin
onUpload={
useSuccessfulUpload === 'true'
? onUploadSucceeded
: onUploadFailed
}
/>,
]}
/>
<Container
padded='small'
top='large'
style={{
fontFamily: "Consolas, 'Courier New', monospace",
background: 'lightyellow',
}}
>
{value}
</Container>
</>
)
}

export default Example
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ page
title: 'Emojis',
takeScreenshot: false,
})
.addExample('RichTextEditor/story/ImageUpload.example.tsx', 'Image upload')
2 changes: 2 additions & 0 deletions packages/picasso-rich-text-editor/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,5 @@ export type {
} from './RichTextEditor'
export { default as RichText } from './RichText'
export type { RichTextProps, ASTType } from './RichText'
export { ImagePlugin } from './plugins'
export type { UploadedImage } from './plugins'
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { useModal } from '@toptal/picasso/utils'
import { useLexicalComposerContext } from '@lexical/react/LexicalComposerContext'
import {
$createParagraphNode,
$getSelection,
$insertNodes,
$isRootOrShadowRoot,
COMMAND_PRIORITY_EDITOR,
Expand All @@ -11,19 +12,28 @@ import { $wrapNodeInElement } from '@lexical/utils'

import type { RTEPlugin } from '../api'
import { RTEPluginMeta, Toolbar } from '../api'
import ImagePluginButton from './ImagePluginButton'
import ImagePluginModal from './ImagePluginModal'
import { ImagePluginButton, ImagePluginModal } from './components'
import { INSERT_IMAGE_COMMAND } from './commands'
import type { ImageNodePayload } from './nodes/ImageNode'
import { $createImageNode, ImageNode } from './nodes/ImageNode'
import type { OnUploadCallback, UploadedImage } from './types'
import type { ImagePluginModalProps } from './components/ImagePluginModal'

const PLUGIN_NAME = 'image'

export type Props = {
accept: ImagePluginModalProps['accept']
maxSize: ImagePluginModalProps['maxSize']
onUpload: OnUploadCallback
'data-testid'?: string
}

const ImagePlugin: RTEPlugin = ({ 'data-testid': testId }: Props) => {
const ImagePlugin: RTEPlugin = ({
accept,
maxSize,
onUpload,
'data-testid': testId,
}: Props) => {
const { isOpen, hideModal, showModal } = useModal()
const [editor] = useLexicalComposerContext()

Expand All @@ -44,12 +54,36 @@ const ImagePlugin: RTEPlugin = ({ 'data-testid': testId }: Props) => {
)
}, [editor])

const onSubmit = (image: UploadedImage, altText: string) => {
editor.update(() => {
if (image.url) {
const imageContainer = $createParagraphNode()
const imageNode = $createImageNode({
alt: altText,
src: image.url,
})

imageContainer.append(imageNode)
const selection = $getSelection()

selection?.insertNodes([imageContainer])
}
})
}

return (
<>
<Toolbar keyName={PLUGIN_NAME}>
<ImagePluginButton onClick={showModal} data-testid={testId} />
</Toolbar>
<ImagePluginModal isOpen={isOpen} onClose={hideModal} />
<ImagePluginModal
accept={accept}
maxSize={maxSize}
isOpen={isOpen}
onUpload={onUpload}
onSubmit={onSubmit}
onClose={hideModal}
/>
</>
)
}
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import { Image16 } from '@toptal/picasso'
import React from 'react'

import { useRTEPluginContext } from '../api'
import RichTextEditorButton from '../../RichTextEditorButton'
import { useRTEPluginContext } from '../../../api'
import RichTextEditorButton from '../../../../RichTextEditorButton'

export type Props = {
'data-testid'?: string
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as ImagePluginButton } from './ImagePluginButton'
Loading

0 comments on commit db8f33c

Please sign in to comment.