feat: threads field config through components and strictly types props (#7754)
## Description Threads the field config to all "field subcomponents" through props, i.e. field label, description, error, etc. This way, the field config that controls any particular component is easily accessible and strongly typed, i.e. `props.field.maxLength`. This is true for both server and client components, whose server-side props are now also contextually typed. This behavior was temporarily removed in #7474 due to bloating HTML, but has since been resolved in #7620. This PR also makes significant improvements to component types by exporting explicit types for _every component of every field_, each with its own client/server variation. Now, a custom component can look something like this: ```tsx import type { TextFieldLabelServerComponent } from 'payload' import React from 'react' export const CustomLabel: TextFieldLabelServerComponent = (props) => { return ( <div>{`The max length of this field is: ${props?.field?.maxLength}`}</div> ) } ``` The following types are now available: ```ts import type { TextFieldClientComponent, TextFieldServerComponent, TextFieldLabelClientComponent, TextFieldLabelServerComponent, TextFieldDescriptionClientComponent, TextFieldDescriptionServerComponent, TextFieldErrorClientComponent, TextFieldErrorServerComponent, // ...and so one for each field } from 'payload' ``` BREAKING CHANGES: In order to strictly type these components, a few breaking changes have been made _solely to type definitions_. This only effects you if you are heavily using custom components. Old ```ts import type { ErrorComponent, LabelComponent, DescriptionComponent } from 'payload' ``` New: ```ts import type { FieldErrorClientComponent, FieldErrorServerComponent, FieldLabelClientComponent, FieldLabelServerComponent, FieldDescriptionClientComponent, FieldDescriptionServerComponent, // Note: these are the generic, underlying types of the more stricter types described above ^ // For example, you should use the type that is explicit for your particular field and environment // i.e. `TextFieldLabelClientComponent` and not simply `FieldLabelClientComponent` } from 'payload' ``` - [x] I have read and understand the [CONTRIBUTING.md](https://github.com/payloadcms/payload/blob/main/CONTRIBUTING.md) document in this repository. ## Type of change - [x] Bug fix (non-breaking change which fixes an issue) ## Checklist: - [x] I have added tests that prove my fix is effective or that my feature works - [x] Existing test suite passes locally with my changes
This commit is contained in:
@@ -347,31 +347,13 @@ Custom Label Components receive all [Field Component](#the-field-component) prop
|
||||
|
||||
#### TypeScript
|
||||
|
||||
When building Custom Label Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Label Component, one for every [Field Type](../fields/overview). The convention is to append `LabelComponent` to the type of field, i.e. `TextFieldLabelComponent`.
|
||||
When building Custom Label Components, you can import the component props to ensure type safety in your component. There is an explicit type for the Label Component, one for every [Field Type](../fields/overview) and server/client environment. The convention is to append `LabelServerComponent` or `LabelClientComponent` to the type of field, i.e. `TextFieldLabelClientComponent`.
|
||||
|
||||
```tsx
|
||||
import type {
|
||||
ArrayFieldLabelComponent,
|
||||
BlocksFieldLabelComponent,
|
||||
CheckboxFieldLabelComponent,
|
||||
CodeFieldLabelComponent,
|
||||
CollapsibleFieldLabelComponent,
|
||||
DateFieldLabelComponent,
|
||||
EmailFieldLabelComponent,
|
||||
GroupFieldLabelComponent,
|
||||
HiddenFieldLabelComponent,
|
||||
JSONFieldLabelComponent,
|
||||
NumberFieldLabelComponent,
|
||||
PointFieldLabelComponent,
|
||||
RadioFieldLabelComponent,
|
||||
RelationshipFieldLabelComponent,
|
||||
RichTextFieldLabelComponent,
|
||||
RowFieldLabelComponent,
|
||||
SelectFieldLabelComponent,
|
||||
TabsFieldLabelComponent,
|
||||
TextFieldLabelComponent,
|
||||
TextareaFieldLabelComponent,
|
||||
UploadFieldLabelComponent
|
||||
TextFieldLabelServerComponent,
|
||||
TextFieldLabelClientComponent,
|
||||
// And so on for each Field Type
|
||||
} from 'payload'
|
||||
```
|
||||
|
||||
@@ -410,31 +392,13 @@ Custom Error Components receive all [Field Component](#the-field-component) prop
|
||||
|
||||
#### 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`.
|
||||
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) and server/client environment. The convention is to append `ErrorServerComponent` or `ErrorClientComponent` to the type of field, i.e. `TextFieldErrorClientComponent`.
|
||||
|
||||
```tsx
|
||||
import type {
|
||||
ArrayFieldErrorComponent,
|
||||
BlocksFieldErrorComponent,
|
||||
CheckboxFieldErrorComponent,
|
||||
CodeFieldErrorComponent,
|
||||
CollapsibleFieldErrorComponent,
|
||||
DateFieldErrorComponent,
|
||||
EmailFieldErrorComponent,
|
||||
GroupFieldErrorComponent,
|
||||
HiddenFieldErrorComponent,
|
||||
JSONFieldErrorComponent,
|
||||
NumberFieldErrorComponent,
|
||||
PointFieldErrorComponent,
|
||||
RadioFieldErrorComponent,
|
||||
RelationshipFieldErrorComponent,
|
||||
RichTextFieldErrorComponent,
|
||||
RowFieldErrorComponent,
|
||||
SelectFieldErrorComponent,
|
||||
TabsFieldErrorComponent,
|
||||
TextFieldErrorComponent,
|
||||
TextareaFieldErrorComponent,
|
||||
UploadFieldErrorComponent
|
||||
TextFieldErrorServerComponent,
|
||||
TextFieldErrorClientComponent,
|
||||
// And so on for each Field Type
|
||||
} from 'payload'
|
||||
```
|
||||
|
||||
@@ -544,31 +508,13 @@ Custom Description Components receive all [Field Component](#the-field-component
|
||||
|
||||
#### 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`.
|
||||
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) and server/client environment. The convention is to append `DescriptionServerComponent` or `DescriptionClientComponent` to the type of field, i.e. `TextFieldDescriptionClientComponent`.
|
||||
|
||||
```tsx
|
||||
import type {
|
||||
ArrayFieldDescriptionComponent,
|
||||
BlocksFieldDescriptionComponent,
|
||||
CheckboxFieldDescriptionComponent,
|
||||
CodeFieldDescriptionComponent,
|
||||
CollapsibleFieldDescriptionComponent,
|
||||
DateFieldDescriptionComponent,
|
||||
EmailFieldDescriptionComponent,
|
||||
GroupFieldDescriptionComponent,
|
||||
HiddenFieldDescriptionComponent,
|
||||
JSONFieldDescriptionComponent,
|
||||
NumberFieldDescriptionComponent,
|
||||
PointFieldDescriptionComponent,
|
||||
RadioFieldDescriptionComponent,
|
||||
RelationshipFieldDescriptionComponent,
|
||||
RichTextFieldDescriptionComponent,
|
||||
RowFieldDescriptionComponent,
|
||||
SelectFieldDescriptionComponent,
|
||||
TabsFieldDescriptionComponent,
|
||||
TextFieldDescriptionComponent,
|
||||
TextareaFieldDescriptionComponent,
|
||||
UploadFieldDescriptionComponent
|
||||
TextFieldDescriptionServerComponent,
|
||||
TextFieldDescriptionClientComponent,
|
||||
// And so on for each Field Type
|
||||
} from 'payload'
|
||||
```
|
||||
|
||||
|
||||
@@ -467,10 +467,10 @@ export const ServerRenderedDescription = () => <ClientRenderedDescription />
|
||||
// file: components/ClientRenderedDescription.tsx
|
||||
'use client'
|
||||
import React from 'react'
|
||||
import type { DescriptionComponent } from 'payload'
|
||||
import type { TextFieldDescriptionClientComponent } from 'payload'
|
||||
import { useFieldProps, useFormFields } from '@payloadcms/ui'
|
||||
|
||||
export const ClientRenderedDescription: DescriptionComponent = () ={
|
||||
export const ClientRenderedDescription: TextFieldDescriptionClientComponent = () ={
|
||||
const { path } = useFieldProps()
|
||||
const { value } = useFormFields(([fields]) => fields[path])
|
||||
const customDescription = `Component description: ${path} - ${value}`
|
||||
|
||||
@@ -7,7 +7,6 @@ import type {
|
||||
} from 'payload'
|
||||
|
||||
import { RenderComponent, getCreateMappedComponent } from '@payloadcms/ui/shared'
|
||||
import { isPlainObject } from 'payload'
|
||||
import React from 'react'
|
||||
|
||||
import { ShouldRenderTabs } from './ShouldRenderTabs.js'
|
||||
|
||||
@@ -11,9 +11,9 @@ import './index.scss'
|
||||
const baseClass = 'payload-settings'
|
||||
|
||||
export const Settings: React.FC<{
|
||||
className?: string
|
||||
i18n: I18n
|
||||
languageOptions: LanguageOptions
|
||||
readonly className?: string
|
||||
readonly i18n: I18n
|
||||
readonly languageOptions: LanguageOptions
|
||||
}> = (props) => {
|
||||
const { className, i18n, languageOptions } = props
|
||||
|
||||
@@ -21,7 +21,7 @@ export const Settings: React.FC<{
|
||||
<div className={[baseClass, className].filter(Boolean).join(' ')}>
|
||||
<h3>{i18n.t('general:payloadSettings')}</h3>
|
||||
<div className={`${baseClass}__language`}>
|
||||
<FieldLabel htmlFor="language-select" label={i18n.t('general:language')} />
|
||||
<FieldLabel field={null} htmlFor="language-select" label={i18n.t('general:language')} />
|
||||
<LanguageSelector languageOptions={languageOptions} />
|
||||
</div>
|
||||
<ToggleTheme />
|
||||
|
||||
@@ -128,8 +128,6 @@ export const getViewsFromConfig = ({
|
||||
views,
|
||||
})
|
||||
|
||||
console.log('CustomViewComponent', customViewKey)
|
||||
|
||||
if (customViewKey) {
|
||||
viewKey = customViewKey
|
||||
|
||||
|
||||
@@ -129,6 +129,7 @@ export const APIKey: React.FC<{ readonly enabled: boolean; readonly readOnly?: b
|
||||
Component: null,
|
||||
RenderedComponent: APIKeyLabel,
|
||||
}}
|
||||
field={null}
|
||||
htmlFor={path}
|
||||
/>
|
||||
<input
|
||||
|
||||
@@ -1,23 +1,33 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { ArrayFieldClient } from '../../fields/config/types.js'
|
||||
import type { ArrayField, ArrayFieldClient } from '../../fields/config/types.js'
|
||||
import type { ArrayFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
DescriptionComponent,
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
LabelComponent,
|
||||
MappedComponent,
|
||||
} from '../types.js'
|
||||
|
||||
type ArrayFieldClientWithoutType = MarkOptional<ArrayFieldClient, 'type'>
|
||||
|
||||
export type ArrayFieldProps = {
|
||||
readonly CustomRowLabel?: MappedComponent
|
||||
readonly field: MarkOptional<ArrayFieldClient, 'type'>
|
||||
readonly validate?: ArrayFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<ArrayFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type ArrayFieldLabelComponent = LabelComponent<'array'>
|
||||
export type ArrayFieldLabelServerComponent = FieldLabelServerComponent<ArrayField>
|
||||
|
||||
export type ArrayFieldDescriptionComponent = DescriptionComponent<'array'>
|
||||
export type ArrayFieldLabelClientComponent = FieldLabelClientComponent<ArrayFieldClientWithoutType>
|
||||
|
||||
export type ArrayFieldErrorComponent = ErrorComponent<'array'>
|
||||
export type ArrayFieldDescriptionServerComponent = FieldDescriptionServerComponent<ArrayField>
|
||||
|
||||
export type ArrayFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<ArrayFieldClientWithoutType>
|
||||
|
||||
export type ArrayFieldErrorServerComponent = FieldErrorServerComponent<ArrayField>
|
||||
|
||||
export type ArrayFieldErrorClientComponent = FieldErrorClientComponent<ArrayFieldClientWithoutType>
|
||||
|
||||
@@ -1,17 +1,31 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { BlockFieldClient } from '../../fields/config/types.js'
|
||||
import type { BlockField, BlockFieldClient } from '../../fields/config/types.js'
|
||||
import type { BlockFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type BlocksFieldClientWithoutType = MarkOptional<BlockFieldClient, 'type'>
|
||||
|
||||
export type BlockFieldProps = {
|
||||
readonly field: MarkOptional<BlockFieldClient, 'type'>
|
||||
readonly validate?: BlockFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<BlocksFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type BlockFieldLabelComponent = LabelComponent<'blocks'>
|
||||
export type BlockFieldLabelServerComponent = FieldLabelServerComponent<BlockField>
|
||||
|
||||
export type BlockFieldDescriptionComponent = DescriptionComponent<'blocks'>
|
||||
export type BlockFieldLabelClientComponent = FieldLabelClientComponent<BlocksFieldClientWithoutType>
|
||||
|
||||
export type BlockFieldErrorComponent = ErrorComponent<'blocks'>
|
||||
export type BlockFieldDescriptionServerComponent = FieldDescriptionServerComponent<BlockField>
|
||||
|
||||
export type BlockFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<BlocksFieldClientWithoutType>
|
||||
|
||||
export type BlockFieldErrorServerComponent = FieldErrorServerComponent<BlockField>
|
||||
|
||||
export type BlockFieldErrorClientComponent = FieldErrorClientComponent<BlocksFieldClientWithoutType>
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { CheckboxFieldClient } from '../../fields/config/types.js'
|
||||
import type { CheckboxField, CheckboxFieldClient } from '../../fields/config/types.js'
|
||||
import type { CheckboxFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type CheckboxFieldClientWithoutType = MarkOptional<CheckboxFieldClient, 'type'>
|
||||
|
||||
export type CheckboxFieldProps = {
|
||||
readonly checked?: boolean
|
||||
readonly disableFormData?: boolean
|
||||
readonly field: MarkOptional<CheckboxFieldClient, 'type'>
|
||||
readonly id?: string
|
||||
readonly onChange?: (value: boolean) => void
|
||||
readonly partialChecked?: boolean
|
||||
readonly validate?: CheckboxFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<CheckboxFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type CheckboxFieldLabelComponent = LabelComponent<'checkbox'>
|
||||
export type CheckboxFieldLabelServerComponent = FieldLabelServerComponent<CheckboxField>
|
||||
|
||||
export type CheckboxFieldDescriptionComponent = DescriptionComponent<'checkbox'>
|
||||
export type CheckboxFieldLabelClientComponent =
|
||||
FieldLabelClientComponent<CheckboxFieldClientWithoutType>
|
||||
|
||||
export type CheckboxFieldErrorComponent = ErrorComponent<'checkbox'>
|
||||
export type CheckboxFieldDescriptionServerComponent = FieldDescriptionServerComponent<CheckboxField>
|
||||
|
||||
export type CheckboxFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<CheckboxFieldClientWithoutType>
|
||||
|
||||
export type CheckboxFieldErrorServerComponent = FieldErrorServerComponent<CheckboxField>
|
||||
|
||||
export type CheckboxFieldErrorClientComponent =
|
||||
FieldErrorClientComponent<CheckboxFieldClientWithoutType>
|
||||
|
||||
@@ -1,18 +1,32 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { CodeFieldClient } from '../../fields/config/types.js'
|
||||
import type { CodeField, CodeFieldClient } from '../../fields/config/types.js'
|
||||
import type { CodeFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type CodeFieldClientWithoutType = MarkOptional<CodeFieldClient, 'type'>
|
||||
|
||||
export type CodeFieldProps = {
|
||||
readonly autoComplete?: string
|
||||
readonly field: MarkOptional<CodeFieldClient, 'type'>
|
||||
readonly validate?: CodeFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<CodeFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type CodeFieldLabelComponent = LabelComponent<'code'>
|
||||
export type CodeFieldLabelServerComponent = FieldLabelServerComponent<CodeField>
|
||||
|
||||
export type CodeFieldDescriptionComponent = DescriptionComponent<'code'>
|
||||
export type CodeFieldLabelClientComponent = FieldLabelClientComponent<CodeFieldClientWithoutType>
|
||||
|
||||
export type CodeFieldErrorComponent = ErrorComponent<'code'>
|
||||
export type CodeFieldDescriptionServerComponent = FieldDescriptionServerComponent<CodeField>
|
||||
|
||||
export type CodeFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<CodeFieldClientWithoutType>
|
||||
|
||||
export type CodeFieldErrorServerComponent = FieldErrorServerComponent<CodeField>
|
||||
|
||||
export type CodeFieldErrorClientComponent = FieldErrorClientComponent<CodeFieldClientWithoutType>
|
||||
|
||||
@@ -1,15 +1,31 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { CollapsibleFieldClient } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { CollapsibleField, CollapsibleFieldClient } from '../../fields/config/types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
export type CollapsibleFieldProps = {
|
||||
readonly field: MarkOptional<CollapsibleFieldClient, 'type'>
|
||||
} & FormFieldBase
|
||||
type CollapsibleFieldClientWithoutType = MarkOptional<CollapsibleFieldClient, 'type'>
|
||||
|
||||
export type CollapsibleFieldLabelComponent = LabelComponent<'collapsible'>
|
||||
export type CollapsibleFieldProps = FormFieldBase<CollapsibleFieldClientWithoutType>
|
||||
|
||||
export type CollapsibleFieldDescriptionComponent = DescriptionComponent<'collapsible'>
|
||||
export type CollapsibleFieldLabelServerComponent = FieldLabelServerComponent<CollapsibleField>
|
||||
|
||||
export type CollapsibleFieldErrorComponent = ErrorComponent<'collapsible'>
|
||||
export type CollapsibleFieldLabelClientComponent =
|
||||
FieldLabelClientComponent<CollapsibleFieldClientWithoutType>
|
||||
|
||||
export type CollapsibleFieldDescriptionServerComponent =
|
||||
FieldDescriptionServerComponent<CollapsibleField>
|
||||
|
||||
export type CollapsibleFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<CollapsibleFieldClientWithoutType>
|
||||
|
||||
export type CollapsibleFieldErrorServerComponent = FieldErrorServerComponent<CollapsibleField>
|
||||
|
||||
export type CollapsibleFieldErrorClientComponent =
|
||||
FieldErrorClientComponent<CollapsibleFieldClientWithoutType>
|
||||
|
||||
@@ -1,17 +1,31 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { DateFieldClient } from '../../fields/config/types.js'
|
||||
import type { DateField, DateFieldClient } from '../../fields/config/types.js'
|
||||
import type { DateFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type DateFieldClientWithoutType = MarkOptional<DateFieldClient, 'type'>
|
||||
|
||||
export type DateFieldProps = {
|
||||
readonly field: MarkOptional<DateFieldClient, 'type'>
|
||||
readonly validate?: DateFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<DateFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type DateFieldLabelComponent = LabelComponent<'date'>
|
||||
export type DateFieldLabelServerComponent = FieldLabelServerComponent<DateField>
|
||||
|
||||
export type DateFieldDescriptionComponent = DescriptionComponent<'date'>
|
||||
export type DateFieldLabelClientComponent = FieldLabelClientComponent<DateFieldClientWithoutType>
|
||||
|
||||
export type DateFieldErrorComponent = ErrorComponent<'date'>
|
||||
export type DateFieldDescriptionServerComponent = FieldDescriptionServerComponent<DateField>
|
||||
|
||||
export type DateFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<DateFieldClientWithoutType>
|
||||
|
||||
export type DateFieldErrorServerComponent = FieldErrorServerComponent<DateField>
|
||||
|
||||
export type DateFieldErrorClientComponent = FieldErrorClientComponent<DateFieldClientWithoutType>
|
||||
|
||||
@@ -1,18 +1,32 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { EmailFieldClient } from '../../fields/config/types.js'
|
||||
import type { EmailField, EmailFieldClient } from '../../fields/config/types.js'
|
||||
import type { EmailFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type EmailFieldClientWithoutType = MarkOptional<EmailFieldClient, 'type'>
|
||||
|
||||
export type EmailFieldProps = {
|
||||
readonly autoComplete?: string
|
||||
readonly field: MarkOptional<EmailFieldClient, 'type'>
|
||||
readonly validate?: EmailFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<EmailFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type EmailFieldLabelComponent = LabelComponent<'email'>
|
||||
export type EmailFieldLabelServerComponent = FieldLabelServerComponent<EmailField>
|
||||
|
||||
export type EmailFieldDescriptionComponent = DescriptionComponent<'email'>
|
||||
export type EmailFieldLabelClientComponent = FieldLabelClientComponent<EmailFieldClientWithoutType>
|
||||
|
||||
export type EmailFieldErrorComponent = ErrorComponent<'email'>
|
||||
export type EmailFieldDescriptionServerComponent = FieldDescriptionServerComponent<EmailField>
|
||||
|
||||
export type EmailFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<EmailFieldClientWithoutType>
|
||||
|
||||
export type EmailFieldErrorServerComponent = FieldErrorServerComponent<EmailField>
|
||||
|
||||
export type EmailFieldErrorClientComponent = FieldErrorClientComponent<EmailFieldClientWithoutType>
|
||||
|
||||
@@ -1,15 +1,28 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { GroupFieldClient } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { GroupField, GroupFieldClient } from '../../fields/config/types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
export type GroupFieldProps = {
|
||||
readonly field: MarkOptional<GroupFieldClient, 'type'>
|
||||
} & FormFieldBase
|
||||
type GroupFieldClientWithoutType = MarkOptional<GroupFieldClient, 'type'>
|
||||
|
||||
export type GroupFieldLabelComponent = LabelComponent<'group'>
|
||||
export type GroupFieldProps = FormFieldBase<GroupFieldClientWithoutType>
|
||||
|
||||
export type GroupFieldDescriptionComponent = DescriptionComponent<'group'>
|
||||
export type GroupFieldLabelServerComponent = FieldLabelServerComponent<GroupField>
|
||||
|
||||
export type GroupFieldErrorComponent = ErrorComponent<'group'>
|
||||
export type GroupFieldLabelClientComponent = FieldLabelClientComponent<GroupFieldClientWithoutType>
|
||||
|
||||
export type GroupFieldDescriptionServerComponent = FieldDescriptionServerComponent<GroupField>
|
||||
|
||||
export type GroupFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<GroupFieldClientWithoutType>
|
||||
|
||||
export type GroupFieldErrorServerComponent = FieldErrorServerComponent<GroupField>
|
||||
|
||||
export type GroupFieldErrorClientComponent = FieldErrorClientComponent<GroupFieldClientWithoutType>
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
import type { ClientField } from '../../fields/config/client.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FormFieldBase } from '../types.js'
|
||||
|
||||
export type HiddenFieldProps = {
|
||||
readonly disableModifyingForm?: false
|
||||
@@ -10,9 +9,3 @@ export type HiddenFieldProps = {
|
||||
readonly forceUsePathFromProps?: boolean
|
||||
readonly value?: unknown
|
||||
} & FormFieldBase
|
||||
|
||||
export type HiddenFieldLabelComponent = LabelComponent<'hidden'>
|
||||
|
||||
export type HiddenFieldDescriptionComponent = DescriptionComponent<'hidden'>
|
||||
|
||||
export type HiddenFieldErrorComponent = ErrorComponent<'hidden'>
|
||||
|
||||
@@ -1,17 +1,31 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { JSONFieldClient } from '../../fields/config/types.js'
|
||||
import type { JSONField, JSONFieldClient } from '../../fields/config/types.js'
|
||||
import type { JSONFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type JSONFieldClientWithoutType = MarkOptional<JSONFieldClient, 'type'>
|
||||
|
||||
export type JSONFieldProps = {
|
||||
readonly field: MarkOptional<JSONFieldClient, 'type'>
|
||||
readonly validate?: JSONFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<JSONFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type JSONFieldLabelComponent = LabelComponent<'json'>
|
||||
export type JSONFieldLabelServerComponent = FieldLabelServerComponent<JSONField>
|
||||
|
||||
export type JSONFieldDescriptionComponent = DescriptionComponent<'json'>
|
||||
export type JSONFieldLabelClientComponent = FieldLabelClientComponent<JSONFieldClientWithoutType>
|
||||
|
||||
export type JSONFieldErrorComponent = ErrorComponent<'json'>
|
||||
export type JSONFieldDescriptionServerComponent = FieldDescriptionServerComponent<JSONField>
|
||||
|
||||
export type JSONFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<JSONFieldClientWithoutType>
|
||||
|
||||
export type JSONFieldErrorServerComponent = FieldErrorServerComponent<JSONField>
|
||||
|
||||
export type JSONFieldErrorClientComponent = FieldErrorClientComponent<JSONFieldClientWithoutType>
|
||||
|
||||
@@ -1,18 +1,34 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { NumberFieldClient } from '../../fields/config/types.js'
|
||||
import type { NumberField, NumberFieldClient } from '../../fields/config/types.js'
|
||||
import type { NumberFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type NumberFieldClientWithoutType = MarkOptional<NumberFieldClient, 'type'>
|
||||
|
||||
export type NumberFieldProps = {
|
||||
readonly field: MarkOptional<NumberFieldClient, 'type'>
|
||||
readonly onChange?: (e: number) => void
|
||||
readonly validate?: NumberFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<NumberFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type NumberFieldLabelComponent = LabelComponent<'number'>
|
||||
export type NumberFieldLabelServerComponent = FieldLabelServerComponent<NumberField>
|
||||
|
||||
export type NumberFieldDescriptionComponent = DescriptionComponent<'number'>
|
||||
export type NumberFieldLabelClientComponent =
|
||||
FieldLabelClientComponent<NumberFieldClientWithoutType>
|
||||
|
||||
export type NumberFieldErrorComponent = ErrorComponent<'number'>
|
||||
export type NumberFieldDescriptionServerComponent = FieldDescriptionServerComponent<NumberField>
|
||||
|
||||
export type NumberFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<NumberFieldClientWithoutType>
|
||||
|
||||
export type NumberFieldErrorServerComponent = FieldErrorServerComponent<NumberField>
|
||||
|
||||
export type NumberFieldErrorClientComponent =
|
||||
FieldErrorClientComponent<NumberFieldClientWithoutType>
|
||||
|
||||
@@ -1,17 +1,31 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { PointFieldClient } from '../../fields/config/types.js'
|
||||
import type { PointField, PointFieldClient } from '../../fields/config/types.js'
|
||||
import type { PointFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type PointFieldClientWithoutType = MarkOptional<PointFieldClient, 'type'>
|
||||
|
||||
export type PointFieldProps = {
|
||||
readonly field: MarkOptional<PointFieldClient, 'type'>
|
||||
readonly validate?: PointFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<PointFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type PointFieldLabelComponent = LabelComponent<'point'>
|
||||
export type PointFieldLabelServerComponent = FieldLabelServerComponent<PointField>
|
||||
|
||||
export type PointFieldDescriptionComponent = DescriptionComponent<'point'>
|
||||
export type PointFieldLabelClientComponent = FieldLabelClientComponent<PointFieldClientWithoutType>
|
||||
|
||||
export type PointFieldErrorComponent = ErrorComponent<'point'>
|
||||
export type PointFieldDescriptionServerComponent = FieldDescriptionServerComponent<PointField>
|
||||
|
||||
export type PointFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<PointFieldClientWithoutType>
|
||||
|
||||
export type PointFieldErrorServerComponent = FieldErrorServerComponent<PointField>
|
||||
|
||||
export type PointFieldErrorClientComponent = FieldErrorClientComponent<PointFieldClientWithoutType>
|
||||
|
||||
@@ -1,21 +1,35 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { RadioFieldClient } from '../../fields/config/types.js'
|
||||
import type { RadioField, RadioFieldClient } from '../../fields/config/types.js'
|
||||
import type { RadioFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type RadioFieldClientWithoutType = MarkOptional<RadioFieldClient, 'type'>
|
||||
|
||||
export type RadioFieldProps = {
|
||||
readonly field: MarkOptional<RadioFieldClient, 'type'>
|
||||
readonly onChange?: OnChange
|
||||
readonly validate?: RadioFieldValidation
|
||||
readonly value?: string
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<RadioFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type OnChange<T = string> = (value: T) => void
|
||||
|
||||
export type RadioFieldLabelComponent = LabelComponent<'radio'>
|
||||
export type RadioFieldLabelServerComponent = FieldLabelServerComponent<RadioField>
|
||||
|
||||
export type RadioFieldDescriptionComponent = DescriptionComponent<'radio'>
|
||||
export type RadioFieldLabelClientComponent = FieldLabelClientComponent<RadioFieldClientWithoutType>
|
||||
|
||||
export type RadioFieldErrorComponent = ErrorComponent<'radio'>
|
||||
export type RadioFieldDescriptionServerComponent = FieldDescriptionServerComponent<RadioField>
|
||||
|
||||
export type RadioFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<RadioFieldClientWithoutType>
|
||||
|
||||
export type RadioFieldErrorServerComponent = FieldErrorServerComponent<RadioField>
|
||||
|
||||
export type RadioFieldErrorClientComponent = FieldErrorClientComponent<RadioFieldClientWithoutType>
|
||||
|
||||
@@ -1,17 +1,34 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { RelationshipFieldClient } from '../../fields/config/types.js'
|
||||
import type { RelationshipField, RelationshipFieldClient } from '../../fields/config/types.js'
|
||||
import type { RelationshipFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type RelationshipFieldClientWithoutType = MarkOptional<RelationshipFieldClient, 'type'>
|
||||
|
||||
export type RelationshipFieldProps = {
|
||||
readonly field: MarkOptional<RelationshipFieldClient, 'type'>
|
||||
readonly validate?: RelationshipFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<RelationshipFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type RelationshipFieldLabelComponent = LabelComponent<'relationship'>
|
||||
export type RelationshipFieldLabelServerComponent = FieldLabelServerComponent<RelationshipField>
|
||||
|
||||
export type RelationshipFieldDescriptionComponent = DescriptionComponent<'relationship'>
|
||||
export type RelationshipFieldLabelClientComponent =
|
||||
FieldLabelClientComponent<RelationshipFieldClientWithoutType>
|
||||
|
||||
export type RelationshipFieldErrorComponent = ErrorComponent<'relationship'>
|
||||
export type RelationshipFieldDescriptionServerComponent =
|
||||
FieldDescriptionServerComponent<RelationshipField>
|
||||
|
||||
export type RelationshipFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<RelationshipFieldClientWithoutType>
|
||||
|
||||
export type RelationshipFieldErrorServerComponent = FieldErrorServerComponent<RelationshipField>
|
||||
|
||||
export type RelationshipFieldErrorClientComponent =
|
||||
FieldErrorClientComponent<RelationshipFieldClientWithoutType>
|
||||
|
||||
@@ -1,21 +1,37 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { RichTextFieldClient } from '../../fields/config/types.js'
|
||||
import type { RichTextField, RichTextFieldClient } from '../../fields/config/types.js'
|
||||
import type { RichTextFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type RichTextFieldClientWithoutType = MarkOptional<RichTextFieldClient, 'type'>
|
||||
|
||||
export type RichTextFieldProps<
|
||||
TValue extends object = any,
|
||||
TAdapterProps = any,
|
||||
TExtraProperties = object,
|
||||
> = {
|
||||
readonly field: MarkOptional<RichTextFieldClient<TValue, TAdapterProps, TExtraProperties>, 'type'>
|
||||
readonly validate?: RichTextFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<RichTextFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type RichTextFieldLabelComponent = LabelComponent<'richText'>
|
||||
export type RichTextFieldLabelServerComponent = FieldLabelServerComponent<RichTextField>
|
||||
|
||||
export type RichTextFieldDescriptionComponent = DescriptionComponent<'richText'>
|
||||
export type RichTextFieldLabelClientComponent =
|
||||
FieldLabelClientComponent<RichTextFieldClientWithoutType>
|
||||
|
||||
export type RichTextFieldErrorComponent = ErrorComponent<'richText'>
|
||||
export type RichTextFieldDescriptionServerComponent = FieldDescriptionServerComponent<RichTextField>
|
||||
|
||||
export type RichTextFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<RichTextFieldClientWithoutType>
|
||||
|
||||
export type RichTextFieldErrorServerComponent = FieldErrorServerComponent<RichTextField>
|
||||
|
||||
export type RichTextFieldErrorClientComponent =
|
||||
FieldErrorClientComponent<RichTextFieldClientWithoutType>
|
||||
|
||||
@@ -1,17 +1,32 @@
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from 'payload'
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { RowFieldClient } from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { RowField, RowFieldClient } from '../../fields/config/types.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldErrorClientComponent,
|
||||
FieldErrorServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type RowFieldClientWithoutType = MarkOptional<RowFieldClient, 'type'>
|
||||
|
||||
export type RowFieldProps = {
|
||||
field: MarkOptional<RowFieldClient, 'type'>
|
||||
forceRender?: boolean
|
||||
indexPath: string
|
||||
} & FormFieldBase
|
||||
readonly forceRender?: boolean
|
||||
readonly indexPath: string
|
||||
} & FormFieldBase<RowFieldClientWithoutType>
|
||||
|
||||
export type RowFieldLabelComponent = LabelComponent<'row'>
|
||||
export type RowFieldLabelServerComponent = FieldLabelServerComponent<RowField>
|
||||
|
||||
export type RowFieldDescriptionComponent = DescriptionComponent<'row'>
|
||||
export type RowFieldLabelClientComponent = FieldLabelClientComponent<RowFieldClientWithoutType>
|
||||
|
||||
export type RowFieldErrorComponent = ErrorComponent<'row'>
|
||||
export type RowFieldDescriptionServerComponent = FieldDescriptionServerComponent<RowField>
|
||||
|
||||
export type RowFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<RowFieldClientWithoutType>
|
||||
|
||||
export type RowFieldErrorServerComponent = FieldErrorServerComponent<RowField>
|
||||
|
||||
export type RowFieldErrorClientComponent = FieldErrorClientComponent<RowFieldClientWithoutType>
|
||||
|
||||
@@ -1,19 +1,35 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { SelectFieldClient } from '../../fields/config/types.js'
|
||||
import type { SelectField, SelectFieldClient } from '../../fields/config/types.js'
|
||||
import type { SelectFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type SelectFieldClientWithoutType = MarkOptional<SelectFieldClient, 'type'>
|
||||
|
||||
export type SelectFieldProps = {
|
||||
readonly field: MarkOptional<SelectFieldClient, 'type'>
|
||||
readonly onChange?: (e: string | string[]) => void
|
||||
readonly validate?: SelectFieldValidation
|
||||
readonly value?: string
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<SelectFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type SelectFieldLabelComponent = LabelComponent<'select'>
|
||||
export type SelectFieldLabelServerComponent = FieldLabelServerComponent<SelectField>
|
||||
|
||||
export type SelectFieldDescriptionComponent = DescriptionComponent<'select'>
|
||||
export type SelectFieldLabelClientComponent =
|
||||
FieldLabelClientComponent<SelectFieldClientWithoutType>
|
||||
|
||||
export type SelectFieldErrorComponent = ErrorComponent<'select'>
|
||||
export type SelectFieldDescriptionServerComponent = FieldDescriptionServerComponent<SelectField>
|
||||
|
||||
export type SelectFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<SelectFieldClientWithoutType>
|
||||
|
||||
export type SelectFieldErrorServerComponent = FieldErrorServerComponent<SelectField>
|
||||
|
||||
export type SelectFieldErrorClientComponent =
|
||||
FieldErrorClientComponent<SelectFieldClientWithoutType>
|
||||
|
||||
@@ -3,22 +3,36 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
import type {
|
||||
ClientField,
|
||||
NamedTab,
|
||||
TabsField,
|
||||
TabsFieldClient,
|
||||
UnnamedTab,
|
||||
} from '../../fields/config/types.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
export type ClientTab =
|
||||
| ({ fields: ClientField[] } & Omit<NamedTab, 'fields'>)
|
||||
| ({ fields: ClientField[] } & Omit<UnnamedTab, 'fields'>)
|
||||
|
||||
export type TabsFieldProps = {
|
||||
readonly field: MarkOptional<TabsFieldClient, 'type'>
|
||||
} & FormFieldBase
|
||||
export type TabsFieldClientWithoutType = MarkOptional<TabsFieldClient, 'type'>
|
||||
|
||||
export type TabsFieldLabelComponent = LabelComponent<'tabs'>
|
||||
export type TabsFieldProps = FormFieldBase<TabsFieldClientWithoutType>
|
||||
|
||||
export type TabsFieldDescriptionComponent = DescriptionComponent<'tabs'>
|
||||
export type TabsFieldLabelServerComponent = FieldLabelServerComponent<TabsField>
|
||||
|
||||
export type TabsFieldErrorComponent = ErrorComponent<'tabs'>
|
||||
export type TabsFieldLabelClientComponent = FieldLabelClientComponent<TabsFieldClientWithoutType>
|
||||
|
||||
export type TabsFieldDescriptionServerComponent = FieldDescriptionServerComponent<TabsField>
|
||||
|
||||
export type TabsFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<TabsFieldClientWithoutType>
|
||||
|
||||
export type TabsFieldErrorServerComponent = FieldErrorServerComponent<TabsField>
|
||||
|
||||
export type TabsFieldErrorClientComponent = FieldErrorClientComponent<TabsFieldClientWithoutType>
|
||||
|
||||
@@ -1,20 +1,34 @@
|
||||
import type React from 'react'
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { TextFieldClient } from '../../fields/config/types.js'
|
||||
import type { TextField, TextFieldClient } from '../../fields/config/types.js'
|
||||
import type { TextFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type TextFieldClientWithoutType = MarkOptional<TextFieldClient, 'type'>
|
||||
|
||||
export type TextFieldProps = {
|
||||
readonly field: MarkOptional<TextFieldClient, 'type'>
|
||||
readonly inputRef?: React.RefObject<HTMLInputElement>
|
||||
readonly onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>
|
||||
readonly validate?: TextFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<TextFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type TextFieldLabelComponent = LabelComponent<'text'>
|
||||
export type TextFieldLabelServerComponent = FieldLabelServerComponent<TextField>
|
||||
|
||||
export type TextFieldDescriptionComponent = DescriptionComponent<'text'>
|
||||
export type TextFieldLabelClientComponent = FieldLabelClientComponent<TextFieldClientWithoutType>
|
||||
|
||||
export type TextFieldErrorComponent = ErrorComponent<'text'>
|
||||
export type TextFieldDescriptionServerComponent = FieldDescriptionServerComponent<TextField>
|
||||
|
||||
export type TextFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<TextFieldClientWithoutType>
|
||||
|
||||
export type TextFieldErrorServerComponent = FieldErrorServerComponent<TextField>
|
||||
|
||||
export type TextFieldErrorClientComponent = FieldErrorClientComponent<TextFieldClientWithoutType>
|
||||
|
||||
@@ -1,20 +1,36 @@
|
||||
import type React from 'react'
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { TextareaFieldClient } from '../../fields/config/types.js'
|
||||
import type { TextareaField, TextareaFieldClient } from '../../fields/config/types.js'
|
||||
import type { TextareaFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type TextareaFieldClientWithoutType = MarkOptional<TextareaFieldClient, 'type'>
|
||||
|
||||
export type TextareaFieldProps = {
|
||||
readonly field: MarkOptional<TextareaFieldClient, 'type'>
|
||||
readonly inputRef?: React.Ref<HTMLInputElement>
|
||||
readonly onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>
|
||||
readonly validate?: TextareaFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<TextareaFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type TextareaFieldLabelComponent = LabelComponent<'textarea'>
|
||||
export type TextareaFieldLabelServerComponent = FieldLabelServerComponent<TextareaField>
|
||||
|
||||
export type TextareaFieldDescriptionComponent = DescriptionComponent<'textarea'>
|
||||
export type TextareaFieldLabelClientComponent =
|
||||
FieldLabelClientComponent<TextareaFieldClientWithoutType>
|
||||
|
||||
export type TextareaFieldErrorComponent = ErrorComponent<'textarea'>
|
||||
export type TextareaFieldDescriptionServerComponent = FieldDescriptionServerComponent<TextareaField>
|
||||
|
||||
export type TextareaFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<TextareaFieldClientWithoutType>
|
||||
|
||||
export type TextareaFieldErrorServerComponent = FieldErrorServerComponent<TextareaField>
|
||||
|
||||
export type TextareaFieldErrorClientComponent =
|
||||
FieldErrorClientComponent<TextareaFieldClientWithoutType>
|
||||
|
||||
@@ -1,17 +1,33 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { UploadFieldClient } from '../../fields/config/types.js'
|
||||
import type { UploadField, UploadFieldClient } from '../../fields/config/types.js'
|
||||
import type { UploadFieldValidation } from '../../fields/validations.js'
|
||||
import type { ErrorComponent } from '../forms/Error.js'
|
||||
import type { DescriptionComponent, FormFieldBase, LabelComponent } from '../types.js'
|
||||
import type { FieldErrorClientComponent, FieldErrorServerComponent } from '../forms/Error.js'
|
||||
import type {
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
FormFieldBase,
|
||||
} from '../types.js'
|
||||
|
||||
type UploadFieldClientWithoutType = MarkOptional<UploadFieldClient, 'type'>
|
||||
|
||||
export type UploadFieldProps = {
|
||||
readonly field: MarkOptional<UploadFieldClient, 'type'>
|
||||
readonly validate?: UploadFieldValidation
|
||||
} & Omit<FormFieldBase, 'validate'>
|
||||
} & Omit<FormFieldBase<UploadFieldClientWithoutType>, 'validate'>
|
||||
|
||||
export type UploadFieldLabelComponent = LabelComponent<'upload'>
|
||||
export type UploadFieldLabelServerComponent = FieldLabelServerComponent<UploadField>
|
||||
|
||||
export type UploadFieldDescriptionComponent = DescriptionComponent<'upload'>
|
||||
export type UploadFieldLabelClientComponent =
|
||||
FieldLabelClientComponent<UploadFieldClientWithoutType>
|
||||
|
||||
export type UploadFieldErrorComponent = ErrorComponent<'upload'>
|
||||
export type UploadFieldDescriptionServerComponent = FieldDescriptionServerComponent<UploadField>
|
||||
|
||||
export type UploadFieldDescriptionClientComponent =
|
||||
FieldDescriptionClientComponent<UploadFieldClientWithoutType>
|
||||
|
||||
export type UploadFieldErrorServerComponent = FieldErrorServerComponent<UploadField>
|
||||
|
||||
export type UploadFieldErrorClientComponent =
|
||||
FieldErrorClientComponent<UploadFieldClientWithoutType>
|
||||
|
||||
38
packages/payload/src/admin/forms/Description.ts
Normal file
38
packages/payload/src/admin/forms/Description.ts
Normal file
@@ -0,0 +1,38 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { LabelFunction, ServerProps } from '../../config/types.js'
|
||||
import type { ClientField, Field } from '../../fields/config/types.js'
|
||||
import type { MappedComponent } from '../types.js'
|
||||
|
||||
export type DescriptionFunction = LabelFunction
|
||||
|
||||
type ClientFieldWithOptionalType = MarkOptional<ClientField, 'type'>
|
||||
|
||||
export type FieldDescriptionClientComponent<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
> = React.ComponentType<FieldDescriptionClientProps<TFieldClient>>
|
||||
|
||||
export type FieldDescriptionServerComponent<TFieldServer extends Field = Field> =
|
||||
React.ComponentType<FieldDescriptionServerProps<TFieldServer>>
|
||||
|
||||
export type StaticDescription = Record<string, string> | string
|
||||
|
||||
export type Description = DescriptionFunction | StaticDescription
|
||||
|
||||
export type GenericDescriptionProps = {
|
||||
readonly Description?: MappedComponent
|
||||
readonly className?: string
|
||||
readonly description?: StaticDescription
|
||||
readonly marginPlacement?: 'bottom' | 'top'
|
||||
}
|
||||
|
||||
export type FieldDescriptionServerProps<TFieldServer extends Field = Field> = {
|
||||
field: TFieldServer
|
||||
} & GenericDescriptionProps &
|
||||
Partial<ServerProps>
|
||||
|
||||
export type FieldDescriptionClientProps<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
> = {
|
||||
field: TFieldClient
|
||||
} & GenericDescriptionProps
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { CustomComponent, ServerProps } from '../../config/types.js'
|
||||
import type { FieldTypes } from '../../fields/config/types.js'
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { ServerProps } from '../../config/types.js'
|
||||
import type { ClientField, Field } from '../../fields/config/types.js'
|
||||
import type { MappedComponent } from '../types.js'
|
||||
|
||||
export type GenericErrorProps = {
|
||||
@@ -10,9 +12,23 @@ export type GenericErrorProps = {
|
||||
readonly showError?: boolean
|
||||
}
|
||||
|
||||
export type ErrorProps<T extends 'hidden' | FieldTypes = any> = {
|
||||
type: T
|
||||
type ClientFieldWithOptionalType = MarkOptional<ClientField, 'type'>
|
||||
|
||||
export type FieldErrorClientProps<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
> = {
|
||||
field: TFieldClient
|
||||
} & GenericErrorProps
|
||||
|
||||
export type FieldErrorServerProps<TFieldServer extends Field> = {
|
||||
field: TFieldServer
|
||||
} & GenericErrorProps &
|
||||
Partial<ServerProps>
|
||||
|
||||
export type ErrorComponent<T extends 'hidden' | FieldTypes = any> = CustomComponent<ErrorProps<T>>
|
||||
export type FieldErrorClientComponent<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
> = React.ComponentType<FieldErrorClientProps<TFieldClient>>
|
||||
|
||||
export type FieldErrorServerComponent<TFieldServer extends Field = Field> = React.ComponentType<
|
||||
FieldErrorServerProps<TFieldServer>
|
||||
>
|
||||
|
||||
@@ -1,24 +1,28 @@
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { User } from '../../auth/types.js'
|
||||
import type { Locale } from '../../config/types.js'
|
||||
import type { Validate } from '../../fields/config/types.js'
|
||||
import type { ClientField, 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 { LabelProps } from './Label.js'
|
||||
import type { FieldDescriptionClientProps } from './Description.js'
|
||||
import type { FieldErrorClientProps } from './Error.js'
|
||||
import type { FieldLabelClientProps } from './Label.js'
|
||||
|
||||
// TODO: Check if we still need this. Shouldnt most of it be present in the field type?
|
||||
export type FormFieldBase = {
|
||||
readonly descriptionProps?: FieldDescriptionProps
|
||||
export type FormFieldBase<
|
||||
TFieldClient extends MarkOptional<ClientField, 'type'> = MarkOptional<ClientField, 'type'>,
|
||||
> = {
|
||||
readonly descriptionProps?: FieldDescriptionClientProps<TFieldClient>
|
||||
readonly docPreferences?: DocumentPreferences
|
||||
readonly errorProps?: ErrorProps
|
||||
readonly errorProps?: FieldErrorClientProps<TFieldClient>
|
||||
readonly field: TFieldClient
|
||||
/**
|
||||
* forceRender is added by RenderField automatically
|
||||
* `forceRender` is added by RenderField automatically.
|
||||
*/
|
||||
readonly forceRender?: boolean
|
||||
readonly labelProps?: LabelProps
|
||||
readonly labelProps?: FieldLabelClientProps<TFieldClient>
|
||||
readonly locale?: Locale
|
||||
/**
|
||||
* forceRender is added by RenderField automatically. This should be used instead of field.admin.readOnly
|
||||
* `readOnly` is added by RenderField automatically. This should be used instead of `field.admin.readOnly`.
|
||||
*/
|
||||
readonly readOnly?: boolean
|
||||
readonly user?: User
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
import type { CustomComponent, LabelFunction, ServerProps } from '../../config/types.js'
|
||||
import type { FieldTypes } from '../../fields/config/types.js'
|
||||
import type { MappedComponent } from '../types.js'
|
||||
|
||||
export type DescriptionFunction = LabelFunction
|
||||
|
||||
export type DescriptionComponent<T extends 'hidden' | FieldTypes = any> = CustomComponent<
|
||||
FieldDescriptionProps<T>
|
||||
>
|
||||
|
||||
export type StaticDescription = Record<string, string> | string
|
||||
|
||||
export type Description = DescriptionFunction | StaticDescription
|
||||
export type GenericDescriptionProps = {
|
||||
readonly Description?: MappedComponent
|
||||
readonly className?: string
|
||||
readonly description?: StaticDescription
|
||||
readonly marginPlacement?: 'bottom' | 'top'
|
||||
}
|
||||
export type FieldDescriptionProps<T extends 'hidden' | FieldTypes = any> = {
|
||||
type: T
|
||||
} & GenericDescriptionProps &
|
||||
Partial<ServerProps>
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { CustomComponent, ServerProps, StaticLabel } from '../../config/types.js'
|
||||
import type { FieldTypes } from '../../fields/config/types.js'
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { ServerProps, StaticLabel } from '../../config/types.js'
|
||||
import type { ClientField, Field } from '../../fields/config/types.js'
|
||||
import type { MappedComponent } from '../types.js'
|
||||
|
||||
export type GenericLabelProps = {
|
||||
@@ -11,14 +13,28 @@ export type GenericLabelProps = {
|
||||
readonly unstyled?: boolean
|
||||
}
|
||||
|
||||
export type LabelProps<T extends 'hidden' | FieldTypes = any> = {
|
||||
type: T
|
||||
type ClientFieldWithOptionalType = MarkOptional<ClientField, 'type'>
|
||||
|
||||
export type FieldLabelClientProps<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
> = {
|
||||
field: TFieldClient
|
||||
} & GenericLabelProps
|
||||
|
||||
export type FieldLabelServerProps<TFieldServer extends Field> = {
|
||||
field: TFieldServer
|
||||
} & GenericLabelProps &
|
||||
Partial<ServerProps>
|
||||
|
||||
export type SanitizedLabelProps<T extends 'hidden' | FieldTypes = any> = Omit<
|
||||
LabelProps<T>,
|
||||
export type SanitizedLabelProps<TFieldClient extends ClientField> = Omit<
|
||||
FieldLabelClientProps<TFieldClient>,
|
||||
'label' | 'required'
|
||||
>
|
||||
|
||||
export type LabelComponent<T extends 'hidden' | FieldTypes = any> = CustomComponent<LabelProps<T>>
|
||||
export type FieldLabelClientComponent<
|
||||
TFieldClient extends ClientFieldWithOptionalType = ClientFieldWithOptionalType,
|
||||
> = React.ComponentType<FieldLabelClientProps<TFieldClient>>
|
||||
|
||||
export type FieldLabelServerComponent<TFieldServer extends Field = Field> = React.ComponentType<
|
||||
FieldLabelServerProps<TFieldServer>
|
||||
>
|
||||
|
||||
@@ -33,172 +33,237 @@ export type {
|
||||
} from './elements/WithServerSideProps.js'
|
||||
|
||||
export type {
|
||||
ArrayFieldDescriptionComponent,
|
||||
ArrayFieldErrorComponent,
|
||||
ArrayFieldLabelComponent,
|
||||
ArrayFieldDescriptionClientComponent,
|
||||
ArrayFieldDescriptionServerComponent,
|
||||
ArrayFieldErrorClientComponent,
|
||||
ArrayFieldErrorServerComponent,
|
||||
ArrayFieldLabelClientComponent,
|
||||
ArrayFieldLabelServerComponent,
|
||||
ArrayFieldProps,
|
||||
} from './fields/Array.js'
|
||||
|
||||
export type {
|
||||
BlockFieldDescriptionComponent,
|
||||
BlockFieldErrorComponent,
|
||||
BlockFieldLabelComponent,
|
||||
BlockFieldDescriptionClientComponent,
|
||||
BlockFieldDescriptionServerComponent,
|
||||
BlockFieldErrorClientComponent,
|
||||
BlockFieldErrorServerComponent,
|
||||
BlockFieldLabelClientComponent,
|
||||
BlockFieldLabelServerComponent,
|
||||
BlockFieldProps,
|
||||
} from './fields/Blocks.js'
|
||||
|
||||
export type {
|
||||
CheckboxFieldDescriptionComponent,
|
||||
CheckboxFieldErrorComponent,
|
||||
CheckboxFieldLabelComponent,
|
||||
CheckboxFieldDescriptionClientComponent,
|
||||
CheckboxFieldDescriptionServerComponent,
|
||||
CheckboxFieldErrorClientComponent,
|
||||
CheckboxFieldErrorServerComponent,
|
||||
CheckboxFieldLabelClientComponent,
|
||||
CheckboxFieldLabelServerComponent,
|
||||
CheckboxFieldProps,
|
||||
} from './fields/Checkbox.js'
|
||||
|
||||
export type {
|
||||
CodeFieldDescriptionComponent,
|
||||
CodeFieldErrorComponent,
|
||||
CodeFieldLabelComponent,
|
||||
CodeFieldDescriptionClientComponent,
|
||||
CodeFieldDescriptionServerComponent,
|
||||
CodeFieldErrorClientComponent,
|
||||
CodeFieldErrorServerComponent,
|
||||
CodeFieldLabelClientComponent,
|
||||
CodeFieldLabelServerComponent,
|
||||
CodeFieldProps,
|
||||
} from './fields/Code.js'
|
||||
|
||||
export type {
|
||||
CollapsibleFieldDescriptionComponent,
|
||||
CollapsibleFieldErrorComponent,
|
||||
CollapsibleFieldLabelComponent,
|
||||
CollapsibleFieldDescriptionClientComponent,
|
||||
CollapsibleFieldDescriptionServerComponent,
|
||||
CollapsibleFieldErrorClientComponent,
|
||||
CollapsibleFieldErrorServerComponent,
|
||||
CollapsibleFieldLabelClientComponent,
|
||||
CollapsibleFieldLabelServerComponent,
|
||||
CollapsibleFieldProps,
|
||||
} from './fields/Collapsible.js'
|
||||
|
||||
export type {
|
||||
DateFieldDescriptionComponent,
|
||||
DateFieldErrorComponent,
|
||||
DateFieldLabelComponent,
|
||||
DateFieldDescriptionClientComponent,
|
||||
DateFieldDescriptionServerComponent,
|
||||
DateFieldErrorClientComponent,
|
||||
DateFieldErrorServerComponent,
|
||||
DateFieldLabelClientComponent,
|
||||
DateFieldLabelServerComponent,
|
||||
DateFieldProps,
|
||||
} from './fields/Date.js'
|
||||
|
||||
export type {
|
||||
EmailFieldDescriptionComponent,
|
||||
EmailFieldErrorComponent,
|
||||
EmailFieldLabelComponent,
|
||||
EmailFieldDescriptionClientComponent,
|
||||
EmailFieldDescriptionServerComponent,
|
||||
EmailFieldErrorClientComponent,
|
||||
EmailFieldErrorServerComponent,
|
||||
EmailFieldLabelClientComponent,
|
||||
EmailFieldLabelServerComponent,
|
||||
EmailFieldProps,
|
||||
} from './fields/Email.js'
|
||||
|
||||
export type {
|
||||
GroupFieldDescriptionComponent,
|
||||
GroupFieldErrorComponent,
|
||||
GroupFieldLabelComponent,
|
||||
GroupFieldDescriptionClientComponent,
|
||||
GroupFieldDescriptionServerComponent,
|
||||
GroupFieldErrorClientComponent,
|
||||
GroupFieldErrorServerComponent,
|
||||
GroupFieldLabelClientComponent,
|
||||
GroupFieldLabelServerComponent,
|
||||
GroupFieldProps,
|
||||
} from './fields/Group.js'
|
||||
|
||||
export type {
|
||||
HiddenFieldDescriptionComponent,
|
||||
HiddenFieldErrorComponent,
|
||||
HiddenFieldLabelComponent,
|
||||
HiddenFieldProps,
|
||||
} from './fields/Hidden.js'
|
||||
export type { HiddenFieldProps } from './fields/Hidden.js'
|
||||
|
||||
export type {
|
||||
JSONFieldDescriptionComponent,
|
||||
JSONFieldErrorComponent,
|
||||
JSONFieldLabelComponent,
|
||||
JSONFieldDescriptionClientComponent,
|
||||
JSONFieldDescriptionServerComponent,
|
||||
JSONFieldErrorClientComponent,
|
||||
JSONFieldErrorServerComponent,
|
||||
JSONFieldLabelClientComponent,
|
||||
JSONFieldLabelServerComponent,
|
||||
JSONFieldProps,
|
||||
} from './fields/JSON.js'
|
||||
|
||||
export type {
|
||||
NumberFieldDescriptionComponent,
|
||||
NumberFieldErrorComponent,
|
||||
NumberFieldLabelComponent,
|
||||
NumberFieldDescriptionClientComponent,
|
||||
NumberFieldDescriptionServerComponent,
|
||||
NumberFieldErrorClientComponent,
|
||||
NumberFieldErrorServerComponent,
|
||||
NumberFieldLabelClientComponent,
|
||||
NumberFieldLabelServerComponent,
|
||||
NumberFieldProps,
|
||||
} from './fields/Number.js'
|
||||
|
||||
export type {
|
||||
PointFieldDescriptionComponent,
|
||||
PointFieldErrorComponent,
|
||||
PointFieldLabelComponent,
|
||||
PointFieldDescriptionClientComponent,
|
||||
PointFieldDescriptionServerComponent,
|
||||
PointFieldErrorClientComponent,
|
||||
PointFieldErrorServerComponent,
|
||||
PointFieldLabelClientComponent,
|
||||
PointFieldLabelServerComponent,
|
||||
PointFieldProps,
|
||||
} from './fields/Point.js'
|
||||
|
||||
export type {
|
||||
RadioFieldDescriptionComponent,
|
||||
RadioFieldErrorComponent,
|
||||
RadioFieldLabelComponent,
|
||||
RadioFieldDescriptionClientComponent,
|
||||
RadioFieldDescriptionServerComponent,
|
||||
RadioFieldErrorClientComponent,
|
||||
RadioFieldErrorServerComponent,
|
||||
RadioFieldLabelClientComponent,
|
||||
RadioFieldLabelServerComponent,
|
||||
RadioFieldProps,
|
||||
} from './fields/Radio.js'
|
||||
|
||||
export type {
|
||||
RelationshipFieldDescriptionComponent,
|
||||
RelationshipFieldErrorComponent,
|
||||
RelationshipFieldLabelComponent,
|
||||
RelationshipFieldDescriptionClientComponent,
|
||||
RelationshipFieldDescriptionServerComponent,
|
||||
RelationshipFieldErrorClientComponent,
|
||||
RelationshipFieldErrorServerComponent,
|
||||
RelationshipFieldLabelClientComponent,
|
||||
RelationshipFieldLabelServerComponent,
|
||||
RelationshipFieldProps,
|
||||
} from './fields/Relationship.js'
|
||||
|
||||
export type {
|
||||
RichTextFieldDescriptionComponent,
|
||||
RichTextFieldErrorComponent,
|
||||
RichTextFieldLabelComponent,
|
||||
RichTextFieldDescriptionClientComponent,
|
||||
RichTextFieldDescriptionServerComponent,
|
||||
RichTextFieldErrorClientComponent,
|
||||
RichTextFieldErrorServerComponent,
|
||||
RichTextFieldLabelClientComponent,
|
||||
RichTextFieldLabelServerComponent,
|
||||
RichTextFieldProps,
|
||||
} from './fields/RichText.js'
|
||||
|
||||
export type {
|
||||
RowFieldDescriptionComponent,
|
||||
RowFieldErrorComponent,
|
||||
RowFieldLabelComponent,
|
||||
RowFieldDescriptionClientComponent,
|
||||
RowFieldDescriptionServerComponent,
|
||||
RowFieldErrorClientComponent,
|
||||
RowFieldErrorServerComponent,
|
||||
RowFieldLabelClientComponent,
|
||||
RowFieldLabelServerComponent,
|
||||
RowFieldProps,
|
||||
} from './fields/Row.js'
|
||||
|
||||
export type {
|
||||
SelectFieldDescriptionComponent,
|
||||
SelectFieldErrorComponent,
|
||||
SelectFieldLabelComponent,
|
||||
SelectFieldDescriptionClientComponent,
|
||||
SelectFieldDescriptionServerComponent,
|
||||
SelectFieldErrorClientComponent,
|
||||
SelectFieldErrorServerComponent,
|
||||
SelectFieldLabelClientComponent,
|
||||
SelectFieldLabelServerComponent,
|
||||
SelectFieldProps,
|
||||
} from './fields/Select.js'
|
||||
|
||||
export type {
|
||||
ClientTab,
|
||||
TabsFieldDescriptionComponent,
|
||||
TabsFieldErrorComponent,
|
||||
TabsFieldLabelComponent,
|
||||
TabsFieldDescriptionClientComponent,
|
||||
TabsFieldDescriptionServerComponent,
|
||||
TabsFieldErrorClientComponent,
|
||||
TabsFieldErrorServerComponent,
|
||||
TabsFieldLabelClientComponent,
|
||||
TabsFieldLabelServerComponent,
|
||||
TabsFieldProps,
|
||||
} from './fields/Tabs.js'
|
||||
|
||||
export type {
|
||||
TextFieldDescriptionComponent,
|
||||
TextFieldErrorComponent,
|
||||
TextFieldLabelComponent,
|
||||
TextFieldDescriptionClientComponent,
|
||||
TextFieldDescriptionServerComponent,
|
||||
TextFieldErrorClientComponent,
|
||||
TextFieldErrorServerComponent,
|
||||
TextFieldLabelClientComponent,
|
||||
TextFieldLabelServerComponent,
|
||||
TextFieldProps,
|
||||
} from './fields/Text.js'
|
||||
|
||||
export type {
|
||||
TextareaFieldDescriptionComponent,
|
||||
TextareaFieldErrorComponent,
|
||||
TextareaFieldLabelComponent,
|
||||
TextareaFieldDescriptionClientComponent,
|
||||
TextareaFieldDescriptionServerComponent,
|
||||
TextareaFieldErrorClientComponent,
|
||||
TextareaFieldErrorServerComponent,
|
||||
TextareaFieldLabelClientComponent,
|
||||
TextareaFieldLabelServerComponent,
|
||||
TextareaFieldProps,
|
||||
} from './fields/Textarea.js'
|
||||
|
||||
export type {
|
||||
UploadFieldDescriptionComponent,
|
||||
UploadFieldErrorComponent,
|
||||
UploadFieldLabelComponent,
|
||||
UploadFieldDescriptionClientComponent,
|
||||
UploadFieldDescriptionServerComponent,
|
||||
UploadFieldErrorClientComponent,
|
||||
UploadFieldErrorServerComponent,
|
||||
UploadFieldLabelClientComponent,
|
||||
UploadFieldLabelServerComponent,
|
||||
UploadFieldProps,
|
||||
} from './fields/Upload.js'
|
||||
|
||||
export type { ErrorComponent, ErrorProps, GenericErrorProps } from './forms/Error.js'
|
||||
|
||||
export type { FormFieldBase } from './forms/Field.js'
|
||||
|
||||
export type {
|
||||
Description,
|
||||
DescriptionComponent,
|
||||
DescriptionFunction,
|
||||
FieldDescriptionProps,
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionClientProps,
|
||||
FieldDescriptionServerComponent,
|
||||
FieldDescriptionServerProps,
|
||||
GenericDescriptionProps,
|
||||
StaticDescription,
|
||||
} from './forms/FieldDescription.js'
|
||||
} from './forms/Description.js'
|
||||
|
||||
export type {
|
||||
FieldErrorClientComponent,
|
||||
FieldErrorClientProps,
|
||||
FieldErrorServerComponent,
|
||||
FieldErrorServerProps,
|
||||
GenericErrorProps,
|
||||
} from './forms/Error.js'
|
||||
|
||||
export type { FormFieldBase } from './forms/Field.js'
|
||||
|
||||
export type { Data, FilterOptionsResult, FormField, FormState, Row } from './forms/Form.js'
|
||||
|
||||
export type {
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelClientProps,
|
||||
FieldLabelServerComponent,
|
||||
FieldLabelServerProps,
|
||||
GenericLabelProps,
|
||||
LabelComponent,
|
||||
LabelProps,
|
||||
SanitizedLabelProps,
|
||||
} from './forms/Label.js'
|
||||
|
||||
@@ -241,14 +306,20 @@ export type MappedComponent<TComponentClientProps extends JsonObject = JsonObjec
|
||||
export type CreateMappedComponent = {
|
||||
<T extends JsonObject>(
|
||||
component: { Component: React.FC<T> } | PayloadComponent<T> | null,
|
||||
props: object,
|
||||
props: {
|
||||
clientProps?: JsonObject
|
||||
serverProps?: object
|
||||
},
|
||||
fallback: React.FC,
|
||||
identifier: string,
|
||||
): MappedComponent<T>
|
||||
|
||||
<T extends JsonObject>(
|
||||
components: ({ Component: React.FC<T> } | PayloadComponent<T>)[],
|
||||
props: object,
|
||||
props: {
|
||||
clientProps?: JsonObject
|
||||
serverProps?: object
|
||||
},
|
||||
fallback: React.FC,
|
||||
identifier: string,
|
||||
): MappedComponent<T>[]
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { MappedComponent } from '../../admin/types.js'
|
||||
import type { MappedComponent, StaticDescription } from '../../admin/types.js'
|
||||
import type { MappedView } from '../../admin/views/types.js'
|
||||
import type { LivePreviewConfig, ServerOnlyLivePreviewProperties } from '../../config/types.js'
|
||||
import type { ClientField } from '../../fields/config/client.js'
|
||||
@@ -46,7 +46,7 @@ export type ClientCollectionConfig = {
|
||||
}
|
||||
}
|
||||
}
|
||||
description?: Record<string, string> | string
|
||||
description?: StaticDescription
|
||||
livePreview?: Omit<LivePreviewConfig, ServerOnlyLivePreviewProperties>
|
||||
} & Omit<
|
||||
SanitizedCollectionConfig['admin'],
|
||||
|
||||
@@ -398,14 +398,14 @@ export type EditViewConfig = {
|
||||
)
|
||||
|
||||
export type ServerProps = {
|
||||
[key: string]: unknown
|
||||
i18n: I18nClient
|
||||
locale?: Locale
|
||||
params?: { [key: string]: string | string[] | undefined }
|
||||
payload: Payload
|
||||
permissions?: Permissions
|
||||
searchParams?: { [key: string]: string | string[] | undefined }
|
||||
user?: TypedUser
|
||||
readonly i18n: I18nClient
|
||||
readonly locale?: Locale
|
||||
readonly params?: { [key: string]: string | string[] | undefined }
|
||||
readonly payload: Payload
|
||||
readonly permissions?: Permissions
|
||||
readonly [key: string]: unknown
|
||||
readonly searchParams?: { [key: string]: string | string[] | undefined }
|
||||
readonly user?: TypedUser
|
||||
}
|
||||
|
||||
export const serverProps: (keyof ServerProps)[] = [
|
||||
|
||||
@@ -6,16 +6,97 @@ import type { CSSProperties } from 'react'
|
||||
import type { DeepUndefinable } from 'ts-essentials'
|
||||
|
||||
import type { RichTextAdapter, RichTextAdapterProvider } from '../../admin/RichText.js'
|
||||
import type { ErrorComponent } from '../../admin/forms/Error.js'
|
||||
import type {
|
||||
ArrayFieldErrorClientComponent,
|
||||
ArrayFieldErrorServerComponent,
|
||||
ArrayFieldLabelClientComponent,
|
||||
ArrayFieldLabelServerComponent,
|
||||
ArrayFieldProps,
|
||||
BlockFieldErrorClientComponent,
|
||||
BlockFieldErrorServerComponent,
|
||||
BlockFieldProps,
|
||||
CheckboxFieldErrorClientComponent,
|
||||
CheckboxFieldErrorServerComponent,
|
||||
CheckboxFieldLabelClientComponent,
|
||||
CheckboxFieldLabelServerComponent,
|
||||
CheckboxFieldProps,
|
||||
ClientTab,
|
||||
CodeFieldErrorClientComponent,
|
||||
CodeFieldErrorServerComponent,
|
||||
CodeFieldLabelClientComponent,
|
||||
CodeFieldLabelServerComponent,
|
||||
CodeFieldProps,
|
||||
CollapsibleFieldLabelClientComponent,
|
||||
CollapsibleFieldLabelServerComponent,
|
||||
CollapsibleFieldProps,
|
||||
ConditionalDateProps,
|
||||
DateFieldErrorClientComponent,
|
||||
DateFieldErrorServerComponent,
|
||||
DateFieldLabelClientComponent,
|
||||
DateFieldLabelServerComponent,
|
||||
DateFieldProps,
|
||||
Description,
|
||||
DescriptionComponent,
|
||||
LabelComponent,
|
||||
EmailFieldErrorClientComponent,
|
||||
EmailFieldErrorServerComponent,
|
||||
EmailFieldLabelClientComponent,
|
||||
EmailFieldLabelServerComponent,
|
||||
EmailFieldProps,
|
||||
FieldDescriptionClientComponent,
|
||||
FieldDescriptionServerComponent,
|
||||
GroupFieldLabelClientComponent,
|
||||
GroupFieldLabelServerComponent,
|
||||
GroupFieldProps,
|
||||
HiddenFieldProps,
|
||||
JSONFieldErrorClientComponent,
|
||||
JSONFieldErrorServerComponent,
|
||||
JSONFieldLabelClientComponent,
|
||||
JSONFieldLabelServerComponent,
|
||||
JSONFieldProps,
|
||||
MappedComponent,
|
||||
NumberFieldErrorClientComponent,
|
||||
NumberFieldErrorServerComponent,
|
||||
NumberFieldLabelClientComponent,
|
||||
NumberFieldLabelServerComponent,
|
||||
NumberFieldProps,
|
||||
PointFieldErrorClientComponent,
|
||||
PointFieldErrorServerComponent,
|
||||
PointFieldLabelClientComponent,
|
||||
PointFieldLabelServerComponent,
|
||||
PointFieldProps,
|
||||
RadioFieldErrorClientComponent,
|
||||
RadioFieldErrorServerComponent,
|
||||
RadioFieldLabelClientComponent,
|
||||
RadioFieldLabelServerComponent,
|
||||
RadioFieldProps,
|
||||
RelationshipFieldErrorClientComponent,
|
||||
RelationshipFieldErrorServerComponent,
|
||||
RelationshipFieldLabelClientComponent,
|
||||
RelationshipFieldLabelServerComponent,
|
||||
RelationshipFieldProps,
|
||||
RichTextFieldProps,
|
||||
RowFieldProps,
|
||||
RowLabelComponent,
|
||||
SelectFieldErrorClientComponent,
|
||||
SelectFieldErrorServerComponent,
|
||||
SelectFieldLabelClientComponent,
|
||||
SelectFieldLabelServerComponent,
|
||||
SelectFieldProps,
|
||||
StaticDescription,
|
||||
TabsFieldProps,
|
||||
TextFieldErrorClientComponent,
|
||||
TextFieldErrorServerComponent,
|
||||
TextFieldLabelClientComponent,
|
||||
TextFieldLabelServerComponent,
|
||||
TextareaFieldErrorClientComponent,
|
||||
TextareaFieldErrorServerComponent,
|
||||
TextareaFieldLabelClientComponent,
|
||||
TextareaFieldLabelServerComponent,
|
||||
TextareaFieldProps,
|
||||
UploadFieldErrorClientComponent,
|
||||
UploadFieldErrorServerComponent,
|
||||
UploadFieldLabelClientComponent,
|
||||
UploadFieldLabelServerComponent,
|
||||
UploadFieldProps,
|
||||
} from '../../admin/types.js'
|
||||
import type { SanitizedCollectionConfig, TypeWithID } from '../../collections/config/types.js'
|
||||
import type {
|
||||
@@ -148,7 +229,7 @@ type Admin = {
|
||||
className?: string
|
||||
components?: {
|
||||
Cell?: CustomComponent
|
||||
Description?: DescriptionComponent
|
||||
Description?: CustomComponent<FieldDescriptionClientComponent | FieldDescriptionServerComponent>
|
||||
Field?: CustomComponent
|
||||
/**
|
||||
* The Filter component has to be a client component
|
||||
@@ -339,8 +420,8 @@ export type NumberField = {
|
||||
/** Set this property to a string that will be used for browser autocomplete. */
|
||||
autoComplete?: string
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<NumberFieldErrorClientComponent | NumberFieldErrorServerComponent>
|
||||
Label?: CustomComponent<NumberFieldLabelClientComponent | NumberFieldLabelServerComponent>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
} & Admin['components']
|
||||
@@ -392,8 +473,8 @@ export type TextField = {
|
||||
admin?: {
|
||||
autoComplete?: string
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<TextFieldErrorClientComponent | TextFieldErrorServerComponent>
|
||||
Label?: CustomComponent<TextFieldLabelClientComponent | TextFieldLabelServerComponent>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
} & Admin['components']
|
||||
@@ -441,8 +522,8 @@ export type EmailField = {
|
||||
admin?: {
|
||||
autoComplete?: string
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<EmailFieldErrorClientComponent | EmailFieldErrorServerComponent>
|
||||
Label?: CustomComponent<EmailFieldLabelClientComponent | EmailFieldLabelServerComponent>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
} & Admin['components']
|
||||
@@ -468,8 +549,8 @@ export type EmailFieldClient = {
|
||||
export type TextareaField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<TextareaFieldErrorClientComponent | TextareaFieldErrorServerComponent>
|
||||
Label?: CustomComponent<TextareaFieldLabelClientComponent | TextareaFieldLabelServerComponent>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
} & Admin['components']
|
||||
@@ -499,8 +580,8 @@ export type TextareaFieldClient = {
|
||||
export type CheckboxField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<CheckboxFieldErrorClientComponent | CheckboxFieldErrorServerComponent>
|
||||
Label?: CustomComponent<CheckboxFieldLabelClientComponent | CheckboxFieldLabelServerComponent>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
} & Admin['components']
|
||||
@@ -524,8 +605,8 @@ export type CheckboxFieldClient = {
|
||||
export type DateField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<DateFieldErrorClientComponent | DateFieldErrorServerComponent>
|
||||
Label?: CustomComponent<DateFieldLabelClientComponent | DateFieldLabelServerComponent>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
} & Admin['components']
|
||||
@@ -552,7 +633,7 @@ export type DateFieldClient = {
|
||||
export type GroupField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Label?: LabelComponent
|
||||
Label?: CustomComponent<GroupFieldLabelClientComponent | GroupFieldLabelServerComponent>
|
||||
} & Admin['components']
|
||||
hideGutter?: boolean
|
||||
} & Admin
|
||||
@@ -598,7 +679,9 @@ export type CollapsibleField = {
|
||||
| {
|
||||
admin: {
|
||||
components: {
|
||||
Label?: LabelComponent
|
||||
Label?: CustomComponent<
|
||||
CollapsibleFieldLabelClientComponent | CollapsibleFieldLabelServerComponent
|
||||
>
|
||||
RowLabel: RowLabelComponent
|
||||
} & Admin['components']
|
||||
initCollapsed?: boolean
|
||||
@@ -608,7 +691,9 @@ export type CollapsibleField = {
|
||||
| {
|
||||
admin?: {
|
||||
components?: {
|
||||
Label?: LabelComponent
|
||||
Label?: CustomComponent<
|
||||
CollapsibleFieldLabelClientComponent | CollapsibleFieldLabelServerComponent
|
||||
>
|
||||
} & Admin['components']
|
||||
initCollapsed?: boolean
|
||||
} & Admin
|
||||
@@ -742,8 +827,8 @@ export type UIFieldClient = {
|
||||
export type UploadField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<UploadFieldErrorClientComponent | UploadFieldErrorServerComponent>
|
||||
Label?: CustomComponent<UploadFieldLabelClientComponent | UploadFieldLabelServerComponent>
|
||||
} & Admin['components']
|
||||
}
|
||||
displayPreview?: boolean
|
||||
@@ -772,8 +857,8 @@ export type UploadFieldClient = {
|
||||
export type CodeField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<CodeFieldErrorClientComponent | CodeFieldErrorServerComponent>
|
||||
Label?: CustomComponent<CodeFieldLabelClientComponent | CodeFieldLabelServerComponent>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
} & Admin['components']
|
||||
@@ -802,8 +887,8 @@ export type CodeFieldClient = {
|
||||
export type JSONField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<JSONFieldErrorClientComponent | JSONFieldErrorServerComponent>
|
||||
Label?: CustomComponent<JSONFieldLabelClientComponent | JSONFieldLabelServerComponent>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
} & Admin['components']
|
||||
@@ -835,8 +920,8 @@ export type JSONFieldClient = {
|
||||
export type SelectField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<SelectFieldErrorClientComponent | SelectFieldErrorServerComponent>
|
||||
Label?: CustomComponent<SelectFieldLabelClientComponent | SelectFieldLabelServerComponent>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
} & Admin['components']
|
||||
@@ -920,8 +1005,12 @@ type SharedRelationshipPropertiesClient = FieldBaseClient &
|
||||
type RelationshipAdmin = {
|
||||
allowCreate?: boolean
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<
|
||||
RelationshipFieldErrorClientComponent | RelationshipFieldErrorServerComponent
|
||||
>
|
||||
Label?: CustomComponent<
|
||||
RelationshipFieldLabelClientComponent | RelationshipFieldLabelServerComponent
|
||||
>
|
||||
} & Admin['components']
|
||||
isSortable?: boolean
|
||||
} & Admin
|
||||
@@ -988,8 +1077,8 @@ export type RichTextField<
|
||||
> = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent
|
||||
Label?: CustomComponent
|
||||
} & Admin['components']
|
||||
} & Admin
|
||||
editor?:
|
||||
@@ -1015,6 +1104,7 @@ export type RichTextFieldClient<
|
||||
Error?: MappedComponent
|
||||
Label?: MappedComponent
|
||||
} & AdminClient['components']
|
||||
placeholder?: Record<string, string> | string
|
||||
} & AdminClient
|
||||
richTextComponentMap?: Map<string, any>
|
||||
} & FieldBaseClient &
|
||||
@@ -1024,8 +1114,8 @@ export type RichTextFieldClient<
|
||||
export type ArrayField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<ArrayFieldErrorClientComponent | ArrayFieldErrorServerComponent>
|
||||
Label?: CustomComponent<ArrayFieldLabelClientComponent | ArrayFieldLabelServerComponent>
|
||||
RowLabel?: RowLabelComponent
|
||||
} & Admin['components']
|
||||
initCollapsed?: boolean
|
||||
@@ -1070,8 +1160,8 @@ export type ArrayFieldClient = {
|
||||
export type RadioField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<RadioFieldErrorClientComponent | RadioFieldErrorServerComponent>
|
||||
Label?: CustomComponent<RadioFieldLabelClientComponent | RadioFieldLabelServerComponent>
|
||||
} & Admin['components']
|
||||
layout?: 'horizontal' | 'vertical'
|
||||
} & Admin
|
||||
@@ -1157,7 +1247,7 @@ export type ClientBlock = {
|
||||
export type BlockField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Error?: CustomComponent<BlockFieldErrorClientComponent | BlockFieldErrorServerComponent>
|
||||
} & Admin['components']
|
||||
initCollapsed?: boolean
|
||||
/**
|
||||
@@ -1189,8 +1279,8 @@ export type BlockFieldClient = {
|
||||
export type PointField = {
|
||||
admin?: {
|
||||
components?: {
|
||||
Error?: ErrorComponent
|
||||
Label?: LabelComponent
|
||||
Error?: CustomComponent<PointFieldErrorClientComponent | PointFieldErrorServerComponent>
|
||||
Label?: CustomComponent<PointFieldLabelClientComponent | PointFieldLabelServerComponent>
|
||||
afterInput?: CustomComponent[]
|
||||
beforeInput?: CustomComponent[]
|
||||
} & Admin['components']
|
||||
@@ -1260,6 +1350,28 @@ export type ClientField =
|
||||
| UIFieldClient
|
||||
| UploadFieldClient
|
||||
|
||||
export type ClientFieldProps =
|
||||
| ArrayFieldProps
|
||||
| BlockFieldProps
|
||||
| CheckboxFieldProps
|
||||
| CodeFieldProps
|
||||
| CollapsibleFieldProps
|
||||
| DateFieldProps
|
||||
| EmailFieldProps
|
||||
| GroupFieldProps
|
||||
| HiddenFieldProps
|
||||
| JSONFieldProps
|
||||
| NumberFieldProps
|
||||
| PointFieldProps
|
||||
| RadioFieldProps
|
||||
| RelationshipFieldProps
|
||||
| RichTextFieldProps
|
||||
| RowFieldProps
|
||||
| SelectFieldProps
|
||||
| TabsFieldProps
|
||||
| TextareaFieldProps
|
||||
| UploadFieldProps
|
||||
|
||||
type ExtractFieldTypes<T> = T extends { type: infer U } ? U : never
|
||||
|
||||
export type FieldTypes = ExtractFieldTypes<Field>
|
||||
@@ -1373,9 +1485,9 @@ export type FieldWithManyClient = RelationshipFieldClient | SelectFieldClient
|
||||
export type FieldWithMaxDepth = RelationshipField | UploadField
|
||||
export type FieldWithMaxDepthClient = RelationshipFieldClient | UploadFieldClient
|
||||
|
||||
export function fieldHasSubFields<T extends ClientField | Field>(
|
||||
field: T,
|
||||
): field is T & (T extends ClientField ? FieldWithSubFieldsClient : FieldWithSubFields) {
|
||||
export function fieldHasSubFields<TField extends ClientField | Field>(
|
||||
field: TField,
|
||||
): field is TField & (TField extends ClientField ? FieldWithSubFieldsClient : FieldWithSubFields) {
|
||||
return (
|
||||
field.type === 'group' ||
|
||||
field.type === 'array' ||
|
||||
@@ -1384,21 +1496,21 @@ export function fieldHasSubFields<T extends ClientField | Field>(
|
||||
)
|
||||
}
|
||||
|
||||
export function fieldIsArrayType<T extends ClientField | Field>(
|
||||
field: T,
|
||||
): field is T & (T extends ClientField ? ArrayFieldClient : ArrayField) {
|
||||
export function fieldIsArrayType<TField extends ClientField | Field>(
|
||||
field: TField,
|
||||
): field is TField & (TField extends ClientField ? ArrayFieldClient : ArrayField) {
|
||||
return field.type === 'array'
|
||||
}
|
||||
|
||||
export function fieldIsBlockType<T extends ClientField | Field>(
|
||||
field: T,
|
||||
): field is T & (T extends ClientField ? BlockFieldClient : BlockField) {
|
||||
export function fieldIsBlockType<TField extends ClientField | Field>(
|
||||
field: TField,
|
||||
): field is TField & (TField extends ClientField ? BlockFieldClient : BlockField) {
|
||||
return field.type === 'blocks'
|
||||
}
|
||||
|
||||
export function fieldIsGroupType<T extends ClientField | Field>(
|
||||
field: T,
|
||||
): field is T & (T extends ClientField ? GroupFieldClient : GroupField) {
|
||||
export function fieldIsGroupType<TField extends ClientField | Field>(
|
||||
field: TField,
|
||||
): field is TField & (TField extends ClientField ? GroupFieldClient : GroupField) {
|
||||
return field.type === 'group'
|
||||
}
|
||||
|
||||
@@ -1414,40 +1526,44 @@ export function optionIsValue(option: Option): option is string {
|
||||
return typeof option === 'string'
|
||||
}
|
||||
|
||||
export function fieldSupportsMany<T extends ClientField | Field>(
|
||||
field: T,
|
||||
): field is T & (T extends ClientField ? FieldWithManyClient : FieldWithMany) {
|
||||
export function fieldSupportsMany<TField extends ClientField | Field>(
|
||||
field: TField,
|
||||
): field is TField & (TField extends ClientField ? FieldWithManyClient : FieldWithMany) {
|
||||
return field.type === 'select' || field.type === 'relationship'
|
||||
}
|
||||
|
||||
export function fieldHasMaxDepth<T extends ClientField | Field>(
|
||||
field: T,
|
||||
): field is T & (T extends ClientField ? FieldWithMaxDepthClient : FieldWithMaxDepth) {
|
||||
export function fieldHasMaxDepth<TField extends ClientField | Field>(
|
||||
field: TField,
|
||||
): field is TField & (TField extends ClientField ? FieldWithMaxDepthClient : FieldWithMaxDepth) {
|
||||
return (
|
||||
(field.type === 'upload' || field.type === 'relationship') && typeof field.maxDepth === 'number'
|
||||
)
|
||||
}
|
||||
|
||||
export function fieldIsPresentationalOnly<
|
||||
T extends ClientField | Field | TabAsField | TabAsFieldClient,
|
||||
>(field: T): field is T & (T extends ClientField | TabAsFieldClient ? UIFieldClient : UIField) {
|
||||
TField extends ClientField | Field | TabAsField | TabAsFieldClient,
|
||||
>(
|
||||
field: TField,
|
||||
): field is TField & (TField extends ClientField | TabAsFieldClient ? UIFieldClient : UIField) {
|
||||
return field.type === 'ui'
|
||||
}
|
||||
|
||||
export function fieldIsSidebar<T extends ClientField | Field | TabAsField | TabAsFieldClient>(
|
||||
field: T,
|
||||
): field is { admin: { position: 'sidebar' } } & T {
|
||||
export function fieldIsSidebar<TField extends ClientField | Field | TabAsField | TabAsFieldClient>(
|
||||
field: TField,
|
||||
): field is { admin: { position: 'sidebar' } } & TField {
|
||||
return 'admin' in field && 'position' in field.admin && field.admin.position === 'sidebar'
|
||||
}
|
||||
|
||||
export function fieldAffectsData<T extends ClientField | Field | TabAsField | TabAsFieldClient>(
|
||||
field: T,
|
||||
): field is T &
|
||||
(T extends ClientField | TabAsFieldClient ? FieldAffectingDataClient : FieldAffectingData) {
|
||||
export function fieldAffectsData<
|
||||
TField extends ClientField | Field | TabAsField | TabAsFieldClient,
|
||||
>(
|
||||
field: TField,
|
||||
): field is TField &
|
||||
(TField extends ClientField | TabAsFieldClient ? FieldAffectingDataClient : FieldAffectingData) {
|
||||
return 'name' in field && !fieldIsPresentationalOnly(field)
|
||||
}
|
||||
|
||||
export function tabHasName<T extends ClientTab | Tab>(tab: T): tab is NamedTab & T {
|
||||
export function tabHasName<TField extends ClientTab | Tab>(tab: TField): tab is NamedTab & TField {
|
||||
return 'name' in tab
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { ClientTab } from '../admin/fields/Tabs.js'
|
||||
import type { ClientField } from '../fields/config/client.js'
|
||||
import type {
|
||||
Field,
|
||||
@@ -14,13 +15,12 @@ import {
|
||||
fieldIsPresentationalOnly,
|
||||
tabHasName,
|
||||
} from '../fields/config/types.js'
|
||||
import { ClientTab } from '../admin/fields/Tabs.js'
|
||||
|
||||
type FlattenedField<T> = T extends ClientField
|
||||
type FlattenedField<TField> = TField extends ClientField
|
||||
? FieldAffectingDataClient | FieldPresentationalOnlyClient
|
||||
: FieldAffectingData | FieldPresentationalOnly
|
||||
|
||||
type TabType<T> = T extends ClientField ? ClientTab : Tab
|
||||
type TabType<TField> = TField extends ClientField ? ClientTab : Tab
|
||||
|
||||
/**
|
||||
* Flattens a collection's fields into a single array of fields, as long
|
||||
@@ -29,27 +29,30 @@ type TabType<T> = T extends ClientField ? ClientTab : Tab
|
||||
* @param fields
|
||||
* @param keepPresentationalFields if true, will skip flattening fields that are presentational only
|
||||
*/
|
||||
function flattenFields<T extends ClientField | Field>(
|
||||
fields: T[],
|
||||
function flattenFields<TField extends ClientField | Field>(
|
||||
fields: TField[],
|
||||
keepPresentationalFields?: boolean,
|
||||
): FlattenedField<T>[] {
|
||||
return fields.reduce<FlattenedField<T>[]>((fieldsToUse, field) => {
|
||||
): FlattenedField<TField>[] {
|
||||
return fields.reduce<FlattenedField<TField>[]>((fieldsToUse, field) => {
|
||||
if (fieldAffectsData(field) || (keepPresentationalFields && fieldIsPresentationalOnly(field))) {
|
||||
return [...fieldsToUse, field as FlattenedField<T>]
|
||||
return [...fieldsToUse, field as FlattenedField<TField>]
|
||||
}
|
||||
|
||||
if (fieldHasSubFields(field)) {
|
||||
return [...fieldsToUse, ...flattenFields(field.fields as T[], keepPresentationalFields)]
|
||||
return [...fieldsToUse, ...flattenFields(field.fields as TField[], keepPresentationalFields)]
|
||||
}
|
||||
|
||||
if (field.type === 'tabs' && 'tabs' in field) {
|
||||
return [
|
||||
...fieldsToUse,
|
||||
...field.tabs.reduce<FlattenedField<T>[]>((tabFields, tab: TabType<T>) => {
|
||||
...field.tabs.reduce<FlattenedField<TField>[]>((tabFields, tab: TabType<TField>) => {
|
||||
if (tabHasName(tab)) {
|
||||
return [...tabFields, { ...tab, type: 'tab' } as unknown as FlattenedField<T>]
|
||||
return [...tabFields, { ...tab, type: 'tab' } as unknown as FlattenedField<TField>]
|
||||
} else {
|
||||
return [...tabFields, ...flattenFields(tab.fields as T[], keepPresentationalFields)]
|
||||
return [
|
||||
...tabFields,
|
||||
...flattenFields(tab.fields as TField[], keepPresentationalFields),
|
||||
]
|
||||
}
|
||||
}, []),
|
||||
]
|
||||
|
||||
@@ -88,7 +88,7 @@ export const getFields = ({ collection, prefix }: Args): Field[] => {
|
||||
type: 'group',
|
||||
fields: [
|
||||
{
|
||||
...(existingSizeURLField || {}),
|
||||
...(existingSizeURLField || ({} as any)),
|
||||
...baseURLField,
|
||||
},
|
||||
],
|
||||
|
||||
@@ -108,7 +108,7 @@ export const getFields = ({
|
||||
fields: [
|
||||
...(adapter.fields || []),
|
||||
{
|
||||
...(existingSizeURLField || {}),
|
||||
...(existingSizeURLField || ({} as any)),
|
||||
...baseURLField,
|
||||
hooks: {
|
||||
afterRead: [
|
||||
|
||||
@@ -24,7 +24,7 @@ import { LengthIndicator } from '../../ui/LengthIndicator.js'
|
||||
const { maxLength, minLength } = defaults.description
|
||||
|
||||
type MetaDescriptionProps = {
|
||||
hasGenerateDescriptionFn: boolean
|
||||
readonly hasGenerateDescriptionFn: boolean
|
||||
} & TextareaFieldProps
|
||||
|
||||
export const MetaDescriptionComponent: React.FC<MetaDescriptionProps> = (props) => {
|
||||
@@ -58,9 +58,16 @@ export const MetaDescriptionComponent: React.FC<MetaDescriptionProps> = (props)
|
||||
|
||||
const genDescriptionResponse = await fetch('/api/plugin-seo/generate-description', {
|
||||
body: JSON.stringify({
|
||||
...docInfo,
|
||||
doc: { ...getData() },
|
||||
id: docInfo.id,
|
||||
slug: docInfo.slug,
|
||||
doc: getData(),
|
||||
docPermissions: docInfo.docPermissions,
|
||||
hasPublishPermission: docInfo.hasPublishPermission,
|
||||
hasSavePermission: docInfo.hasSavePermission,
|
||||
initialData: docInfo.initialData,
|
||||
initialState: docInfo.initialState,
|
||||
locale: typeof locale === 'object' ? locale?.code : locale,
|
||||
title: docInfo.title,
|
||||
} satisfies Omit<Parameters<GenerateDescription>[0], 'req'>),
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
@@ -87,7 +94,7 @@ export const MetaDescriptionComponent: React.FC<MetaDescriptionProps> = (props)
|
||||
}}
|
||||
>
|
||||
<div className="plugin-seo__field">
|
||||
<FieldLabel Label={Label} label={label} {...(labelProps || {})} />
|
||||
<FieldLabel Label={Label} field={null} label={label} {...(labelProps || {})} />
|
||||
{hasGenerateDescriptionFn && (
|
||||
<React.Fragment>
|
||||
—
|
||||
|
||||
@@ -21,7 +21,7 @@ import type { GenerateImage } from '../../types.js'
|
||||
import { Pill } from '../../ui/Pill.js'
|
||||
|
||||
type MetaImageProps = {
|
||||
hasGenerateImageFn: boolean
|
||||
readonly hasGenerateImageFn: boolean
|
||||
} & UploadFieldProps
|
||||
|
||||
export const MetaImageComponent: React.FC<MetaImageProps> = (props) => {
|
||||
@@ -54,9 +54,16 @@ export const MetaImageComponent: React.FC<MetaImageProps> = (props) => {
|
||||
|
||||
const genImageResponse = await fetch('/api/plugin-seo/generate-image', {
|
||||
body: JSON.stringify({
|
||||
...docInfo,
|
||||
doc: { ...getData() },
|
||||
id: docInfo.id,
|
||||
slug: docInfo.slug,
|
||||
doc: getData(),
|
||||
docPermissions: docInfo.docPermissions,
|
||||
hasPublishPermission: docInfo.hasPublishPermission,
|
||||
hasSavePermission: docInfo.hasSavePermission,
|
||||
initialData: docInfo.initialData,
|
||||
initialState: docInfo.initialState,
|
||||
locale: typeof locale === 'object' ? locale?.code : locale,
|
||||
title: docInfo.title,
|
||||
} satisfies Omit<Parameters<GenerateImage>[0], 'req'>),
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
@@ -91,7 +98,7 @@ export const MetaImageComponent: React.FC<MetaImageProps> = (props) => {
|
||||
}}
|
||||
>
|
||||
<div className="plugin-seo__field">
|
||||
<FieldLabel Label={Label} label={label} {...(labelProps || {})} />
|
||||
<FieldLabel Label={Label} field={null} label={label} {...(labelProps || {})} />
|
||||
{hasGenerateImageFn && (
|
||||
<React.Fragment>
|
||||
—
|
||||
|
||||
@@ -25,7 +25,7 @@ import '../index.scss'
|
||||
const { maxLength, minLength } = defaults.title
|
||||
|
||||
type MetaTitleProps = {
|
||||
hasGenerateTitleFn: boolean
|
||||
readonly hasGenerateTitleFn: boolean
|
||||
} & TextFieldProps
|
||||
|
||||
export const MetaTitleComponent: React.FC<MetaTitleProps> = (props) => {
|
||||
@@ -59,9 +59,16 @@ export const MetaTitleComponent: React.FC<MetaTitleProps> = (props) => {
|
||||
|
||||
const genTitleResponse = await fetch('/api/plugin-seo/generate-title', {
|
||||
body: JSON.stringify({
|
||||
...docInfo,
|
||||
doc: { ...getData() },
|
||||
id: docInfo.id,
|
||||
slug: docInfo.slug,
|
||||
doc: getData(),
|
||||
docPermissions: docInfo.docPermissions,
|
||||
hasPublishPermission: docInfo.hasPublishPermission,
|
||||
hasSavePermission: docInfo.hasSavePermission,
|
||||
initialData: docInfo.initialData,
|
||||
initialState: docInfo.initialState,
|
||||
locale: typeof locale === 'object' ? locale?.code : locale,
|
||||
title: docInfo.title,
|
||||
} satisfies Omit<Parameters<GenerateTitle>[0], 'req'>),
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
@@ -88,7 +95,7 @@ export const MetaTitleComponent: React.FC<MetaTitleProps> = (props) => {
|
||||
}}
|
||||
>
|
||||
<div className="plugin-seo__field">
|
||||
<FieldLabel Label={Label} label={label} {...(labelProps || {})} />
|
||||
<FieldLabel Label={Label} field={null} label={label} {...(labelProps || {})} />
|
||||
{hasGenerateTitleFn && (
|
||||
<React.Fragment>
|
||||
—
|
||||
|
||||
@@ -15,16 +15,18 @@ import type { PluginSEOTranslationKeys, PluginSEOTranslations } from '../../tran
|
||||
import type { GenerateURL } from '../../types.js'
|
||||
|
||||
type PreviewProps = {
|
||||
descriptionPath?: string
|
||||
hasGenerateURLFn: boolean
|
||||
titlePath?: string
|
||||
readonly descriptionPath?: string
|
||||
readonly hasGenerateURLFn: boolean
|
||||
readonly titlePath?: string
|
||||
} & UIField
|
||||
|
||||
export const PreviewComponent: React.FC<PreviewProps> = ({
|
||||
descriptionPath: descriptionPathFromContext,
|
||||
hasGenerateURLFn,
|
||||
titlePath: titlePathFromContext,
|
||||
}) => {
|
||||
export const PreviewComponent: React.FC<PreviewProps> = (props) => {
|
||||
const {
|
||||
descriptionPath: descriptionPathFromContext,
|
||||
hasGenerateURLFn,
|
||||
titlePath: titlePathFromContext,
|
||||
} = props
|
||||
|
||||
const { t } = useTranslation<PluginSEOTranslations, PluginSEOTranslationKeys>()
|
||||
|
||||
const locale = useLocale()
|
||||
@@ -46,9 +48,15 @@ export const PreviewComponent: React.FC<PreviewProps> = ({
|
||||
const getHref = async () => {
|
||||
const genURLResponse = await fetch('/api/plugin-seo/generate-url', {
|
||||
body: JSON.stringify({
|
||||
...docInfo,
|
||||
doc: { ...getData() },
|
||||
id: docInfo.id,
|
||||
doc: getData(),
|
||||
docPermissions: docInfo.docPermissions,
|
||||
hasPublishPermission: docInfo.hasPublishPermission,
|
||||
hasSavePermission: docInfo.hasSavePermission,
|
||||
initialData: docInfo.initialData,
|
||||
initialState: docInfo.initialState,
|
||||
locale: typeof locale === 'object' ? locale?.code : locale,
|
||||
title: docInfo.title,
|
||||
} satisfies Omit<Parameters<GenerateURL>[0], 'req'>),
|
||||
credentials: 'include',
|
||||
headers: {
|
||||
|
||||
@@ -1,8 +1,23 @@
|
||||
import type { DocumentInfoContext } from '@payloadcms/ui'
|
||||
import type { Field, PayloadRequest, TextField, TextareaField, UploadField } from 'payload'
|
||||
|
||||
export type PartialDocumentInfoContext = Pick<
|
||||
DocumentInfoContext,
|
||||
| 'docPermissions'
|
||||
| 'hasPublishPermission'
|
||||
| 'hasSavePermission'
|
||||
| 'id'
|
||||
| 'initialData'
|
||||
| 'initialState'
|
||||
| 'preferencesKey'
|
||||
| 'publishedDoc'
|
||||
| 'slug'
|
||||
| 'title'
|
||||
| 'versionsCount'
|
||||
>
|
||||
|
||||
export type GenerateTitle<T = any> = (
|
||||
args: { doc: T; locale?: string; req: PayloadRequest } & DocumentInfoContext,
|
||||
args: { doc: T; locale?: string; req: PayloadRequest } & PartialDocumentInfoContext,
|
||||
) => Promise<string> | string
|
||||
|
||||
export type GenerateDescription<T = any> = (
|
||||
@@ -10,15 +25,15 @@ export type GenerateDescription<T = any> = (
|
||||
doc: T
|
||||
locale?: string
|
||||
req: PayloadRequest
|
||||
} & DocumentInfoContext,
|
||||
} & PartialDocumentInfoContext,
|
||||
) => Promise<string> | string
|
||||
|
||||
export type GenerateImage<T = any> = (
|
||||
args: { doc: T; locale?: string; req: PayloadRequest } & DocumentInfoContext,
|
||||
args: { doc: T; locale?: string; req: PayloadRequest } & PartialDocumentInfoContext,
|
||||
) => Promise<string> | string
|
||||
|
||||
export type GenerateURL<T = any> = (
|
||||
args: { doc: T; locale?: string; req: PayloadRequest } & DocumentInfoContext,
|
||||
args: { doc: T; locale?: string; req: PayloadRequest } & PartialDocumentInfoContext,
|
||||
) => Promise<string> | string
|
||||
|
||||
export type SEOPluginConfig = {
|
||||
|
||||
@@ -18,8 +18,8 @@ import { getEnabledNodes } from '../lexical/nodes/index.js'
|
||||
|
||||
export const RichTextCell: React.FC<
|
||||
{
|
||||
admin?: LexicalFieldAdminProps
|
||||
lexicalEditorConfig: LexicalEditorConfig
|
||||
readonly admin?: LexicalFieldAdminProps
|
||||
readonly lexicalEditorConfig: LexicalEditorConfig
|
||||
} & CellComponentProps<RichTextFieldClient>
|
||||
> = (props) => {
|
||||
const {
|
||||
|
||||
@@ -94,8 +94,20 @@ const RichTextComponent: React.FC<
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<FieldError CustomError={Error} path={path} {...(errorProps || {})} alignCaret="left" />
|
||||
<FieldLabel Label={Label} label={label} required={required} {...(labelProps || {})} />
|
||||
<FieldError
|
||||
CustomError={Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
alignCaret="left"
|
||||
/>
|
||||
<FieldLabel
|
||||
Label={Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
/>
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<ErrorBoundary fallbackRender={fallbackRender} onReset={() => {}}>
|
||||
<LexicalProvider
|
||||
@@ -119,7 +131,7 @@ const RichTextComponent: React.FC<
|
||||
value={value}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
<FieldDescription Description={Description} {...(descriptionProps || {})} />
|
||||
<FieldDescription Description={Description} field={field} {...(descriptionProps || {})} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -44,9 +44,11 @@ export const getGenerateComponentMap =
|
||||
const mappedComponent: MappedComponent = createMappedComponent(
|
||||
payloadComponent,
|
||||
{
|
||||
componentKey,
|
||||
featureKey: resolvedFeature.key,
|
||||
key: `${resolvedFeature.key}-${componentKey}`,
|
||||
clientProps: {
|
||||
componentKey,
|
||||
featureKey: resolvedFeature.key,
|
||||
key: `${resolvedFeature.key}-${componentKey}`,
|
||||
},
|
||||
},
|
||||
undefined,
|
||||
'lexical-from-resolvedFeature',
|
||||
|
||||
@@ -54,6 +54,7 @@ const RichTextField: React.FC<LoadedSlateFieldProps> = (props) => {
|
||||
descriptionProps,
|
||||
elements,
|
||||
errorProps,
|
||||
field,
|
||||
field: {
|
||||
name,
|
||||
_path: pathFromProps,
|
||||
@@ -316,9 +317,15 @@ const RichTextField: React.FC<LoadedSlateFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<FieldLabel Label={Label} label={label} required={required} {...(labelProps || {})} />
|
||||
<FieldLabel
|
||||
Label={Label}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
field={field}
|
||||
/>
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<FieldError CustomError={Error} path={path} {...(errorProps || {})} />
|
||||
<FieldError CustomError={Error} field={field} path={path} {...(errorProps || {})} />
|
||||
<Slate
|
||||
editor={editor}
|
||||
key={JSON.stringify({ initialValue, path })} // makes sure slate is completely re-rendered when initialValue changes, bypassing the slate-internal value memoization. That way, external changes to the form will update the editor
|
||||
@@ -449,7 +456,7 @@ const RichTextField: React.FC<LoadedSlateFieldProps> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
</Slate>
|
||||
<FieldDescription Description={Description} {...(descriptionProps || {})} />
|
||||
<FieldDescription Description={Description} field={field} {...(descriptionProps || {})} />
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -175,7 +175,7 @@ export const FieldSelect: React.FC<FieldSelectProps> = ({ fields, setSelected })
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<FieldLabel label={t('fields:selectFieldsToEdit')} />
|
||||
<FieldLabel field={null} label={t('fields:selectFieldsToEdit')} />
|
||||
<ReactSelect
|
||||
getOptionValue={(option) => {
|
||||
if (typeof option.value === 'object' && 'path' in option.value) {
|
||||
|
||||
@@ -258,7 +258,7 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = ({
|
||||
)}
|
||||
{moreThanOneAvailableCollection && (
|
||||
<div className={`${baseClass}__select-collection-wrap`}>
|
||||
<FieldLabel label={t('upload:selectCollectionToBrowse')} />
|
||||
<FieldLabel field={null} label={t('upload:selectCollectionToBrowse')} />
|
||||
<ReactSelect
|
||||
className={`${baseClass}__select-collection`}
|
||||
onChange={setSelectedOption} // this is only changing the options which is not rerunning my effect
|
||||
|
||||
@@ -100,6 +100,7 @@ export const buildColumnState = (args: Args): Column[] => {
|
||||
const Label = (
|
||||
<FieldLabel
|
||||
Label={CustomLabelToRender}
|
||||
field={field}
|
||||
label={'label' in field ? (field.label as StaticLabel) : undefined}
|
||||
unstyled
|
||||
/>
|
||||
|
||||
@@ -222,7 +222,7 @@ export const Upload: React.FC<UploadProps> = (props) => {
|
||||
|
||||
return (
|
||||
<div className={[fieldBaseClass, baseClass].filter(Boolean).join(' ')}>
|
||||
<FieldError message={errorMessage} showError={showError} />
|
||||
<FieldError field={null} message={errorMessage} showError={showError} />
|
||||
{doc.filename && !replacingFile && (
|
||||
<FileDetails
|
||||
collectionSlug={collectionSlug}
|
||||
|
||||
@@ -1,21 +1,21 @@
|
||||
'use client'
|
||||
import type { DescriptionFunction, StaticDescription } from 'payload'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import React from 'react'
|
||||
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import './index.scss'
|
||||
|
||||
export type DescriptionFunction = () => string
|
||||
export type ViewDescriptionComponent = React.ComponentType<any>
|
||||
|
||||
export type DescriptionComponent = React.ComponentType<any>
|
||||
|
||||
type Description = DescriptionComponent | DescriptionFunction | Record<string, string> | string
|
||||
type Description = DescriptionFunction | StaticDescription | ViewDescriptionComponent | string
|
||||
|
||||
export type ViewDescriptionProps = {
|
||||
description?: Description
|
||||
readonly description?: Description
|
||||
}
|
||||
|
||||
export function isComponent(description: Description): description is DescriptionComponent {
|
||||
export function isComponent(description: Description): description is ViewDescriptionComponent {
|
||||
return React.isValidElement(description)
|
||||
}
|
||||
|
||||
@@ -29,11 +29,7 @@ export const ViewDescription: React.FC<ViewDescriptionProps> = (props) => {
|
||||
}
|
||||
|
||||
if (description) {
|
||||
return (
|
||||
<div className="view-description">
|
||||
{typeof description === 'function' ? description() : getTranslation(description, i18n)}
|
||||
</div>
|
||||
)
|
||||
return <div className="view-description">{getTranslation(description, i18n)}</div>
|
||||
}
|
||||
|
||||
return null
|
||||
|
||||
@@ -215,6 +215,7 @@ export const ArrayFieldComponent: React.FC<ArrayFieldProps> = (props) => {
|
||||
{showError && (
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
/>
|
||||
@@ -226,6 +227,7 @@ export const ArrayFieldComponent: React.FC<ArrayFieldProps> = (props) => {
|
||||
<FieldLabel
|
||||
Label={field?.admin?.components?.Label}
|
||||
as="span"
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
unstyled
|
||||
@@ -262,6 +264,7 @@ export const ArrayFieldComponent: React.FC<ArrayFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</header>
|
||||
|
||||
@@ -56,6 +56,7 @@ const BlocksFieldComponent: React.FC<BlockFieldProps> = (props) => {
|
||||
readOnly: readOnlyFromTopLevelProps,
|
||||
validate,
|
||||
} = props
|
||||
|
||||
const readOnlyFromProps = readOnlyFromTopLevelProps || readOnlyFromAdmin
|
||||
|
||||
const { indexPath, readOnly: readOnlyFromContext } = useFieldProps()
|
||||
@@ -217,6 +218,7 @@ const BlocksFieldComponent: React.FC<BlockFieldProps> = (props) => {
|
||||
{showError && (
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
/>
|
||||
@@ -228,6 +230,7 @@ const BlocksFieldComponent: React.FC<BlockFieldProps> = (props) => {
|
||||
<FieldLabel
|
||||
Label={field?.admin?.components?.Description}
|
||||
as="span"
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
unstyled
|
||||
@@ -264,6 +267,7 @@ const BlocksFieldComponent: React.FC<BlockFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</header>
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
'use client'
|
||||
import type { LabelProps, MappedComponent, SanitizedLabelProps } from 'payload'
|
||||
import type {
|
||||
CheckboxFieldClient,
|
||||
FieldLabelClientProps,
|
||||
MappedComponent,
|
||||
StaticLabel,
|
||||
} from 'payload'
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
@@ -14,10 +20,11 @@ export type CheckboxInputProps = {
|
||||
readonly beforeInput?: MappedComponent[]
|
||||
readonly checked?: boolean
|
||||
readonly className?: string
|
||||
readonly field?: MarkOptional<CheckboxFieldClient, 'type'>
|
||||
readonly id?: string
|
||||
readonly inputRef?: React.RefObject<HTMLInputElement | null>
|
||||
readonly label?: LabelProps<'checkbox'>['label']
|
||||
readonly labelProps?: SanitizedLabelProps
|
||||
readonly label?: StaticLabel
|
||||
readonly labelProps?: FieldLabelClientProps<MarkOptional<CheckboxFieldClient, 'type'>>
|
||||
readonly name?: string
|
||||
readonly onToggle: (event: React.ChangeEvent<HTMLInputElement>) => void
|
||||
readonly partialChecked?: boolean
|
||||
@@ -35,6 +42,7 @@ export const CheckboxInput: React.FC<CheckboxInputProps> = ({
|
||||
beforeInput,
|
||||
checked,
|
||||
className,
|
||||
field,
|
||||
inputRef,
|
||||
label,
|
||||
labelProps,
|
||||
@@ -79,6 +87,7 @@ export const CheckboxInput: React.FC<CheckboxInputProps> = ({
|
||||
</div>
|
||||
<FieldLabel
|
||||
Label={Label}
|
||||
field={field}
|
||||
htmlFor={id}
|
||||
label={label}
|
||||
required={required}
|
||||
|
||||
@@ -103,6 +103,7 @@ const CheckboxFieldComponent: React.FC<CheckboxFieldProps> = (props) => {
|
||||
>
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
alignCaret="left"
|
||||
@@ -125,6 +126,7 @@ const CheckboxFieldComponent: React.FC<CheckboxFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -85,6 +85,7 @@ const CodeFieldComponent: React.FC<CodeFieldProps> = (props) => {
|
||||
>
|
||||
<FieldLabel
|
||||
Label={field?.admin?.components?.Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
@@ -92,6 +93,7 @@ const CodeFieldComponent: React.FC<CodeFieldProps> = (props) => {
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
/>
|
||||
@@ -108,6 +110,7 @@ const CodeFieldComponent: React.FC<CodeFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -163,6 +163,7 @@ const CollapsibleFieldComponent: React.FC<CollapsibleFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -38,12 +38,13 @@ export const ConfirmPasswordField: React.FC<ConfirmPasswordFieldProps> = (props)
|
||||
.join(' ')}
|
||||
>
|
||||
<FieldLabel
|
||||
field={null}
|
||||
htmlFor="field-confirm-password"
|
||||
label={t('authentication:confirmPassword')}
|
||||
required
|
||||
/>
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError path={path} />
|
||||
<FieldError field={null} path={path} />
|
||||
{/* disable eslint here because the label is dynamic */}
|
||||
{}
|
||||
<input
|
||||
|
||||
@@ -83,6 +83,7 @@ const DateTimeFieldComponent: React.FC<DateFieldProps> = (props) => {
|
||||
>
|
||||
<FieldLabel
|
||||
Label={field?.admin?.components?.Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
@@ -90,6 +91,7 @@ const DateTimeFieldComponent: React.FC<DateFieldProps> = (props) => {
|
||||
<div className={`${fieldBaseClass}__wrap`} id={`field-${path.replace(/\./g, '__')}`}>
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
/>
|
||||
@@ -108,6 +110,7 @@ const DateTimeFieldComponent: React.FC<DateFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -20,7 +20,6 @@ const EmailFieldComponent: React.FC<EmailFieldProps> = (props) => {
|
||||
autoComplete,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
field,
|
||||
field: {
|
||||
name,
|
||||
_path: pathFromProps,
|
||||
@@ -36,10 +35,12 @@ const EmailFieldComponent: React.FC<EmailFieldProps> = (props) => {
|
||||
label,
|
||||
required,
|
||||
} = {} as EmailFieldProps['field'],
|
||||
field,
|
||||
labelProps,
|
||||
readOnly: readOnlyFromTopLevelProps,
|
||||
validate,
|
||||
} = props
|
||||
|
||||
const readOnlyFromProps = readOnlyFromTopLevelProps || readOnlyFromAdmin
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
@@ -74,6 +75,7 @@ const EmailFieldComponent: React.FC<EmailFieldProps> = (props) => {
|
||||
>
|
||||
<FieldLabel
|
||||
Label={field?.admin?.components?.Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
@@ -81,6 +83,7 @@ const EmailFieldComponent: React.FC<EmailFieldProps> = (props) => {
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
/>
|
||||
@@ -103,6 +106,7 @@ const EmailFieldComponent: React.FC<EmailFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import type { GenericDescriptionProps } from 'payload'
|
||||
import type { FieldDescriptionClientComponent, GenericDescriptionProps } from 'payload'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import React from 'react'
|
||||
@@ -38,7 +38,7 @@ const DefaultFieldDescription: React.FC<GenericDescriptionProps> = (props) => {
|
||||
return null
|
||||
}
|
||||
|
||||
export const FieldDescription: React.FC<GenericDescriptionProps> = (props) => {
|
||||
export const FieldDescription: FieldDescriptionClientComponent = (props) => {
|
||||
const { Description, ...rest } = props
|
||||
|
||||
if (Description) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { GenericErrorProps } from 'payload'
|
||||
import type { FieldErrorClientComponent, GenericErrorProps } from 'payload'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
@@ -42,7 +42,7 @@ const DefaultFieldError: React.FC<GenericErrorProps> = (props) => {
|
||||
return null
|
||||
}
|
||||
|
||||
export const FieldError: React.FC<GenericErrorProps> = (props) => {
|
||||
export const FieldError: FieldErrorClientComponent = (props) => {
|
||||
const { CustomError, ...rest } = props
|
||||
|
||||
if (CustomError) {
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
|
||||
import type { GenericLabelProps } from 'payload'
|
||||
import type { FieldLabelClientComponent, GenericLabelProps } from 'payload'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import React from 'react'
|
||||
@@ -41,7 +41,7 @@ const DefaultFieldLabel: React.FC<GenericLabelProps> = (props) => {
|
||||
return null
|
||||
}
|
||||
|
||||
export const FieldLabel: React.FC<GenericLabelProps> = (props) => {
|
||||
export const FieldLabel: FieldLabelClientComponent = (props) => {
|
||||
const { Label, ...rest } = props
|
||||
|
||||
if (Label) {
|
||||
|
||||
@@ -96,6 +96,7 @@ export const GroupFieldComponent: React.FC<GroupFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</header>
|
||||
|
||||
@@ -128,6 +128,7 @@ const JSONFieldComponent: React.FC<JSONFieldProps> = (props) => {
|
||||
>
|
||||
<FieldLabel
|
||||
Label={field?.admin?.components?.Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
@@ -135,6 +136,7 @@ const JSONFieldComponent: React.FC<JSONFieldProps> = (props) => {
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
/>
|
||||
@@ -152,6 +154,7 @@ const JSONFieldComponent: React.FC<JSONFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -149,6 +149,7 @@ const NumberFieldComponent: React.FC<NumberFieldProps> = (props) => {
|
||||
>
|
||||
<FieldLabel
|
||||
Label={field?.admin?.components?.Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
@@ -156,6 +157,7 @@ const NumberFieldComponent: React.FC<NumberFieldProps> = (props) => {
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
/>
|
||||
@@ -210,6 +212,7 @@ const NumberFieldComponent: React.FC<NumberFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -23,6 +23,7 @@ export const PasswordInput: React.FC<PasswordInputProps> = (props) => {
|
||||
beforeInput,
|
||||
className,
|
||||
errorProps,
|
||||
field,
|
||||
inputRef,
|
||||
label,
|
||||
labelProps,
|
||||
@@ -59,13 +60,14 @@ export const PasswordInput: React.FC<PasswordInputProps> = (props) => {
|
||||
>
|
||||
<FieldLabel
|
||||
Label={Label}
|
||||
field={field}
|
||||
htmlFor={`field-${path.replace(/\./g, '__')}`}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
/>
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError CustomError={Error} path={path} {...(errorProps || {})} />
|
||||
<FieldError CustomError={Error} field={field} path={path} {...(errorProps || {})} />
|
||||
<div>
|
||||
<RenderComponent mappedComponent={beforeInput} />
|
||||
<input
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import type {
|
||||
ErrorProps,
|
||||
FieldBaseClient,
|
||||
FieldDescriptionClientProps,
|
||||
FieldErrorClientProps,
|
||||
FieldLabelClientProps,
|
||||
FormFieldBase,
|
||||
LabelProps,
|
||||
MappedComponent,
|
||||
PasswordFieldValidation,
|
||||
StaticDescription,
|
||||
@@ -14,8 +15,11 @@ import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
export type PasswordFieldProps = {
|
||||
readonly autoComplete?: string
|
||||
readonly descriptionProps?: FieldDescriptionClientProps<MarkOptional<TextFieldClient, 'type'>>
|
||||
readonly errorProps?: FieldErrorClientProps<MarkOptional<TextFieldClient, 'type'>>
|
||||
readonly field: MarkOptional<TextFieldClient, 'type'>
|
||||
readonly inputRef?: React.RefObject<HTMLInputElement>
|
||||
readonly labelProps?: FieldLabelClientProps<MarkOptional<TextFieldClient, 'type'>>
|
||||
readonly validate?: PasswordFieldValidation
|
||||
} & FormFieldBase
|
||||
|
||||
@@ -28,10 +32,11 @@ export type PasswordInputProps = {
|
||||
readonly beforeInput?: MappedComponent[]
|
||||
readonly className?: string
|
||||
readonly description?: StaticDescription
|
||||
readonly errorProps: ErrorProps
|
||||
readonly errorProps: FieldErrorClientProps<MarkOptional<TextFieldClient, 'type'>>
|
||||
readonly field?: MarkOptional<TextFieldClient, 'type'>
|
||||
readonly inputRef?: React.RefObject<HTMLInputElement>
|
||||
readonly label: FieldBaseClient['label']
|
||||
readonly labelProps: LabelProps
|
||||
readonly labelProps: FieldLabelClientProps<MarkOptional<TextFieldClient, 'type'>>
|
||||
readonly onChange?: (e: ChangeEvent<HTMLInputElement>) => void
|
||||
readonly onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>
|
||||
readonly path: string
|
||||
|
||||
@@ -133,11 +133,13 @@ export const PointFieldComponent: React.FC<PointFieldProps> = (props) => {
|
||||
<li>
|
||||
<FieldLabel
|
||||
Label={field?.admin?.components?.Label}
|
||||
field={field}
|
||||
{...getCoordinateFieldLabel('latitude')}
|
||||
/>
|
||||
<div className="input-wrapper">
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
/>
|
||||
@@ -161,6 +163,7 @@ export const PointFieldComponent: React.FC<PointFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -93,12 +93,14 @@ const RadioGroupFieldComponent: React.FC<RadioFieldProps> = (props) => {
|
||||
>
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
alignCaret="left"
|
||||
/>
|
||||
<FieldLabel
|
||||
Label={field?.admin?.components?.Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
@@ -144,6 +146,7 @@ const RadioGroupFieldComponent: React.FC<RadioFieldProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -489,6 +489,7 @@ const RelationshipFieldComponent: React.FC<RelationshipFieldProps> = (props) =>
|
||||
>
|
||||
<FieldLabel
|
||||
Label={field?.admin?.components?.Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
@@ -496,6 +497,7 @@ const RelationshipFieldComponent: React.FC<RelationshipFieldProps> = (props) =>
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError
|
||||
CustomError={field?.admin?.components?.Error}
|
||||
field={field}
|
||||
path={path}
|
||||
{...(errorProps || {})}
|
||||
/>
|
||||
@@ -606,6 +608,7 @@ const RelationshipFieldComponent: React.FC<RelationshipFieldProps> = (props) =>
|
||||
<FieldDescription
|
||||
Description={field?.admin?.components?.Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,12 @@
|
||||
'use client'
|
||||
import type { MappedComponent, OptionObject, StaticDescription, StaticLabel } from 'payload'
|
||||
import type {
|
||||
MappedComponent,
|
||||
OptionObject,
|
||||
SelectFieldClient,
|
||||
StaticDescription,
|
||||
StaticLabel,
|
||||
} from 'payload'
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import React from 'react'
|
||||
@@ -25,6 +32,7 @@ export type SelectInputProps = {
|
||||
readonly description?: StaticDescription
|
||||
readonly descriptionProps?: Record<string, unknown>
|
||||
readonly errorProps?: Record<string, unknown>
|
||||
readonly field?: MarkOptional<SelectFieldClient, 'type'>
|
||||
readonly hasMany?: boolean
|
||||
readonly isClearable?: boolean
|
||||
readonly isSortable?: boolean
|
||||
@@ -53,6 +61,7 @@ export const SelectInput: React.FC<SelectInputProps> = (props) => {
|
||||
description,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
field,
|
||||
hasMany = false,
|
||||
isClearable = true,
|
||||
isSortable = true,
|
||||
@@ -106,9 +115,15 @@ export const SelectInput: React.FC<SelectInputProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<FieldLabel Label={Label} label={label} required={required} {...(labelProps || {})} />
|
||||
<FieldLabel
|
||||
Label={Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
/>
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError CustomError={Error} path={path} {...(errorProps || {})} />
|
||||
<FieldError CustomError={Error} field={field} path={path} {...(errorProps || {})} />
|
||||
<RenderComponent mappedComponent={beforeInput} />
|
||||
<ReactSelect
|
||||
disabled={readOnly}
|
||||
@@ -128,6 +143,7 @@ export const SelectInput: React.FC<SelectInputProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -101,6 +101,7 @@ const SelectFieldComponent: React.FC<SelectFieldProps> = (props) => {
|
||||
beforeInput={field?.admin?.components?.beforeInput}
|
||||
className={className}
|
||||
description={description}
|
||||
field={field}
|
||||
hasMany={hasMany}
|
||||
isClearable={isClearable}
|
||||
isSortable={isSortable}
|
||||
|
||||
@@ -154,7 +154,7 @@ const TabsFieldComponent: React.FC<TabsFieldProps> = (props) => {
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
>
|
||||
<FieldDescription Description={field?.admin?.components?.Description} />
|
||||
<FieldDescription Description={field?.admin?.components?.Description} field={field} />
|
||||
<RenderFields
|
||||
fields={activeTabConfig.fields}
|
||||
forceRender={forceRender}
|
||||
|
||||
@@ -26,6 +26,7 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
|
||||
description,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
field,
|
||||
hasMany,
|
||||
inputRef,
|
||||
label,
|
||||
@@ -64,9 +65,15 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<FieldLabel Label={Label} label={label} required={required} {...(labelProps || {})} />
|
||||
<FieldLabel
|
||||
Label={Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
/>
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError CustomError={Error} path={path} {...(errorProps || {})} />
|
||||
<FieldError CustomError={Error} field={field} path={path} {...(errorProps || {})} />
|
||||
<RenderComponent mappedComponent={beforeInput} />
|
||||
{hasMany ? (
|
||||
<ReactSelect
|
||||
@@ -111,6 +118,7 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -127,6 +127,7 @@ const TextFieldComponent: React.FC<TextFieldProps> = (props) => {
|
||||
beforeInput={field?.admin?.components?.beforeInput}
|
||||
className={className}
|
||||
description={description}
|
||||
field={field}
|
||||
hasMany={hasMany}
|
||||
inputRef={inputRef}
|
||||
label={label}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import type { MappedComponent, StaticDescription, StaticLabel } from 'payload'
|
||||
import type { MappedComponent, StaticDescription, StaticLabel, TextFieldClient } from 'payload'
|
||||
import type { ChangeEvent } from 'react'
|
||||
import type React from 'react'
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import type { Option, ReactSelectAdapterProps } from '../../elements/ReactSelect/types.js'
|
||||
|
||||
@@ -24,6 +25,7 @@ export type TextInputProps = {
|
||||
readonly description?: StaticDescription
|
||||
readonly descriptionProps?: Record<string, unknown>
|
||||
readonly errorProps?: Record<string, unknown>
|
||||
readonly field?: MarkOptional<TextFieldClient, 'type'>
|
||||
readonly inputRef?: React.RefObject<HTMLInputElement>
|
||||
readonly label: StaticLabel
|
||||
readonly labelProps?: Record<string, unknown>
|
||||
|
||||
@@ -23,6 +23,7 @@ export const TextareaInput: React.FC<TextAreaInputProps> = (props) => {
|
||||
description,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
field,
|
||||
label,
|
||||
labelProps,
|
||||
onChange,
|
||||
@@ -56,9 +57,15 @@ export const TextareaInput: React.FC<TextAreaInputProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<FieldLabel Label={Label} label={label} required={required} {...(labelProps || {})} />
|
||||
<FieldLabel
|
||||
Label={Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
/>
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError CustomError={Error} path={path} {...(errorProps || {})} />
|
||||
<FieldError CustomError={Error} field={field} path={path} {...(errorProps || {})} />
|
||||
<RenderComponent mappedComponent={beforeInput} />
|
||||
<label className="textarea-outer" htmlFor={`field-${path.replace(/\./g, '__')}`}>
|
||||
<div className="textarea-inner">
|
||||
@@ -80,6 +87,7 @@ export const TextareaInput: React.FC<TextAreaInputProps> = (props) => {
|
||||
<FieldDescription
|
||||
Description={Description}
|
||||
description={description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -19,6 +19,8 @@ export { TextAreaInputProps, TextareaInput }
|
||||
|
||||
const TextareaFieldComponent: React.FC<TextareaFieldProps> = (props) => {
|
||||
const {
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
field,
|
||||
field: {
|
||||
name,
|
||||
@@ -39,10 +41,12 @@ const TextareaFieldComponent: React.FC<TextareaFieldProps> = (props) => {
|
||||
minLength,
|
||||
required,
|
||||
},
|
||||
labelProps,
|
||||
locale,
|
||||
readOnly: readOnlyFromTopLevelProps,
|
||||
validate,
|
||||
} = props
|
||||
|
||||
const readOnlyFromProps = readOnlyFromTopLevelProps || readOnlyFromAdmin
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
@@ -84,7 +88,10 @@ const TextareaFieldComponent: React.FC<TextareaFieldProps> = (props) => {
|
||||
beforeInput={field?.admin?.components?.beforeInput}
|
||||
className={className}
|
||||
description={description}
|
||||
descriptionProps={descriptionProps}
|
||||
errorProps={errorProps}
|
||||
label={label}
|
||||
labelProps={labelProps}
|
||||
onChange={(e) => {
|
||||
setValue(e.target.value)
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
import type { MappedComponent, StaticDescription, StaticLabel } from 'payload'
|
||||
import type {
|
||||
FieldDescriptionClientProps,
|
||||
FieldErrorClientProps,
|
||||
FieldLabelClientProps,
|
||||
MappedComponent,
|
||||
StaticDescription,
|
||||
StaticLabel,
|
||||
TextareaFieldClient,
|
||||
} from 'payload'
|
||||
import type React from 'react'
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import { type ChangeEvent } from 'react'
|
||||
|
||||
@@ -11,11 +20,12 @@ export type TextAreaInputProps = {
|
||||
readonly beforeInput?: MappedComponent[]
|
||||
readonly className?: string
|
||||
readonly description?: StaticDescription
|
||||
readonly descriptionProps?: Record<string, unknown>
|
||||
readonly errorProps?: Record<string, unknown>
|
||||
readonly descriptionProps?: FieldDescriptionClientProps<MarkOptional<TextareaFieldClient, 'type'>>
|
||||
readonly errorProps?: FieldErrorClientProps<MarkOptional<TextareaFieldClient, 'type'>>
|
||||
readonly field?: MarkOptional<TextareaFieldClient, 'type'>
|
||||
readonly inputRef?: React.RefObject<HTMLInputElement>
|
||||
readonly label: StaticLabel
|
||||
readonly labelProps?: Record<string, unknown>
|
||||
readonly labelProps?: FieldLabelClientProps<MarkOptional<TextareaFieldClient, 'type'>>
|
||||
readonly onChange?: (e: ChangeEvent<HTMLTextAreaElement>) => void
|
||||
readonly onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>
|
||||
readonly path: string
|
||||
|
||||
@@ -2,12 +2,17 @@
|
||||
|
||||
import type {
|
||||
ClientCollectionConfig,
|
||||
FieldDescriptionClientProps,
|
||||
FieldErrorClientProps,
|
||||
FieldLabelClientProps,
|
||||
FilterOptionsResult,
|
||||
MappedComponent,
|
||||
StaticDescription,
|
||||
StaticLabel,
|
||||
UploadField,
|
||||
UploadFieldClient,
|
||||
} from 'payload'
|
||||
import type { MarkOptional } from 'ts-essentials'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
@@ -41,11 +46,12 @@ export type UploadInputProps = {
|
||||
readonly collection?: ClientCollectionConfig
|
||||
readonly customUploadActions?: React.ReactNode[]
|
||||
readonly description?: StaticDescription
|
||||
readonly descriptionProps?: Record<string, unknown>
|
||||
readonly errorProps?: Record<string, unknown>
|
||||
readonly descriptionProps?: FieldDescriptionClientProps<MarkOptional<UploadFieldClient, 'type'>>
|
||||
readonly errorProps?: FieldErrorClientProps<MarkOptional<UploadFieldClient, 'type'>>
|
||||
readonly field?: MarkOptional<UploadFieldClient, 'type'>
|
||||
readonly filterOptions?: FilterOptionsResult
|
||||
readonly label: StaticLabel
|
||||
readonly labelProps?: Record<string, unknown>
|
||||
readonly labelProps?: FieldLabelClientProps<MarkOptional<UploadFieldClient, 'type'>>
|
||||
readonly onChange?: (e) => void
|
||||
readonly readOnly?: boolean
|
||||
readonly relationTo?: UploadField['relationTo']
|
||||
@@ -69,6 +75,7 @@ export const UploadInput: React.FC<UploadInputProps> = (props) => {
|
||||
customUploadActions,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
field,
|
||||
filterOptions,
|
||||
label,
|
||||
labelProps,
|
||||
@@ -159,10 +166,15 @@ export const UploadInput: React.FC<UploadInputProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<FieldLabel Label={Label} label={label} required={required} {...(labelProps || {})} />
|
||||
<FieldLabel
|
||||
Label={Label}
|
||||
field={field}
|
||||
label={label}
|
||||
required={required}
|
||||
{...(labelProps || {})}
|
||||
/>
|
||||
<div className={`${fieldBaseClass}__wrap`}>
|
||||
<FieldError CustomError={Error} {...(errorProps || {})} />
|
||||
|
||||
<FieldError CustomError={Error} field={field} {...(errorProps || {})} />
|
||||
{collection?.upload && (
|
||||
<React.Fragment>
|
||||
{fileDoc && !missingFile && (
|
||||
@@ -203,7 +215,11 @@ export const UploadInput: React.FC<UploadInputProps> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<FieldDescription Description={Description} {...(descriptionProps || {})} />
|
||||
<FieldDescription
|
||||
Description={Description}
|
||||
field={field}
|
||||
{...(descriptionProps || {})}
|
||||
/>
|
||||
</React.Fragment>
|
||||
)}
|
||||
{!readOnly && <DocumentDrawer onSave={onSave} />}
|
||||
|
||||
@@ -19,6 +19,8 @@ export type { UploadInputProps }
|
||||
|
||||
const UploadComponent: React.FC<UploadFieldProps> = (props) => {
|
||||
const {
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
field,
|
||||
field: {
|
||||
_path: pathFromProps,
|
||||
@@ -27,9 +29,11 @@ const UploadComponent: React.FC<UploadFieldProps> = (props) => {
|
||||
relationTo,
|
||||
required,
|
||||
},
|
||||
labelProps,
|
||||
readOnly: readOnlyFromTopLevelProps,
|
||||
validate,
|
||||
} = props
|
||||
|
||||
const readOnlyFromProps = readOnlyFromTopLevelProps || readOnlyFromAdmin
|
||||
|
||||
const {
|
||||
@@ -92,8 +96,11 @@ const UploadComponent: React.FC<UploadFieldProps> = (props) => {
|
||||
api={apiRoute}
|
||||
className={className}
|
||||
collection={collection}
|
||||
descriptionProps={descriptionProps}
|
||||
errorProps={errorProps}
|
||||
filterOptions={filterOptions}
|
||||
label={label}
|
||||
labelProps={labelProps}
|
||||
onChange={onChange}
|
||||
readOnly={disabled}
|
||||
relationTo={relationTo}
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
import type { I18nClient } from '@payloadcms/translations'
|
||||
import type { LabelProps, MappedComponent } from 'payload'
|
||||
import type { MappedComponent, StaticLabel } from 'payload'
|
||||
|
||||
export type RowLabelProps = {
|
||||
readonly RowLabel?: MappedComponent
|
||||
readonly className?: string
|
||||
readonly i18n: I18nClient
|
||||
readonly path: string
|
||||
readonly rowLabel?: LabelProps['label']
|
||||
readonly rowLabel?: StaticLabel
|
||||
readonly rowNumber?: number
|
||||
}
|
||||
|
||||
@@ -210,6 +210,7 @@ export const createClientCollectionConfig = ({
|
||||
}
|
||||
|
||||
let description = undefined
|
||||
|
||||
if (collection.admin?.description) {
|
||||
if (
|
||||
typeof collection.admin?.description === 'string' ||
|
||||
@@ -220,13 +221,16 @@ export const createClientCollectionConfig = ({
|
||||
description = collection.admin?.description({ t: i18n.t })
|
||||
}
|
||||
}
|
||||
|
||||
clientCollection.admin.description = description
|
||||
|
||||
if (collection.admin.components.edit?.Description) {
|
||||
clientCollection.admin.components.edit.Description = createMappedComponent(
|
||||
collection.admin.components.edit.Description,
|
||||
{
|
||||
description,
|
||||
clientProps: {
|
||||
description,
|
||||
},
|
||||
},
|
||||
undefined,
|
||||
'collection.admin.components.edit.Description',
|
||||
@@ -261,7 +265,9 @@ export const createClientCollectionConfig = ({
|
||||
? collection.admin.components.views.edit.default.Component
|
||||
: null,
|
||||
{
|
||||
collectionSlug: collection.slug,
|
||||
clientProps: {
|
||||
collectionSlug: collection.slug,
|
||||
},
|
||||
},
|
||||
DefaultEditView,
|
||||
'collection.admin.components.views.edit.default',
|
||||
@@ -280,7 +286,9 @@ export const createClientCollectionConfig = ({
|
||||
clientCollection.admin.components.views.edit[key].Component = createMappedComponent(
|
||||
view.Component,
|
||||
{
|
||||
collectionSlug: collection.slug,
|
||||
clientProps: {
|
||||
collectionSlug: collection.slug,
|
||||
},
|
||||
},
|
||||
undefined,
|
||||
'collection.admin.components.views.edit.key.Component',
|
||||
@@ -318,7 +326,9 @@ export const createClientCollectionConfig = ({
|
||||
? collection.admin.components.views.list.Component
|
||||
: null,
|
||||
{
|
||||
collectionSlug: collection.slug,
|
||||
clientProps: {
|
||||
collectionSlug: collection.slug,
|
||||
},
|
||||
},
|
||||
DefaultListView,
|
||||
'collection.admin.components.views.list',
|
||||
|
||||
@@ -7,8 +7,9 @@ import type {
|
||||
ClientField,
|
||||
CreateMappedComponent,
|
||||
Field,
|
||||
FieldLabelClientComponent,
|
||||
FieldLabelServerComponent,
|
||||
ImportMap,
|
||||
LabelComponent,
|
||||
LabelsClient,
|
||||
MappedComponent,
|
||||
Payload,
|
||||
@@ -106,12 +107,14 @@ export const createClientField = ({
|
||||
clientField.label = incomingField.label({ t: i18n.t })
|
||||
}
|
||||
|
||||
const CustomLabel: LabelComponent | RowLabelComponent =
|
||||
const CustomLabel: FieldLabelClientComponent | FieldLabelServerComponent | RowLabelComponent =
|
||||
'admin' in incomingField &&
|
||||
'components' in incomingField.admin &&
|
||||
'Label' in incomingField.admin.components &&
|
||||
incomingField.admin.components.Label
|
||||
|
||||
const serverProps = { serverProps: { field: incomingField } }
|
||||
|
||||
switch (incomingField.type) {
|
||||
case 'array':
|
||||
case 'group':
|
||||
@@ -133,7 +136,7 @@ export const createClientField = ({
|
||||
if (incomingField?.admin?.components && 'RowLabel' in incomingField.admin.components) {
|
||||
;(field as unknown as ArrayFieldClient).admin.components.RowLabel = createMappedComponent(
|
||||
incomingField.admin.components.RowLabel,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.admin.components.RowLabel',
|
||||
)
|
||||
@@ -178,7 +181,7 @@ export const createClientField = ({
|
||||
if (block.admin?.components?.Label) {
|
||||
clientBlock.admin.components.Label = createMappedComponent(
|
||||
block.admin.components.Label,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'block.admin.components.Label',
|
||||
)
|
||||
@@ -202,36 +205,40 @@ export const createClientField = ({
|
||||
}
|
||||
|
||||
case 'richText': {
|
||||
const field = clientField as RichTextFieldClient
|
||||
const field = clientField
|
||||
|
||||
if (!incomingField?.editor) {
|
||||
throw new MissingEditorProp(incomingField) // while we allow disabling editor functionality, you should not have any richText fields defined if you do not have an editor
|
||||
}
|
||||
|
||||
if (typeof incomingField?.editor === 'function') {
|
||||
throw new Error('Attempted to access unsanitized rich text editor.')
|
||||
}
|
||||
|
||||
if (!field.admin) {
|
||||
field.admin = {}
|
||||
}
|
||||
|
||||
if (!field.admin.components) {
|
||||
field.admin.components = {}
|
||||
}
|
||||
|
||||
field.admin.components.Field = createMappedComponent(
|
||||
incomingField.editor.FieldComponent,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.editor.FieldComponent',
|
||||
)
|
||||
|
||||
field.admin.components.Cell = createMappedComponent(
|
||||
incomingField.editor.CellComponent,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.editor.CellComponent',
|
||||
)
|
||||
|
||||
if (incomingField.editor.generateComponentMap) {
|
||||
const { Component: generateComponentMap, serverProps } = getComponent({
|
||||
const { Component: generateComponentMap, serverProps: richTextServerProps } = getComponent({
|
||||
identifier: 'richText-generateComponentMap',
|
||||
importMap,
|
||||
payloadComponent: incomingField.editor.generateComponentMap,
|
||||
@@ -241,10 +248,10 @@ export const createClientField = ({
|
||||
if (generateComponentMap) {
|
||||
const actualGenerateComponentMap: RichTextGenerateComponentMap = (
|
||||
generateComponentMap as any
|
||||
)(serverProps)
|
||||
)(richTextServerProps)
|
||||
|
||||
const result = actualGenerateComponentMap({
|
||||
clientField: field,
|
||||
clientField: field as RichTextFieldClient,
|
||||
createMappedComponent,
|
||||
field: incomingField,
|
||||
i18n,
|
||||
@@ -253,7 +260,7 @@ export const createClientField = ({
|
||||
schemaPath: field._schemaPath,
|
||||
})
|
||||
|
||||
field.richTextComponentMap = result
|
||||
;(field as RichTextFieldClient).richTextComponentMap = result
|
||||
}
|
||||
}
|
||||
break
|
||||
@@ -349,7 +356,7 @@ export const createClientField = ({
|
||||
if (incomingField?.admin?.components?.Cell !== undefined) {
|
||||
clientField.admin.components.Cell = createMappedComponent(
|
||||
incomingField.admin.components.Cell,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.admin.components.Cell',
|
||||
)
|
||||
@@ -367,7 +374,7 @@ export const createClientField = ({
|
||||
;(clientField as FieldWithDescriptionComponent).admin.components.Description =
|
||||
createMappedComponent(
|
||||
incomingField.admin.components.Description,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.admin.components.Description',
|
||||
)
|
||||
@@ -387,7 +394,7 @@ export const createClientField = ({
|
||||
) {
|
||||
;(clientField as FieldWithErrorComponent).admin.components.Error = createMappedComponent(
|
||||
incomingField.admin.components.Error,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.admin.components.Error',
|
||||
)
|
||||
@@ -396,7 +403,7 @@ export const createClientField = ({
|
||||
if (incomingField?.admin?.components?.Field !== undefined) {
|
||||
clientField.admin.components.Field = createMappedComponent(
|
||||
incomingField.admin.components.Field,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.admin.components.Field',
|
||||
)
|
||||
@@ -409,7 +416,7 @@ export const createClientField = ({
|
||||
) {
|
||||
clientField.admin.components.Filter = createMappedComponent(
|
||||
incomingField.admin.components.Filter,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.admin.components.Filter',
|
||||
)
|
||||
@@ -429,7 +436,7 @@ export const createClientField = ({
|
||||
) {
|
||||
;(clientField as FieldWithLabelComponent).admin.components.Label = createMappedComponent(
|
||||
CustomLabel,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.admin.components.Label',
|
||||
)
|
||||
@@ -450,7 +457,7 @@ export const createClientField = ({
|
||||
;(clientField as FieldWithBeforeInputComponent).admin.components.beforeInput =
|
||||
createMappedComponent(
|
||||
incomingField.admin?.components?.beforeInput,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.admin.components.beforeInput',
|
||||
)
|
||||
@@ -471,7 +478,7 @@ export const createClientField = ({
|
||||
;(clientField as FieldWithAfterInputComponent).admin.components.afterInput =
|
||||
createMappedComponent(
|
||||
incomingField.admin?.components?.afterInput,
|
||||
undefined,
|
||||
serverProps,
|
||||
undefined,
|
||||
'incomingField.admin.components.afterInput',
|
||||
)
|
||||
@@ -512,10 +519,12 @@ export const createClientFields = ({
|
||||
parentPath,
|
||||
payload,
|
||||
})
|
||||
|
||||
if (newField) {
|
||||
newClientFields.push({ ...newField })
|
||||
}
|
||||
}
|
||||
|
||||
const hasID = newClientFields.findIndex((f) => fieldAffectsData(f) && f.name === 'id') > -1
|
||||
|
||||
if (!disableAddingID && !hasID) {
|
||||
|
||||
@@ -27,10 +27,15 @@ export function getCreateMappedComponent({
|
||||
const createSingleMappedComponent = (
|
||||
payloadComponent: { ReactComponent: React.FC<any> } | PayloadComponent,
|
||||
key: number | string,
|
||||
props: JsonObject,
|
||||
props: {
|
||||
clientProps: JsonObject
|
||||
serverProps: object
|
||||
},
|
||||
Fallback: React.FC<any>,
|
||||
identifier: string,
|
||||
): MappedComponent => {
|
||||
const { clientProps, serverProps: componentServerProps } = props || {}
|
||||
|
||||
if (payloadComponent === undefined || payloadComponent === null) {
|
||||
if (!Fallback) {
|
||||
return undefined
|
||||
@@ -40,7 +45,9 @@ export function getCreateMappedComponent({
|
||||
return {
|
||||
type: 'server',
|
||||
Component: null,
|
||||
RenderedComponent: <Fallback key={key} {...serverProps} {...props} />,
|
||||
RenderedComponent: (
|
||||
<Fallback key={key} {...serverProps} {...componentServerProps} {...clientProps} />
|
||||
),
|
||||
}
|
||||
} else {
|
||||
const toReturn: MappedComponent = {
|
||||
@@ -49,7 +56,7 @@ export function getCreateMappedComponent({
|
||||
}
|
||||
|
||||
// conditionally set props here to avoid bloating the HTML with `$undefined` props
|
||||
if (props) toReturn.props = props
|
||||
if (clientProps) toReturn.props = clientProps
|
||||
|
||||
return toReturn
|
||||
}
|
||||
@@ -88,7 +95,13 @@ export function getCreateMappedComponent({
|
||||
type: 'server',
|
||||
Component: null,
|
||||
RenderedComponent: (
|
||||
<Component key={key} {...serverProps} {...resolvedComponent.serverProps} {...props} />
|
||||
<Component
|
||||
key={key}
|
||||
{...serverProps}
|
||||
{...resolvedComponent.serverProps}
|
||||
{...componentServerProps}
|
||||
{...clientProps}
|
||||
/>
|
||||
),
|
||||
}
|
||||
} else {
|
||||
@@ -101,7 +114,7 @@ export function getCreateMappedComponent({
|
||||
Component: resolvedComponent.Component,
|
||||
props: {
|
||||
...(resolvedComponent.clientProps || {}),
|
||||
...props,
|
||||
...clientProps,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
@@ -142,7 +142,9 @@ export const createClientGlobalConfig = ({
|
||||
? global.admin.components.views.edit.default.Component
|
||||
: null,
|
||||
{
|
||||
globalSlug: global.slug,
|
||||
clientProps: {
|
||||
globalSlug: global.slug,
|
||||
},
|
||||
},
|
||||
DefaultEditView,
|
||||
'global.admin.components.views.edit.default',
|
||||
@@ -160,7 +162,9 @@ export const createClientGlobalConfig = ({
|
||||
clientGlobal.admin.components.views.edit[key].Component = createMappedComponent(
|
||||
view.Component,
|
||||
{
|
||||
globalSlug: global.slug,
|
||||
clientProps: {
|
||||
globalSlug: global.slug,
|
||||
},
|
||||
},
|
||||
undefined,
|
||||
'global.admin.components.views.edit.key.Component',
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
'use client'
|
||||
import type { DescriptionComponent, PayloadClientReactComponent } from 'payload'
|
||||
import type { FieldDescriptionClientComponent } from 'payload'
|
||||
|
||||
import { useFieldProps, useFormFields } from '@payloadcms/ui'
|
||||
import React from 'react'
|
||||
|
||||
export const FieldDescriptionComponent: PayloadClientReactComponent<
|
||||
DescriptionComponent<'text'>
|
||||
> = () => {
|
||||
export const FieldDescriptionComponent: FieldDescriptionClientComponent = () => {
|
||||
const { path } = useFieldProps()
|
||||
const field = useFormFields(([fields]) => (fields && fields?.[path]) || null)
|
||||
const { value } = field || {}
|
||||
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { TextFieldDescriptionComponent } from 'payload'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
export const CustomDescription: TextFieldDescriptionComponent = (props) => {
|
||||
return (
|
||||
<div id="custom-field-description">{`Description: the max length of this field is: ${props?.maxLength}`}</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
'use client'
|
||||
import type { TextFieldDescriptionClientComponent } from 'payload'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
export const CustomClientDescription: TextFieldDescriptionClientComponent = (props) => {
|
||||
return (
|
||||
<div id="custom-client-field-description">{`Description: the max length of this field is: ${props?.field?.maxLength}`}</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { TextFieldDescriptionServerComponent } from 'payload'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
export const CustomServerDescription: TextFieldDescriptionServerComponent = (props) => {
|
||||
return (
|
||||
<div id="custom-server-field-description">{`Description: the max length of this field is: ${props?.field?.maxLength}`}</div>
|
||||
)
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
import type { TextFieldLabelComponent } from 'payload'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
export const CustomLabel: TextFieldLabelComponent = (props) => {
|
||||
return (
|
||||
<div id="custom-field-label">{`Label: the max length of this field is: ${props?.maxLength}`}</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
'use client'
|
||||
import type { TextFieldLabelClientComponent } from 'payload'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
export const CustomClientLabel: TextFieldLabelClientComponent = (props) => {
|
||||
return (
|
||||
<div id="custom-client-field-label">{`Label: the max length of this field is: ${props?.field?.maxLength}`}</div>
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
import type { TextFieldLabelServerComponent } from 'payload'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
export const CustomServerLabel: TextFieldLabelServerComponent = (props) => {
|
||||
return (
|
||||
<div id="custom-server-field-label">{`Label: the max length of this field is: ${props?.field?.maxLength}`}</div>
|
||||
)
|
||||
}
|
||||
@@ -6,7 +6,7 @@ export const CustomFields: CollectionConfig = {
|
||||
slug: customFieldsSlug,
|
||||
fields: [
|
||||
{
|
||||
name: 'customTextField',
|
||||
name: 'customTextServerField',
|
||||
type: 'text',
|
||||
maxLength: 100,
|
||||
admin: {
|
||||
@@ -14,8 +14,26 @@ export const CustomFields: CollectionConfig = {
|
||||
components: {
|
||||
afterInput: ['/collections/CustomFields/AfterInput.js#AfterInput'],
|
||||
beforeInput: ['/collections/CustomFields/BeforeInput.js#BeforeInput'],
|
||||
Label: '/collections/CustomFields/fields/Text/Label.js#CustomLabel',
|
||||
Description: '/collections/CustomFields/fields/Text/Description.js#CustomDescription',
|
||||
Label: '/collections/CustomFields/fields/Text/LabelServer.js#CustomServerLabel',
|
||||
Description:
|
||||
'/collections/CustomFields/fields/Text/DescriptionServer.js#CustomServerDescription',
|
||||
Error: '/collections/CustomFields/CustomError.js#CustomError',
|
||||
},
|
||||
},
|
||||
minLength: 3,
|
||||
},
|
||||
{
|
||||
name: 'customTextClientField',
|
||||
type: 'text',
|
||||
maxLength: 100,
|
||||
admin: {
|
||||
placeholder: 'This is a placeholder',
|
||||
components: {
|
||||
afterInput: ['/collections/CustomFields/AfterInput.js#AfterInput'],
|
||||
beforeInput: ['/collections/CustomFields/BeforeInput.js#BeforeInput'],
|
||||
Label: '/collections/CustomFields/fields/Text/LabelClient.js#CustomClientLabel',
|
||||
Description:
|
||||
'/collections/CustomFields/fields/Text/DescriptionClient.js#CustomClientDescription',
|
||||
Error: '/collections/CustomFields/CustomError.js#CustomError',
|
||||
},
|
||||
},
|
||||
|
||||
@@ -555,25 +555,47 @@ describe('admin1', () => {
|
||||
test('renders custom label component', async () => {
|
||||
await page.goto(customFieldsURL.create)
|
||||
await page.waitForURL(customFieldsURL.create)
|
||||
await expect(page.locator('#custom-field-label')).toBeVisible()
|
||||
await expect(page.locator('#custom-client-field-label')).toBeVisible()
|
||||
await expect(page.locator('#custom-server-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()
|
||||
await expect(page.locator('#custom-client-field-description')).toBeVisible()
|
||||
await expect(page.locator('#custom-server-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',
|
||||
// )
|
||||
// })
|
||||
test('custom server components should receive field props', async () => {
|
||||
await page.goto(customFieldsURL.create)
|
||||
await page.waitForURL(customFieldsURL.create)
|
||||
await expect(
|
||||
page.locator('#custom-server-field-label', {
|
||||
hasText: exactText('Label: the max length of this field is: 100'),
|
||||
}),
|
||||
).toBeVisible()
|
||||
|
||||
await expect(
|
||||
page.locator('#custom-server-field-description', {
|
||||
hasText: exactText('Description: the max length of this field is: 100'),
|
||||
}),
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
test('custom client components should receive field props', async () => {
|
||||
await page.goto(customFieldsURL.create)
|
||||
await page.waitForURL(customFieldsURL.create)
|
||||
await expect(
|
||||
page.locator('#custom-client-field-label', {
|
||||
hasText: exactText('Label: the max length of this field is: 100'),
|
||||
}),
|
||||
).toBeVisible()
|
||||
await expect(
|
||||
page.locator('#custom-client-field-description', {
|
||||
hasText: exactText('Description: the max length of this field is: 100'),
|
||||
}),
|
||||
).toBeVisible()
|
||||
})
|
||||
|
||||
describe('field descriptions', () => {
|
||||
test('should render static field description', async () => {
|
||||
@@ -606,10 +628,10 @@ describe('admin1', () => {
|
||||
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"]')
|
||||
const input = page.locator('input[id="field-customTextClientField"]')
|
||||
await input.fill('ab')
|
||||
await expect(input).toHaveValue('ab')
|
||||
const error = page.locator('.custom-error:near(input[id="field-customTextField"])')
|
||||
const error = page.locator('.custom-error:near(input[id="field-customTextClientField"])')
|
||||
const submit = page.locator('button[type="button"][id="action-save"]')
|
||||
await submit.click()
|
||||
await expect(error).toHaveText('#custom-error')
|
||||
@@ -617,17 +639,19 @@ describe('admin1', () => {
|
||||
|
||||
test('should render beforeInput and afterInput', async () => {
|
||||
await page.goto(customFieldsURL.create)
|
||||
const input = page.locator('input[id="field-customTextField"]')
|
||||
const input = page.locator('input[id="field-customTextClientField"]')
|
||||
|
||||
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')
|
||||
})
|
||||
|
||||
@@ -172,7 +172,8 @@ export interface CustomViewsTwo {
|
||||
*/
|
||||
export interface CustomField {
|
||||
id: string;
|
||||
customTextField?: string | null;
|
||||
customTextServerField?: string | null;
|
||||
customTextClientField?: string | null;
|
||||
descriptionAsString?: string | null;
|
||||
descriptionAsFunction?: string | null;
|
||||
descriptionAsComponent?: string | null;
|
||||
|
||||
Reference in New Issue
Block a user