diff --git a/docs/admin/components.mdx b/docs/admin/components.mdx index a1f44664c..bfa5866cc 100644 --- a/docs/admin/components.mdx +++ b/docs/admin/components.mdx @@ -432,14 +432,14 @@ All Payload fields support the ability to swap in your own React components. So, | **`Cell`** | Used in the `List` view's table to represent a table-based preview of the data stored in the field. [More](#cell-component) | | **`Field`** | Swap out the field itself within all `Edit` views. [More](#field-component) | -As an alternative to replacing the entire Field component, you may want to keep the majority of the default Field component and only swap components within. This allows you to replace the **`Label`** or **`Error`** within a field component or add additional components inside the field with **`BeforeInput`** or **`AfterInput`**. **`BeforeInput`** and **`AfterInput`** are allowed in any fields that don't contain other fields, except [UI](/docs/fields/ui) and [Rich Text](/docs/fields/rich-text). +As an alternative to replacing the entire Field component, you may want to keep the majority of the default Field component and only swap components within. This allows you to replace the **`Label`** or **`Error`** within a field component or add additional components inside the field with **`beforeInput`** or **`afterInput`**. **`beforeInput`** and **`afterInput`** are allowed in any fields that don't contain other fields, except [UI](/docs/fields/ui) and [Rich Text](/docs/fields/rich-text). | Component | Description | | ----------------- | --------------------------------------------------------------------------------------------------------------- | | **`Label`** | Override the default Label in the Field Component. [More](#label-component) | | **`Error`** | Override the default Label in the Field Component. [More](#error-component) | -| **`BeforeInput`** | An array of elements that will be added before `input`/`textarea` elements. [More](#afterinput-and-beforeinput) | -| **`AfterInput`** | An array of elements that will be added after `input`/`textarea` elements. [More](#afterinput-and-beforeinput) | +| **`beforeInput`** | An array of elements that will be added before `input`/`textarea` elements. [More](#afterinput-and-beforeinput) | +| **`afterInput`** | An array of elements that will be added after `input`/`textarea` elements. [More](#afterinput-and-beforeinput) | ## Cell Component @@ -530,7 +530,7 @@ const CustomLabel: React.FC = (props) => { {getTranslation(label, i18n)} {required && *} ); - } + } return null } @@ -564,7 +564,7 @@ const CustomError: React.FC = (props) => { } ``` -## AfterInput and BeforeInput +## afterInput and beforeInput With these properties you can add multiple components before and after the input element. For example, you can add an absolutely positioned button to clear the current field value. @@ -583,9 +583,7 @@ const fieldField: Field = { type: 'text', admin: { components: { - AfterInput: [ - - ] + afterInput: [ClearButton] } } } diff --git a/packages/payload/src/admin/components/forms/field-types/Checkbox/Input.tsx b/packages/payload/src/admin/components/forms/field-types/Checkbox/Input.tsx index d4cc638d4..4cbb79791 100644 --- a/packages/payload/src/admin/components/forms/field-types/Checkbox/Input.tsx +++ b/packages/payload/src/admin/components/forms/field-types/Checkbox/Input.tsx @@ -10,10 +10,10 @@ import './index.scss' const baseClass = 'checkbox-input' type CheckboxInputProps = { - AfterInput?: React.ReactElement[] - BeforeInput?: React.ReactElement[] Label?: React.ComponentType + afterInput?: React.ComponentType[] 'aria-label'?: string + beforeInput?: React.ComponentType[] checked?: boolean className?: string id?: string @@ -30,10 +30,10 @@ export const CheckboxInput: React.FC = (props) => { const { id, name, - AfterInput, - BeforeInput, Label, + afterInput, 'aria-label': ariaLabel, + beforeInput, checked, className, inputRef, @@ -58,7 +58,7 @@ export const CheckboxInput: React.FC = (props) => { .join(' ')} >
- {BeforeInput} + {Array.isArray(beforeInput) && beforeInput.map((Component, i) => )} = (props) => { ref={inputRef} type="checkbox" /> - {AfterInput} + {Array.isArray(afterInput) && afterInput.map((Component, i) => )} {!partialChecked && } {partialChecked && } diff --git a/packages/payload/src/admin/components/forms/field-types/Checkbox/index.tsx b/packages/payload/src/admin/components/forms/field-types/Checkbox/index.tsx index 9b3507d2f..4addc0fb0 100644 --- a/packages/payload/src/admin/components/forms/field-types/Checkbox/index.tsx +++ b/packages/payload/src/admin/components/forms/field-types/Checkbox/index.tsx @@ -20,12 +20,12 @@ const Checkbox: React.FC = (props) => { name, admin: { className, + components: { Error, Label, afterInput, beforeInput } = {}, condition, description, readOnly, style, width, - components: { Error, Label, BeforeInput, AfterInput } = {}, } = {}, disableFormData, label, @@ -85,15 +85,15 @@ const Checkbox: React.FC = (props) => {
diff --git a/packages/payload/src/admin/components/forms/field-types/Code/index.tsx b/packages/payload/src/admin/components/forms/field-types/Code/index.tsx index 9dbef2c80..732000d9b 100644 --- a/packages/payload/src/admin/components/forms/field-types/Code/index.tsx +++ b/packages/payload/src/admin/components/forms/field-types/Code/index.tsx @@ -9,8 +9,8 @@ import FieldDescription from '../../FieldDescription' import DefaultLabel from '../../Label' import useField from '../../useField' import withCondition from '../../withCondition' -import './index.scss' import { fieldBaseClass } from '../shared' +import './index.scss' const prismToMonacoLanguageMap = { js: 'javascript', @@ -24,6 +24,7 @@ const Code: React.FC = (props) => { name, admin: { className, + components: { Error, Label } = {}, condition, description, editorOptions, @@ -31,7 +32,6 @@ const Code: React.FC = (props) => { readOnly, style, width, - components: { Error, Label } = {}, } = {}, label, path: pathFromProps, diff --git a/packages/payload/src/admin/components/forms/field-types/DateTime/Input.tsx b/packages/payload/src/admin/components/forms/field-types/DateTime/Input.tsx index 43abbb0a8..5ba0cb2fd 100644 --- a/packages/payload/src/admin/components/forms/field-types/DateTime/Input.tsx +++ b/packages/payload/src/admin/components/forms/field-types/DateTime/Input.tsx @@ -17,10 +17,10 @@ const baseClass = 'date-time-field' export type DateTimeInputProps = Omit & { className?: string components: { - AfterInput?: React.ReactElement[] - BeforeInput?: React.ReactElement[] Error?: React.ComponentType Label?: React.ComponentType + afterInput?: React.ComponentType[] + beforeInput?: React.ComponentType[] } datePickerProps?: DateField['admin']['date'] description?: Description @@ -39,7 +39,7 @@ export type DateTimeInputProps = Omit & { export const DateTimeInput: React.FC = (props) => { const { className, - components: { AfterInput, BeforeInput, Error, Label } = {}, + components: { Error, Label, afterInput, beforeInput } = {}, datePickerProps, description, errorMessage, @@ -81,7 +81,7 @@ export const DateTimeInput: React.FC = (props) => {
- {BeforeInput} + {Array.isArray(beforeInput) && beforeInput.map((Component, i) => )} = (props) => { readOnly={readOnly} value={value} /> - {AfterInput} + {Array.isArray(afterInput) && afterInput.map((Component, i) => )}
diff --git a/packages/payload/src/admin/components/forms/field-types/Email/index.tsx b/packages/payload/src/admin/components/forms/field-types/Email/index.tsx index d5adf7e88..3f06a98d0 100644 --- a/packages/payload/src/admin/components/forms/field-types/Email/index.tsx +++ b/packages/payload/src/admin/components/forms/field-types/Email/index.tsx @@ -10,8 +10,8 @@ import FieldDescription from '../../FieldDescription' import DefaultLabel from '../../Label' import useField from '../../useField' import withCondition from '../../withCondition' -import './index.scss' import { fieldBaseClass } from '../shared' +import './index.scss' const Email: React.FC = (props) => { const { @@ -19,13 +19,13 @@ const Email: React.FC = (props) => { admin: { autoComplete, className, + components: { Error, Label, afterInput, beforeInput } = {}, condition, description, placeholder, readOnly, style, width, - components: { Error, Label, BeforeInput, AfterInput } = {}, } = {}, label, path: pathFromProps, @@ -68,7 +68,7 @@ const Email: React.FC = (props) => {
- {BeforeInput} + {Array.isArray(beforeInput) && beforeInput.map((Component, i) => )} = (props) => { type="email" value={(value as string) || ''} /> - {AfterInput} + {Array.isArray(afterInput) && afterInput.map((Component, i) => )}
diff --git a/packages/payload/src/admin/components/forms/field-types/Number/index.tsx b/packages/payload/src/admin/components/forms/field-types/Number/index.tsx index a6ef7c7c3..ea5ff5c76 100644 --- a/packages/payload/src/admin/components/forms/field-types/Number/index.tsx +++ b/packages/payload/src/admin/components/forms/field-types/Number/index.tsx @@ -13,14 +13,15 @@ import FieldDescription from '../../FieldDescription' import DefaultLabel from '../../Label' import useField from '../../useField' import withCondition from '../../withCondition' -import './index.scss' import { fieldBaseClass } from '../shared' +import './index.scss' const NumberField: React.FC = (props) => { const { name, admin: { className, + components: { Error, Label, afterInput, beforeInput } = {}, condition, description, placeholder, @@ -28,7 +29,6 @@ const NumberField: React.FC = (props) => { step, style, width, - components: { Error, Label, BeforeInput, AfterInput } = {}, } = {}, hasMany, label, @@ -162,7 +162,7 @@ const NumberField: React.FC = (props) => { /> ) : (
- {BeforeInput} + {Array.isArray(beforeInput) && beforeInput.map((Component, i) => )} = (props) => { type="number" value={typeof value === 'number' ? value : ''} /> - {AfterInput} + {Array.isArray(afterInput) && afterInput.map((Component, i) => )}
)} diff --git a/packages/payload/src/admin/components/forms/field-types/Point/index.tsx b/packages/payload/src/admin/components/forms/field-types/Point/index.tsx index 77ac8cb2f..6c893af4d 100644 --- a/packages/payload/src/admin/components/forms/field-types/Point/index.tsx +++ b/packages/payload/src/admin/components/forms/field-types/Point/index.tsx @@ -10,8 +10,8 @@ import FieldDescription from '../../FieldDescription' import DefaultLabel from '../../Label' import useField from '../../useField' import withCondition from '../../withCondition' -import './index.scss' import { fieldBaseClass } from '../shared' +import './index.scss' const baseClass = 'point' @@ -20,6 +20,7 @@ const PointField: React.FC = (props) => { name, admin: { className, + components: { Error, Label, afterInput, beforeInput } = {}, condition, description, placeholder, @@ -27,7 +28,6 @@ const PointField: React.FC = (props) => { step, style, width, - components: { Error, Label, BeforeInput, AfterInput } = {}, } = {}, label, path: pathFromProps, @@ -98,7 +98,7 @@ const PointField: React.FC = (props) => { required={required} />
- {BeforeInput} + {Array.isArray(beforeInput) && beforeInput.map((Component, i) => )} = (props) => { type="number" value={value && typeof value[0] === 'number' ? value[0] : ''} /> - {AfterInput} + {Array.isArray(afterInput) && afterInput.map((Component, i) => )}
  • @@ -119,7 +119,7 @@ const PointField: React.FC = (props) => { required={required} />
    - {BeforeInput} + {Array.isArray(beforeInput) && beforeInput.map((Component, i) => )} = (props) => { type="number" value={value && typeof value[1] === 'number' ? value[1] : ''} /> - {AfterInput} + {Array.isArray(afterInput) && afterInput.map((Component, i) => )}
  • diff --git a/packages/payload/src/admin/components/forms/field-types/Text/Input.tsx b/packages/payload/src/admin/components/forms/field-types/Text/Input.tsx index 358bc00b4..364379749 100644 --- a/packages/payload/src/admin/components/forms/field-types/Text/Input.tsx +++ b/packages/payload/src/admin/components/forms/field-types/Text/Input.tsx @@ -14,6 +14,10 @@ import { fieldBaseClass } from '../shared' import './index.scss' export type TextInputProps = Omit & { + Error?: React.ComponentType + Label?: React.ComponentType + afterInput?: React.ComponentType[] + beforeInput?: React.ComponentType[] className?: string description?: Description errorMessage?: string @@ -29,14 +33,14 @@ export type TextInputProps = Omit & { style?: React.CSSProperties value?: string width?: string - Error?: React.ComponentType - Label?: React.ComponentType - BeforeInput?: React.ReactElement[] - AfterInput?: React.ReactElement[] } const TextInput: React.FC = (props) => { const { + Error, + Label, + afterInput, + beforeInput, className, description, errorMessage, @@ -53,10 +57,6 @@ const TextInput: React.FC = (props) => { style, value, width, - Error, - Label, - BeforeInput, - AfterInput, } = props const { i18n } = useTranslation() @@ -77,7 +77,7 @@ const TextInput: React.FC = (props) => {
    - {BeforeInput} + {Array.isArray(beforeInput) && beforeInput.map((Component, i) => )} = (props) => { type="text" value={value || ''} /> - {AfterInput} + {Array.isArray(afterInput) && afterInput.map((Component, i) => )}
    = (props) => { name, admin: { className, + components: { Error, Label, afterInput, beforeInput } = {}, condition, description, placeholder, @@ -22,7 +23,6 @@ const Text: React.FC = (props) => { rtl, style, width, - components: { Error, Label, BeforeInput, AfterInput } = {}, } = {}, inputRef, label, @@ -60,6 +60,10 @@ const Text: React.FC = (props) => { return ( = (props) => { style={style} value={value} width={width} - Error={Error} - Label={Label} - BeforeInput={BeforeInput} - AfterInput={AfterInput} /> ) } diff --git a/packages/payload/src/admin/components/forms/field-types/Textarea/Input.tsx b/packages/payload/src/admin/components/forms/field-types/Textarea/Input.tsx index 0127db81e..42a448ebe 100644 --- a/packages/payload/src/admin/components/forms/field-types/Textarea/Input.tsx +++ b/packages/payload/src/admin/components/forms/field-types/Textarea/Input.tsx @@ -10,10 +10,14 @@ import { getTranslation } from '../../../../../utilities/getTranslation' import DefaultError from '../../Error' import FieldDescription from '../../FieldDescription' import DefaultLabel from '../../Label' -import './index.scss' import { fieldBaseClass } from '../shared' +import './index.scss' export type TextAreaInputProps = Omit & { + Error?: React.ComponentType + Label?: React.ComponentType + afterInput?: React.ComponentType[] + beforeInput?: React.ComponentType[] className?: string description?: Description errorMessage?: string @@ -28,14 +32,14 @@ export type TextAreaInputProps = Omit & { style?: React.CSSProperties value?: string width?: string - Error?: React.ComponentType - Label?: React.ComponentType - BeforeInput?: React.ReactElement[] - AfterInput?: React.ReactElement[] } const TextareaInput: React.FC = (props) => { const { + Error, + Label, + afterInput, + beforeInput, className, description, errorMessage, @@ -51,10 +55,6 @@ const TextareaInput: React.FC = (props) => { style, value, width, - Error, - Label, - BeforeInput, - AfterInput, } = props const { i18n } = useTranslation() @@ -83,7 +83,7 @@ const TextareaInput: React.FC = (props) => {