diff --git a/packages/payload/src/admin/types.ts b/packages/payload/src/admin/types.ts index 5e2ef5c43..c1082b653 100644 --- a/packages/payload/src/admin/types.ts +++ b/packages/payload/src/admin/types.ts @@ -227,8 +227,13 @@ export type MappedClientComponent = | MappedClientComponent + | MappedEmptyComponent | MappedServerComponent | undefined diff --git a/packages/payload/src/auth/baseFields/apiKey.ts b/packages/payload/src/auth/baseFields/apiKey.ts index c53cc9612..64082f0fb 100644 --- a/packages/payload/src/auth/baseFields/apiKey.ts +++ b/packages/payload/src/auth/baseFields/apiKey.ts @@ -13,7 +13,7 @@ export const apiKeyFields = [ type: 'checkbox', admin: { components: { - Field: '@payloadcms/ui/shared#emptyComponent', + Field: false, }, }, label: ({ t }) => t('authentication:enableAPIKey'), @@ -23,7 +23,7 @@ export const apiKeyFields = [ type: 'text', admin: { components: { - Field: '@payloadcms/ui/shared#emptyComponent', + Field: false, }, }, hooks: { diff --git a/packages/payload/src/auth/baseFields/email.ts b/packages/payload/src/auth/baseFields/email.ts index 60bf21668..8cf4caf02 100644 --- a/packages/payload/src/auth/baseFields/email.ts +++ b/packages/payload/src/auth/baseFields/email.ts @@ -7,7 +7,7 @@ export const emailFieldConfig: EmailField = { type: 'email', admin: { components: { - Field: '@payloadcms/ui/shared#emptyComponent', + Field: false, }, }, hooks: { diff --git a/packages/payload/src/auth/baseFields/username.ts b/packages/payload/src/auth/baseFields/username.ts index 9f436a732..4c202f63f 100644 --- a/packages/payload/src/auth/baseFields/username.ts +++ b/packages/payload/src/auth/baseFields/username.ts @@ -7,7 +7,7 @@ export const usernameFieldConfig: TextField = { type: 'text', admin: { components: { - Field: '@payloadcms/ui/shared#emptyComponent', + Field: false, }, }, hooks: { diff --git a/packages/payload/src/auth/baseFields/verification.ts b/packages/payload/src/auth/baseFields/verification.ts index 16ed0fddc..6c41136b4 100644 --- a/packages/payload/src/auth/baseFields/verification.ts +++ b/packages/payload/src/auth/baseFields/verification.ts @@ -26,7 +26,7 @@ export const verificationFields: Field[] = [ }, admin: { components: { - Field: '@payloadcms/ui/shared#emptyComponent', + Field: false, }, }, label: ({ t }) => t('authentication:verified'), diff --git a/packages/payload/src/bin/generateImportMap/parsePayloadComponent.ts b/packages/payload/src/bin/generateImportMap/parsePayloadComponent.ts index 60785586c..588cd2e0d 100644 --- a/packages/payload/src/bin/generateImportMap/parsePayloadComponent.ts +++ b/packages/payload/src/bin/generateImportMap/parsePayloadComponent.ts @@ -4,6 +4,9 @@ export function parsePayloadComponent(payloadComponent: PayloadComponent): { exportName: string path: string } { + if (!payloadComponent) { + return null + } const pathAndMaybeExport = typeof payloadComponent === 'string' ? payloadComponent : payloadComponent.path diff --git a/packages/payload/src/config/types.ts b/packages/payload/src/config/types.ts index 24a0cb135..dfb3e765a 100644 --- a/packages/payload/src/config/types.ts +++ b/packages/payload/src/config/types.ts @@ -13,7 +13,7 @@ import type { default as sharp } from 'sharp' import type { DeepRequired } from 'ts-essentials' import type { RichTextAdapterProvider } from '../admin/RichText.js' -import type { DocumentTabConfig, MappedComponent, RichTextAdapter } from '../admin/types.js' +import type { DocumentTabConfig, RichTextAdapter } from '../admin/types.js' import type { AdminViewConfig, ServerSideEditViewProps } from '../admin/views/types.js' import type { Permissions } from '../auth/index.js' import type { @@ -38,12 +38,12 @@ import type { PayloadLogger } from '../utilities/logger.js' /** * The string path pointing to the React component. If one of the generics is `never`, you effectively mark it as a server-only or client-only component. * - * If the path is an empty string, it will be treated as () => null + * If it is `false` an empty component will be rendered. */ export type PayloadComponent< TComponentServerProps extends never | object = Record, TComponentClientProps extends never | object = Record, -> = RawPayloadComponent | string +> = RawPayloadComponent | false | string // We need the actual object as its own type, otherwise the infers for the PayloadClientReactComponent / PayloadServerReactComponent will not work due to the string union. // We also NEED to actually use those generics for this to work, thus they are part of the props. diff --git a/packages/payload/src/versions/baseFields.ts b/packages/payload/src/versions/baseFields.ts index f9f3a3ded..0fb743d63 100644 --- a/packages/payload/src/versions/baseFields.ts +++ b/packages/payload/src/versions/baseFields.ts @@ -17,7 +17,7 @@ const baseVersionFields: Field[] = [ type: 'select', admin: { components: { - Field: '@payloadcms/ui/shared#emptyComponent', + Field: false, }, disableBulkEdit: true, }, diff --git a/packages/richtext-slate/src/field/elements/textAlign/index.tsx b/packages/richtext-slate/src/field/elements/textAlign/index.tsx index ab4b1ed4d..9acb0ddbe 100644 --- a/packages/richtext-slate/src/field/elements/textAlign/index.tsx +++ b/packages/richtext-slate/src/field/elements/textAlign/index.tsx @@ -3,5 +3,5 @@ import type { RichTextCustomElement } from '../../../types.js' export const textAlign: RichTextCustomElement = { name: 'alignment', Button: '@payloadcms/richtext-slate/client#TextAlignElementButton', - Element: '@payloadcms/ui/shared#emptyComponent', + Element: false, } diff --git a/packages/ui/src/exports/shared/index.ts b/packages/ui/src/exports/shared/index.ts index 9bbc4b4fc..049cee407 100644 --- a/packages/ui/src/exports/shared/index.ts +++ b/packages/ui/src/exports/shared/index.ts @@ -21,5 +21,3 @@ export { } from '../../utilities/groupNavItems.js' export { hasSavePermission } from '../../utilities/hasSavePermission.js' export { isEditing } from '../../utilities/isEditing.js' - -export const emptyComponent = () => null diff --git a/packages/ui/src/providers/Config/RenderComponent.tsx b/packages/ui/src/providers/Config/RenderComponent.tsx index 9f4fe77e0..4f24664e7 100644 --- a/packages/ui/src/providers/Config/RenderComponent.tsx +++ b/packages/ui/src/providers/Config/RenderComponent.tsx @@ -58,6 +58,10 @@ export const RenderComponent: React.FC<{ )) } + if (mappedComponent.type === 'empty') { + return null + } + if (mappedComponent.RenderedComponent) { return mappedComponent.RenderedComponent } diff --git a/packages/ui/src/providers/Config/createClientConfig/collections.tsx b/packages/ui/src/providers/Config/createClientConfig/collections.tsx index cfcf44372..25f802223 100644 --- a/packages/ui/src/providers/Config/createClientConfig/collections.tsx +++ b/packages/ui/src/providers/Config/createClientConfig/collections.tsx @@ -257,7 +257,9 @@ export const createClientCollectionConfig = ({ Component: createMappedComponent( hasEditView && 'Component' in collection.admin.components.views.edit.default && - collection.admin.components.views.edit.default.Component, + collection.admin.components.views.edit.default.Component + ? collection.admin.components.views.edit.default.Component + : null, { collectionSlug: collection.slug, }, @@ -312,7 +314,9 @@ export const createClientCollectionConfig = ({ clientCollection.admin.components.views.list.Component = createMappedComponent( hasListView && 'Component' in collection.admin.components.views.list && - collection.admin.components.views.list.Component, + collection.admin.components.views.list.Component + ? collection.admin.components.views.list.Component + : null, { collectionSlug: collection.slug, }, diff --git a/packages/ui/src/providers/Config/createClientConfig/getComponent.ts b/packages/ui/src/providers/Config/createClientConfig/getComponent.ts index 2e5eec0e0..bf66fe7ca 100644 --- a/packages/ui/src/providers/Config/createClientConfig/getComponent.ts +++ b/packages/ui/src/providers/Config/createClientConfig/getComponent.ts @@ -3,7 +3,7 @@ import type { ImportMap, PayloadComponent, ResolvedComponent } from 'payload' import { parsePayloadComponent } from 'payload/shared' /** - * Gets th resolved React component from `PayloadComponent` from the importMap + * Gets the resolved React component from `PayloadComponent` from the importMap */ export const getComponent = < TComponentServerProps extends object, @@ -23,6 +23,7 @@ export const getComponent = < silent?: boolean }): ResolvedComponent => { if (!payloadComponent) { + // undefined, null or false return { Component: undefined, clientProps: undefined, diff --git a/packages/ui/src/providers/Config/createClientConfig/getCreateMappedComponent.tsx b/packages/ui/src/providers/Config/createClientConfig/getCreateMappedComponent.tsx index a177192d7..decff2fb2 100644 --- a/packages/ui/src/providers/Config/createClientConfig/getCreateMappedComponent.tsx +++ b/packages/ui/src/providers/Config/createClientConfig/getCreateMappedComponent.tsx @@ -31,7 +31,7 @@ export function getCreateMappedComponent({ Fallback: React.FC, identifier: string, ): MappedComponent => { - if (!payloadComponent) { + if (payloadComponent === undefined || payloadComponent === null) { if (!Fallback) { return undefined } @@ -55,6 +55,12 @@ export function getCreateMappedComponent({ } } + if (payloadComponent === false) { + return { + type: 'empty', + } + } + const resolvedComponent = payloadComponent && typeof payloadComponent === 'object' && @@ -107,7 +113,7 @@ export function getCreateMappedComponent({ fallback, identifier, ) => { - if (!payloadComponent && !fallback) { + if ((payloadComponent === undefined || payloadComponent === null) && !fallback) { return undefined as any } diff --git a/packages/ui/src/providers/Config/createClientConfig/globals.tsx b/packages/ui/src/providers/Config/createClientConfig/globals.tsx index 8cbeaca96..6ad7b3e8e 100644 --- a/packages/ui/src/providers/Config/createClientConfig/globals.tsx +++ b/packages/ui/src/providers/Config/createClientConfig/globals.tsx @@ -138,7 +138,9 @@ export const createClientGlobalConfig = ({ Component: createMappedComponent( hasEditView && 'Component' in global.admin.components.views.edit.default && - global.admin.components.views.edit.default.Component, + global.admin.components.views.edit.default.Component + ? global.admin.components.views.edit.default.Component + : null, { globalSlug: global.slug, },