import { jsx as _jsx } from "react/jsx-runtime"; import { getTranslation } from '@payloadcms/translations'; import { createClientField, MissingEditorProp } from 'payload'; import { fieldIsHiddenOrDisabled } from 'payload/shared'; import { RenderServerComponent } from '../../elements/RenderServerComponent/index.js'; // eslint-disable-next-line payload/no-imports-from-exports-dir -- MUST reference the exports dir: https://github.com/payloadcms/payload/issues/12002#issuecomment-2791493587 import { FieldDescription, WatchCondition } from '../../exports/client/index.js'; const defaultUIFieldComponentKeys = ['Cell', 'Description', 'Field', 'Filter']; export const renderField = ({ id, clientFieldSchemaMap, collectionSlug, data, fieldConfig, fieldSchemaMap, fieldState, forceCreateClientField, formState, indexPath, lastRenderedPath, mockRSCs, operation, parentPath, parentSchemaPath, path, permissions, preferences, readOnly: readOnlyFromProps, renderAllFields, req, schemaPath, siblingData }) => { // Fields with beforeInput/afterInput need custom components created, so they require render const hasBeforeOrAfterInput = fieldConfig.admin?.components && ('beforeInput' in fieldConfig.admin.components || 'afterInput' in fieldConfig.admin.components); const requiresRender = renderAllFields || !lastRenderedPath || lastRenderedPath !== path || hasBeforeOrAfterInput; if (!requiresRender && fieldConfig.type !== 'array' && fieldConfig.type !== 'blocks') { return; } const clientField = clientFieldSchemaMap && !forceCreateClientField ? clientFieldSchemaMap.get(schemaPath) : createClientField({ defaultIDType: req.payload.config.db.defaultIDType, field: fieldConfig, i18n: req.i18n, importMap: req.payload.importMap }); const clientProps = { field: clientField, path, permissions, readOnly: readOnlyFromProps === true ? true : typeof permissions === 'boolean' ? !permissions : !permissions?.[operation], schemaPath }; if (fieldState?.customComponents) { clientProps.customComponents = fieldState.customComponents; } // fields with subfields if (['array', 'blocks', 'collapsible', 'group', 'row', 'tabs'].includes(fieldConfig.type)) { clientProps.indexPath = indexPath; clientProps.parentPath = parentPath; clientProps.parentSchemaPath = parentSchemaPath; } const serverProps = { id, clientField, clientFieldSchemaMap, data, field: fieldConfig, fieldSchemaMap, permissions, // TODO: Should we pass explicit values? initialValue, value, valid // value and initialValue should be typed collectionSlug, formState, i18n: req.i18n, operation, payload: req.payload, preferences, req, siblingData, user: req.user, value: 'name' in fieldConfig && data?.[fieldConfig.name] }; switch (fieldConfig.type) { case 'array': { fieldState?.rows?.forEach((row, rowIndex) => { const rowLastRenderedPath = row.lastRenderedPath; const rowPath = `${path}.${rowIndex}`; const rowRequiresRender = renderAllFields || !rowLastRenderedPath || rowLastRenderedPath !== rowPath; if (!rowRequiresRender) { return; } row.lastRenderedPath = rowPath; if (fieldConfig.admin?.components && 'RowLabel' in fieldConfig.admin.components) { if (!row.customComponents) { row.customComponents = {}; } row.customComponents.RowLabel = !mockRSCs ? RenderServerComponent({ clientProps, Component: fieldConfig.admin.components.RowLabel, importMap: req.payload.importMap, key: `${rowIndex}`, serverProps: { ...serverProps, rowLabel: `${getTranslation(fieldConfig.labels.singular, req.i18n)} ${String(rowIndex + 1).padStart(2, '0')}`, rowNumber: rowIndex + 1 } }) : 'Mock'; } }); break; } case 'blocks': { fieldState?.rows?.forEach((row, rowIndex) => { const rowLastRenderedPath = row.lastRenderedPath; const rowPath = `${path}.${rowIndex}`; const rowRequiresRender = renderAllFields || !rowLastRenderedPath || rowLastRenderedPath !== rowPath; if (!rowRequiresRender) { return; } row.lastRenderedPath = rowPath; const blockTypeToMatch = row.blockType; const blockConfig = req.payload.blocks[blockTypeToMatch] ?? (fieldConfig.blockReferences ?? fieldConfig.blocks).find(block => typeof block !== 'string' && block.slug === blockTypeToMatch); if (blockConfig.admin?.components && 'Label' in blockConfig.admin.components) { if (!fieldState.rows[rowIndex]?.customComponents) { fieldState.rows[rowIndex].customComponents = {}; } fieldState.rows[rowIndex].customComponents.RowLabel = !mockRSCs ? RenderServerComponent({ clientProps, Component: blockConfig.admin.components.Label, importMap: req.payload.importMap, key: `${rowIndex}`, serverProps: { ...serverProps, blockType: row.blockType, rowLabel: `${getTranslation(blockConfig.labels.singular, req.i18n)} ${String(rowIndex + 1).padStart(2, '0')}`, rowNumber: rowIndex + 1 } }) : 'Mock'; } }); break; } } if (!requiresRender) { return; } /** * Set the `lastRenderedPath` equal to the new path of the field, this will prevent it from being rendered again */ fieldState.lastRenderedPath = path; if (fieldIsHiddenOrDisabled(clientField)) { return; } /** * Only create the `customComponents` object if needed. * This will prevent unnecessary data from being transferred to the client. */ if (fieldConfig.admin) { if ((Object.keys(fieldConfig.admin.components || {}).length > 0 || fieldConfig.type === 'richText' || 'description' in fieldConfig.admin && typeof fieldConfig.admin.description === 'function') && !fieldState?.customComponents) { fieldState.customComponents = {}; } } switch (fieldConfig.type) { case 'richText': { if (!fieldConfig?.editor) { throw new MissingEditorProp(fieldConfig) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor ; } if (typeof fieldConfig?.editor === 'function') { throw new Error('Attempted to access unsanitized rich text editor.'); } if (!fieldConfig.admin) { fieldConfig.admin = {}; } if (!fieldConfig.admin.components) { fieldConfig.admin.components = {}; } fieldState.customComponents.Field = !mockRSCs ? /*#__PURE__*/_jsx(WatchCondition, { path: path, children: RenderServerComponent({ clientProps, Component: fieldConfig.editor.FieldComponent, importMap: req.payload.importMap, serverProps: { ...serverProps, // Manually inject lexical-specific `sanitizedEditorConfig` server prop, in order to reduce the size of the field schema. // Otherwise, the editorConfig would be included twice - once on the top-level, and once as part of the `FieldComponent` server props. sanitizedEditorConfig: 'editorConfig' in fieldConfig.editor ? fieldConfig.editor.editorConfig : undefined } }) }) : 'Mock'; break; } case 'ui': { if (fieldConfig?.admin?.components) { // Render any extra, untyped components for (const key in fieldConfig.admin.components) { if (key in defaultUIFieldComponentKeys) { continue; } const Component = fieldConfig.admin.components[key]; fieldState.customComponents[key] = !mockRSCs ? RenderServerComponent({ clientProps, Component, importMap: req.payload.importMap, key: `field.admin.components.${key}`, serverProps }) : 'Mock'; } } break; } default: { break; } } if (fieldConfig.admin) { if ('description' in fieldConfig.admin && typeof fieldConfig.admin?.description === 'function') { fieldState.customComponents.Description = !mockRSCs ? /*#__PURE__*/_jsx(FieldDescription, { description: fieldConfig.admin?.description({ i18n: req.i18n, t: req.i18n.t }), path: path }) : 'Mock'; } if (fieldConfig.admin?.components) { if ('afterInput' in fieldConfig.admin.components) { fieldState.customComponents.AfterInput = !mockRSCs ? RenderServerComponent({ clientProps, Component: fieldConfig.admin.components.afterInput, importMap: req.payload.importMap, key: `field.admin.components.afterInput.${path}`, serverProps }) : 'Mock'; } if ('beforeInput' in fieldConfig.admin.components) { fieldState.customComponents.BeforeInput = !mockRSCs ? RenderServerComponent({ clientProps, Component: fieldConfig.admin.components.beforeInput, importMap: req.payload.importMap, key: `field.admin.components.beforeInput.${path}`, serverProps }) : 'Mock'; } if ('Description' in fieldConfig.admin.components) { fieldState.customComponents.Description = !mockRSCs ? RenderServerComponent({ clientProps, Component: fieldConfig.admin.components.Description, importMap: req.payload.importMap, key: 'field.admin.components.Description', serverProps }) : 'Mock'; } if ('Error' in fieldConfig.admin.components) { fieldState.customComponents.Error = !mockRSCs ? RenderServerComponent({ clientProps, Component: fieldConfig.admin.components.Error, importMap: req.payload.importMap, key: 'field.admin.components.Error', serverProps }) : 'Mock'; } if ('Label' in fieldConfig.admin.components) { fieldState.customComponents.Label = !mockRSCs ? RenderServerComponent({ clientProps, Component: fieldConfig.admin.components.Label, importMap: req.payload.importMap, key: 'field.admin.components.Label', serverProps }) : 'Mock'; } if ('Field' in fieldConfig.admin.components) { fieldState.customComponents.Field = !mockRSCs ? /*#__PURE__*/_jsx(WatchCondition, { path: path, children: RenderServerComponent({ clientProps, Component: fieldConfig.admin.components.Field, importMap: req.payload.importMap, key: 'field.admin.components.Field', serverProps }) }) : 'Mock'; } } } }; //# sourceMappingURL=renderField.js.map