diff --git a/packages/richtext-lexical/src/field/features/blocks/component/index.tsx b/packages/richtext-lexical/src/field/features/blocks/component/index.tsx index f3f2346a02..15b8be6e23 100644 --- a/packages/richtext-lexical/src/field/features/blocks/component/index.tsx +++ b/packages/richtext-lexical/src/field/features/blocks/component/index.tsx @@ -7,14 +7,22 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react' import { type BlockFields } from '../nodes/BlocksNode.js' const baseClass = 'lexical-block' - import type { ReducedBlock } from '@payloadcms/ui/utilities/buildComponentMap' import type { FormState } from 'payload/types' +import { getTranslation } from '@payloadcms/translations' +import { Button } from '@payloadcms/ui/elements/Button' +import { Collapsible } from '@payloadcms/ui/elements/Collapsible' +import { ErrorPill } from '@payloadcms/ui/elements/ErrorPill' +import { Pill } from '@payloadcms/ui/elements/Pill' +import { ShimmerEffect } from '@payloadcms/ui/elements/ShimmerEffect' +import { SectionTitle } from '@payloadcms/ui/fields/Blocks/SectionTitle' import { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider' import { useFormSubmitted } from '@payloadcms/ui/forms/Form' +import { RenderFields } from '@payloadcms/ui/forms/RenderFields' import { useConfig } from '@payloadcms/ui/providers/Config' import { useDocumentInfo } from '@payloadcms/ui/providers/DocumentInfo' +import { useTranslation } from '@payloadcms/ui/providers/Translation' import { getFormState } from '@payloadcms/ui/utilities/getFormState' import { v4 as uuid } from 'uuid' @@ -118,38 +126,62 @@ export const BlockComponent: React.FC = (props) => { [config.routes.api, config.serverURL, schemaFieldsPath, id, formData.blockName], ) + const { i18n } = useTranslation() + + const classNames = [`${baseClass}__row`, `${baseClass}__row--no-errors`].filter(Boolean).join(' ') // Memoized Form JSX const formContent = useMemo(() => { - return ( - reducedBlock && - initialState !== false && ( -
- - - ) + return reducedBlock && initialState !== false ? ( +
+ + + ) : ( + +
+ + {typeof reducedBlock.labels.singular === 'string' + ? getTranslation(reducedBlock.labels.singular, i18n) + : '[Singular Label]'} + + +
+ + } + key={0} + > + +
) }, [ fieldMap, parentLexicalRichTextField, nodeKey, + i18n, submitted, initialState, reducedBlock, diff --git a/test/fields/collections/Lexical/e2e.spec.ts b/test/fields/collections/Lexical/e2e.spec.ts index c9b9427345..5277641a51 100644 --- a/test/fields/collections/Lexical/e2e.spec.ts +++ b/test/fields/collections/Lexical/e2e.spec.ts @@ -1109,25 +1109,52 @@ describe('lexical', () => { test('should respect required error state in deeply nested text field', async () => { await navigateToLexicalFields() + await wait(300) const richTextField = page.locator('.rich-text-lexical').nth(1) // second + await wait(300) + await richTextField.scrollIntoViewIfNeeded() + await wait(300) + await expect(richTextField).toBeVisible() + await wait(300) const conditionalArrayBlock = richTextField.locator('.lexical-block').nth(7) + await wait(300) await conditionalArrayBlock.scrollIntoViewIfNeeded() - await expect(conditionalArrayBlock).toBeVisible() + await wait(300) - await conditionalArrayBlock.locator('.btn__label:has-text("Add Sub Array")').first().click() + await expect(conditionalArrayBlock).toBeVisible() + await wait(300) + + const addSubArrayButton = conditionalArrayBlock.locator( + '.btn__label:has-text("Add Sub Array")', + ) + await addSubArrayButton.scrollIntoViewIfNeeded() + await wait(300) + + await expect(addSubArrayButton).toBeVisible() + await wait(300) + + await addSubArrayButton.first().click() + await wait(300) await page.click('#action-save', { delay: 100 }) + await wait(300) + await expect(page.locator('.Toastify')).toContainText('The following field is invalid') + await wait(300) const requiredTooltip = conditionalArrayBlock .locator('.tooltip-content:has-text("This field is required.")') .first() + await wait(300) + await requiredTooltip.scrollIntoViewIfNeeded() // Check if error is shown next to field + await wait(300) + await expect(requiredTooltip).toBeInViewport() // toBeVisible() doesn't work for some reason }) })