Skip to content

Instantly share code, notes, and snippets.

@wkentdag
Created November 6, 2024 23:46
Show Gist options
  • Save wkentdag/39d7c2a88127f254f67a057ddc4ba011 to your computer and use it in GitHub Desktop.
Save wkentdag/39d7c2a88127f254f67a057ddc4ba011 to your computer and use it in GitHub Desktop.
import { createHeadlessEditor } from '@lexical/headless'
import {
EditorConfig,
getEnabledNodes,
sanitizeEditorConfig,
} from '@payloadcms/richtext-lexical'
import { $getRoot, SerializedRootNode } from 'lexical'
import { Validate } from 'payload/types'
import { simple } from '../config/lexical'
type LexicalWordCountProps = {
length?: number
config?: EditorConfig
}
const defaultProps: LexicalWordCountProps = {
length: 160,
config: simple,
}
/**
* Cap lexical fields at a specific char count
* @param {number} props.length - max chars (120 default)
* @param {EditorConfig} props.config - specify an editor config
* @returns
*/
export default function lexicalCharCount({
length = defaultProps.length,
config = defaultProps.config,
}: LexicalWordCountProps = defaultProps): Validate<{
root: SerializedRootNode
}> {
return async (state): Promise<string | true> => {
if (!state) {
return true
}
try {
const editor = createHeadlessEditor({
// https://payloadcms.com/docs/rich-text/lexical#headless-editor
nodes: getEnabledNodes({
editorConfig: sanitizeEditorConfig(config),
}),
onError: (e) => {
throw e
},
})
editor.setEditorState(editor.parseEditorState(state))
const textContent =
editor.getEditorState().read(() => {
return $getRoot().getTextContent()
}) || ''
const charCount = textContent.length
if (charCount > length) {
return `Current character count (${charCount}) is over the limit (${length}).`
}
return true
} catch (error) {
console.error(`[lexicalCharCount] uncaught validation error`)
console.error(error)
return true
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment