diff --git a/docs/admin/fields.mdx b/docs/admin/fields.mdx index 8b3dad20ba..21ae641009 100644 --- a/docs/admin/fields.mdx +++ b/docs/admin/fields.mdx @@ -266,12 +266,10 @@ export const myField: Field = { _For details on how to build Custom Components, see [Building Custom Components](./components#building-custom-components)._ -All Label Components receive the following props: +Custom Label Components receive all [Field Component](#the-field-component) props, plus the following props: | Property | Description | | -------------- | ---------------------------------------------------------------- | -| **`label`** | Label value provided in field, it can be used with i18n. | -| **`required`** | The `admin.required` property defined in the [Field Config](../fields/overview). | | **`schemaPath`** | The path to the field in the schema. Similar to `path`, but without dynamic indices. | @@ -279,6 +277,36 @@ All Label Components receive the following props: All [Custom Server Components](./components) receive the `payload` and `i18n` properties by default. See [Building Custom Components](./components#building-custom-components) for more details. +#### TypeScript + +When building Custom Error Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Error Component, one for every [Field Type](../fields/overview). The convention is to append `ErrorComponent` to the type of field, i.e. `TextFieldErrorComponent`. + +```tsx +import type { + ArrayFieldLabelComponent, + BlocksFieldLabelComponent, + CheckboxFieldLabelComponent, + CodeFieldLabelComponent, + CollapsibleFieldLabelComponent, + DateFieldLabelComponent, + EmailFieldLabelComponent, + GroupFieldLabelComponent, + HiddenFieldLabelComponent, + JSONFieldLabelComponent, + NumberFieldLabelComponent, + PointFieldLabelComponent, + RadioFieldLabelComponent, + RelationshipFieldLabelComponent, + RichTextFieldLabelComponent, + RowFieldLabelComponent, + SelectFieldLabelComponent, + TabsFieldLabelComponent, + TextFieldLabelComponent, + TextareaFieldLabelComponent, + UploadFieldLabelComponent +} from 'payload' +``` + ### The Error Component The Error Component is rendered when a field fails validation. It is typically displayed beneath the field input in a visually-compelling style. @@ -301,7 +329,7 @@ export const myField: Field = { _For details on how to build Custom Components, see [Building Custom Components](./components#building-custom-components)._ -All Error Components receive the following props: +Custom Error Components receive all [Field Component](#the-field-component) props, plus the following props: | Property | Description | | --------------- | ------------------------------------------------------------- | @@ -312,6 +340,36 @@ All Error Components receive the following props: All [Custom Server Components](./components) receive the `payload` and `i18n` properties by default. See [Building Custom Components](./components#building-custom-components) for more details. +#### TypeScript + +When building Custom Error Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Error Component, one for every [Field Type](../fields/overview). The convention is to append `ErrorComponent` to the type of field, i.e. `TextFieldErrorComponent`. + +```tsx +import type { + ArrayFieldErrorComponent, + BlocksFieldErrorComponent, + CheckboxFieldErrorComponent, + CodeFieldErrorComponent, + CollapsibleFieldErrorComponent, + DateFieldErrorComponent, + EmailFieldErrorComponent, + GroupFieldErrorComponent, + HiddenFieldErrorComponent, + JSONFieldErrorComponent, + NumberFieldErrorComponent, + PointFieldErrorComponent, + RadioFieldErrorComponent, + RelationshipFieldErrorComponent, + RichTextFieldErrorComponent, + RowFieldErrorComponent, + SelectFieldErrorComponent, + TabsFieldErrorComponent, + TextFieldErrorComponent, + TextareaFieldErrorComponent, + UploadFieldErrorComponent +} from 'payload' +``` + ### The Description Property Field Descriptions are used to provide additional information to the editor about a field, such as special instructions. Their placement varies from field to field, but typically are displayed with subtle style differences beneath the field inputs. @@ -406,7 +464,7 @@ export const MyCollectionConfig: SanitizedCollectionConfig = { _For details on how to build a Custom Description, see [Building Custom Components](./components#building-custom-components)._ -All Description Components receive the following props: +Custom Description Components receive all [Field Component](#the-field-component) props, plus the following props: | Property | Description | | -------------- | ---------------------------------------------------------------- | @@ -417,6 +475,36 @@ All Description Components receive the following props: All [Custom Server Components](./components) receive the `payload` and `i18n` properties by default. See [Building Custom Components](./components#building-custom-components) for more details. +#### TypeScript + +When building Custom Description Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Description Component, one for every [Field Type](../fields/overview). The convention is to append `DescriptionComponent` to the type of field, i.e. `TextFieldDescriptionComponent`. + +```tsx +import type { + ArrayFieldDescriptionComponent, + BlocksFieldDescriptionComponent, + CheckboxFieldDescriptionComponent, + CodeFieldDescriptionComponent, + CollapsibleFieldDescriptionComponent, + DateFieldDescriptionComponent, + EmailFieldDescriptionComponent, + GroupFieldDescriptionComponent, + HiddenFieldDescriptionComponent, + JSONFieldDescriptionComponent, + NumberFieldDescriptionComponent, + PointFieldDescriptionComponent, + RadioFieldDescriptionComponent, + RelationshipFieldDescriptionComponent, + RichTextFieldDescriptionComponent, + RowFieldDescriptionComponent, + SelectFieldDescriptionComponent, + TabsFieldDescriptionComponent, + TextFieldDescriptionComponent, + TextareaFieldDescriptionComponent, + UploadFieldDescriptionComponent +} from 'payload' +``` + ### afterInput and beforeInput With these properties you can add multiple components _before_ and _after_ the input element, as their name suggests. This is useful when you need to render additional elements alongside the field without replacing the entire field component. diff --git a/docs/migration-guide/overview.mdx b/docs/migration-guide/overview.mdx index ff1ee1e2b9..00bd1348a1 100644 --- a/docs/migration-guide/overview.mdx +++ b/docs/migration-guide/overview.mdx @@ -335,7 +335,6 @@ import { FieldMap, File, Form, - FormFieldBase, FormLoadingOverlayToggle, FormSubmit, GenerateConfirmation, diff --git a/packages/create-payload-app/src/lib/wrap-next-config.ts b/packages/create-payload-app/src/lib/wrap-next-config.ts index b2e1e208a9..cf9626f4ee 100644 --- a/packages/create-payload-app/src/lib/wrap-next-config.ts +++ b/packages/create-payload-app/src/lib/wrap-next-config.ts @@ -138,7 +138,7 @@ export async function parseAndModifyConfigContent( (m) => m.type === 'ExportDefaultExpression' && (m.expression.type === 'Identifier' || m.expression.type === 'CallExpression'), - ) as ExportDefaultExpression | undefined + ) if (exportDefaultDeclaration) { if (!('span' in exportDefaultDeclaration.expression)) { diff --git a/packages/drizzle/src/transform/read/traverseFields.ts b/packages/drizzle/src/transform/read/traverseFields.ts index ef28c8cc3f..a899079f9a 100644 --- a/packages/drizzle/src/transform/read/traverseFields.ts +++ b/packages/drizzle/src/transform/read/traverseFields.ts @@ -1,5 +1,4 @@ - -import type { Field, SanitizedConfig , TabAsField } from 'payload' +import type { Field, SanitizedConfig, TabAsField } from 'payload' import { fieldAffectsData } from 'payload/shared' diff --git a/packages/next/src/views/LivePreview/index.client.tsx b/packages/next/src/views/LivePreview/index.client.tsx index 688de86fc3..d696c6e5e9 100644 --- a/packages/next/src/views/LivePreview/index.client.tsx +++ b/packages/next/src/views/LivePreview/index.client.tsx @@ -1,11 +1,11 @@ 'use client' import type { FormProps } from '@payloadcms/ui' -import type { FieldMap } from '@payloadcms/ui/utilities/buildComponentMap' import type { ClientCollectionConfig, ClientConfig, ClientGlobalConfig, Data, + FieldMap, LivePreviewConfig, } from 'payload' diff --git a/packages/next/src/views/Version/Default/SetStepNav.tsx b/packages/next/src/views/Version/Default/SetStepNav.tsx index 3efb70ff6b..4c26643465 100644 --- a/packages/next/src/views/Version/Default/SetStepNav.tsx +++ b/packages/next/src/views/Version/Default/SetStepNav.tsx @@ -1,6 +1,5 @@ import type { StepNavItem } from '@payloadcms/ui' -import type { FieldMap } from '@payloadcms/ui/utilities/buildComponentMap' -import type { ClientCollectionConfig, ClientGlobalConfig } from 'payload' +import type { ClientCollectionConfig, ClientGlobalConfig, FieldMap } from 'payload' import type React from 'react' import { getTranslation } from '@payloadcms/translations' diff --git a/packages/next/src/views/Version/RenderFieldsToDiff/fields/Iterable/index.tsx b/packages/next/src/views/Version/RenderFieldsToDiff/fields/Iterable/index.tsx index 29e674a212..c8788515a1 100644 --- a/packages/next/src/views/Version/RenderFieldsToDiff/fields/Iterable/index.tsx +++ b/packages/next/src/views/Version/RenderFieldsToDiff/fields/Iterable/index.tsx @@ -1,4 +1,4 @@ -import type { MappedField } from '@payloadcms/ui/utilities/buildComponentMap' +import type { MappedField } from 'payload' import { getTranslation } from '@payloadcms/translations' import { getUniqueListBy } from 'payload/shared' diff --git a/packages/next/src/views/Version/RenderFieldsToDiff/fields/Relationship/index.tsx b/packages/next/src/views/Version/RenderFieldsToDiff/fields/Relationship/index.tsx index 9c5ae384ef..4dbc06da68 100644 --- a/packages/next/src/views/Version/RenderFieldsToDiff/fields/Relationship/index.tsx +++ b/packages/next/src/views/Version/RenderFieldsToDiff/fields/Relationship/index.tsx @@ -1,8 +1,8 @@ 'use client' -import type { ClientCollectionConfig } from 'payload' +import type { ClientCollectionConfig, MappedField } from 'payload' import { getTranslation } from '@payloadcms/translations' -import { type MappedField, useConfig } from '@payloadcms/ui' +import { useConfig } from '@payloadcms/ui' import { fieldAffectsData, fieldIsPresentationalOnly } from 'payload/shared' import React from 'react' import ReactDiffViewerImport from 'react-diff-viewer-continued' diff --git a/packages/next/src/views/Version/RenderFieldsToDiff/fields/Select/index.tsx b/packages/next/src/views/Version/RenderFieldsToDiff/fields/Select/index.tsx index 85b294cdfc..54d692fc75 100644 --- a/packages/next/src/views/Version/RenderFieldsToDiff/fields/Select/index.tsx +++ b/packages/next/src/views/Version/RenderFieldsToDiff/fields/Select/index.tsx @@ -1,7 +1,5 @@ import type { I18nClient } from '@payloadcms/translations' -import type { SelectFieldProps } from '@payloadcms/ui' -import type { MappedField } from '@payloadcms/ui/utilities/buildComponentMap' -import type { OptionObject, SelectField } from 'payload' +import type { MappedField, OptionObject, SelectField, SelectFieldProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import React from 'react' diff --git a/packages/next/src/views/Version/RenderFieldsToDiff/fields/Tabs/index.tsx b/packages/next/src/views/Version/RenderFieldsToDiff/fields/Tabs/index.tsx index adc5a689a5..b984f4096c 100644 --- a/packages/next/src/views/Version/RenderFieldsToDiff/fields/Tabs/index.tsx +++ b/packages/next/src/views/Version/RenderFieldsToDiff/fields/Tabs/index.tsx @@ -1,4 +1,4 @@ -import type { MappedField, TabsFieldProps } from '@payloadcms/ui' +import type { MappedField, TabsFieldProps } from 'payload' import React from 'react' diff --git a/packages/next/src/views/Version/RenderFieldsToDiff/fields/types.ts b/packages/next/src/views/Version/RenderFieldsToDiff/fields/types.ts index 74488f4e51..c032cb0462 100644 --- a/packages/next/src/views/Version/RenderFieldsToDiff/fields/types.ts +++ b/packages/next/src/views/Version/RenderFieldsToDiff/fields/types.ts @@ -1,6 +1,5 @@ import type { I18nClient } from '@payloadcms/translations' -import type { FieldMap, MappedField } from '@payloadcms/ui/utilities/buildComponentMap' -import type { FieldPermissions } from 'payload' +import type { FieldMap, FieldPermissions, MappedField } from 'payload' import type React from 'react' import type { DiffMethod } from 'react-diff-viewer-continued' diff --git a/packages/next/src/views/Version/RenderFieldsToDiff/types.ts b/packages/next/src/views/Version/RenderFieldsToDiff/types.ts index a9205769ef..265d9e9b5d 100644 --- a/packages/next/src/views/Version/RenderFieldsToDiff/types.ts +++ b/packages/next/src/views/Version/RenderFieldsToDiff/types.ts @@ -1,6 +1,5 @@ import type { I18nClient } from '@payloadcms/translations' -import type { FieldMap, MappedField } from '@payloadcms/ui/utilities/buildComponentMap' -import type { FieldPermissions } from 'payload' +import type { FieldMap, FieldPermissions, MappedField } from 'payload' import type { DiffMethod } from 'react-diff-viewer-continued' import type { DiffComponents } from './fields/types.js' diff --git a/packages/payload/src/admin/elements/Cell.ts b/packages/payload/src/admin/elements/Cell.ts index 97fc349f29..4f07ec6e51 100644 --- a/packages/payload/src/admin/elements/Cell.ts +++ b/packages/payload/src/admin/elements/Cell.ts @@ -8,6 +8,7 @@ import type { RelationshipField, SelectField, } from '../../fields/config/types.js' +import type { FormFieldBase } from '../types.js' export type RowData = Record @@ -20,7 +21,7 @@ export type CellComponentProps = { dateDisplayFormat?: DateField['admin']['date']['displayFormat'] fieldType?: Field['type'] isFieldAffectingData?: boolean - label?: Record | string + label?: FormFieldBase['label'] labels?: Labels link?: boolean name: FieldBase['name'] diff --git a/packages/payload/src/admin/fields/Array.ts b/packages/payload/src/admin/fields/Array.ts new file mode 100644 index 0000000000..0721189a87 --- /dev/null +++ b/packages/payload/src/admin/fields/Array.ts @@ -0,0 +1,22 @@ +import type { ArrayField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { FieldMap } from '../forms/FieldMap.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type ArrayFieldProps = { + CustomRowLabel?: React.ReactNode + fieldMap: FieldMap + forceRender?: boolean + isSortable?: boolean + labels?: ArrayField['labels'] + maxRows?: ArrayField['maxRows'] + minRows?: ArrayField['minRows'] + name?: string + width?: string +} & FormFieldBase + +export type ArrayFieldLabelComponent = LabelComponent<'array'> + +export type ArrayFieldDescriptionComponent = DescriptionComponent<'array'> + +export type ArrayFieldErrorComponent = ErrorComponent<'array'> diff --git a/packages/payload/src/admin/fields/Blocks.ts b/packages/payload/src/admin/fields/Blocks.ts new file mode 100644 index 0000000000..494702e1a6 --- /dev/null +++ b/packages/payload/src/admin/fields/Blocks.ts @@ -0,0 +1,32 @@ +import type { Block, BlockField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { FieldMap } from '../forms/FieldMap.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type BlocksFieldProps = { + blocks?: ReducedBlock[] + forceRender?: boolean + isSortable?: boolean + labels?: BlockField['labels'] + maxRows?: number + minRows?: number + name?: string + slug?: string + width?: string +} & FormFieldBase + +export type ReducedBlock = { + LabelComponent: Block['admin']['components']['Label'] + custom?: Record + fieldMap: FieldMap + imageAltText?: string + imageURL?: string + labels: BlockField['labels'] + slug: string +} + +export type BlocksFieldLabelComponent = LabelComponent<'blocks'> + +export type BlocksFieldDescriptionComponent = DescriptionComponent<'blocks'> + +export type BlocksFieldErrorComponent = ErrorComponent<'blocks'> diff --git a/packages/payload/src/admin/fields/Checkbox.ts b/packages/payload/src/admin/fields/Checkbox.ts new file mode 100644 index 0000000000..5fa9c22502 --- /dev/null +++ b/packages/payload/src/admin/fields/Checkbox.ts @@ -0,0 +1,19 @@ +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type CheckboxFieldProps = { + checked?: boolean + disableFormData?: boolean + id?: string + name?: string + onChange?: (val: boolean) => void + partialChecked?: boolean + path?: string + width?: string +} & FormFieldBase + +export type CheckboxFieldLabelComponent = LabelComponent<'checkbox'> + +export type CheckboxFieldDescriptionComponent = DescriptionComponent<'checkbox'> + +export type CheckboxFieldErrorComponent = ErrorComponent<'checkbox'> diff --git a/packages/payload/src/admin/fields/Code.ts b/packages/payload/src/admin/fields/Code.ts new file mode 100644 index 0000000000..dd9158369a --- /dev/null +++ b/packages/payload/src/admin/fields/Code.ts @@ -0,0 +1,17 @@ +import type { CodeField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type CodeFieldProps = { + editorOptions?: CodeField['admin']['editorOptions'] + language?: CodeField['admin']['language'] + name?: string + path?: string + width: string +} & FormFieldBase + +export type CodeFieldLabelComponent = LabelComponent<'code'> + +export type CodeFieldDescriptionComponent = DescriptionComponent<'code'> + +export type CodeFieldErrorComponent = ErrorComponent<'code'> diff --git a/packages/payload/src/admin/fields/Collapsible.ts b/packages/payload/src/admin/fields/Collapsible.ts new file mode 100644 index 0000000000..602c728be0 --- /dev/null +++ b/packages/payload/src/admin/fields/Collapsible.ts @@ -0,0 +1,15 @@ +import type { ErrorComponent } from '../forms/Error.js' +import type { FieldMap } from '../forms/FieldMap.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type CollapsibleFieldProps = { + fieldMap: FieldMap + initCollapsed?: boolean + width?: string +} & FormFieldBase + +export type CollapsibleFieldLabelComponent = LabelComponent<'collapsible'> + +export type CollapsibleFieldDescriptionComponent = DescriptionComponent<'collapsible'> + +export type CollapsibleFieldErrorComponent = ErrorComponent<'collapsible'> diff --git a/packages/payload/src/admin/fields/Date.ts b/packages/payload/src/admin/fields/Date.ts new file mode 100644 index 0000000000..9c40c6ee28 --- /dev/null +++ b/packages/payload/src/admin/fields/Date.ts @@ -0,0 +1,17 @@ +import type { DateField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type DateFieldProps = { + date?: DateField['admin']['date'] + name?: string + path?: string + placeholder?: DateField['admin']['placeholder'] | string + width?: string +} & FormFieldBase + +export type DateFieldLabelComponent = LabelComponent<'date'> + +export type DateFieldDescriptionComponent = DescriptionComponent<'date'> + +export type DateFieldErrorComponent = ErrorComponent<'date'> diff --git a/packages/payload/src/admin/fields/Email.ts b/packages/payload/src/admin/fields/Email.ts new file mode 100644 index 0000000000..3b6aef47d7 --- /dev/null +++ b/packages/payload/src/admin/fields/Email.ts @@ -0,0 +1,17 @@ +import type { EmailField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type EmailFieldProps = { + autoComplete?: string + name?: string + path?: string + placeholder?: EmailField['admin']['placeholder'] + width?: string +} & FormFieldBase + +export type EmailFieldLabelComponent = LabelComponent<'email'> + +export type EmailFieldDescriptionComponent = DescriptionComponent<'email'> + +export type EmailFieldErrorComponent = ErrorComponent<'email'> diff --git a/packages/payload/src/admin/fields/Group.ts b/packages/payload/src/admin/fields/Group.ts new file mode 100644 index 0000000000..d8d183c0e2 --- /dev/null +++ b/packages/payload/src/admin/fields/Group.ts @@ -0,0 +1,17 @@ +import type { ErrorComponent } from '../forms/Error.js' +import type { FieldMap } from '../forms/FieldMap.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type GroupFieldProps = { + fieldMap: FieldMap + forceRender?: boolean + hideGutter?: boolean + name?: string + width?: string +} & FormFieldBase + +export type GroupFieldLabelComponent = LabelComponent<'group'> + +export type GroupFieldDescriptionComponent = DescriptionComponent<'group'> + +export type GroupFieldErrorComponent = ErrorComponent<'group'> diff --git a/packages/payload/src/admin/fields/Hidden.ts b/packages/payload/src/admin/fields/Hidden.ts new file mode 100644 index 0000000000..5cfeeda1d7 --- /dev/null +++ b/packages/payload/src/admin/fields/Hidden.ts @@ -0,0 +1,16 @@ +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type HiddenFieldProps = { + disableModifyingForm?: false + forceUsePathFromProps?: boolean + name?: string + path?: string + value?: unknown +} & FormFieldBase + +export type HiddenFieldLabelComponent = LabelComponent<'hidden'> + +export type HiddenFieldDescriptionComponent = DescriptionComponent<'hidden'> + +export type HiddenFieldErrorComponent = ErrorComponent<'hidden'> diff --git a/packages/payload/src/admin/fields/JSON.ts b/packages/payload/src/admin/fields/JSON.ts new file mode 100644 index 0000000000..3d1d9bf57d --- /dev/null +++ b/packages/payload/src/admin/fields/JSON.ts @@ -0,0 +1,17 @@ +import type { JSONField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type JSONFieldProps = { + editorOptions?: JSONField['admin']['editorOptions'] + jsonSchema?: Record + name?: string + path?: string + width?: string +} & FormFieldBase + +export type JSONFieldLabelComponent = LabelComponent<'json'> + +export type JSONFieldDescriptionComponent = DescriptionComponent<'json'> + +export type JSONFieldErrorComponent = ErrorComponent<'json'> diff --git a/packages/payload/src/admin/fields/Number.ts b/packages/payload/src/admin/fields/Number.ts new file mode 100644 index 0000000000..94a18bd8cc --- /dev/null +++ b/packages/payload/src/admin/fields/Number.ts @@ -0,0 +1,22 @@ +import type { NumberField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type NumberFieldProps = { + hasMany?: boolean + max?: number + maxRows?: number + min?: number + name?: string + onChange?: (e: number) => void + path?: string + placeholder?: NumberField['admin']['placeholder'] + step?: number + width?: string +} & FormFieldBase + +export type NumberFieldLabelComponent = LabelComponent<'number'> + +export type NumberFieldDescriptionComponent = DescriptionComponent<'number'> + +export type NumberFieldErrorComponent = ErrorComponent<'number'> diff --git a/packages/payload/src/admin/fields/Point.ts b/packages/payload/src/admin/fields/Point.ts new file mode 100644 index 0000000000..0a60c9d062 --- /dev/null +++ b/packages/payload/src/admin/fields/Point.ts @@ -0,0 +1,16 @@ +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type PointFieldProps = { + name?: string + path?: string + placeholder?: string + step?: number + width?: string +} & FormFieldBase + +export type PointFieldLabelComponent = LabelComponent<'point'> + +export type PointFieldDescriptionComponent = DescriptionComponent<'point'> + +export type PointFieldErrorComponent = ErrorComponent<'point'> diff --git a/packages/payload/src/admin/fields/Radio.ts b/packages/payload/src/admin/fields/Radio.ts new file mode 100644 index 0000000000..19a4c18274 --- /dev/null +++ b/packages/payload/src/admin/fields/Radio.ts @@ -0,0 +1,21 @@ +import type { Option } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type RadioFieldProps = { + layout?: 'horizontal' | 'vertical' + name?: string + onChange?: OnChange + options?: Option[] + path?: string + value?: string + width?: string +} & FormFieldBase + +export type OnChange = (value: T) => void + +export type RadioFieldLabelComponent = LabelComponent<'radio'> + +export type RadioFieldDescriptionComponent = DescriptionComponent<'radio'> + +export type RadioFieldErrorComponent = ErrorComponent<'radio'> diff --git a/packages/payload/src/admin/fields/Relationship.ts b/packages/payload/src/admin/fields/Relationship.ts new file mode 100644 index 0000000000..525cec6963 --- /dev/null +++ b/packages/payload/src/admin/fields/Relationship.ts @@ -0,0 +1,19 @@ +import type { RelationshipField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type RelationshipFieldProps = { + allowCreate?: RelationshipField['admin']['allowCreate'] + hasMany?: boolean + isSortable?: boolean + name: string + relationTo?: RelationshipField['relationTo'] + sortOptions?: RelationshipField['admin']['sortOptions'] + width?: string +} & FormFieldBase + +export type RelationshipFieldLabelComponent = LabelComponent<'relationship'> + +export type RelationshipFieldDescriptionComponent = DescriptionComponent<'relationship'> + +export type RelationshipFieldErrorComponent = ErrorComponent<'relationship'> diff --git a/packages/payload/src/admin/fields/RichText.ts b/packages/payload/src/admin/fields/RichText.ts new file mode 100644 index 0000000000..ce4707ecef --- /dev/null +++ b/packages/payload/src/admin/fields/RichText.ts @@ -0,0 +1,15 @@ +import type { ErrorComponent } from '../forms/Error.js' +import type { MappedField } from '../forms/FieldMap.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type RichTextComponentProps = { + name: string + richTextComponentMap?: Map + width?: string +} & FormFieldBase + +export type RichTextFieldLabelComponent = LabelComponent<'richText'> + +export type RichTextFieldDescriptionComponent = DescriptionComponent<'richText'> + +export type RichTextFieldErrorComponent = ErrorComponent<'richText'> diff --git a/packages/payload/src/admin/fields/Row.ts b/packages/payload/src/admin/fields/Row.ts new file mode 100644 index 0000000000..e3734e8af2 --- /dev/null +++ b/packages/payload/src/admin/fields/Row.ts @@ -0,0 +1,18 @@ +import type { DescriptionComponent, FormFieldBase, LabelComponent } from 'payload' + +import type { ErrorComponent } from '../forms/Error.js' +import type { FieldMap } from '../forms/FieldMap.js' + +export type RowFieldProps = { + fieldMap: FieldMap + forceRender?: boolean + indexPath: string + path?: string + width?: string +} & FormFieldBase + +export type RowFieldLabelComponent = LabelComponent<'row'> + +export type RowFieldDescriptionComponent = DescriptionComponent<'row'> + +export type RowFieldErrorComponent = ErrorComponent<'row'> diff --git a/packages/payload/src/admin/fields/Select.ts b/packages/payload/src/admin/fields/Select.ts new file mode 100644 index 0000000000..4c830f0b67 --- /dev/null +++ b/packages/payload/src/admin/fields/Select.ts @@ -0,0 +1,21 @@ +import type { Option } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type SelectFieldProps = { + hasMany?: boolean + isClearable?: boolean + isSortable?: boolean + name?: string + onChange?: (e: string | string[]) => void + options?: Option[] + path?: string + value?: string + width?: string +} & FormFieldBase + +export type SelectFieldLabelComponent = LabelComponent<'select'> + +export type SelectFieldDescriptionComponent = DescriptionComponent<'select'> + +export type SelectFieldErrorComponent = ErrorComponent<'select'> diff --git a/packages/payload/src/admin/fields/Tabs.ts b/packages/payload/src/admin/fields/Tabs.ts new file mode 100644 index 0000000000..f11613fb10 --- /dev/null +++ b/packages/payload/src/admin/fields/Tabs.ts @@ -0,0 +1,24 @@ +import type { TabsField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { FieldMap } from '../forms/FieldMap.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type TabsFieldProps = { + forceRender?: boolean + name?: string + path?: string + tabs?: MappedTab[] + width?: string +} & FormFieldBase + +export type MappedTab = { + fieldMap?: FieldMap + label: TabsField['tabs'][0]['label'] + name?: string +} + +export type TabsFieldLabelComponent = LabelComponent<'tabs'> + +export type TabsFieldDescriptionComponent = DescriptionComponent<'tabs'> + +export type TabsFieldErrorComponent = ErrorComponent<'tabs'> diff --git a/packages/payload/src/admin/fields/Text.ts b/packages/payload/src/admin/fields/Text.ts new file mode 100644 index 0000000000..9f01b7de70 --- /dev/null +++ b/packages/payload/src/admin/fields/Text.ts @@ -0,0 +1,23 @@ +import type { TextField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type TextFieldProps = { + hasMany?: boolean + inputRef?: React.MutableRefObject + maxLength?: number + maxRows?: number + minLength?: number + minRows?: number + name?: string + onKeyDown?: React.KeyboardEventHandler + path?: string + placeholder?: TextField['admin']['placeholder'] + width?: string +} & FormFieldBase + +export type TextFieldLabelComponent = LabelComponent<'text'> + +export type TextFieldDescriptionComponent = DescriptionComponent<'text'> + +export type TextFieldErrorComponent = ErrorComponent<'text'> diff --git a/packages/payload/src/admin/fields/Textarea.ts b/packages/payload/src/admin/fields/Textarea.ts new file mode 100644 index 0000000000..fd7c6977cf --- /dev/null +++ b/packages/payload/src/admin/fields/Textarea.ts @@ -0,0 +1,19 @@ +import type { TextareaField } from '../../fields/config/types.js' +import type { ErrorComponent } from '../forms/Error.js' +import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js' + +export type TextareaFieldProps = { + maxLength?: number + minLength?: number + name?: string + path?: string + placeholder?: TextareaField['admin']['placeholder'] + rows?: number + width?: string +} & FormFieldBase + +export type TextareaFieldLabelComponent = LabelComponent<'textarea'> + +export type TextareaFieldDescriptionComponent = DescriptionComponent<'textarea'> + +export type TextareaFieldErrorComponent = ErrorComponent<'textarea'> diff --git a/packages/payload/src/admin/fields/Upload.ts b/packages/payload/src/admin/fields/Upload.ts new file mode 100644 index 0000000000..27496fcc2c --- /dev/null +++ b/packages/payload/src/admin/fields/Upload.ts @@ -0,0 +1,17 @@ +import type { DescriptionComponent, FormFieldBase, LabelComponent, UploadField } from 'payload' + +import type { ErrorComponent } from '../forms/Error.js' + +export type UploadFieldProps = { + filterOptions?: UploadField['filterOptions'] + name?: string + path?: string + relationTo?: UploadField['relationTo'] + width?: string +} & FormFieldBase + +export type UploadFieldLabelComponent = LabelComponent<'upload'> + +export type UploadFieldDescriptionComponent = DescriptionComponent<'upload'> + +export type UploadFieldErrorComponent = ErrorComponent<'upload'> diff --git a/packages/payload/src/admin/fields/index.ts b/packages/payload/src/admin/fields/index.ts new file mode 100644 index 0000000000..835ccf0732 --- /dev/null +++ b/packages/payload/src/admin/fields/index.ts @@ -0,0 +1,86 @@ +import type { ArrayFieldProps } from './Array.js' +import type { BlocksFieldProps } from './Blocks.js' +import type { CheckboxFieldProps } from './Checkbox.js' +import type { CodeFieldProps } from './Code.js' +import type { CollapsibleFieldProps } from './Collapsible.js' +import type { DateFieldProps } from './Date.js' +import type { EmailFieldProps } from './Email.js' +import type { GroupFieldProps } from './Group.js' +import type { HiddenFieldProps } from './Hidden.js' +import type { JSONFieldProps } from './JSON.js' +import type { NumberFieldProps } from './Number.js' +import type { PointFieldProps } from './Point.js' +import type { RadioFieldProps } from './Radio.js' +import type { RelationshipFieldProps } from './Relationship.js' +import type { RichTextComponentProps } from './RichText.js' +import type { RowFieldProps } from './Row.js' +import type { SelectFieldProps } from './Select.js' +import type { TabsFieldProps } from './Tabs.js' +import type { TextFieldProps } from './Text.js' +import type { TextareaFieldProps } from './Textarea.js' +import type { UploadFieldProps } from './Upload.js' + +export type FieldComponentProps = + | ({ + type: 'array' + } & ArrayFieldProps) + | ({ + type: 'blocks' + } & BlocksFieldProps) + | ({ + type: 'checkbox' + } & CheckboxFieldProps) + | ({ + type: 'code' + } & CodeFieldProps) + | ({ + type: 'collapsible' + } & CollapsibleFieldProps) + | ({ + type: 'date' + } & DateFieldProps) + | ({ + type: 'email' + } & EmailFieldProps) + | ({ + type: 'group' + } & GroupFieldProps) + | ({ + type: 'hidden' + } & HiddenFieldProps) + | ({ + type: 'json' + } & JSONFieldProps) + | ({ + type: 'number' + } & NumberFieldProps) + | ({ + type: 'point' + } & PointFieldProps) + | ({ + type: 'radio' + } & RadioFieldProps) + | ({ + type: 'relationship' + } & RelationshipFieldProps) + | ({ + type: 'richText' + } & RichTextComponentProps) + | ({ + type: 'row' + } & RowFieldProps) + | ({ + type: 'select' + } & SelectFieldProps) + | ({ + type: 'tabs' + } & TabsFieldProps) + | ({ + type: 'text' + } & TextFieldProps) + | ({ + type: 'textarea' + } & TextareaFieldProps) + | ({ + type: 'upload' + } & UploadFieldProps) diff --git a/packages/payload/src/admin/forms/Error.ts b/packages/payload/src/admin/forms/Error.ts index 8d3472e05a..cbff6e4432 100644 --- a/packages/payload/src/admin/forms/Error.ts +++ b/packages/payload/src/admin/forms/Error.ts @@ -1,7 +1,19 @@ -export type ErrorProps = { +import type { CustomComponent, ServerProps } from '../../config/types.js' +import type { FieldComponentProps } from '../types.js' +import type { FieldTypes } from './FieldTypes.js' + +export type GenericErrorProps = { CustomError?: React.ReactNode alignCaret?: 'center' | 'left' | 'right' message?: string path?: string showError?: boolean } + +export type ErrorProps = { + type: T +} & FieldComponentProps & + GenericErrorProps & + Partial + +export type ErrorComponent = CustomComponent> diff --git a/packages/payload/src/admin/forms/Field.ts b/packages/payload/src/admin/forms/Field.ts new file mode 100644 index 0000000000..2ce02a8939 --- /dev/null +++ b/packages/payload/src/admin/forms/Field.ts @@ -0,0 +1,32 @@ +import type { User } from '../../auth/types.js' +import type { LabelStatic, Locale } from '../../config/types.js' +import type { Validate } from '../../fields/config/types.js' +import type { DocumentPreferences } from '../../preferences/types.js' +import type { ErrorProps } from './Error.js' +import type { FieldDescriptionProps } from './FieldDescription.js' +import type { SanitizedLabelProps } from './Label.js' + +export type FormFieldBase = { + AfterInput?: React.ReactNode + BeforeInput?: React.ReactNode + CustomDescription?: React.ReactNode + CustomError?: React.ReactNode + CustomLabel?: React.ReactNode + className?: string + custom?: Record + descriptionProps?: Omit + disabled?: boolean + docPreferences?: DocumentPreferences + errorProps?: Omit + label?: LabelStatic | false + labelProps?: SanitizedLabelProps + locale?: Locale + localized?: boolean + path?: string + readOnly?: boolean + required?: boolean + rtl?: boolean + style?: React.CSSProperties + user?: User + validate?: Validate +} diff --git a/packages/payload/src/admin/forms/FieldDescription.ts b/packages/payload/src/admin/forms/FieldDescription.ts index 23883aa197..f2e8e5726d 100644 --- a/packages/payload/src/admin/forms/FieldDescription.ts +++ b/packages/payload/src/admin/forms/FieldDescription.ts @@ -1,18 +1,24 @@ import type React from 'react' -import type { CustomComponent, LabelFunction } from '../../config/types.js' -import type { Payload } from '../../index.js' +import type { CustomComponent, LabelFunction, ServerProps } from '../../config/types.js' +import type { FieldComponentProps } from '../types.js' +import type { FieldTypes } from './FieldTypes.js' export type DescriptionFunction = LabelFunction -export type DescriptionComponent = CustomComponent +export type DescriptionComponent = CustomComponent< + FieldDescriptionProps +> export type Description = DescriptionFunction | Record | string - -export type FieldDescriptionProps = { +export type GenericDescriptionProps = { CustomDescription?: React.ReactNode className?: string description?: Record | string marginPlacement?: 'bottom' | 'top' - payload?: Payload } +export type FieldDescriptionProps = { + type: T +} & FieldComponentProps & + GenericDescriptionProps & + Partial diff --git a/packages/payload/src/admin/forms/FieldMap.ts b/packages/payload/src/admin/forms/FieldMap.ts new file mode 100644 index 0000000000..dfceaa6aa8 --- /dev/null +++ b/packages/payload/src/admin/forms/FieldMap.ts @@ -0,0 +1,24 @@ +import type { CellComponentProps, FieldComponentProps } from '../types.js' +import type { FieldTypes } from './FieldTypes.js' + +export type MappedField = { + CustomCell?: React.ReactNode + CustomField?: React.ReactNode + cellComponentProps: CellComponentProps + custom?: Record + disableBulkEdit?: boolean + disableListColumn?: boolean + disableListFilter?: boolean + disabled?: boolean + fieldComponentProps: FieldComponentProps + fieldIsPresentational: boolean + isFieldAffectingData: boolean + isHidden?: boolean + isSidebar?: boolean + localized: boolean + name?: string + type: keyof FieldTypes + unique?: boolean +} + +export type FieldMap = MappedField[] diff --git a/packages/payload/src/admin/forms/Label.ts b/packages/payload/src/admin/forms/Label.ts index 37ac85cbe3..43497c20c3 100644 --- a/packages/payload/src/admin/forms/Label.ts +++ b/packages/payload/src/admin/forms/Label.ts @@ -1,11 +1,24 @@ -export type LabelProps = { - CustomLabel?: React.ReactNode +import type { CustomComponent, ServerProps } from '../../config/types.js' +import type { FieldComponentProps } from '../fields/index.js' +import type { FormFieldBase } from './Field.js' +import type { FieldTypes } from './FieldTypes.js' + +export type GenericLabelProps = { as?: 'label' | 'span' htmlFor?: string - label?: Record | string - required?: boolean schemaPath?: string unstyled?: boolean -} +} & FormFieldBase -export type SanitizedLabelProps = Omit +export type LabelProps = { + type: T +} & FieldComponentProps & + GenericLabelProps & + Partial + +export type SanitizedLabelProps = Omit< + LabelProps, + 'label' | 'required' +> + +export type LabelComponent = CustomComponent> diff --git a/packages/payload/src/admin/types.ts b/packages/payload/src/admin/types.ts index ad37c5148f..6a8919e54c 100644 --- a/packages/payload/src/admin/types.ts +++ b/packages/payload/src/admin/types.ts @@ -7,6 +7,7 @@ export type { CustomPreviewButton } from './elements/PreviewButton.js' export type { CustomPublishButton } from './elements/PublishButton.js' export type { CustomSaveButton } from './elements/SaveButton.js' export type { CustomSaveDraftButton } from './elements/SaveDraftButton.js' + export type { DocumentTab, DocumentTabComponent, @@ -14,20 +15,191 @@ export type { DocumentTabConfig, DocumentTabProps, } from './elements/Tab.js' + export type { CustomUpload } from './elements/Upload.js' + export type { WithServerSidePropsComponent, WithServerSidePropsComponentProps, } from './elements/WithServerSideProps.js' -export type { ErrorProps } from './forms/Error.js' + +export type { + ArrayFieldDescriptionComponent, + ArrayFieldErrorComponent, + ArrayFieldLabelComponent, + ArrayFieldProps, +} from './fields/Array.js' + +export type { ReducedBlock } from './fields/Blocks.js' + +export type { + BlocksFieldDescriptionComponent, + BlocksFieldErrorComponent, + BlocksFieldLabelComponent, + BlocksFieldProps, +} from './fields/Blocks.js' + +export type { + CheckboxFieldDescriptionComponent, + CheckboxFieldErrorComponent, + CheckboxFieldLabelComponent, + CheckboxFieldProps, +} from './fields/Checkbox.js' + +export type { + CodeFieldDescriptionComponent, + CodeFieldErrorComponent, + CodeFieldLabelComponent, + CodeFieldProps, +} from './fields/Code.js' + +export type { + CollapsibleFieldDescriptionComponent, + CollapsibleFieldErrorComponent, + CollapsibleFieldLabelComponent, + CollapsibleFieldProps, +} from './fields/Collapsible.js' + +export type { + DateFieldDescriptionComponent, + DateFieldErrorComponent, + DateFieldLabelComponent, + DateFieldProps, +} from './fields/Date.js' + +export type { + EmailFieldDescriptionComponent, + EmailFieldErrorComponent, + EmailFieldLabelComponent, + EmailFieldProps, +} from './fields/Email.js' + +export type { + GroupFieldDescriptionComponent, + GroupFieldErrorComponent, + GroupFieldLabelComponent, + GroupFieldProps, +} from './fields/Group.js' + +export type { + HiddenFieldDescriptionComponent, + HiddenFieldErrorComponent, + HiddenFieldLabelComponent, + HiddenFieldProps, +} from './fields/Hidden.js' + +export type { + JSONFieldDescriptionComponent, + JSONFieldErrorComponent, + JSONFieldLabelComponent, + JSONFieldProps, +} from './fields/JSON.js' + +export type { + NumberFieldDescriptionComponent, + NumberFieldErrorComponent, + NumberFieldLabelComponent, + NumberFieldProps, +} from './fields/Number.js' + +export type { + PointFieldDescriptionComponent, + PointFieldErrorComponent, + PointFieldLabelComponent, + PointFieldProps, +} from './fields/Point.js' + +export type { + RadioFieldDescriptionComponent, + RadioFieldErrorComponent, + RadioFieldLabelComponent, + RadioFieldProps, +} from './fields/Radio.js' + +export type { + RelationshipFieldDescriptionComponent, + RelationshipFieldErrorComponent, + RelationshipFieldLabelComponent, + RelationshipFieldProps, +} from './fields/Relationship.js' + +export type { + RichTextComponentProps, + RichTextFieldDescriptionComponent, + RichTextFieldErrorComponent, + RichTextFieldLabelComponent, +} from './fields/RichText.js' + +export type { + RowFieldDescriptionComponent, + RowFieldErrorComponent, + RowFieldLabelComponent, + RowFieldProps, +} from './fields/Row.js' + +export type { + SelectFieldDescriptionComponent, + SelectFieldErrorComponent, + SelectFieldLabelComponent, + SelectFieldProps, +} from './fields/Select.js' + +export type { MappedTab } from './fields/Tabs.js' + +export type { + TabsFieldDescriptionComponent, + TabsFieldErrorComponent, + TabsFieldLabelComponent, + TabsFieldProps, +} from './fields/Tabs.js' + +export type { + TextFieldDescriptionComponent, + TextFieldErrorComponent, + TextFieldLabelComponent, + TextFieldProps, +} from './fields/Text.js' + +export type { + TextareaFieldDescriptionComponent, + TextareaFieldErrorComponent, + TextareaFieldLabelComponent, + TextareaFieldProps, +} from './fields/Textarea.js' + +export type { + UploadFieldDescriptionComponent, + UploadFieldErrorComponent, + UploadFieldLabelComponent, + UploadFieldProps, +} from './fields/Upload.js' + +export type { FieldComponentProps } from './fields/index.js' + +export type { ErrorComponent, ErrorProps, GenericErrorProps } from './forms/Error.js' + +export type { FormFieldBase } from './forms/Field.js' + export type { Description, DescriptionComponent, DescriptionFunction, FieldDescriptionProps, + GenericDescriptionProps, } from './forms/FieldDescription.js' + +export type { MappedField } from './forms/FieldMap.js' + +export type { FieldMap } from './forms/FieldMap.js' + export type { Data, FilterOptionsResult, FormField, FormState, Row } from './forms/Form.js' -export type { LabelProps, SanitizedLabelProps } from './forms/Label.js' + +export type { + GenericLabelProps, + LabelComponent, + LabelProps, + SanitizedLabelProps, +} from './forms/Label.js' export type { RowLabel, RowLabelComponent } from './forms/RowLabel.js' diff --git a/packages/payload/src/collections/config/types.ts b/packages/payload/src/collections/config/types.ts index adf299c885..6239b6ec37 100644 --- a/packages/payload/src/collections/config/types.ts +++ b/packages/payload/src/collections/config/types.ts @@ -23,6 +23,7 @@ import type { EntityDescriptionComponent, GeneratePreviewURL, LabelFunction, + LabelStatic, LivePreviewConfig, OpenGraphConfig, } from '../../config/types.js' @@ -438,8 +439,8 @@ export type CollectionConfig = { * Label configuration */ labels?: { - plural?: LabelFunction | Record | string - singular?: LabelFunction | Record | string + plural?: LabelFunction | LabelStatic + singular?: LabelFunction | LabelStatic } slug: string /** diff --git a/packages/payload/src/config/types.ts b/packages/payload/src/config/types.ts index b4a4306516..d0eb0a9cc7 100644 --- a/packages/payload/src/config/types.ts +++ b/packages/payload/src/config/types.ts @@ -423,6 +423,8 @@ export type LocalizationConfig = Prettify< export type LabelFunction = ({ t }: { t: TFunction }) => string +export type LabelStatic = Record | string + export type SharpDependency = ( input?: | ArrayBuffer diff --git a/packages/payload/src/fields/config/types.ts b/packages/payload/src/fields/config/types.ts index 5986440b49..611a1e588b 100644 --- a/packages/payload/src/fields/config/types.ts +++ b/packages/payload/src/fields/config/types.ts @@ -9,16 +9,16 @@ import type { JSONSchema4 } from 'json-schema' import type React from 'react' import type { RichTextAdapter, RichTextAdapterProvider } from '../../admin/RichText.js' +import type { ErrorComponent } from '../../admin/forms/Error.js' import type { ConditionalDateProps, Description, DescriptionComponent, - ErrorProps, - LabelProps, + LabelComponent, RowLabelComponent, } from '../../admin/types.js' import type { SanitizedCollectionConfig, TypeWithID } from '../../collections/config/types.js' -import type { CustomComponent, LabelFunction } from '../../config/types.js' +import type { CustomComponent, LabelFunction, LabelStatic } from '../../config/types.js' import type { DBIdentifierName } from '../../database/types.js' import type { SanitizedGlobalConfig } from '../../globals/config/types.js' import type { CollectionSlug } from '../../index.js' @@ -171,8 +171,8 @@ type Admin = { } export type Labels = { - plural: LabelFunction | Record | string - singular: LabelFunction | Record | string + plural: LabelFunction | LabelStatic + singular: LabelFunction | LabelStatic } export type BaseValidateOptions = { @@ -203,7 +203,7 @@ export type Validate< export type ClientValidate = Omit export type OptionObject = { - label: LabelFunction | Record | string + label: LabelFunction | LabelStatic value: string } @@ -231,7 +231,7 @@ export interface FieldBase { beforeValidate?: FieldHook[] } index?: boolean - label?: LabelFunction | Record | false | string + label?: LabelFunction | LabelStatic | false localized?: boolean /** * The name of the field. Must be alphanumeric and cannot contain ' . ' @@ -256,8 +256,8 @@ export type NumberField = { /** Set this property to a string that will be used for browser autocomplete. */ autoComplete?: string components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent afterInput?: CustomComponent[] beforeInput?: CustomComponent[] } @@ -295,8 +295,8 @@ export type TextField = { admin?: { autoComplete?: string components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent afterInput?: CustomComponent[] beforeInput?: CustomComponent[] } @@ -330,8 +330,8 @@ export type EmailField = { admin?: { autoComplete?: string components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent afterInput?: CustomComponent[] beforeInput?: CustomComponent[] } @@ -343,8 +343,8 @@ export type EmailField = { export type TextareaField = { admin?: { components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent afterInput?: CustomComponent[] beforeInput?: CustomComponent[] } @@ -360,8 +360,8 @@ export type TextareaField = { export type CheckboxField = { admin?: { components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent afterInput?: CustomComponent[] beforeInput?: CustomComponent[] } @@ -372,8 +372,8 @@ export type CheckboxField = { export type DateField = { admin?: { components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent afterInput?: CustomComponent[] beforeInput?: CustomComponent[] } @@ -508,8 +508,8 @@ export type UIField = { export type UploadField = { admin?: { components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent } } filterOptions?: FilterOptions @@ -525,8 +525,8 @@ export type UploadField = { type CodeAdmin = { components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent } editorOptions?: EditorProps['options'] language?: string @@ -541,8 +541,8 @@ export type CodeField = { type JSONAdmin = { components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent } editorOptions?: EditorProps['options'] } & Admin @@ -560,8 +560,8 @@ export type JSONField = { export type SelectField = { admin?: { components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent } isClearable?: boolean isSortable?: boolean @@ -622,8 +622,8 @@ type SharedRelationshipProperties = { type RelationshipAdmin = { allowCreate?: boolean components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent } isSortable?: boolean } & Admin @@ -663,8 +663,8 @@ export type RichTextField< > = { admin?: { components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent } } & Admin editor?: @@ -712,8 +712,8 @@ export type ArrayField = { export type RadioField = { admin?: { components?: { - Error?: CustomComponent - Label?: CustomComponent + Error?: ErrorComponent + Label?: LabelComponent } layout?: 'horizontal' | 'vertical' } & Admin diff --git a/packages/plugin-form-builder/src/collections/Forms/DynamicFieldSelector.tsx b/packages/plugin-form-builder/src/collections/Forms/DynamicFieldSelector.tsx index 90dfdab224..351369bc4a 100644 --- a/packages/plugin-form-builder/src/collections/Forms/DynamicFieldSelector.tsx +++ b/packages/plugin-form-builder/src/collections/Forms/DynamicFieldSelector.tsx @@ -1,6 +1,6 @@ 'use client' -import type { TextFieldProps } from '@payloadcms/ui' +import type { TextFieldProps } from 'payload' import { SelectField, useForm } from '@payloadcms/ui' import React, { useEffect, useState } from 'react' @@ -34,7 +34,5 @@ export const DynamicFieldSelector: React.FC = (props) => { } }, [fields, getDataByPath]) - // TODO: label from config is Record | false | string - // but the FormFieldBase type has only label?: string, changing FormFieldBase breaks other ui components return } diff --git a/packages/plugin-form-builder/src/collections/Forms/DynamicPriceSelector.tsx b/packages/plugin-form-builder/src/collections/Forms/DynamicPriceSelector.tsx index ea8bee6e57..a0d858203a 100644 --- a/packages/plugin-form-builder/src/collections/Forms/DynamicPriceSelector.tsx +++ b/packages/plugin-form-builder/src/collections/Forms/DynamicPriceSelector.tsx @@ -1,7 +1,6 @@ 'use client' -import type { TextFieldProps } from '@payloadcms/ui' -import type { Data } from 'payload' +import type { Data, TextFieldProps } from 'payload' import { TextField, useLocale, useWatchForm } from '@payloadcms/ui' import React, { useEffect, useState } from 'react' diff --git a/packages/plugin-form-builder/src/collections/Forms/index.ts b/packages/plugin-form-builder/src/collections/Forms/index.ts index 404d4e19b6..02362e9ec6 100644 --- a/packages/plugin-form-builder/src/collections/Forms/index.ts +++ b/packages/plugin-form-builder/src/collections/Forms/index.ts @@ -2,7 +2,7 @@ import type { Block, CollectionConfig, Field } from 'payload' import { deepMergeWithSourceArrays } from 'payload' -import type { FieldConfig, FormBuilderPluginConfig } from '../../types.js' +import type { FormBuilderPluginConfig } from '../../types.js' import { fields } from './fields.js' diff --git a/packages/plugin-seo/src/fields/MetaDescription/MetaDescriptionComponent.tsx b/packages/plugin-seo/src/fields/MetaDescription/MetaDescriptionComponent.tsx index 826e7c0ab4..a3c2d67829 100644 --- a/packages/plugin-seo/src/fields/MetaDescription/MetaDescriptionComponent.tsx +++ b/packages/plugin-seo/src/fields/MetaDescription/MetaDescriptionComponent.tsx @@ -1,6 +1,7 @@ 'use client' -import type { FieldType, FormFieldBase, Options } from '@payloadcms/ui' +import type { FieldType, Options } from '@payloadcms/ui' +import type { FormFieldBase } from 'payload' import { FieldLabel, @@ -82,7 +83,9 @@ export const MetaDescriptionComponent: React.FC = (props)   —   diff --git a/packages/ui/src/fields/Blocks/BlockRow.tsx b/packages/ui/src/fields/Blocks/BlockRow.tsx index 278fbe59aa..e32282615c 100644 --- a/packages/ui/src/fields/Blocks/BlockRow.tsx +++ b/packages/ui/src/fields/Blocks/BlockRow.tsx @@ -1,11 +1,10 @@ 'use client' -import type { FieldPermissions, Labels, Row } from 'payload' +import type { FieldPermissions, Labels, ReducedBlock, Row } from 'payload' import { getTranslation } from '@payloadcms/translations' import React from 'react' import type { UseDraggableSortableReturn } from '../../elements/DraggableSortable/useDraggableSortable/types.js' -import type { ReducedBlock } from '../../providers/ComponentMap/buildComponentMap/types.js' import { Collapsible } from '../../elements/Collapsible/index.js' import { ErrorPill } from '../../elements/ErrorPill/index.js' @@ -19,7 +18,7 @@ import { SectionTitle } from './SectionTitle/index.js' const baseClass = 'blocks-field' type BlockFieldProps = { - addRow: (rowIndex: number, blockType: string) => void + addRow: (rowIndex: number, blockType: string) => Promise | void block: ReducedBlock blocks: ReducedBlock[] duplicateRow: (rowIndex: number) => void diff --git a/packages/ui/src/fields/Blocks/BlocksDrawer/index.tsx b/packages/ui/src/fields/Blocks/BlocksDrawer/index.tsx index ad2b41df13..938742a0fe 100644 --- a/packages/ui/src/fields/Blocks/BlocksDrawer/index.tsx +++ b/packages/ui/src/fields/Blocks/BlocksDrawer/index.tsx @@ -1,13 +1,11 @@ 'use client' import type { I18nClient } from '@payloadcms/translations' -import type { Labels } from 'payload' +import type { Labels, ReducedBlock } from 'payload' import { useModal } from '@faceless-ui/modal' import { getTranslation } from '@payloadcms/translations' import React, { useEffect, useState } from 'react' -import type { ReducedBlock } from '../../../providers/ComponentMap/buildComponentMap/types.js' - import { Drawer } from '../../../elements/Drawer/index.js' import { ThumbnailCard } from '../../../elements/ThumbnailCard/index.js' import { DefaultBlockImage } from '../../../graphics/DefaultBlockImage/index.js' @@ -16,7 +14,7 @@ import { BlockSearch } from './BlockSearch/index.js' import './index.scss' export type Props = { - addRow: (index: number, blockType?: string) => void + addRow: (index: number, blockType?: string) => Promise | void addRowIndex: number blocks: ReducedBlock[] drawerSlug: string @@ -76,7 +74,7 @@ export const BlocksDrawer: React.FC = (props) => { alignLabel="center" label={getTranslation(blockLabels?.singular, i18n)} onClick={() => { - addRow(addRowIndex, slug) + void addRow(addRowIndex, slug) closeModal(drawerSlug) }} thumbnail={ diff --git a/packages/ui/src/fields/Blocks/RowActions.tsx b/packages/ui/src/fields/Blocks/RowActions.tsx index bd99969835..a3ef63160b 100644 --- a/packages/ui/src/fields/Blocks/RowActions.tsx +++ b/packages/ui/src/fields/Blocks/RowActions.tsx @@ -1,20 +1,15 @@ 'use client' -import type { Labels } from 'payload' +import type { FieldMap, Labels, ReducedBlock } from 'payload' import { useModal } from '@faceless-ui/modal' import React from 'react' -import type { - FieldMap, - ReducedBlock, -} from '../../providers/ComponentMap/buildComponentMap/types.js' - import { ArrayAction } from '../../elements/ArrayAction/index.js' import { useDrawerSlug } from '../../elements/Drawer/useDrawerSlug.js' import { BlocksDrawer } from './BlocksDrawer/index.js' export const RowActions: React.FC<{ - addRow: (rowIndex: number, blockType: string) => void + addRow: (rowIndex: number, blockType: string) => Promise | void blockType: string blocks: ReducedBlock[] duplicateRow: (rowIndex: number, blockType: string) => void @@ -51,7 +46,7 @@ export const RowActions: React.FC<{ { if (typeof addRow === 'function') { - addRow(indexToAdd, rowBlockType) + void addRow(indexToAdd, rowBlockType) } closeModal(drawerSlug) }} diff --git a/packages/ui/src/fields/Blocks/index.tsx b/packages/ui/src/fields/Blocks/index.tsx index a422afcfd7..716db879f0 100644 --- a/packages/ui/src/fields/Blocks/index.tsx +++ b/packages/ui/src/fields/Blocks/index.tsx @@ -1,12 +1,9 @@ 'use client' -import type { BlockField } from 'payload' +import type { BlocksFieldProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import React, { Fragment, useCallback } from 'react' -import type { ReducedBlock } from '../../providers/ComponentMap/buildComponentMap/types.js' -import type { FormFieldBase } from '../shared/index.js' - import { Banner } from '../../elements/Banner/index.js' import { Button } from '../../elements/Button/index.js' import { DraggableSortableItem } from '../../elements/DraggableSortable/DraggableSortableItem/index.js' @@ -34,18 +31,6 @@ import './index.scss' const baseClass = 'blocks-field' -export type BlocksFieldProps = { - blocks?: ReducedBlock[] - forceRender?: boolean - isSortable?: boolean - labels?: BlockField['labels'] - maxRows?: number - minRows?: number - name?: string - slug?: string - width?: string -} & FormFieldBase - const BlocksFieldComponent: React.FC = (props) => { const { i18n, t } = useTranslation() @@ -132,7 +117,7 @@ const BlocksFieldComponent: React.FC = (props) => { const disabled = readOnlyFromProps || readOnlyFromContext || formProcessing || formInitializing const addRow = useCallback( - async (rowIndex: number, blockType: string) => { + async (rowIndex: number, blockType: string): Promise => { await addFieldRow({ data: { blockType }, path, @@ -278,7 +263,6 @@ const BlocksFieldComponent: React.FC = (props) => { {(draggableSortableItemProps) => ( = (props) => { - label?: LabelProps['label'] + label?: LabelProps<'checkbox'>['label'] labelProps?: SanitizedLabelProps name?: string onToggle: (event: React.ChangeEvent) => void diff --git a/packages/ui/src/fields/Checkbox/index.tsx b/packages/ui/src/fields/Checkbox/index.tsx index 5fdb7f7139..6687a9939e 100644 --- a/packages/ui/src/fields/Checkbox/index.tsx +++ b/packages/ui/src/fields/Checkbox/index.tsx @@ -1,10 +1,9 @@ 'use client' -import type { ClientValidate } from 'payload' +import type { CheckboxFieldProps, ClientValidate } from 'payload' import React, { useCallback } from 'react' import type { CheckboxInputProps } from './Input.js' -import type { CheckboxFieldProps } from './types.js' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { useForm } from '../../forms/Form/context.js' diff --git a/packages/ui/src/fields/Checkbox/types.ts b/packages/ui/src/fields/Checkbox/types.ts deleted file mode 100644 index 5b26ebbde2..0000000000 --- a/packages/ui/src/fields/Checkbox/types.ts +++ /dev/null @@ -1,12 +0,0 @@ -import type { FormFieldBase } from '../shared/index.js' - -export type CheckboxFieldProps = { - checked?: boolean - disableFormData?: boolean - id?: string - name?: string - onChange?: (val: boolean) => void - partialChecked?: boolean - path?: string - width?: string -} & FormFieldBase diff --git a/packages/ui/src/fields/Code/index.tsx b/packages/ui/src/fields/Code/index.tsx index c97168ffa9..5ae3fd58a7 100644 --- a/packages/ui/src/fields/Code/index.tsx +++ b/packages/ui/src/fields/Code/index.tsx @@ -1,10 +1,8 @@ 'use client' -import type { CodeField as CodeFieldType } from 'payload' +import type { CodeFieldProps } from 'payload' import React, { useCallback } from 'react' -import type { FormFieldBase } from '../shared/index.js' - import { CodeEditor } from '../../elements/CodeEditor/index.js' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { useField } from '../../forms/useField/index.js' @@ -15,14 +13,6 @@ import { FieldLabel } from '../FieldLabel/index.js' import { fieldBaseClass } from '../shared/index.js' import './index.scss' -export type CodeFieldProps = { - editorOptions?: CodeFieldType['admin']['editorOptions'] - language?: CodeFieldType['admin']['language'] - name?: string - path?: string - width: string -} & FormFieldBase - const prismToMonacoLanguageMap = { js: 'javascript', ts: 'typescript', diff --git a/packages/ui/src/fields/Collapsible/index.tsx b/packages/ui/src/fields/Collapsible/index.tsx index 072ac604e0..8e5a2242d8 100644 --- a/packages/ui/src/fields/Collapsible/index.tsx +++ b/packages/ui/src/fields/Collapsible/index.tsx @@ -1,5 +1,5 @@ 'use client' -import type { DocumentPreferences, FieldPermissions } from 'payload' +import type { CollapsibleFieldProps, DocumentPreferences } from 'payload' import React, { Fragment, useCallback, useEffect, useState } from 'react' @@ -18,18 +18,9 @@ import './index.scss' const baseClass = 'collapsible-field' -import type { FieldMap } from '../../providers/ComponentMap/buildComponentMap/types.js' -import type { FormFieldBase } from '../shared/index.js' - import { useFormInitializing, useFormProcessing } from '../../forms/Form/context.js' import { FieldDescription } from '../FieldDescription/index.js' -export type CollapsibleFieldProps = { - fieldMap: FieldMap - initCollapsed?: boolean - width?: string -} & FormFieldBase - const CollapsibleFieldComponent: React.FC = (props) => { const { CustomDescription, @@ -65,7 +56,7 @@ const CollapsibleFieldComponent: React.FC = (props) => { const fieldHasErrors = errorCount > 0 const onToggle = useCallback( - async (newCollapsedState: boolean) => { + async (newCollapsedState: boolean): Promise => { const existingPreferences: DocumentPreferences = await getPreference(preferencesKey) if (preferencesKey) { @@ -145,7 +136,6 @@ const CollapsibleFieldComponent: React.FC = (props) => { } initCollapsed={collapsedOnMount} - // eslint-disable-next-line @typescript-eslint/no-misused-promises onToggle={onToggle} > = (props) => { const { name, diff --git a/packages/ui/src/fields/Email/index.tsx b/packages/ui/src/fields/Email/index.tsx index 3309740117..5e4be3ca00 100644 --- a/packages/ui/src/fields/Email/index.tsx +++ b/packages/ui/src/fields/Email/index.tsx @@ -1,11 +1,9 @@ 'use client' -import type { ClientValidate, EmailField as EmailFieldType } from 'payload' +import type { ClientValidate, EmailFieldProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import React, { useCallback } from 'react' -import type { FormFieldBase } from '../shared/index.js' - import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { useField } from '../../forms/useField/index.js' import { withCondition } from '../../forms/withCondition/index.js' @@ -16,14 +14,6 @@ import { FieldLabel } from '../FieldLabel/index.js' import { fieldBaseClass } from '../shared/index.js' import './index.scss' -export type EmailFieldProps = { - autoComplete?: string - name?: string - path?: string - placeholder?: EmailFieldType['admin']['placeholder'] - width?: string -} & FormFieldBase - const EmailFieldComponent: React.FC = (props) => { const { name, diff --git a/packages/ui/src/fields/FieldDescription/index.tsx b/packages/ui/src/fields/FieldDescription/index.tsx index 3c195f2eb0..c7988265ca 100644 --- a/packages/ui/src/fields/FieldDescription/index.tsx +++ b/packages/ui/src/fields/FieldDescription/index.tsx @@ -1,5 +1,5 @@ 'use client' -import type { FieldDescriptionProps } from 'payload' +import type { GenericDescriptionProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import React from 'react' @@ -10,7 +10,7 @@ import './index.scss' const baseClass = 'field-description' -const DefaultFieldDescription: React.FC = (props) => { +const DefaultFieldDescription: React.FC = (props) => { const { className, description, marginPlacement } = props const { path } = useFieldProps() @@ -37,7 +37,7 @@ const DefaultFieldDescription: React.FC = (props) => { return null } -export const FieldDescription: React.FC = (props) => { +export const FieldDescription: React.FC = (props) => { const { CustomDescription } = props if (CustomDescription !== undefined) { diff --git a/packages/ui/src/fields/FieldError/index.tsx b/packages/ui/src/fields/FieldError/index.tsx index 49178cf616..71a3036267 100644 --- a/packages/ui/src/fields/FieldError/index.tsx +++ b/packages/ui/src/fields/FieldError/index.tsx @@ -1,6 +1,6 @@ 'use client' -import type { ErrorProps } from 'payload' +import type { GenericErrorProps } from 'payload' import React from 'react' @@ -11,7 +11,7 @@ import './index.scss' const baseClass = 'field-error' -const DefaultFieldError: React.FC = (props) => { +const DefaultFieldError: React.FC = (props) => { const { alignCaret = 'right', message: messageFromProps, @@ -41,7 +41,7 @@ const DefaultFieldError: React.FC = (props) => { return null } -export const FieldError: React.FC = (props) => { +export const FieldError: React.FC = (props) => { const { CustomError } = props if (CustomError !== undefined) { diff --git a/packages/ui/src/fields/FieldLabel/index.tsx b/packages/ui/src/fields/FieldLabel/index.tsx index 2cb2dafc36..3f6a568648 100644 --- a/packages/ui/src/fields/FieldLabel/index.tsx +++ b/packages/ui/src/fields/FieldLabel/index.tsx @@ -1,6 +1,6 @@ 'use client' -import type { LabelProps } from 'payload' +import type { GenericLabelProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import React from 'react' @@ -12,7 +12,7 @@ import { useTranslation } from '../../providers/Translation/index.js' import { generateFieldID } from '../../utilities/generateFieldID.js' import './index.scss' -const DefaultFieldLabel: React.FC = (props) => { +const DefaultFieldLabel: React.FC = (props) => { const { as: Element = 'label', htmlFor: htmlForFromProps, @@ -40,7 +40,7 @@ const DefaultFieldLabel: React.FC = (props) => { return null } -export const FieldLabel: React.FC = (props) => { +export const FieldLabel: React.FC = (props) => { const { CustomLabel } = props if (CustomLabel !== undefined) { diff --git a/packages/ui/src/fields/Group/index.tsx b/packages/ui/src/fields/Group/index.tsx index d10a07e903..fb92068195 100644 --- a/packages/ui/src/fields/Group/index.tsx +++ b/packages/ui/src/fields/Group/index.tsx @@ -1,11 +1,10 @@ 'use client' +import type { GroupFieldProps } from 'payload' + import { getTranslation } from '@payloadcms/translations' import React, { Fragment } from 'react' -import type { FieldMap } from '../../providers/ComponentMap/buildComponentMap/types.js' -import type { FormFieldBase } from '../shared/index.js' - import { useCollapsible } from '../../elements/Collapsible/provider.js' import { ErrorPill } from '../../elements/ErrorPill/index.js' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' @@ -27,15 +26,7 @@ import { GroupProvider, useGroup } from './provider.js' const baseClass = 'group-field' -export type GroupFieldProps = { - fieldMap: FieldMap - forceRender?: boolean - hideGutter?: boolean - name?: string - width?: string -} & FormFieldBase - -const GroupFieldComponent: React.FC = (props) => { +export const GroupFieldComponent: React.FC = (props) => { const { CustomDescription, CustomLabel, diff --git a/packages/ui/src/fields/Hidden/index.tsx b/packages/ui/src/fields/Hidden/index.tsx index e07d27869d..49568c8a9c 100644 --- a/packages/ui/src/fields/Hidden/index.tsx +++ b/packages/ui/src/fields/Hidden/index.tsx @@ -1,25 +1,18 @@ 'use client' -import React, { useEffect } from 'react' -import type { FormFieldBase } from '../index.js' +import type { HiddenFieldProps } from 'payload' + +import React, { useEffect } from 'react' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { useField } from '../../forms/useField/index.js' import { withCondition } from '../../forms/withCondition/index.js' -export type HiddenInputFieldProps = { - disableModifyingForm?: false - forceUsePathFromProps?: boolean - name?: string - path?: string - value?: unknown -} & FormFieldBase - /** * This is mainly used to save a value on the form that is not visible to the user. * For example, this sets the `ìd` property of a block in the Blocks field. */ -const HiddenFieldComponent: React.FC = (props) => { +const HiddenFieldComponent: React.FC = (props) => { const { name, disableModifyingForm = true, diff --git a/packages/ui/src/fields/JSON/index.tsx b/packages/ui/src/fields/JSON/index.tsx index 6bc10d2a7c..2408107273 100644 --- a/packages/ui/src/fields/JSON/index.tsx +++ b/packages/ui/src/fields/JSON/index.tsx @@ -1,5 +1,5 @@ 'use client' -import type { ClientValidate, JSONField as JSONFieldType } from 'payload' +import type { ClientValidate, JSONFieldProps } from 'payload' import React, { useCallback, useEffect, useState } from 'react' @@ -12,20 +12,10 @@ import './index.scss' const baseClass = 'json-field' -import type { FormFieldBase } from '../shared/index.js' - import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { FieldDescription } from '../FieldDescription/index.js' import { FieldError } from '../FieldError/index.js' -export type JSONFieldProps = { - editorOptions?: JSONFieldType['admin']['editorOptions'] - jsonSchema?: Record - name?: string - path?: string - width?: string -} & FormFieldBase - const JSONFieldComponent: React.FC = (props) => { const { name, diff --git a/packages/ui/src/fields/Number/index.tsx b/packages/ui/src/fields/Number/index.tsx index 026bc88536..5c2c729204 100644 --- a/packages/ui/src/fields/Number/index.tsx +++ b/packages/ui/src/fields/Number/index.tsx @@ -1,12 +1,11 @@ 'use client' -import type { NumberField as NumberFieldType } from 'payload' +import type { NumberFieldProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import { isNumber } from 'payload/shared' import React, { useCallback, useEffect, useState } from 'react' import type { Option } from '../../elements/ReactSelect/types.js' -import type { FormFieldBase } from '../shared/index.js' import { ReactSelect } from '../../elements/ReactSelect/index.js' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' @@ -19,19 +18,6 @@ import { FieldLabel } from '../FieldLabel/index.js' import { fieldBaseClass } from '../shared/index.js' import './index.scss' -export type NumberFieldProps = { - hasMany?: boolean - max?: number - maxRows?: number - min?: number - name?: string - onChange?: (e: number) => void - path?: string - placeholder?: NumberFieldType['admin']['placeholder'] - step?: number - width?: string -} & FormFieldBase - const NumberFieldComponent: React.FC = (props) => { const { name, diff --git a/packages/ui/src/fields/Password/index.tsx b/packages/ui/src/fields/Password/index.tsx index 161d4fe8cc..353a5ee948 100644 --- a/packages/ui/src/fields/Password/index.tsx +++ b/packages/ui/src/fields/Password/index.tsx @@ -1,10 +1,8 @@ 'use client' -import type { ClientValidate, Description, Validate } from 'payload' +import type { ClientValidate, Description, FormFieldBase , Validate } from 'payload' import React, { useCallback } from 'react' -import type { FormFieldBase } from '../shared/index.js' - import { useField } from '../../forms/useField/index.js' import { withCondition } from '../../forms/withCondition/index.js' import { FieldError } from '../FieldError/index.js' diff --git a/packages/ui/src/fields/Point/index.tsx b/packages/ui/src/fields/Point/index.tsx index 1a568a7374..7fc951c5b2 100644 --- a/packages/ui/src/fields/Point/index.tsx +++ b/packages/ui/src/fields/Point/index.tsx @@ -1,5 +1,5 @@ 'use client' -import type { ClientValidate } from 'payload' +import type { ClientValidate, PointFieldProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import React, { useCallback } from 'react' @@ -12,22 +12,12 @@ import './index.scss' const baseClass = 'point' -import type { FormFieldBase } from '../shared/index.js' - import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { FieldDescription } from '../FieldDescription/index.js' import { FieldError } from '../FieldError/index.js' import { FieldLabel } from '../FieldLabel/index.js' -export type PointFieldProps = { - name?: string - path?: string - placeholder?: string - step?: number - width?: string -} & FormFieldBase - -const PointFieldComponent: React.FC = (props) => { +export const PointFieldComponent: React.FC = (props) => { const { name, AfterInput, diff --git a/packages/ui/src/fields/RadioGroup/Radio/index.tsx b/packages/ui/src/fields/RadioGroup/Radio/index.tsx index cfffb46ff8..86ea5fa2fd 100644 --- a/packages/ui/src/fields/RadioGroup/Radio/index.tsx +++ b/packages/ui/src/fields/RadioGroup/Radio/index.tsx @@ -1,11 +1,9 @@ 'use client' -import type { OptionObject } from 'payload' +import type { OptionObject, RadioFieldProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import React from 'react' -import type { OnChange } from '../index.js' - import { useEditDepth } from '../../../providers/EditDepth/index.js' import { useTranslation } from '../../../providers/Translation/index.js' import './index.scss' @@ -15,7 +13,7 @@ const baseClass = 'radio-input' export const Radio: React.FC<{ id: string isSelected: boolean - onChange: OnChange + onChange: RadioFieldProps['onChange'] option: OptionObject path: string readOnly?: boolean diff --git a/packages/ui/src/fields/RadioGroup/index.tsx b/packages/ui/src/fields/RadioGroup/index.tsx index e1660a0a41..671ae5efac 100644 --- a/packages/ui/src/fields/RadioGroup/index.tsx +++ b/packages/ui/src/fields/RadioGroup/index.tsx @@ -1,5 +1,5 @@ 'use client' -import type { Option } from 'payload' +import type { RadioFieldProps } from 'payload' import { optionIsObject } from 'payload/shared' import React, { useCallback } from 'react' @@ -14,24 +14,10 @@ import './index.scss' const baseClass = 'radio-group' -import type { FormFieldBase } from '../shared/index.js' - import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { FieldDescription } from '../FieldDescription/index.js' import { FieldError } from '../FieldError/index.js' -export type RadioFieldProps = { - layout?: 'horizontal' | 'vertical' - name?: string - onChange?: OnChange - options?: Option[] - path?: string - value?: string - width?: string -} & FormFieldBase - -export type OnChange = (value: T) => void - const RadioGroupFieldComponent: React.FC = (props) => { const { name, diff --git a/packages/ui/src/fields/Relationship/index.tsx b/packages/ui/src/fields/Relationship/index.tsx index 4823b16eb9..42000cae48 100644 --- a/packages/ui/src/fields/Relationship/index.tsx +++ b/packages/ui/src/fields/Relationship/index.tsx @@ -1,12 +1,12 @@ 'use client' -import type { PaginatedDocs, Where } from 'payload' +import type { PaginatedDocs, RelationshipFieldProps, Where } from 'payload' import { wordBoundariesRegex } from 'payload/shared' import * as qs from 'qs-esm' import React, { useCallback, useEffect, useReducer, useRef, useState } from 'react' import type { DocumentDrawerProps } from '../../elements/DocumentDrawer/types.js' -import type { GetResults, Option, RelationshipFieldProps, Value } from './types.js' +import type { GetResults, Option, Value } from './types.js' import { ReactSelect } from '../../elements/ReactSelect/index.js' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' @@ -33,8 +33,6 @@ const maxResultsPerRequest = 10 const baseClass = 'relationship' -export { RelationshipFieldProps } - const RelationshipFieldComponent: React.FC = (props) => { const { name, diff --git a/packages/ui/src/fields/Relationship/types.ts b/packages/ui/src/fields/Relationship/types.ts index 5b41d4dd2d..5d2e959486 100644 --- a/packages/ui/src/fields/Relationship/types.ts +++ b/packages/ui/src/fields/Relationship/types.ts @@ -1,17 +1,5 @@ import type { I18nClient } from '@payloadcms/translations' -import type { ClientCollectionConfig, RelationshipField, SanitizedConfig } from 'payload' - -import type { FormFieldBase } from '../shared/index.js' - -export type RelationshipFieldProps = { - allowCreate?: RelationshipField['admin']['allowCreate'] - hasMany?: boolean - isSortable?: boolean - name: string - relationTo?: RelationshipField['relationTo'] - sortOptions?: RelationshipField['admin']['sortOptions'] - width?: string -} & FormFieldBase +import type { ClientCollectionConfig, SanitizedConfig } from 'payload' export type Option = { label: string diff --git a/packages/ui/src/fields/RichText/index.tsx b/packages/ui/src/fields/RichText/index.tsx index 42effa1384..7cc03c87da 100644 --- a/packages/ui/src/fields/RichText/index.tsx +++ b/packages/ui/src/fields/RichText/index.tsx @@ -1,14 +1,6 @@ +import type { RichTextComponentProps } from 'payload' import type React from 'react' -import type { MappedField } from '../../providers/ComponentMap/buildComponentMap/types.js' -import type { FormFieldBase } from '../shared/index.js' - -export type RichTextFieldProps = { - name: string - richTextComponentMap?: Map - width?: string -} & FormFieldBase - -export const RichTextField: React.FC = () => { +export const RichTextField: React.FC = () => { return null } diff --git a/packages/ui/src/fields/Row/index.tsx b/packages/ui/src/fields/Row/index.tsx index 45af477415..d60ea75a7f 100644 --- a/packages/ui/src/fields/Row/index.tsx +++ b/packages/ui/src/fields/Row/index.tsx @@ -1,7 +1,7 @@ 'use client' -import React from 'react' +import type { RowFieldProps } from 'payload' -import type { RowFieldProps } from './types.js' +import React from 'react' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { RenderFields } from '../../forms/RenderFields/index.js' diff --git a/packages/ui/src/fields/Row/types.ts b/packages/ui/src/fields/Row/types.ts deleted file mode 100644 index 940bb2b64e..0000000000 --- a/packages/ui/src/fields/Row/types.ts +++ /dev/null @@ -1,13 +0,0 @@ -import type { FieldPermissions } from 'payload' - -import type { FieldMap } from '../../providers/ComponentMap/buildComponentMap/types.js' -import type { FormFieldBase } from '../shared/index.js' - -export type RowFieldProps = { - fieldMap: FieldMap - forceRender?: boolean - indexPath: string - path?: string - permissions?: FieldPermissions - width?: string -} & FormFieldBase diff --git a/packages/ui/src/fields/Select/Input.tsx b/packages/ui/src/fields/Select/Input.tsx index 6893631906..844aef5988 100644 --- a/packages/ui/src/fields/Select/Input.tsx +++ b/packages/ui/src/fields/Select/Input.tsx @@ -1,11 +1,10 @@ 'use client' -import type { OptionObject } from 'payload' +import type { OptionObject, SelectFieldProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import React from 'react' import type { ReactSelectAdapterProps } from '../../elements/ReactSelect/types.js' -import type { SelectFieldProps } from './index.js' import { ReactSelect } from '../../elements/ReactSelect/index.js' import { useTranslation } from '../../providers/Translation/index.js' diff --git a/packages/ui/src/fields/Select/index.tsx b/packages/ui/src/fields/Select/index.tsx index ea3647c3f9..715beab5e9 100644 --- a/packages/ui/src/fields/Select/index.tsx +++ b/packages/ui/src/fields/Select/index.tsx @@ -1,10 +1,9 @@ 'use client' -import type { ClientValidate, Option, OptionObject } from 'payload' +import type { ClientValidate, Option, OptionObject, SelectFieldProps } from 'payload' import React, { useCallback } from 'react' import type { ReactSelectAdapterProps } from '../../elements/ReactSelect/types.js' -import type { FormFieldBase } from '../shared/index.js' import type { SelectInputProps } from './Input.js' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' @@ -12,18 +11,6 @@ import { useField } from '../../forms/useField/index.js' import { withCondition } from '../../forms/withCondition/index.js' import { SelectInput } from './Input.js' -export type SelectFieldProps = { - hasMany?: boolean - isClearable?: boolean - isSortable?: boolean - name?: string - onChange?: (e: string | string[]) => void - options?: Option[] - path?: string - value?: string - width?: string -} & FormFieldBase - const formatOptions = (options: Option[]): OptionObject[] => options.map((option) => { if (typeof option === 'object' && (option.value || option.value === '')) { diff --git a/packages/ui/src/fields/Tabs/Tab/index.tsx b/packages/ui/src/fields/Tabs/Tab/index.tsx index 1c755ff8f5..93b391932f 100644 --- a/packages/ui/src/fields/Tabs/Tab/index.tsx +++ b/packages/ui/src/fields/Tabs/Tab/index.tsx @@ -1,9 +1,9 @@ 'use client' +import type { MappedTab } from 'payload' + import { getTranslation } from '@payloadcms/translations' import React, { useState } from 'react' -import type { MappedTab } from '../../../providers/ComponentMap/buildComponentMap/types.js' - import { ErrorPill } from '../../../elements/ErrorPill/index.js' import { WatchChildErrors } from '../../../forms/WatchChildErrors/index.js' import { useTranslation } from '../../../providers/Translation/index.js' diff --git a/packages/ui/src/fields/Tabs/index.tsx b/packages/ui/src/fields/Tabs/index.tsx index dc77a1bea0..60f93f1849 100644 --- a/packages/ui/src/fields/Tabs/index.tsx +++ b/packages/ui/src/fields/Tabs/index.tsx @@ -1,13 +1,10 @@ 'use client' -import type { DocumentPreferences } from 'payload' +import type { DocumentPreferences, TabsFieldProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import { toKebabCase } from 'payload/shared' import React, { useCallback, useEffect, useState } from 'react' -import type { MappedTab } from '../../providers/ComponentMap/buildComponentMap/types.js' -import type { FormFieldBase } from '../shared/index.js' - import { useCollapsible } from '../../elements/Collapsible/provider.js' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { RenderFields } from '../../forms/RenderFields/index.js' @@ -25,14 +22,6 @@ const baseClass = 'tabs-field' export { TabsProvider } -export type TabsFieldProps = { - forceRender?: boolean - name?: string - path?: string - tabs?: MappedTab[] - width?: string -} & FormFieldBase - const TabsFieldComponent: React.FC = (props) => { const { name, @@ -76,7 +65,7 @@ const TabsFieldComponent: React.FC = (props) => { }, [path, getPreference, preferencesKey, tabsPrefKey]) const handleTabChange = useCallback( - async (incomingTabIndex: number) => { + async (incomingTabIndex: number): Promise => { setActiveTabIndex(incomingTabIndex) const existingPreferences: DocumentPreferences = await getPreference(preferencesKey) @@ -142,7 +131,9 @@ const TabsFieldComponent: React.FC = (props) => { isActive={activeTabIndex === tabIndex} key={tabIndex} parentPath={path} - setIsActive={() => void handleTabChange(tabIndex)} + setIsActive={() => { + void handleTabChange(tabIndex) + }} tab={tab} /> ) diff --git a/packages/ui/src/fields/Text/index.tsx b/packages/ui/src/fields/Text/index.tsx index 2458c1eb90..99d6fe36a7 100644 --- a/packages/ui/src/fields/Text/index.tsx +++ b/packages/ui/src/fields/Text/index.tsx @@ -1,10 +1,10 @@ 'use client' -import type { ClientValidate } from 'payload' +import type { ClientValidate, TextFieldProps } from 'payload' import React, { useCallback, useEffect, useState } from 'react' import type { Option } from '../../elements/ReactSelect/types.js' -import type { TextFieldProps, TextInputProps } from './types.js' +import type { TextInputProps } from './types.js' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { useField } from '../../forms/useField/index.js' @@ -15,7 +15,7 @@ import { isFieldRTL } from '../shared/index.js' import { TextInput } from './Input.js' import './index.scss' -export { TextFieldProps, TextInput, TextInputProps } +export { TextInput, TextInputProps } const TextFieldComponent: React.FC = (props) => { const { diff --git a/packages/ui/src/fields/Text/types.ts b/packages/ui/src/fields/Text/types.ts index 74d9f1870b..2d60f0dba8 100644 --- a/packages/ui/src/fields/Text/types.ts +++ b/packages/ui/src/fields/Text/types.ts @@ -1,22 +1,7 @@ -import type { TextField } from 'payload' +import type { TextFieldProps } from 'payload' import type { ChangeEvent } from 'react' import type { Option, ReactSelectAdapterProps } from '../../elements/ReactSelect/types.js' -import type { FormFieldBase } from '../shared/index.js' - -export type TextFieldProps = { - hasMany?: boolean - inputRef?: React.MutableRefObject - maxLength?: number - maxRows?: number - minLength?: number - minRows?: number - name?: string - onKeyDown?: React.KeyboardEventHandler - path?: string - placeholder?: TextField['admin']['placeholder'] - width?: string -} & FormFieldBase export type SharedTextFieldProps = | { diff --git a/packages/ui/src/fields/Textarea/index.tsx b/packages/ui/src/fields/Textarea/index.tsx index 5bf8dbfb9f..2d61204a28 100644 --- a/packages/ui/src/fields/Textarea/index.tsx +++ b/packages/ui/src/fields/Textarea/index.tsx @@ -1,10 +1,10 @@ 'use client' -import type { ClientValidate } from 'payload' +import type { ClientValidate, TextareaFieldProps } from 'payload' import { getTranslation } from '@payloadcms/translations' import React, { useCallback } from 'react' -import type { TextAreaInputProps, TextareaFieldProps } from './types.js' +import type { TextAreaInputProps } from './types.js' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { useField } from '../../forms/useField/index.js' @@ -15,7 +15,7 @@ import { isFieldRTL } from '../shared/index.js' import { TextareaInput } from './Input.js' import './index.scss' -export { TextAreaInputProps, TextareaFieldProps, TextareaInput } +export { TextAreaInputProps, TextareaInput } const TextareaFieldComponent: React.FC = (props) => { const { diff --git a/packages/ui/src/fields/Textarea/types.ts b/packages/ui/src/fields/Textarea/types.ts index f597a20d26..b33a83aba5 100644 --- a/packages/ui/src/fields/Textarea/types.ts +++ b/packages/ui/src/fields/Textarea/types.ts @@ -1,19 +1,7 @@ -import type { TextareaField as TextareaFieldType } from 'payload' +import type { TextareaFieldProps } from 'payload' import { type ChangeEvent } from 'react' -import type { FormFieldBase } from '../shared/index.js' - -export type TextareaFieldProps = { - maxLength?: number - minLength?: number - name?: string - path?: string - placeholder?: TextareaFieldType['admin']['placeholder'] - rows?: number - width?: string -} & FormFieldBase - export type TextAreaInputProps = { onChange?: (e: ChangeEvent) => void rows?: number diff --git a/packages/ui/src/fields/Upload/Input.tsx b/packages/ui/src/fields/Upload/Input.tsx index c5aab5f2fb..c207349e48 100644 --- a/packages/ui/src/fields/Upload/Input.tsx +++ b/packages/ui/src/fields/Upload/Input.tsx @@ -1,13 +1,17 @@ 'use client' -import type { ClientCollectionConfig, FilterOptionsResult, UploadField } from 'payload' +import type { + ClientCollectionConfig, + FilterOptionsResult, + UploadField, + UploadFieldProps, +} from 'payload' import { getTranslation } from '@payloadcms/translations' import React, { useCallback, useEffect, useState } from 'react' import type { DocumentDrawerProps } from '../../elements/DocumentDrawer/types.js' import type { ListDrawerProps } from '../../elements/ListDrawer/types.js' -import type { UploadFieldProps } from './types.js' import { Button } from '../../elements/Button/index.js' import { useDocumentDrawer } from '../../elements/DocumentDrawer/index.js' diff --git a/packages/ui/src/fields/Upload/index.tsx b/packages/ui/src/fields/Upload/index.tsx index 7ee3cd0019..363f044f02 100644 --- a/packages/ui/src/fields/Upload/index.tsx +++ b/packages/ui/src/fields/Upload/index.tsx @@ -1,9 +1,10 @@ 'use client' +import type { UploadFieldProps } from 'payload' + import React, { useCallback, useMemo } from 'react' import type { UploadInputProps } from './Input.js' -import type { UploadFieldProps } from './types.js' import { useFieldProps } from '../../forms/FieldPropsProvider/index.js' import { useField } from '../../forms/useField/index.js' diff --git a/packages/ui/src/fields/Upload/types.ts b/packages/ui/src/fields/Upload/types.ts deleted file mode 100644 index 91bd277ca1..0000000000 --- a/packages/ui/src/fields/Upload/types.ts +++ /dev/null @@ -1,11 +0,0 @@ -import type { UploadField } from 'payload' - -import type { FormFieldBase } from '../shared/index.js' - -export type UploadFieldProps = { - filterOptions?: UploadField['filterOptions'] - name?: string - path?: string - relationTo?: UploadField['relationTo'] - width?: string -} & FormFieldBase diff --git a/packages/ui/src/fields/shared/index.tsx b/packages/ui/src/fields/shared/index.tsx index 82ed8b5c50..7263610442 100644 --- a/packages/ui/src/fields/shared/index.tsx +++ b/packages/ui/src/fields/shared/index.tsx @@ -1,42 +1,7 @@ -import type { - DocumentPreferences, - ErrorProps, - FieldDescriptionProps, - LabelProps, - Locale, - SanitizedLabelProps, - SanitizedLocalizationConfig, - User, - Validate, -} from 'payload' +import type { Locale, SanitizedLocalizationConfig } from 'payload' export const fieldBaseClass = 'field-type' -export type FormFieldBase = { - AfterInput?: React.ReactNode - BeforeInput?: React.ReactNode - CustomDescription?: React.ReactNode - CustomError?: React.ReactNode - CustomLabel?: React.ReactNode - className?: string - custom?: Record - descriptionProps?: FieldDescriptionProps - disabled?: boolean - docPreferences?: DocumentPreferences - errorProps?: ErrorProps - label?: LabelProps['label'] - labelProps?: SanitizedLabelProps - locale?: Locale - localized?: boolean - path?: string - readOnly?: boolean - required?: boolean - rtl?: boolean - style?: React.CSSProperties - user?: User - validate?: Validate -} - /** * Determines whether a field should be displayed as right-to-left (RTL) based on its configuration, payload's localization configuration and the adming user's currently enabled locale. diff --git a/packages/ui/src/forms/Form/createNestedFieldPath.ts b/packages/ui/src/forms/Form/createNestedFieldPath.ts index 3be2c91502..fcfdef69bc 100644 --- a/packages/ui/src/forms/Form/createNestedFieldPath.ts +++ b/packages/ui/src/forms/Form/createNestedFieldPath.ts @@ -1,9 +1,7 @@ -import type { Field } from 'payload' +import type { Field, MappedField } from 'payload' import { fieldAffectsData } from 'payload/shared' -import type { MappedField } from '../../providers/ComponentMap/buildComponentMap/types.js' - export const createNestedFieldPath = (parentPath: string, field: Field): string => { if (parentPath) { if (fieldAffectsData(field)) { diff --git a/packages/ui/src/forms/RenderFields/RenderField.tsx b/packages/ui/src/forms/RenderFields/RenderField.tsx index 8d0aff7e71..63a76030cc 100644 --- a/packages/ui/src/forms/RenderFields/RenderField.tsx +++ b/packages/ui/src/forms/RenderFields/RenderField.tsx @@ -1,14 +1,9 @@ 'use client' -import type { FieldPermissions, FieldTypes } from 'payload' +import type { FieldComponentProps, FieldPermissions, FieldTypes, MappedField } from 'payload' import React from 'react' -import type { - FieldComponentProps, - MappedField, -} from '../../providers/ComponentMap/buildComponentMap/types.js' - import { HiddenField } from '../../fields/Hidden/index.js' import { useFieldComponents } from '../../providers/FieldComponents/index.js' import { useOperation } from '../../providers/Operation/index.js' @@ -18,7 +13,9 @@ type Props = { CustomField: MappedField['CustomField'] custom?: Record disabled: boolean - fieldComponentProps?: FieldComponentProps + fieldComponentProps?: { + forceRender?: boolean + } & FieldComponentProps indexPath?: string isHidden?: boolean name?: string diff --git a/packages/ui/src/forms/RenderFields/types.ts b/packages/ui/src/forms/RenderFields/types.ts index ee9809599b..5de018917f 100644 --- a/packages/ui/src/forms/RenderFields/types.ts +++ b/packages/ui/src/forms/RenderFields/types.ts @@ -1,6 +1,4 @@ -import type { FieldPermissions, Operation } from 'payload' - -import type { FieldMap } from '../../providers/ComponentMap/buildComponentMap/types.js' +import type { FieldMap, FieldPermissions, Operation } from 'payload' export type Props = { className?: string diff --git a/packages/ui/src/forms/WatchChildErrors/buildPathSegments.ts b/packages/ui/src/forms/WatchChildErrors/buildPathSegments.ts index fdb94eda30..3e0a162ec0 100644 --- a/packages/ui/src/forms/WatchChildErrors/buildPathSegments.ts +++ b/packages/ui/src/forms/WatchChildErrors/buildPathSegments.ts @@ -1,4 +1,4 @@ -import type { FieldMap } from '../../providers/ComponentMap/buildComponentMap/types.js' +import type { FieldMap } from 'payload' export const buildPathSegments = (parentPath: string, fieldMap: FieldMap): string[] => { const pathNames = fieldMap.reduce((acc, field) => { diff --git a/packages/ui/src/forms/WatchChildErrors/index.tsx b/packages/ui/src/forms/WatchChildErrors/index.tsx index 69c9fa1f0c..7a9bab7517 100644 --- a/packages/ui/src/forms/WatchChildErrors/index.tsx +++ b/packages/ui/src/forms/WatchChildErrors/index.tsx @@ -1,8 +1,7 @@ 'use client' +import type { FieldMap } from 'payload' import type React from 'react' -import type { FieldMap } from '../../providers/ComponentMap/buildComponentMap/types.js' - import { useThrottledEffect } from '../../hooks/useThrottledEffect.js' import { useAllFormFields, useFormSubmitted } from '../Form/context.js' import { buildPathSegments } from './buildPathSegments.js' diff --git a/packages/ui/src/hooks/useUseAsTitle.ts b/packages/ui/src/hooks/useUseAsTitle.ts index 52c70841b4..68e2e889d4 100644 --- a/packages/ui/src/hooks/useUseAsTitle.ts +++ b/packages/ui/src/hooks/useUseAsTitle.ts @@ -1,6 +1,4 @@ -import type { ClientCollectionConfig } from 'payload' - -import type { FieldMap, MappedField } from '../providers/ComponentMap/buildComponentMap/types.js' +import type { ClientCollectionConfig, FieldMap, MappedField } from 'payload' import { flattenFieldMap } from '../utilities/flattenFieldMap.js' diff --git a/packages/ui/src/providers/ComponentMap/buildComponentMap/fields.tsx b/packages/ui/src/providers/ComponentMap/buildComponentMap/fields.tsx index 7027c58c57..76d8a5030d 100644 --- a/packages/ui/src/providers/ComponentMap/buildComponentMap/fields.tsx +++ b/packages/ui/src/providers/ComponentMap/buildComponentMap/fields.tsx @@ -1,53 +1,50 @@ import type { I18nClient } from '@payloadcms/translations' import type { + ArrayFieldProps, + BlocksFieldProps, CellComponentProps, + CheckboxFieldProps, + CodeFieldProps, + CollapsibleFieldProps, CustomComponent, + DateFieldProps, + EmailFieldProps, + ErrorProps, Field, + FieldComponentProps, FieldDescriptionProps, + FieldMap, FieldWithPath, + FormFieldBase, + GroupFieldProps, + JSONFieldProps, LabelProps, + MappedField, + MappedTab, + NumberFieldProps, Option, + PointFieldProps, + RadioFieldProps, + ReducedBlock, + RelationshipFieldProps, + RichTextComponentProps, + RowFieldProps, SanitizedConfig, + SelectFieldProps, + TabsFieldProps, + TextFieldProps, + TextareaFieldProps, + UploadFieldProps, } from 'payload' import { MissingEditorProp } from 'payload' -import { fieldAffectsData, fieldIsPresentationalOnly } from 'payload/shared' +import { deepCopyObject, fieldAffectsData, fieldIsPresentationalOnly } from 'payload/shared' import React, { Fragment } from 'react' -import type { ArrayFieldProps } from '../../../fields/Array/index.js' -import type { BlocksFieldProps } from '../../../fields/Blocks/index.js' -import type { CheckboxFieldProps } from '../../../fields/Checkbox/index.js' -import type { CodeFieldProps } from '../../../fields/Code/index.js' -import type { CollapsibleFieldProps } from '../../../fields/Collapsible/index.js' -import type { DateFieldProps } from '../../../fields/DateTime/index.js' -import type { EmailFieldProps } from '../../../fields/Email/index.js' -import type { GroupFieldProps } from '../../../fields/Group/index.js' -import type { JSONFieldProps } from '../../../fields/JSON/index.js' -import type { NumberFieldProps } from '../../../fields/Number/index.js' -import type { PointFieldProps } from '../../../fields/Point/index.js' -import type { RadioFieldProps } from '../../../fields/RadioGroup/index.js' -import type { RelationshipFieldProps } from '../../../fields/Relationship/types.js' -import type { RichTextFieldProps } from '../../../fields/RichText/index.js' -import type { RowFieldProps } from '../../../fields/Row/types.js' -import type { SelectFieldProps } from '../../../fields/Select/index.js' -import type { TabsFieldProps } from '../../../fields/Tabs/index.js' -import type { TextFieldProps } from '../../../fields/Text/types.js' -import type { TextareaFieldProps } from '../../../fields/Textarea/types.js' -import type { UploadFieldProps } from '../../../fields/Upload/types.js' -import type { FormFieldBase } from '../../../fields/shared/index.js' import type { WithServerSidePropsPrePopulated } from './index.js' -import type { - FieldComponentProps, - FieldMap, - MappedField, - MappedTab, - ReducedBlock, -} from './types.js' // eslint-disable-next-line payload/no-imports-from-exports-dir -import { FieldDescription } from '../../../exports/client/index.js' -// eslint-disable-next-line payload/no-imports-from-exports-dir -import { HiddenField } from '../../../exports/client/index.js' +import { FieldDescription, HiddenField } from '../../../exports/client/index.js' function generateFieldPath(parentPath, name) { let tabPath = parentPath || '' @@ -60,6 +57,20 @@ function generateFieldPath(parentPath, name) { return tabPath } +function prepareCustomComponentProps( + props: { + [key: string]: any + } & FieldComponentProps, +) { + return deepCopyObject({ + ...props, + fieldMap: undefined, + richTextComponentMap: undefined, + rows: undefined, + tabs: undefined, + }) +} + export const mapFields = (args: { WithServerSideProps: WithServerSidePropsPrePopulated config: SanitizedConfig @@ -134,7 +145,8 @@ export const mapFields = (args: { )) || null - let label = undefined + let label: FormFieldBase['label'] = undefined + if ('label' in field) { if (typeof field.label === 'string' || typeof field.label === 'object') { label = field.label @@ -143,93 +155,18 @@ export const mapFields = (args: { } } - const labelProps: LabelProps = { - label, - required: 'required' in field ? field.required : undefined, - schemaPath: path, - } - - const CustomLabelComponent = - ('admin' in field && - field.admin?.components && - 'Label' in field.admin.components && - field.admin.components?.Label) || - undefined - - // If we return undefined here (so if no CUSTOM label component is set), the field client component is responsible for falling back to the default label - const CustomLabel = - CustomLabelComponent !== undefined ? ( - - ) : undefined - - let description = undefined - if (field.admin && 'description' in field.admin) { - if ( - typeof field.admin?.description === 'string' || - typeof field.admin?.description === 'object' - ) { - description = field.admin.description - } else if (typeof field.admin?.description === 'function') { - description = field.admin?.description({ t }) - } - } - - const descriptionProps: FieldDescriptionProps = { - description, - } - - let CustomDescriptionComponent = undefined - if ( - field.admin?.components && - 'Description' in field.admin.components && - field.admin.components?.Description - ) { - CustomDescriptionComponent = field.admin.components.Description - } else if (description) { - CustomDescriptionComponent = FieldDescription - } - - const CustomDescription = - CustomDescriptionComponent !== undefined ? ( - - ) : undefined - - const errorProps = { - path, - } - - const CustomErrorComponent = - ('admin' in field && - field.admin?.components && - 'Error' in field.admin.components && - field.admin?.components?.Error) || - undefined - - const CustomError = - CustomErrorComponent !== undefined ? ( - - ) : undefined - // These fields are shared across all field types even if they are not used in the default field, as the custom field component can use them const baseFieldProps: FormFieldBase = { AfterInput, BeforeInput, - CustomDescription, - CustomError, - CustomLabel, custom: 'admin' in field && 'custom' in field.admin ? field.admin?.custom : undefined, - descriptionProps, disabled: 'admin' in field && 'disabled' in field.admin ? field.admin?.disabled : false, - errorProps, - label: labelProps?.label, + label, path, required: 'required' in field ? field.required : undefined, } - let fieldComponentProps: FieldComponentProps + let fieldComponentPropsBase: Omit let fieldOptions: Option[] @@ -250,7 +187,7 @@ export const mapFields = (args: { name: 'name' in field ? field.name : undefined, fieldType: field.type, isFieldAffectingData, - label: labelProps?.label || undefined, + label, labels: 'labels' in field ? field.labels : undefined, options: 'options' in field ? fieldOptions : undefined, relationTo: 'relationTo' in field ? field.relationTo : undefined, @@ -259,24 +196,9 @@ export const mapFields = (args: { switch (field.type) { case 'array': { - let CustomRowLabel: React.ReactNode - - if ( - 'admin' in field && - field.admin.components && - 'RowLabel' in field.admin.components && - field.admin.components.RowLabel - ) { - const CustomRowLabelComponent = field.admin.components.RowLabel - CustomRowLabel = ( - - ) - } - - const arrayFieldProps: Omit = { + const arrayFieldProps: ArrayFieldProps = { ...baseFieldProps, name: field.name, - CustomRowLabel, className: field.admin?.className, disabled: field.admin?.disabled, fieldMap: mapFields({ @@ -298,7 +220,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = arrayFieldProps + fieldComponentPropsBase = arrayFieldProps break } case 'blocks': { @@ -326,7 +248,7 @@ export const mapFields = (args: { return reducedBlock }) - const blocksField: Omit = { + const blocksField: BlocksFieldProps = { ...baseFieldProps, name: field.name, blocks, @@ -342,7 +264,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = blocksField + fieldComponentPropsBase = blocksField cellComponentProps.blocks = field.blocks.map((b) => ({ slug: b.slug, @@ -363,7 +285,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = checkboxField + fieldComponentPropsBase = checkboxField break } case 'code': { @@ -380,28 +302,12 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = codeField + fieldComponentPropsBase = codeField break } case 'collapsible': { - let CustomCollapsibleLabel: React.ReactNode - if ( - field?.admin?.components && - 'RowLabel' in field.admin.components && - field?.admin?.components?.RowLabel - ) { - const CustomCollapsibleLabelComponent = field.admin.components.RowLabel - CustomCollapsibleLabel = ( - - ) - } - - const collapsibleField: Omit = { + const collapsibleField: CollapsibleFieldProps = { ...baseFieldProps, - CustomLabel: CustomCollapsibleLabel, className: field.admin?.className, disabled: field.admin?.disabled, fieldMap: mapFields({ @@ -421,7 +327,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = collapsibleField as CollapsibleFieldProps // TODO: dunno why this is needed + fieldComponentPropsBase = collapsibleField // TODO: dunno why this is needed break } case 'date': { @@ -438,7 +344,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = dateField + fieldComponentPropsBase = dateField cellComponentProps.dateDisplayFormat = field.admin?.date?.displayFormat break } @@ -456,11 +362,11 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = emailField + fieldComponentPropsBase = emailField break } case 'group': { - const groupField: Omit = { + const groupField: GroupFieldProps = { ...baseFieldProps, name: field.name, className: field.admin?.className, @@ -481,7 +387,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = groupField + fieldComponentPropsBase = groupField break } case 'json': { @@ -498,7 +404,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = jsonField + fieldComponentPropsBase = jsonField break } case 'number': { @@ -518,7 +424,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = numberField + fieldComponentPropsBase = numberField break } case 'point': { @@ -533,7 +439,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = pointField + fieldComponentPropsBase = pointField break } case 'relationship': { @@ -554,7 +460,7 @@ export const mapFields = (args: { } cellComponentProps.relationTo = field.relationTo - fieldComponentProps = relationshipField + fieldComponentPropsBase = relationshipField break } case 'radio': { @@ -572,11 +478,11 @@ export const mapFields = (args: { } cellComponentProps.options = fieldOptions - fieldComponentProps = radioField + fieldComponentPropsBase = radioField break } case 'richText': { - const richTextField: RichTextFieldProps = { + const richTextField: RichTextComponentProps = { ...baseFieldProps, name: field.name, className: field.admin?.className, @@ -586,9 +492,11 @@ export const mapFields = (args: { style: field.admin?.style, width: field.admin?.width, } + if (!field?.editor) { throw new MissingEditorProp(field) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor } + if (typeof field?.editor === 'function') { throw new Error('Attempted to access unsanitized rich text editor.') } @@ -603,6 +511,7 @@ export const mapFields = (args: { i18n, schemaPath: path, }) + richTextField.richTextComponentMap = result cellComponentProps.richTextComponentMap = result } @@ -615,12 +524,12 @@ export const mapFields = (args: { CustomCellComponent = RichTextCellComponent } - fieldComponentProps = richTextField + fieldComponentPropsBase = richTextField break } case 'row': { - const rowField: Omit = { + const rowField: Omit = { ...baseFieldProps, className: field.admin?.className, disabled: field.admin?.disabled, @@ -640,7 +549,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = rowField + fieldComponentPropsBase = rowField break } case 'tabs': { @@ -666,7 +575,7 @@ export const mapFields = (args: { return reducedTab }) - const tabsField: Omit = { + const tabsField: Omit = { ...baseFieldProps, name: 'name' in field ? (field.name as string) : undefined, className: field.admin?.className, @@ -678,7 +587,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = tabsField + fieldComponentPropsBase = tabsField break } case 'text': { @@ -697,7 +606,7 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = textField + fieldComponentPropsBase = textField break } case 'textarea': { @@ -716,11 +625,11 @@ export const mapFields = (args: { width: field.admin?.width, } - fieldComponentProps = textareaField + fieldComponentPropsBase = textareaField break } case 'ui': { - fieldComponentProps = baseFieldProps + fieldComponentPropsBase = baseFieldProps break } case 'upload': { @@ -738,7 +647,7 @@ export const mapFields = (args: { } cellComponentProps.relationTo = field.relationTo - fieldComponentProps = uploadField + fieldComponentPropsBase = uploadField break } case 'select': { @@ -757,7 +666,7 @@ export const mapFields = (args: { } cellComponentProps.options = fieldOptions - fieldComponentProps = selectField + fieldComponentPropsBase = selectField break } default: { @@ -765,6 +674,142 @@ export const mapFields = (args: { } } + const labelProps: Omit = prepareCustomComponentProps({ + ...fieldComponentPropsBase, + type: undefined, + schemaPath: path, + }) + + const CustomLabelComponent = + ('admin' in field && + field.admin?.components && + 'Label' in field.admin.components && + field.admin.components?.Label) || + undefined + + // If we return undefined here (so if no CUSTOM label component is set), + // the field client component is responsible for falling back to the default label + let CustomLabel: React.ReactNode = + CustomLabelComponent !== undefined ? ( + + ) : undefined + + switch (field.type) { + case 'array': { + let CustomRowLabel: React.ReactNode + + if ( + 'admin' in field && + field.admin.components && + 'RowLabel' in field.admin.components && + field.admin.components.RowLabel + ) { + const CustomRowLabelComponent = field.admin.components.RowLabel + CustomRowLabel = ( + + ) + } + + // @ts-expect-error + fieldComponentPropsBase.CustomRowLabel = CustomRowLabel + + break + } + + case 'collapsible': { + let CustomCollapsibleLabel: React.ReactNode + + if ( + field?.admin?.components && + 'RowLabel' in field.admin.components && + field?.admin?.components?.RowLabel + ) { + const CustomCollapsibleLabelComponent = field.admin.components.RowLabel + CustomCollapsibleLabel = ( + + ) + } + + CustomLabel = CustomCollapsibleLabel + + break + } + + default: + break + } + + let description = undefined + + if (field.admin && 'description' in field.admin) { + if ( + typeof field.admin?.description === 'string' || + typeof field.admin?.description === 'object' + ) { + description = field.admin.description + } else if (typeof field.admin?.description === 'function') { + description = field.admin?.description({ t }) + } + } + + const descriptionProps: FieldDescriptionProps = prepareCustomComponentProps({ + ...fieldComponentPropsBase, + type: undefined, + description, + }) + + let CustomDescriptionComponent = undefined + + if ( + field.admin?.components && + 'Description' in field.admin.components && + field.admin.components?.Description + ) { + CustomDescriptionComponent = field.admin.components.Description + } else if (description) { + CustomDescriptionComponent = FieldDescription + } + + const CustomDescription = + CustomDescriptionComponent !== undefined ? ( + + ) : undefined + + const errorProps: ErrorProps = prepareCustomComponentProps({ + ...fieldComponentPropsBase, + type: undefined, + path, + }) + + const CustomErrorComponent = + ('admin' in field && + field.admin?.components && + 'Error' in field.admin.components && + field.admin?.components?.Error) || + undefined + + const CustomError = + CustomErrorComponent !== undefined ? ( + + ) : undefined + + const fieldComponentProps: FieldComponentProps = { + ...fieldComponentPropsBase, + type: undefined, + CustomDescription, + CustomError, + CustomLabel, + descriptionProps, + errorProps, + labelProps, + } + const reducedField: MappedField = { name: 'name' in field ? field.name : undefined, type: field.type, @@ -772,7 +817,7 @@ export const mapFields = (args: { ) : undefined, CustomField: CustomFieldComponent ? ( - + ) : undefined, cellComponentProps, custom: field?.admin?.custom, @@ -803,7 +848,7 @@ export const mapFields = (args: { result.findIndex((f) => 'name' in f && f.isFieldAffectingData && f.name === 'id') > -1 if (!disableAddingID && !hasID) { - // TODO: For all fields (not just this one) we need to add the name to both .fieldComponentProps.name AND .name. This can probably be improved + // TODO: For all fields (not just this one) we need to add the name to both .fieldComponentPropsBase.name AND .name. This can probably be improved result.push({ name: 'id', type: 'text', @@ -815,6 +860,7 @@ export const mapFields = (args: { disableBulkEdit: true, fieldComponentProps: { name: 'id', + type: undefined, label: 'ID', }, fieldIsPresentational: false, diff --git a/packages/ui/src/providers/ComponentMap/buildComponentMap/types.ts b/packages/ui/src/providers/ComponentMap/buildComponentMap/types.ts index cf79ccb251..7f9ccf6d32 100644 --- a/packages/ui/src/providers/ComponentMap/buildComponentMap/types.ts +++ b/packages/ui/src/providers/ComponentMap/buildComponentMap/types.ts @@ -1,93 +1,4 @@ -import type { - Block, - BlockField, - CellComponentProps, - FieldTypes, - SanitizedCollectionConfig, - SanitizedGlobalConfig, - TabsField, -} from 'payload' - -import type { ArrayFieldProps } from '../../../fields/Array/index.js' -import type { BlocksFieldProps } from '../../../fields/Blocks/index.js' -import type { CheckboxFieldProps } from '../../../fields/Checkbox/types.js' -import type { CodeFieldProps } from '../../../fields/Code/index.js' -import type { CollapsibleFieldProps } from '../../../fields/Collapsible/index.js' -import type { DateFieldProps } from '../../../fields/DateTime/index.js' -import type { EmailFieldProps } from '../../../fields/Email/index.js' -import type { GroupFieldProps } from '../../../fields/Group/index.js' -import type { HiddenInputFieldProps } from '../../../fields/Hidden/index.js' -import type { JSONFieldProps } from '../../../fields/JSON/index.js' -import type { NumberFieldProps } from '../../../fields/Number/index.js' -import type { PointFieldProps } from '../../../fields/Point/index.js' -import type { RelationshipFieldProps } from '../../../fields/Relationship/index.js' -import type { RichTextFieldProps } from '../../../fields/RichText/index.js' -import type { RowFieldProps } from '../../../fields/Row/types.js' -import type { SelectFieldProps } from '../../../fields/Select/index.js' -import type { TabsFieldProps } from '../../../fields/Tabs/index.js' -import type { TextFieldProps } from '../../../fields/Text/types.js' -import type { TextareaFieldProps } from '../../../fields/Textarea/types.js' -import type { UploadFieldProps } from '../../../fields/Upload/types.js' - -export type MappedTab = { - fieldMap?: FieldMap - label: TabsField['tabs'][0]['label'] - name?: string -} - -export type ReducedBlock = { - LabelComponent: Block['admin']['components']['Label'] - custom?: Record - fieldMap: FieldMap - imageAltText?: string - imageURL?: string - labels: BlockField['labels'] - slug: string -} - -export type FieldComponentProps = - | ArrayFieldProps - | BlocksFieldProps - | CheckboxFieldProps - | CodeFieldProps - | CollapsibleFieldProps - | DateFieldProps - | EmailFieldProps - | GroupFieldProps - | HiddenInputFieldProps - | JSONFieldProps - | NumberFieldProps - | PointFieldProps - | RelationshipFieldProps - | RichTextFieldProps - | RowFieldProps - | SelectFieldProps - | TabsFieldProps - | TextFieldProps - | TextareaFieldProps - | UploadFieldProps - -export type MappedField = { - CustomCell?: React.ReactNode - CustomField?: React.ReactNode - cellComponentProps: CellComponentProps - custom?: Record - disableBulkEdit?: boolean - disableListColumn?: boolean - disableListFilter?: boolean - disabled?: boolean - fieldComponentProps: FieldComponentProps - fieldIsPresentational: boolean - isFieldAffectingData: boolean - isHidden?: boolean - isSidebar?: boolean - localized: boolean - name?: string - type: keyof FieldTypes - unique?: boolean -} - -export type FieldMap = MappedField[] +import type { FieldMap, SanitizedCollectionConfig, SanitizedGlobalConfig } from 'payload' export type ActionMap = { Edit: { diff --git a/packages/ui/src/providers/ComponentMap/index.tsx b/packages/ui/src/providers/ComponentMap/index.tsx index 79e0b4efbb..ee961de62c 100644 --- a/packages/ui/src/providers/ComponentMap/index.tsx +++ b/packages/ui/src/providers/ComponentMap/index.tsx @@ -1,7 +1,9 @@ 'use client' +import type { FieldMap, MappedField } from 'payload' + import React, { createContext, useCallback, useContext } from 'react' -import type { ComponentMap, FieldMap, MappedField } from './buildComponentMap/types.js' +import type { ComponentMap } from './buildComponentMap/types.js' export type IComponentMapContext = { componentMap: ComponentMap diff --git a/packages/ui/src/utilities/flattenFieldMap.ts b/packages/ui/src/utilities/flattenFieldMap.ts index a1557980ec..010a40dc16 100644 --- a/packages/ui/src/utilities/flattenFieldMap.ts +++ b/packages/ui/src/utilities/flattenFieldMap.ts @@ -1,4 +1,4 @@ -import type { FieldMap } from '../providers/ComponentMap/buildComponentMap/types.js' +import type { FieldMap } from 'payload' /** * Flattens a collection's fields into a single array of fields, as long diff --git a/test/fields/collections/Text/AfterInput.tsx b/test/admin/collections/CustomFields/AfterInput.tsx similarity index 100% rename from test/fields/collections/Text/AfterInput.tsx rename to test/admin/collections/CustomFields/AfterInput.tsx diff --git a/test/fields/collections/Text/BeforeInput.tsx b/test/admin/collections/CustomFields/BeforeInput.tsx similarity index 100% rename from test/fields/collections/Text/BeforeInput.tsx rename to test/admin/collections/CustomFields/BeforeInput.tsx diff --git a/test/fields/collections/Text/CustomError.tsx b/test/admin/collections/CustomFields/CustomError.tsx similarity index 86% rename from test/fields/collections/Text/CustomError.tsx rename to test/admin/collections/CustomFields/CustomError.tsx index 7ff8665fd6..1af8bae903 100644 --- a/test/fields/collections/Text/CustomError.tsx +++ b/test/admin/collections/CustomFields/CustomError.tsx @@ -3,7 +3,7 @@ import { useField, useFormFields, useFormSubmitted } from '@payloadcms/ui' import React from 'react' -const CustomError: React.FC = (props) => { +export const CustomError: React.FC = (props) => { const { path: pathFromProps } = props const submitted = useFormSubmitted() const { path } = useField(pathFromProps) @@ -18,5 +18,3 @@ const CustomError: React.FC = (props) => { return null } - -export default CustomError diff --git a/test/admin/components/FieldDescription/index.tsx b/test/admin/collections/CustomFields/FieldDescription/index.tsx similarity index 84% rename from test/admin/components/FieldDescription/index.tsx rename to test/admin/collections/CustomFields/FieldDescription/index.tsx index 5972bcfe40..62ad3eec43 100644 --- a/test/admin/components/FieldDescription/index.tsx +++ b/test/admin/collections/CustomFields/FieldDescription/index.tsx @@ -4,7 +4,7 @@ import type { DescriptionComponent } from 'payload' import { useFieldProps, useFormFields } from '@payloadcms/ui' import React from 'react' -export const FieldDescriptionComponent: DescriptionComponent = () => { +export const FieldDescriptionComponent: DescriptionComponent<'text'> = () => { const { path } = useFieldProps() const field = useFormFields(([fields]) => (fields && fields?.[path]) || null) const { value } = field || {} diff --git a/test/admin/collections/CustomFields/components/CustomSelect.tsx b/test/admin/collections/CustomFields/fields/Select/index.tsx similarity index 87% rename from test/admin/collections/CustomFields/components/CustomSelect.tsx rename to test/admin/collections/CustomFields/fields/Select/index.tsx index c333d66adc..783b3ff812 100644 --- a/test/admin/collections/CustomFields/components/CustomSelect.tsx +++ b/test/admin/collections/CustomFields/fields/Select/index.tsx @@ -2,10 +2,11 @@ import type { Option } from 'payload' -import { SelectField, useField } from '@payloadcms/ui' +import { SelectField, useField, useFieldProps } from '@payloadcms/ui' import React from 'react' -export const CustomSelect = ({ path }: { path: string }) => { +export const CustomSelect = () => { + const { path } = useFieldProps() const { setValue, value } = useField({ path }) const [options, setOptions] = React.useState<{ label: string; value: string }[]>([]) diff --git a/test/admin/collections/CustomFields/fields/Text/Description.tsx b/test/admin/collections/CustomFields/fields/Text/Description.tsx new file mode 100644 index 0000000000..e166bbbb78 --- /dev/null +++ b/test/admin/collections/CustomFields/fields/Text/Description.tsx @@ -0,0 +1,9 @@ +import type { TextFieldDescriptionComponent } from 'payload' + +import React from 'react' + +export const CustomDescription: TextFieldDescriptionComponent = (props) => { + return ( +
{`The max length of this field is: ${props?.maxLength}`}
+ ) +} diff --git a/test/admin/collections/CustomFields/fields/Text/Label.tsx b/test/admin/collections/CustomFields/fields/Text/Label.tsx new file mode 100644 index 0000000000..1274beed03 --- /dev/null +++ b/test/admin/collections/CustomFields/fields/Text/Label.tsx @@ -0,0 +1,7 @@ +import type { TextFieldLabelComponent } from 'payload' + +import React from 'react' + +export const CustomLabel: TextFieldLabelComponent = (props) => { + return
{`The max length of this field is: ${props?.maxLength}`}
+} diff --git a/test/admin/collections/CustomFields/index.ts b/test/admin/collections/CustomFields/index.ts index de155bef32..1e3c8ab9b6 100644 --- a/test/admin/collections/CustomFields/index.ts +++ b/test/admin/collections/CustomFields/index.ts @@ -1,11 +1,55 @@ import type { CollectionConfig } from 'payload' import { customFieldsSlug } from '../../slugs.js' -import { CustomSelect } from './components/CustomSelect.js' +import { AfterInput } from './AfterInput.js' +import { BeforeInput } from './BeforeInput.js' +import { CustomError } from './CustomError.js' +import { FieldDescriptionComponent } from './FieldDescription/index.js' +import { CustomSelect } from './fields/Select/index.js' +import { CustomDescription } from './fields/Text/Description.js' +import { CustomLabel } from './fields/Text/Label.js' export const CustomFields: CollectionConfig = { slug: customFieldsSlug, fields: [ + { + name: 'customTextField', + type: 'text', + maxLength: 100, + admin: { + components: { + afterInput: [AfterInput], + beforeInput: [BeforeInput], + Label: CustomLabel, + Description: CustomDescription, + Error: CustomError, + }, + }, + minLength: 3, + }, + { + name: 'descriptionAsString', + type: 'text', + admin: { + description: 'Static field description.', + }, + }, + { + name: 'descriptionAsFunction', + type: 'text', + admin: { + description: () => 'Function description', + }, + }, + { + name: 'descriptionAsComponent', + type: 'text', + admin: { + components: { + Description: FieldDescriptionComponent, + }, + }, + }, { name: 'customSelectField', type: 'text', diff --git a/test/admin/collections/Posts.ts b/test/admin/collections/Posts.ts index e9051cfac2..8e1d6008f5 100644 --- a/test/admin/collections/Posts.ts +++ b/test/admin/collections/Posts.ts @@ -5,7 +5,6 @@ import { slateEditor } from '@payloadcms/richtext-slate' import { CustomCell } from '../components/CustomCell/index.js' import { DemoUIFieldCell } from '../components/DemoUIField/Cell.js' import { DemoUIField } from '../components/DemoUIField/Field.js' -import { FieldDescriptionComponent } from '../components/FieldDescription/index.js' import { slugPluralLabel, slugSingularLabel } from '../shared.js' import { postsCollectionSlug } from '../slugs.js' @@ -108,29 +107,6 @@ export const Posts: CollectionConfig = { position: 'sidebar', }, }, - { - name: 'descriptionAsString', - type: 'text', - admin: { - description: 'Static field description.', - }, - }, - { - name: 'descriptionAsFunction', - type: 'text', - admin: { - description: () => 'Function description', - }, - }, - { - name: 'descriptionAsComponent', - type: 'text', - admin: { - components: { - Description: FieldDescriptionComponent, - }, - }, - }, ], labels: { plural: slugPluralLabel, diff --git a/test/admin/e2e/1/e2e.spec.ts b/test/admin/e2e/1/e2e.spec.ts index b858b5093f..f79987a1c2 100644 --- a/test/admin/e2e/1/e2e.spec.ts +++ b/test/admin/e2e/1/e2e.spec.ts @@ -500,9 +500,90 @@ describe('admin1', () => { }) describe('custom fields', () => { + test('renders custom label component', async () => { + await page.goto(customFieldsURL.create) + await page.waitForURL(customFieldsURL.create) + await expect(page.locator('#custom-field-label')).toBeVisible() + }) + + test('renders custom description component', async () => { + await page.goto(customFieldsURL.create) + await page.waitForURL(customFieldsURL.create) + await expect(page.locator('#custom-field-description')).toBeVisible() + }) + + test('ensure custom components receive field props', async () => { + await page.goto(customFieldsURL.create) + await page.waitForURL(customFieldsURL.create) + await expect(page.locator('#custom-field-label')).toContainText( + 'The max length of this field is: 100', + ) + await expect(page.locator('#custom-field-description')).toContainText( + 'The max length of this field is: 100', + ) + }) + + describe('field descriptions', () => { + test('should render static field description', async () => { + await page.goto(customFieldsURL.create) + await page.waitForURL(customFieldsURL.create) + await expect(page.locator('.field-description-descriptionAsString')).toContainText( + 'Static field description.', + ) + }) + + test('should render functional field description', async () => { + await page.goto(customFieldsURL.create) + await page.waitForURL(customFieldsURL.create) + await page.locator('#field-descriptionAsFunction').fill('functional') + await expect(page.locator('.field-description-descriptionAsFunction')).toContainText( + 'Function description', + ) + }) + }) + + test('should render component field description', async () => { + await page.goto(customFieldsURL.create) + await page.waitForURL(customFieldsURL.create) + await page.locator('#field-descriptionAsComponent').fill('component') + await expect(page.locator('.field-description-descriptionAsComponent')).toContainText( + 'Component description: descriptionAsComponent - component', + ) + }) + + test('should render custom error component', async () => { + await page.goto(customFieldsURL.create) + await page.waitForURL(customFieldsURL.create) + const input = page.locator('input[id="field-customTextField"]') + await input.fill('ab') + await expect(input).toHaveValue('ab') + const error = page.locator('.custom-error:near(input[id="field-customTextField"])') + const submit = page.locator('button[type="button"][id="action-save"]') + await submit.click() + await expect(error).toHaveText('#custom-error') + }) + + test('should render beforeInput and afterInput', async () => { + await page.goto(customFieldsURL.create) + const input = page.locator('input[id="field-customTextField"]') + + const prevSibling = await input.evaluateHandle((el) => { + return el.previousElementSibling + }) + const prevSiblingText = await page.evaluate((el) => el.textContent, prevSibling) + expect(prevSiblingText).toEqual('#before-input') + + const nextSibling = await input.evaluateHandle((el) => { + return el.nextElementSibling + }) + const nextSiblingText = await page.evaluate((el) => el.textContent, nextSibling) + expect(nextSiblingText).toEqual('#after-input') + }) + describe('select field', () => { test('should render custom select options', async () => { await page.goto(customFieldsURL.create) + await page.waitForURL(customFieldsURL.create) await page.locator('#field-customSelectField .rs__control').click() await expect(page.locator('#field-customSelectField .rs__option')).toHaveCount(2) }) diff --git a/test/admin/e2e/2/e2e.spec.ts b/test/admin/e2e/2/e2e.spec.ts index c0b7db8dbc..4e8a061e5d 100644 --- a/test/admin/e2e/2/e2e.spec.ts +++ b/test/admin/e2e/2/e2e.spec.ts @@ -782,29 +782,6 @@ describe('admin2', () => { }) }) }) - - describe('field descriptions', () => { - test('should render static field description', async () => { - await page.goto(postsUrl.create) - await expect(page.locator('.field-description-descriptionAsString')).toContainText( - 'Static field description.', - ) - }) - test('should render functional field description', async () => { - await page.goto(postsUrl.create) - await page.locator('#field-descriptionAsFunction').fill('functional') - await expect(page.locator('.field-description-descriptionAsFunction')).toContainText( - 'Function description', - ) - }) - test('should render component field description', async () => { - await page.goto(postsUrl.create) - await page.locator('#field-descriptionAsComponent').fill('component') - await expect(page.locator('.field-description-descriptionAsComponent')).toContainText( - 'Component description: descriptionAsComponent - component', - ) - }) - }) }) async function createPost(overrides?: Partial): Promise { diff --git a/test/admin/payload-types.ts b/test/admin/payload-types.ts index d13e671147..bd0ee8ff88 100644 --- a/test/admin/payload-types.ts +++ b/test/admin/payload-types.ts @@ -102,9 +102,6 @@ export interface Post { relationship?: (string | null) | Post; customCell?: string | null; sidebarField?: string | null; - descriptionAsString?: string | null; - descriptionAsFunction?: string | null; - descriptionAsComponent?: string | null; updatedAt: string; createdAt: string; _status?: ('draft' | 'published') | null; @@ -173,6 +170,10 @@ export interface CustomViewsTwo { */ export interface CustomField { id: string; + customTextField?: string | null; + descriptionAsString?: string | null; + descriptionAsFunction?: string | null; + descriptionAsComponent?: string | null; customSelectField?: string | null; updatedAt: string; createdAt: string; diff --git a/test/fields/collections/Number/e2e.spec.ts b/test/fields/collections/Number/e2e.spec.ts index 8a1d7d7160..918dc71339 100644 --- a/test/fields/collections/Number/e2e.spec.ts +++ b/test/fields/collections/Number/e2e.spec.ts @@ -53,19 +53,16 @@ describe('Number', () => { }) await ensureCompilationIsDone({ page, serverURL }) }) + beforeEach(async () => { await reInitializeDB({ serverURL, snapshotKey: 'fieldsNumberTest', uploadsDir: path.resolve(dirname, './collections/Upload/uploads'), }) - - if (client) { - await client.logout() - } + if (client) await client.logout() client = new RESTClient(null, { defaultSlug: 'users', serverURL }) await client.login() - await ensureCompilationIsDone({ page, serverURL }) }) @@ -77,26 +74,17 @@ describe('Number', () => { test('should filter Number fields in the collection view - greaterThanOrEqual', async () => { await page.goto(url.list) - - // should have 3 entries await expect(page.locator('table >> tbody >> tr')).toHaveCount(3) - - // open the filter options await page.locator('.list-controls__toggle-where').click() await expect(page.locator('.list-controls__where.rah-static--height-auto')).toBeVisible() await page.locator('.where-builder__add-first-filter').click() - const initialField = page.locator('.condition__field') const operatorField = page.locator('.condition__operator') const valueField = page.locator('.condition__value >> input') - - // select Number field to filter on await initialField.click() const initialFieldOptions = initialField.locator('.rs__option') await initialFieldOptions.locator('text=number').first().click() await expect(initialField.locator('.rs__single-value')).toContainText('Number') - - // select >= operator await operatorField.click() const operatorOptions = operatorField.locator('.rs__option') await operatorOptions.last().click() @@ -108,14 +96,11 @@ describe('Number', () => { await valueField.fill('3') await expect(valueField).toHaveValue('3') await wait(300) - - // should have 2 entries after filtering await expect(page.locator('table >> tbody >> tr')).toHaveCount(2) }) test('should create', async () => { const input = 5 - await page.goto(url.create) const field = page.locator('#field-number') await field.fill(String(input)) @@ -125,7 +110,6 @@ describe('Number', () => { test('should create hasMany', async () => { const input = 5 - await page.goto(url.create) const field = page.locator('.field-hasMany') await field.click() @@ -138,19 +122,16 @@ describe('Number', () => { test('should bypass min rows validation when no rows present and field is not required', async () => { await page.goto(url.create) await saveDocAndAssert(page) - await expect(page.locator('.payload-toast-container')).toContainText('successfully') + expect(true).toBe(true) // the above fn contains the assertion }) test('should fail min rows validation when rows are present', async () => { const input = 5 - await page.goto(url.create) await page.locator('.field-withMinRows').click() - await page.keyboard.type(String(input)) await page.keyboard.press('Enter') await page.click('#action-save', { delay: 100 }) - await expect(page.locator('.payload-toast-container')).toContainText( 'The following field is invalid: withMinRows', ) diff --git a/test/fields/collections/Text/CustomLabel.tsx b/test/fields/collections/Text/CustomLabel.tsx deleted file mode 100644 index 96ad9b4031..0000000000 --- a/test/fields/collections/Text/CustomLabel.tsx +++ /dev/null @@ -1,18 +0,0 @@ -'use client' - -import { useFieldProps } from '@payloadcms/ui' -import React from 'react' - -const CustomLabel = ({ schemaPath }) => { - const { path: pathFromContext } = useFieldProps() - - const path = pathFromContext ?? schemaPath // pathFromContext will be undefined in list view - - return ( - - ) -} - -export default CustomLabel diff --git a/test/fields/collections/Text/e2e.spec.ts b/test/fields/collections/Text/e2e.spec.ts index 36ec866e4e..1526382cf9 100644 --- a/test/fields/collections/Text/e2e.spec.ts +++ b/test/fields/collections/Text/e2e.spec.ts @@ -154,40 +154,6 @@ describe('Text', () => { await expect(description).toHaveText('en description') }) - test('should render custom label', async () => { - await page.goto(url.create) - const label = page.locator('label.custom-label[for="field-customLabel"]') - await expect(label).toHaveText('#label') - }) - - test('should render custom error', async () => { - await page.goto(url.create) - const input = page.locator('input[id="field-customError"]') - await input.fill('ab') - await expect(input).toHaveValue('ab') - const error = page.locator('.custom-error:near(input[id="field-customError"])') - const submit = page.locator('button[type="button"][id="action-save"]') - await submit.click() - await expect(error).toHaveText('#custom-error') - }) - - test('should render beforeInput and afterInput', async () => { - await page.goto(url.create) - const input = page.locator('input[id="field-beforeAndAfterInput"]') - - const prevSibling = await input.evaluateHandle((el) => { - return el.previousElementSibling - }) - const prevSiblingText = await page.evaluate((el) => el.textContent, prevSibling) - expect(prevSiblingText).toEqual('#before-input') - - const nextSibling = await input.evaluateHandle((el) => { - return el.nextElementSibling - }) - const nextSiblingText = await page.evaluate((el) => el.textContent, nextSibling) - expect(nextSiblingText).toEqual('#after-input') - }) - test('should create hasMany with multiple texts', async () => { const input = 'five' const furtherInput = 'six' diff --git a/test/fields/collections/Text/index.ts b/test/fields/collections/Text/index.ts index 1c7c547163..24aa8ac482 100644 --- a/test/fields/collections/Text/index.ts +++ b/test/fields/collections/Text/index.ts @@ -1,9 +1,5 @@ import type { CollectionConfig } from 'payload' -import { AfterInput } from './AfterInput.js' -import { BeforeInput } from './BeforeInput.js' -import CustomError from './CustomError.js' -import CustomLabel from './CustomLabel.js' import { defaultText, textFieldsSlug } from './shared.js' const TextFields: CollectionConfig = { @@ -93,35 +89,6 @@ const TextFields: CollectionConfig = { ], }, }, - { - name: 'customLabel', - type: 'text', - admin: { - components: { - Label: CustomLabel, - }, - }, - }, - { - name: 'customError', - type: 'text', - admin: { - components: { - Error: CustomError, - }, - }, - minLength: 3, - }, - { - name: 'beforeAndAfterInput', - type: 'text', - admin: { - components: { - afterInput: [AfterInput], - beforeInput: [BeforeInput], - }, - }, - }, { name: 'hasMany', type: 'text', diff --git a/test/fields/payload-types.ts b/test/fields/payload-types.ts index 3e8c6a7eef..85031f46d0 100644 --- a/test/fields/payload-types.ts +++ b/test/fields/payload-types.ts @@ -61,7 +61,7 @@ export interface Config { 'payload-migrations': PayloadMigration; }; db: { - defaultIDType: number; + defaultIDType: string; }; globals: { tabsWithRichText: TabsWithRichText; @@ -92,7 +92,7 @@ export interface UserAuthOperations { * via the `definition` "lexical-fields". */ export interface LexicalField { - id: number; + id: string; title: string; lexicalSimple?: { root: { @@ -133,7 +133,7 @@ export interface LexicalField { * via the `definition` "lexical-migrate-fields". */ export interface LexicalMigrateField { - id: number; + id: string; title: string; lexicalWithLexicalPluginData?: { root: { @@ -228,7 +228,7 @@ export interface LexicalMigrateField { * via the `definition` "lexical-localized-fields". */ export interface LexicalLocalizedField { - id: number; + id: string; title: string; lexicalBlocksSubLocalized?: { root: { @@ -268,7 +268,7 @@ export interface LexicalLocalizedField { * via the `definition` "users". */ export interface User { - id: number; + id: string; canViewConditionalField?: boolean | null; updatedAt: string; createdAt: string; @@ -286,7 +286,7 @@ export interface User { * via the `definition` "array-fields". */ export interface ArrayField { - id: number; + id: string; title?: string | null; items: { text: string; @@ -350,7 +350,7 @@ export interface ArrayField { * via the `definition` "block-fields". */ export interface BlockField { - id: number; + id: string; blocks: ( | { text: string; @@ -677,7 +677,7 @@ export interface BlockField { | null; relationshipBlocks?: | { - relationship?: (number | null) | TextField; + relationship?: (string | null) | TextField; id?: string | null; blockName?: string | null; blockType: 'relationships'; @@ -691,7 +691,7 @@ export interface BlockField { * via the `definition` "text-fields". */ export interface TextField { - id: number; + id: string; text: string; localizedText?: string | null; i18nText?: string | null; @@ -702,9 +702,6 @@ export interface TextField { overrideLength?: string | null; fieldWithDefaultValue?: string | null; dependentOnFieldWithDefaultValue?: string | null; - customLabel?: string | null; - customError?: string | null; - beforeAndAfterInput?: string | null; hasMany?: string[] | null; validatesHasMany?: string[] | null; localizedHasMany?: string[] | null; @@ -720,7 +717,7 @@ export interface TextField { * via the `definition` "checkbox-fields". */ export interface CheckboxField { - id: number; + id: string; checkbox: boolean; updatedAt: string; createdAt: string; @@ -730,7 +727,7 @@ export interface CheckboxField { * via the `definition` "code-fields". */ export interface CodeField { - id: number; + id: string; javascript?: string | null; typescript?: string | null; json?: string | null; @@ -744,7 +741,7 @@ export interface CodeField { * via the `definition` "collapsible-fields". */ export interface CollapsibleField { - id: number; + id: string; text: string; group?: { textWithinGroup?: string | null; @@ -776,7 +773,7 @@ export interface CollapsibleField { * via the `definition` "conditional-logic". */ export interface ConditionalLogic { - id: number; + id: string; text: string; toggleField?: boolean | null; fieldToToggle?: string | null; @@ -801,7 +798,7 @@ export interface ConditionalLogic { * via the `definition` "date-fields". */ export interface DateField { - id: number; + id: string; default: string; timeOnly?: string | null; timeOnlyWithCustomFormat?: string | null; @@ -816,9 +813,10 @@ export interface DateField { * via the `definition` "email-fields". */ export interface EmailField { - id: number; + id: string; email: string; localizedEmail?: string | null; + emailWithAutocomplete?: string | null; i18nEmail?: string | null; defaultEmail?: string | null; defaultEmptyString?: string | null; @@ -837,7 +835,7 @@ export interface EmailField { * via the `definition` "radio-fields". */ export interface RadioField { - id: number; + id: string; radio?: ('one' | 'two' | 'three') | null; updatedAt: string; createdAt: string; @@ -847,7 +845,7 @@ export interface RadioField { * via the `definition` "group-fields". */ export interface GroupField { - id: number; + id: string; group: { text: string; defaultParent?: string | null; @@ -922,7 +920,7 @@ export interface RowField { * via the `definition` "indexed-fields". */ export interface IndexedField { - id: number; + id: string; text: string; uniqueText?: string | null; uniqueRequiredText: string; @@ -951,7 +949,7 @@ export interface IndexedField { * via the `definition` "json-fields". */ export interface JsonField { - id: number; + id: string; json?: { foo?: 'bar' | 'foobar'; number?: 10 | 5; @@ -976,7 +974,7 @@ export interface JsonField { * via the `definition` "number-fields". */ export interface NumberField { - id: number; + id: string; number?: number | null; min?: number | null; max?: number | null; @@ -997,7 +995,7 @@ export interface NumberField { * via the `definition` "point-fields". */ export interface PointField { - id: number; + id: string; /** * @minItems 2 * @maxItems 2 @@ -1023,49 +1021,49 @@ export interface PointField { * via the `definition` "relationship-fields". */ export interface RelationshipField { - id: number; + id: string; text?: string | null; relationship: | { relationTo: 'text-fields'; - value: number | TextField; + value: string | TextField; } | { relationTo: 'array-fields'; - value: number | ArrayField; + value: string | ArrayField; }; relationHasManyPolymorphic?: | ( | { relationTo: 'text-fields'; - value: number | TextField; + value: string | TextField; } | { relationTo: 'array-fields'; - value: number | ArrayField; + value: string | ArrayField; } )[] | null; - relationToSelf?: (number | null) | RelationshipField; - relationToSelfSelectOnly?: (number | null) | RelationshipField; - relationWithDynamicDefault?: (number | null) | User; + relationToSelf?: (string | null) | RelationshipField; + relationToSelfSelectOnly?: (string | null) | RelationshipField; + relationWithDynamicDefault?: (string | null) | User; relationHasManyWithDynamicDefault?: { relationTo: 'users'; - value: number | User; + value: string | User; } | null; - relationshipWithMin?: (number | TextField)[] | null; - relationshipWithMax?: (number | TextField)[] | null; - relationshipHasMany?: (number | TextField)[] | null; + relationshipWithMin?: (string | TextField)[] | null; + relationshipWithMax?: (string | TextField)[] | null; + relationshipHasMany?: (string | TextField)[] | null; array?: | { - relationship?: (number | null) | TextField; + relationship?: (string | null) | TextField; id?: string | null; }[] | null; relationshipWithMinRows?: | { relationTo: 'text-fields'; - value: number | TextField; + value: string | TextField; }[] | null; updatedAt: string; @@ -1076,7 +1074,7 @@ export interface RelationshipField { * via the `definition` "rich-text-fields". */ export interface RichTextField { - id: number; + id: string; title: string; lexicalCustomFields: { root: { @@ -1151,7 +1149,7 @@ export interface RichTextField { * via the `definition` "select-fields". */ export interface SelectField { - id: number; + id: string; select?: ('one' | 'two' | 'three') | null; selectReadOnly?: ('one' | 'two' | 'three') | null; selectHasMany?: ('one' | 'two' | 'three' | 'four' | 'five' | 'six')[] | null; @@ -1169,7 +1167,7 @@ export interface SelectField { * via the `definition` "tabs-fields-2". */ export interface TabsFields2 { - id: number; + id: string; tabsInArray?: | { text?: string | null; @@ -1187,7 +1185,7 @@ export interface TabsFields2 { * via the `definition` "tabs-fields". */ export interface TabsField { - id: number; + id: string; sidebarField?: string | null; array: { text: string; @@ -1296,9 +1294,9 @@ export interface TabsField { * via the `definition` "uploads". */ export interface Upload { - id: number; + id: string; text?: string | null; - media?: number | Upload | null; + media?: string | Upload | null; richText?: { root: { type: string; @@ -1331,9 +1329,9 @@ export interface Upload { * via the `definition` "uploads2". */ export interface Uploads2 { - id: number; + id: string; text?: string | null; - media?: number | Uploads2 | null; + media?: string | Uploads2 | null; updatedAt: string; createdAt: string; url?: string | null; @@ -1351,8 +1349,8 @@ export interface Uploads2 { * via the `definition` "uploads3". */ export interface Uploads3 { - id: number; - media?: number | Uploads3 | null; + id: string; + media?: string | Uploads3 | null; richText?: { root: { type: string; @@ -1385,7 +1383,7 @@ export interface Uploads3 { * via the `definition` "ui-fields". */ export interface UiField { - id: number; + id: string; text: string; updatedAt: string; createdAt: string; @@ -1395,10 +1393,10 @@ export interface UiField { * via the `definition` "payload-preferences". */ export interface PayloadPreference { - id: number; + id: string; user: { relationTo: 'users'; - value: number | User; + value: string | User; }; key?: string | null; value?: @@ -1418,7 +1416,7 @@ export interface PayloadPreference { * via the `definition` "payload-migrations". */ export interface PayloadMigration { - id: number; + id: string; name?: string | null; batch?: number | null; updatedAt: string; @@ -1429,7 +1427,7 @@ export interface PayloadMigration { * via the `definition` "tabsWithRichText". */ export interface TabsWithRichText { - id: number; + id: string; tab1?: { rt1?: { root: { diff --git a/test/live-preview/payload-types.ts b/test/live-preview/payload-types.ts index 2816a31307..906006fbad 100644 --- a/test/live-preview/payload-types.ts +++ b/test/live-preview/payload-types.ts @@ -22,6 +22,9 @@ export interface Config { 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; }; + db: { + defaultIDType: string; + }; globals: { header: Header; footer: Footer; @@ -36,13 +39,16 @@ export interface UserAuthOperations { email: string; }; login: { - password: string; email: string; + password: string; }; registerFirstUser: { email: string; password: string; }; + unlock: { + email: string; + }; } /** * This interface was referenced by `Config`'s JSON-Schema diff --git a/test/plugin-form-builder/payload-types.ts b/test/plugin-form-builder/payload-types.ts index 9e976d94d2..aacc681db8 100644 --- a/test/plugin-form-builder/payload-types.ts +++ b/test/plugin-form-builder/payload-types.ts @@ -18,6 +18,9 @@ export interface Config { 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; }; + db: { + defaultIDType: string; + }; globals: {}; locale: 'en' | 'es' | 'de'; user: User & { @@ -29,13 +32,16 @@ export interface UserAuthOperations { email: string; }; login: { - password: string; email: string; + password: string; }; registerFirstUser: { email: string; password: string; }; + unlock: { + email: string; + }; } /** * This interface was referenced by `Config`'s JSON-Schema diff --git a/test/plugin-seo/payload-types.ts b/test/plugin-seo/payload-types.ts index 8ee16f98c7..fedbade769 100644 --- a/test/plugin-seo/payload-types.ts +++ b/test/plugin-seo/payload-types.ts @@ -18,6 +18,9 @@ export interface Config { 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; }; + db: { + defaultIDType: string; + }; globals: {}; locale: 'en' | 'es' | 'de'; user: User & { @@ -29,13 +32,16 @@ export interface UserAuthOperations { email: string; }; login: { - password: string; email: string; + password: string; }; registerFirstUser: { email: string; password: string; }; + unlock: { + email: string; + }; } /** * This interface was referenced by `Config`'s JSON-Schema diff --git a/test/versions/payload-types.ts b/test/versions/payload-types.ts index 0f0262c78f..f9846c56a8 100644 --- a/test/versions/payload-types.ts +++ b/test/versions/payload-types.ts @@ -22,6 +22,9 @@ export interface Config { 'payload-preferences': PayloadPreference; 'payload-migrations': PayloadMigration; }; + db: { + defaultIDType: string; + }; globals: { 'autosave-global': AutosaveGlobal; 'draft-global': DraftGlobal; @@ -38,13 +41,16 @@ export interface UserAuthOperations { email: string; }; login: { - password: string; email: string; + password: string; }; registerFirstUser: { email: string; password: string; }; + unlock: { + email: string; + }; } /** * This interface was referenced by `Config`'s JSON-Schema