RHFRichTextEditor
RHFRichTextEditor is a powerful and flexible rich text editor designed for
content creation within forms. It allows users to format text with features
like bold, italics, lists, links, images,
and more, making it suitable for blog posts, comments, or any content
requiring rich formatting. This component is built on top of
CkEditor,
a highly customizable editor that supports advanced features like
codeBlocks, findAndReplace, tables, and more.
The latest versions of CkEditor require a paid license key. Therefore, we will use the free version of this package.
To use the latest version, refer to the Use Latest Version section.
npm i ckeditor5@43.0.0 @ckeditor/ckeditor5-react@9.0.0
yarn add ckeditor5@43.0.0 @ckeditor/ckeditor5-react@9.0.0
Usage
import RHFRichTextEditor, { RHFRichTextEditorProps, DefaultEditorConfig } from '@nish1896/rhf-mui-components/misc/rich-text-editor';
<RHFRichTextEditor
fieldName='bio'
control={control}
errorMessage={errors?.bio?.message}
/>
To reorder formatting options or add advanced features, you can provide
a custom configuration via the editorConfig prop, or override the existing
configuration by modifying the DefaultEditorConfig object. You can check the
default configuration here.
To customize editor theme, check the theme customization guide.
For advanced features like findAndReplace, inserting images, markdown support, and word count, refer to this example. For a full list of available CKEditor features, visit the CKEditor documentation.
If your website supports both light and dark themes, styling CKEditor5 for theme switching
can be challenging, as the editor doesn't dynamically adapt to theme changes once rendered.
To address this, you can override the editor's CSS based on the active theme by
referring this gist.
You may also refer CkEditor5 documentation for a better understanding.
With Latest Version
The latest version of CKEditor5 requires a paid license key. To continue accessing the newest features of the editor while preserving the underlying form logic, update your code as follows:
-
Obtain a License Key: Acquire a commercial license key from the CKEditor Pricing Page.
-
Update Your CKEditor 5 Configuration: Incorporate the licenseKey into your editor configuration:
import RHFRichTextEditor, { DefaultEditorConfig } from '@nish1896/rhf-mui-components/misc/rich-text-editor';
<RHFRichTextEditor
fieldName='bio'
control={control}
editorConfig={{
licenseKey: 'YOUR_LICENSE_KEY',
...DefaultEditorConfig,
}}
errorMessage={errors?.bio?.message}
/>Replace 'YOUR_LICENSE_KEY' with the license key you've obtained. Additionally you can also configure your own editor settings in favor of the default configuration.
Examples
Alternatives
I chose CKEditor for its advanced features, customization options and support for multiple languages. Although the documentation can be overwhelming, I've provided both basic and advanced configuration options for this component. If you're looking for a simpler solution, you can consider implementing mui-rte.
API
RHFRichTextEditorProps accepts the following props:
| Name | Type | Required | Description |
|---|---|---|---|
| fieldName | string | ✅ | React Hook Form requires name as a key for the registration process. This is a required prop for all components. |
| control | UseFormControl | ✅ | The control option yielded on calling the useForm hook. |
| registerOptions | RegisterOptions | Register options for validation if using react-hook-form without any validation libraries like yup or Joi. | |
| required | boolean | Indicates that the field is mandatory by adding an asterisk symbol (*) to the formLabel. This visual cue helps users quickly identify required fields in the form. | |
| id | string | The context ID. When this property changes, the component restarts the context with its editor and reinitializes it based on the current configuration. | |
| editorConfig | EditorConfig | A Configuration object for CkEditor to customize formatting controls and toolbar positioning, as per requirement. Refer to the toolbar positioning guide for more details. | |
| onReady | (editor: ClassicEditor) => void | A function called when the context is ready and all editors inside were (re)initialized with the context instance. | |
| onFocus | (event: EventInfo<string, unknown>, editor: ClassicEditor) => void | Callback function triggered when the editor gains focus. | |
| onValueChange | (newValue: string, event: EventInfo, editor: ClassicEditor) => void | Callback function returning the editor value, event object and editor details. | |
| onBlur | (event: EventInfo<string, unknown>, editor: ClassicEditor) => void | Callback function triggered when the editor gains loses focus. | |
| disabled | boolean | A boolean value to enable or disable editing of the form field. | |
| label | ReactNode | The text to render in FormLabel component. By default, the value of fieldName such as firstName will be transformed to display "First Name" using the fieldNameToLabel function. | |
| showLabelAboveFormField | boolean | Renders the form label above the field by default. Set this prop to false to hide the label. | |
| formLabelProps | FormLabelProps | FormLabelProps to customise FormLabel component for a field. Multiple fields can be configured using the ConfigProvider component. | |
| helperText | ReactNode | The content to display within the FormHelperText component below the field. If the field validation fails, this content will be overridden by the corresponding error message. | |
| onError | (error: Error, details: ErrorDetails) => void | A function called when the editor has crashed during the initialization or runtime. It receives two arguments: the error instance and the error details. | |
| errorMessage | ReactNode | Error message to be shown for a field in FormHelperText component. | |
| hideErrorMessage | boolean | A flag to prevent replacement of helper text of a field by the error message when the validation is triggered. | |
| formHelperTextProps | FormHelperTextProps | FormHelperTextProps to customise FormHelperText component for a field. Multiple fields can be configured using the ConfigProvider component. |