From 9e8b1839da93982f4ea958b541a0cf0bf6443c51 Mon Sep 17 00:00:00 2001 From: Eric Xian Date: Tue, 26 Mar 2024 18:30:38 -0700 Subject: [PATCH 1/2] Update RichTextEditor to be a forwardRef and expose setContent --- src/RichTextEditor/RichTextEditor.mdx | 6 ++- src/RichTextEditor/RichTextEditor.stories.jsx | 22 ++++++++- src/RichTextEditor/RichTextEditor.tsx | 48 ++++++++++++------- 3 files changed, 57 insertions(+), 19 deletions(-) diff --git a/src/RichTextEditor/RichTextEditor.mdx b/src/RichTextEditor/RichTextEditor.mdx index a1a74156..92459a8b 100644 --- a/src/RichTextEditor/RichTextEditor.mdx +++ b/src/RichTextEditor/RichTextEditor.mdx @@ -10,7 +10,7 @@ import * as ComponentStories from './RichTextEditor.stories'; -### When to use +### When to use To allow users to edit text where formatting is important, such as messages to be sent via email. ### When to not use @@ -45,3 +45,7 @@ RichTextEditor also has an error state to display that the input is invalid. The but by setting `hasErrors` via your provided `onChange` callback you can check the HTML produced by the RichTextEditor for any requirements that you have. + +RichTextEditor can optionally take in a forwardedRef to allow content to be programmatically manipulated. + + diff --git a/src/RichTextEditor/RichTextEditor.stories.jsx b/src/RichTextEditor/RichTextEditor.stories.jsx index 00defcd8..fe62b2f8 100644 --- a/src/RichTextEditor/RichTextEditor.stories.jsx +++ b/src/RichTextEditor/RichTextEditor.stories.jsx @@ -1,5 +1,6 @@ -import React from 'react'; +import React, {useRef} from 'react'; +import Button from 'src/Button'; import { RichTextEditor, RichTextEditorActions } from 'src/RichTextEditor'; import mdx from './RichTextEditor.mdx'; @@ -60,3 +61,22 @@ export const Error = () => ( onChange={() => null} /> ); + +export const SetContent = () => { + const ref = useRef(null); + + const handleClick = () => { + ref.current.setContent('Oh hey'); + } + + return ( + <> + + null} + /> + + ) +} diff --git a/src/RichTextEditor/RichTextEditor.tsx b/src/RichTextEditor/RichTextEditor.tsx index c299a537..92a89cf8 100644 --- a/src/RichTextEditor/RichTextEditor.tsx +++ b/src/RichTextEditor/RichTextEditor.tsx @@ -4,7 +4,7 @@ import type { Extension, Node as TipTapNode, Mark } from '@tiptap/core'; import './RichTextEditor.scss'; -import React from 'react'; +import React, { forwardRef, type ForwardedRef, useImperativeHandle } from 'react'; import classNames from 'classnames'; @@ -94,21 +94,28 @@ export type RichTextEditorProps = { onChange: (arg0: string) => void; } -function RichTextEditor({ - allowedAttributes, - allowedTags, - ariaAttributes, - availableActions = RichTextEditorDefaultActionsArray, - characterLimit, - className, - hasErrors, - id, - initialValue, - isOneLine, - onChange, - placeholder, - customExtensions = [], -}: RichTextEditorProps) { +export type RichTextEditorRef = { + setContent: (content: string) => void; +} + +const RichTextEditor = forwardRef(( + { + allowedAttributes, + allowedTags, + ariaAttributes, + availableActions = RichTextEditorDefaultActionsArray, + characterLimit, + className, + hasErrors, + id, + initialValue, + isOneLine, + onChange, + placeholder, + customExtensions = [], + }: RichTextEditorProps, + ref: ForwardedRef = null, +) => { const oneLineExtension = isOneLine ? [OneLineLimit] : []; const requiredExtensions = [ @@ -183,6 +190,13 @@ function RichTextEditor({ }, }); + useImperativeHandle(ref, () => ({ + setContent: (content: string) => { + editor?.commands.setContent(content); + onChange(content); + }, + })); + return ( editor ? (
) ); -} +}) // eslint-disable-next-line import/no-default-export export default RichTextEditor; From 0245735d8f9687fde3d3d0281855b5a23bba534e Mon Sep 17 00:00:00 2001 From: Eric Xian Date: Tue, 26 Mar 2024 18:38:52 -0700 Subject: [PATCH 2/2] lint --- src/RichTextEditor/RichTextEditor.stories.jsx | 8 ++++---- src/RichTextEditor/RichTextEditor.tsx | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/RichTextEditor/RichTextEditor.stories.jsx b/src/RichTextEditor/RichTextEditor.stories.jsx index fe62b2f8..c169504e 100644 --- a/src/RichTextEditor/RichTextEditor.stories.jsx +++ b/src/RichTextEditor/RichTextEditor.stories.jsx @@ -1,4 +1,4 @@ -import React, {useRef} from 'react'; +import React, { useRef } from 'react'; import Button from 'src/Button'; import { RichTextEditor, RichTextEditorActions } from 'src/RichTextEditor'; @@ -67,7 +67,7 @@ export const SetContent = () => { const handleClick = () => { ref.current.setContent('Oh hey'); - } + }; return ( <> @@ -78,5 +78,5 @@ export const SetContent = () => { onChange={() => null} /> - ) -} + ); +}; diff --git a/src/RichTextEditor/RichTextEditor.tsx b/src/RichTextEditor/RichTextEditor.tsx index 92a89cf8..fba8c2c8 100644 --- a/src/RichTextEditor/RichTextEditor.tsx +++ b/src/RichTextEditor/RichTextEditor.tsx @@ -94,7 +94,7 @@ export type RichTextEditorProps = { onChange: (arg0: string) => void; } -export type RichTextEditorRef = { +export type RichTextEditorRef = { setContent: (content: string) => void; } @@ -235,7 +235,7 @@ const RichTextEditor = forwardRef(( ) ); -}) +}); // eslint-disable-next-line import/no-default-export export default RichTextEditor;