feat(richtext-lexical): export hasText helper (#9484)
### What? Extracted `hasText` helper method in `richTextValidateHOC` ### Why? The new exported `hasText` helper method can now also be used during front-end serialization - for example, to check whether a caption element should be rendered when text is optional and therefore possibly empty (which would allow us to prevent rendering an empty caption element).
This commit is contained in:
@@ -7,3 +7,4 @@ export {
|
||||
objectToFrontmatter,
|
||||
propsToJSXString,
|
||||
} from '../utilities/jsx/jsx.js'
|
||||
export { hasText } from '../validate/hasText.js'
|
||||
|
||||
36
packages/richtext-lexical/src/validate/hasText.ts
Normal file
36
packages/richtext-lexical/src/validate/hasText.ts
Normal file
@@ -0,0 +1,36 @@
|
||||
import type {
|
||||
SerializedEditorState,
|
||||
SerializedLexicalNode,
|
||||
SerializedParagraphNode,
|
||||
SerializedTextNode,
|
||||
} from 'lexical'
|
||||
|
||||
export function hasText(
|
||||
value: null | SerializedEditorState<SerializedLexicalNode> | undefined,
|
||||
): boolean {
|
||||
const hasChildren = !!value?.root?.children?.length
|
||||
|
||||
let hasOnlyEmptyParagraph = false
|
||||
if (value?.root?.children?.length === 1) {
|
||||
if (value?.root?.children[0]?.type === 'paragraph') {
|
||||
const paragraphNode = value?.root?.children[0] as SerializedParagraphNode
|
||||
|
||||
if (!paragraphNode?.children || paragraphNode?.children?.length === 0) {
|
||||
hasOnlyEmptyParagraph = true
|
||||
} else if (paragraphNode?.children?.length === 1) {
|
||||
const paragraphNodeChild = paragraphNode?.children[0]
|
||||
if (paragraphNodeChild.type === 'text') {
|
||||
if (!(paragraphNodeChild as SerializedTextNode | undefined)?.['text']?.length) {
|
||||
hasOnlyEmptyParagraph = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasChildren || hasOnlyEmptyParagraph) {
|
||||
return false
|
||||
} else {
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,9 @@
|
||||
import type { SerializedEditorState, SerializedParagraphNode, SerializedTextNode } from 'lexical'
|
||||
import type { SerializedEditorState } from 'lexical'
|
||||
import type { RichTextField, Validate } from 'payload'
|
||||
|
||||
import type { SanitizedServerEditorConfig } from '../lexical/config/types.js'
|
||||
|
||||
import { hasText } from './hasText.js'
|
||||
import { validateNodes } from './validateNodes.js'
|
||||
|
||||
export const richTextValidateHOC = ({
|
||||
@@ -19,30 +20,8 @@ export const richTextValidateHOC = ({
|
||||
required,
|
||||
} = options
|
||||
|
||||
if (required) {
|
||||
const hasChildren = !!value?.root?.children?.length
|
||||
|
||||
let hasOnlyEmptyParagraph = false
|
||||
if (value?.root?.children?.length === 1) {
|
||||
if (value?.root?.children[0]?.type === 'paragraph') {
|
||||
const paragraphNode = value?.root?.children[0] as SerializedParagraphNode
|
||||
|
||||
if (!paragraphNode?.children || paragraphNode?.children?.length === 0) {
|
||||
hasOnlyEmptyParagraph = true
|
||||
} else if (paragraphNode?.children?.length === 1) {
|
||||
const paragraphNodeChild = paragraphNode?.children[0]
|
||||
if (paragraphNodeChild.type === 'text') {
|
||||
if (!(paragraphNodeChild as SerializedTextNode | undefined)?.['text']?.length) {
|
||||
hasOnlyEmptyParagraph = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasChildren || hasOnlyEmptyParagraph) {
|
||||
return t('validation:required')
|
||||
}
|
||||
if (required && hasText(value) === false) {
|
||||
return t('validation:required')
|
||||
}
|
||||
|
||||
// Traverse through nodes and validate them. Just like a node can hook into the population process (e.g. link or relationship nodes),
|
||||
|
||||
Reference in New Issue
Block a user