chore(ui): client-side renders all default field labels, descriptions, and errors
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
import { ReactSelect } from '@payloadcms/ui/elements/ReactSelect'
|
||||
import { Label } from '@payloadcms/ui/forms/Label'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
||||
import React from 'react'
|
||||
|
||||
@@ -20,7 +20,7 @@ export const Settings: React.FC<{
|
||||
<div className={[baseClass, className].filter(Boolean).join(' ')}>
|
||||
<h3>{t('general:payloadSettings')}</h3>
|
||||
<div className={`${baseClass}__language`}>
|
||||
<Label htmlFor="language-select" label={t('general:language')} />
|
||||
<FieldLabel htmlFor="language-select" label={t('general:language')} />
|
||||
<ReactSelect
|
||||
inputId="language-select"
|
||||
onChange={async ({ value }) => {
|
||||
|
||||
@@ -3,8 +3,8 @@ import type { PayloadRequest } from 'payload/types'
|
||||
|
||||
import { CopyToClipboard } from '@payloadcms/ui/elements/CopyToClipboard'
|
||||
import { GenerateConfirmation } from '@payloadcms/ui/elements/GenerateConfirmation'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import { useFormFields } from '@payloadcms/ui/forms/Form'
|
||||
import { Label } from '@payloadcms/ui/forms/Label'
|
||||
import { useField } from '@payloadcms/ui/forms/useField'
|
||||
import { useConfig } from '@payloadcms/ui/providers/Config'
|
||||
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
||||
@@ -89,7 +89,7 @@ export const APIKey: React.FC<{ readOnly?: boolean }> = ({ readOnly }) => {
|
||||
return (
|
||||
<React.Fragment>
|
||||
<div className={[fieldBaseClass, 'api-key', 'read-only'].filter(Boolean).join(' ')}>
|
||||
<Label htmlFor={path} label={APIKeyLabel} />
|
||||
<FieldLabel htmlFor={path} label={APIKeyLabel} />
|
||||
<input
|
||||
className={highlightedField ? 'highlight' : undefined}
|
||||
disabled
|
||||
|
||||
@@ -145,7 +145,6 @@ export const DefaultEditView: React.FC = () => {
|
||||
entitySlug,
|
||||
user,
|
||||
collectionSlug,
|
||||
userSlug,
|
||||
getVersions,
|
||||
getDocPermissions,
|
||||
isEditing,
|
||||
|
||||
@@ -97,7 +97,7 @@ export const VersionsViewClient: React.FC<{
|
||||
)}
|
||||
{versionCount > 0 && (
|
||||
<React.Fragment>
|
||||
<Table columns={columns} data={data?.docs} />
|
||||
<Table columns={columns} data={data?.docs} fieldMap={componentMap?.fieldMap} />
|
||||
<div className={`${baseClass}__page-controls`}>
|
||||
<Pagination
|
||||
hasNextPage={data.hasNextPage}
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { FormFieldBase } from '@payloadcms/ui/fields/shared'
|
||||
import type { FieldType, Options } from '@payloadcms/ui/forms/useField'
|
||||
|
||||
import { TextareaInput } from '@payloadcms/ui/fields/Textarea'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider'
|
||||
import { useAllFormFields } from '@payloadcms/ui/forms/Form'
|
||||
import { useField } from '@payloadcms/ui/forms/useField'
|
||||
@@ -26,7 +27,7 @@ type MetaDescriptionProps = FormFieldBase & {
|
||||
}
|
||||
|
||||
export const MetaDescription: React.FC<MetaDescriptionProps> = (props) => {
|
||||
const { Label, hasGenerateDescriptionFn, path, required } = props
|
||||
const { CustomLabel, hasGenerateDescriptionFn, labelProps, path, required } = props
|
||||
const { path: pathFromContext } = useFieldProps()
|
||||
|
||||
const { t } = useTranslation()
|
||||
@@ -75,8 +76,7 @@ export const MetaDescription: React.FC<MetaDescriptionProps> = (props) => {
|
||||
}}
|
||||
>
|
||||
<div className="plugin-seo__field">
|
||||
{Label}
|
||||
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
{required && (
|
||||
<span
|
||||
style={{
|
||||
@@ -131,7 +131,7 @@ export const MetaDescription: React.FC<MetaDescriptionProps> = (props) => {
|
||||
}}
|
||||
>
|
||||
<TextareaInput
|
||||
Error={errorMessage} // TODO: Fix
|
||||
CustomError={errorMessage}
|
||||
onChange={setValue}
|
||||
path={pathFromContext}
|
||||
required={required}
|
||||
|
||||
@@ -4,6 +4,7 @@ import type { UploadInputProps } from '@payloadcms/ui/fields/Upload'
|
||||
import type { FieldType, Options } from '@payloadcms/ui/forms/useField'
|
||||
|
||||
import { UploadInput } from '@payloadcms/ui/fields/Upload'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import { useAllFormFields } from '@payloadcms/ui/forms/Form'
|
||||
import { useField } from '@payloadcms/ui/forms/useField'
|
||||
import { useConfig } from '@payloadcms/ui/providers/Config'
|
||||
@@ -22,7 +23,7 @@ type MetaImageProps = UploadInputProps & {
|
||||
}
|
||||
|
||||
export const MetaImage: React.FC<MetaImageProps> = (props) => {
|
||||
const { Label, hasGenerateImageFn, relationTo, required } = props || {}
|
||||
const { CustomLabel, hasGenerateImageFn, labelProps, relationTo, required } = props || {}
|
||||
|
||||
const field: FieldType<string> = useField(props as Options)
|
||||
|
||||
@@ -76,8 +77,7 @@ export const MetaImage: React.FC<MetaImageProps> = (props) => {
|
||||
}}
|
||||
>
|
||||
<div className="plugin-seo__field">
|
||||
{Label}
|
||||
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
{required && (
|
||||
<span
|
||||
style={{
|
||||
@@ -88,7 +88,6 @@ export const MetaImage: React.FC<MetaImageProps> = (props) => {
|
||||
*
|
||||
</span>
|
||||
)}
|
||||
|
||||
{hasGenerateImageFn && (
|
||||
<React.Fragment>
|
||||
—
|
||||
@@ -127,7 +126,7 @@ export const MetaImage: React.FC<MetaImageProps> = (props) => {
|
||||
}}
|
||||
>
|
||||
<UploadInput
|
||||
Error={errorMessage} // TODO: Fix
|
||||
CustomError={errorMessage}
|
||||
api={api}
|
||||
collection={collection}
|
||||
filterOptions={{}}
|
||||
|
||||
@@ -5,6 +5,7 @@ import type { Options } from '@payloadcms/ui/forms/useField'
|
||||
import type { FieldType } from '@payloadcms/ui/forms/useField'
|
||||
|
||||
import { TextInput } from '@payloadcms/ui/fields/Text'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import { useFieldProps } from '@payloadcms/ui/forms/FieldPropsProvider'
|
||||
import { useAllFormFields } from '@payloadcms/ui/forms/Form'
|
||||
import { useField } from '@payloadcms/ui/forms/useField'
|
||||
@@ -27,7 +28,7 @@ type MetaTitleProps = FormFieldBase & {
|
||||
}
|
||||
|
||||
export const MetaTitle: React.FC<MetaTitleProps> = (props) => {
|
||||
const { Label, hasGenerateTitleFn, path, required } = props || {}
|
||||
const { CustomLabel, hasGenerateTitleFn, labelProps, path, required } = props || {}
|
||||
const { path: pathFromContext } = useFieldProps()
|
||||
|
||||
const { t } = useTranslation()
|
||||
@@ -76,8 +77,7 @@ export const MetaTitle: React.FC<MetaTitleProps> = (props) => {
|
||||
}}
|
||||
>
|
||||
<div className="plugin-seo__field">
|
||||
{Label}
|
||||
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
{required && (
|
||||
<span
|
||||
style={{
|
||||
@@ -88,7 +88,6 @@ export const MetaTitle: React.FC<MetaTitleProps> = (props) => {
|
||||
*
|
||||
</span>
|
||||
)}
|
||||
|
||||
{hasGenerateTitleFn && (
|
||||
<React.Fragment>
|
||||
—
|
||||
@@ -133,7 +132,7 @@ export const MetaTitle: React.FC<MetaTitleProps> = (props) => {
|
||||
}}
|
||||
>
|
||||
<TextInput
|
||||
Error={errorMessage} // TODO: fix errormessage
|
||||
CustomError={errorMessage}
|
||||
onChange={setValue}
|
||||
path={pathFromContext}
|
||||
required={required}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
import type { FormFieldBase } from '@payloadcms/ui/fields/shared'
|
||||
import type { SerializedEditorState } from 'lexical'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import { useField } from '@payloadcms/ui/forms/useField'
|
||||
import React, { useCallback } from 'react'
|
||||
import { ErrorBoundary } from 'react-error-boundary'
|
||||
@@ -23,11 +26,14 @@ export const RichText: React.FC<
|
||||
> = (props) => {
|
||||
const {
|
||||
name,
|
||||
Description,
|
||||
Error,
|
||||
Label,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
editorConfig,
|
||||
errorProps,
|
||||
labelProps,
|
||||
path: pathFromProps,
|
||||
readOnly,
|
||||
required,
|
||||
@@ -75,8 +81,8 @@ export const RichText: React.FC<
|
||||
}}
|
||||
>
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<ErrorBoundary fallbackRender={fallbackRender} onReset={() => {}}>
|
||||
<LexicalProvider
|
||||
editorConfig={editorConfig}
|
||||
@@ -99,7 +105,11 @@ export const RichText: React.FC<
|
||||
value={value}
|
||||
/>
|
||||
</ErrorBoundary>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -6,6 +6,9 @@ import type { HistoryEditor } from 'slate-history'
|
||||
import type { ReactEditor } from 'slate-react'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import { useField } from '@payloadcms/ui/forms/useField'
|
||||
import { withCondition } from '@payloadcms/ui/forms/withCondition'
|
||||
import { useEditDepth } from '@payloadcms/ui/providers/EditDepth'
|
||||
@@ -55,11 +58,14 @@ const RichTextField: React.FC<
|
||||
> = (props) => {
|
||||
const {
|
||||
name,
|
||||
Description,
|
||||
Error,
|
||||
Label,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
elements,
|
||||
errorProps,
|
||||
labelProps,
|
||||
leaves,
|
||||
path: pathFromProps,
|
||||
placeholder,
|
||||
@@ -299,8 +305,8 @@ const RichTextField: React.FC<
|
||||
}}
|
||||
>
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<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
|
||||
@@ -430,7 +436,11 @@ const RichTextField: React.FC<
|
||||
</div>
|
||||
</div>
|
||||
</Slate>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -4,9 +4,9 @@ import React, { Fragment, useState } from 'react'
|
||||
|
||||
import type { FieldMap, MappedField } from '../../providers/ComponentMap/buildComponentMap/types.js'
|
||||
|
||||
import { FieldLabel } from '../../forms/FieldLabel/index.js'
|
||||
import { useForm } from '../../forms/Form/context.js'
|
||||
import { createNestedClientFieldPath } from '../../forms/Form/createNestedFieldPath.js'
|
||||
import { Label } from '../../forms/Label/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import { ReactSelect } from '../ReactSelect/index.js'
|
||||
import './index.scss'
|
||||
@@ -23,7 +23,18 @@ const combineLabel = (prefix: JSX.Element, field: MappedField): JSX.Element => {
|
||||
<Fragment>
|
||||
<span style={{ display: 'inline-block' }}>{prefix}</span>
|
||||
{prefix ? <Fragment>{' > '}</Fragment> : ''}
|
||||
<span style={{ display: 'inline-block' }}>{field.fieldComponentProps.Label}</span>
|
||||
<span style={{ display: 'inline-block' }}>
|
||||
{'CustomLabel' in field.fieldComponentProps &&
|
||||
field.fieldComponentProps.CustomLabel !== undefined ? (
|
||||
field.fieldComponentProps.CustomLabel
|
||||
) : (
|
||||
<FieldLabel
|
||||
{...(('labelProps' in field.fieldComponentProps &&
|
||||
field.fieldComponentProps.labelProps) ||
|
||||
{})}
|
||||
/>
|
||||
)}
|
||||
</span>
|
||||
</Fragment>
|
||||
)
|
||||
}
|
||||
@@ -45,7 +56,7 @@ const reduceFields = (
|
||||
(field.disableBulkEdit ||
|
||||
field.unique ||
|
||||
field.isHidden ||
|
||||
field.fieldComponentProps?.readOnly)
|
||||
('readOnly' in field.fieldComponentProps && field.fieldComponentProps.readOnly))
|
||||
) {
|
||||
return fieldsToUse
|
||||
}
|
||||
@@ -128,7 +139,7 @@ export const FieldSelect: React.FC<FieldSelectProps> = ({ fieldMap, setSelected
|
||||
|
||||
return (
|
||||
<div className={baseClass}>
|
||||
<Label label={t('fields:selectFieldsToEdit')} />
|
||||
<FieldLabel label={t('fields:selectFieldsToEdit')} />
|
||||
<ReactSelect isMulti onChange={handleChange} options={options} />
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -9,7 +9,7 @@ import React, { useCallback, useEffect, useReducer, useState } from 'react'
|
||||
import type { ListPreferences } from '../TableColumns/index.js'
|
||||
import type { ListDrawerProps } from './types.js'
|
||||
|
||||
import { Label } from '../../forms/Label/index.js'
|
||||
import { FieldLabel } from '../../forms/FieldLabel/index.js'
|
||||
import usePayloadAPI from '../../hooks/usePayloadAPI.js'
|
||||
import { useUseTitleField } from '../../hooks/useUseAsTitle.js'
|
||||
import { X } from '../../icons/X/index.js'
|
||||
@@ -264,7 +264,7 @@ export const ListDrawerContent: React.FC<ListDrawerProps> = ({
|
||||
)}
|
||||
{moreThanOneAvailableCollection && (
|
||||
<div className={`${baseClass}__select-collection-wrap`}>
|
||||
<Label label={t('upload:selectCollectionToBrowse')} />
|
||||
<FieldLabel label={t('upload:selectCollectionToBrowse')} />
|
||||
<ReactSelect
|
||||
className={`${baseClass}__select-collection`}
|
||||
onChange={setSelectedOption} // this is only changing the options which is not rerunning my effect
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
'use client'
|
||||
import type { FormState, SanitizedCollectionConfig } from 'payload/types'
|
||||
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { isImage } from 'payload/utilities'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
import { fieldBaseClass } from '../../fields/shared/index.js'
|
||||
import { Error } from '../../forms/Error/index.js'
|
||||
import { useFormSubmitted } from '../../forms/Form/context.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { useDocumentInfo } from '../../providers/DocumentInfo/index.js'
|
||||
@@ -135,7 +135,7 @@ export const Upload: React.FC<UploadProps> = (props) => {
|
||||
|
||||
return (
|
||||
<div className={[fieldBaseClass, baseClass].filter(Boolean).join(' ')}>
|
||||
<Error message={errorMessage} showError={showError} />
|
||||
<FieldError message={errorMessage} showError={showError} />
|
||||
{doc.filename && !replacingFile && (
|
||||
<FileDetails
|
||||
canEdit={showCrop || showFocalPoint}
|
||||
|
||||
@@ -4,6 +4,9 @@ import type { FieldBase } from 'payload/types'
|
||||
import type { ArrayField as ArrayFieldType } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import React, { useCallback } from 'react'
|
||||
|
||||
import type { FieldMap } from '../../providers/ComponentMap/buildComponentMap/types.js'
|
||||
@@ -15,7 +18,6 @@ import { DraggableSortableItem } from '../../elements/DraggableSortable/Draggabl
|
||||
import { DraggableSortable } from '../../elements/DraggableSortable/index.js'
|
||||
import { ErrorPill } from '../../elements/ErrorPill/index.js'
|
||||
import { useForm, useFormSubmitted } from '../../forms/Form/context.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { NullifyLocaleField } from '../../forms/NullifyField/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { useConfig } from '../../providers/Config/index.js'
|
||||
@@ -46,15 +48,17 @@ export type ArrayFieldProps = FormFieldBase & {
|
||||
export const ArrayField: React.FC<ArrayFieldProps> = (props) => {
|
||||
const {
|
||||
name,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
RowLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
fieldMap,
|
||||
forceRender = false,
|
||||
indexPath,
|
||||
label,
|
||||
labelProps,
|
||||
localized,
|
||||
maxRows,
|
||||
minRows,
|
||||
@@ -65,8 +69,6 @@ export const ArrayField: React.FC<ArrayFieldProps> = (props) => {
|
||||
validate,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { setDocFieldPreferences } = useDocumentInfo()
|
||||
const { addFieldRow, dispatchFields, setModified } = useForm()
|
||||
const submitted = useFormSubmitted()
|
||||
@@ -194,11 +196,17 @@ export const ArrayField: React.FC<ArrayFieldProps> = (props) => {
|
||||
.join(' ')}
|
||||
id={`field-${path.replace(/\./g, '__')}`}
|
||||
>
|
||||
{showError && <div className={`${baseClass}__error-wrap`}>{Error}</div>}
|
||||
{showError && (
|
||||
<div className={`${baseClass}__error-wrap`}>
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
</div>
|
||||
)}
|
||||
<header className={`${baseClass}__header`}>
|
||||
<div className={`${baseClass}__header-wrap`}>
|
||||
<div className={`${baseClass}__header-content`}>
|
||||
<h3 className={`${baseClass}__title`}>{Label}</h3>
|
||||
<h3 className={`${baseClass}__title`}>
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
</h3>
|
||||
{fieldHasErrors && fieldErrorCount > 0 && (
|
||||
<ErrorPill count={fieldErrorCount} i18n={i18n} withMessage />
|
||||
)}
|
||||
@@ -226,7 +234,11 @@ export const ArrayField: React.FC<ArrayFieldProps> = (props) => {
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</header>
|
||||
<NullifyLocaleField fieldValue={value} localized={localized} path={path} />
|
||||
{(rows.length > 0 || (!valid && (showRequired || showMinRows))) && (
|
||||
|
||||
@@ -10,7 +10,6 @@ import { DrawerToggler } from '../../elements/Drawer/index.js'
|
||||
import { useDrawerSlug } from '../../elements/Drawer/useDrawerSlug.js'
|
||||
import { ErrorPill } from '../../elements/ErrorPill/index.js'
|
||||
import { useForm, useFormSubmitted } from '../../forms/Form/context.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { NullifyLocaleField } from '../../forms/NullifyField/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { useConfig } from '../../providers/Config/index.js'
|
||||
@@ -28,6 +27,10 @@ const baseClass = 'blocks-field'
|
||||
import type { FieldPermissions } from 'payload/auth'
|
||||
import type { BlockField, FieldBase } from 'payload/types'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
|
||||
import type {
|
||||
FieldMap,
|
||||
ReducedBlock,
|
||||
@@ -54,14 +57,16 @@ export const BlocksField: React.FC<BlocksFieldProps> = (props) => {
|
||||
|
||||
const {
|
||||
name,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
blocks,
|
||||
className,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
forceRender = false,
|
||||
indexPath,
|
||||
label,
|
||||
labelProps,
|
||||
labels: labelsFromProps,
|
||||
localized,
|
||||
maxRows,
|
||||
@@ -72,8 +77,6 @@ export const BlocksField: React.FC<BlocksFieldProps> = (props) => {
|
||||
validate,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { setDocFieldPreferences } = useDocumentInfo()
|
||||
const { addFieldRow, dispatchFields, setModified } = useForm()
|
||||
const { code: locale } = useLocale()
|
||||
@@ -207,11 +210,17 @@ export const BlocksField: React.FC<BlocksFieldProps> = (props) => {
|
||||
.join(' ')}
|
||||
id={`field-${path.replace(/\./g, '__')}`}
|
||||
>
|
||||
{showError && <div className={`${baseClass}__error-wrap`}>{Error}</div>}
|
||||
{showError && (
|
||||
<div className={`${baseClass}__error-wrap`}>
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
</div>
|
||||
)}
|
||||
<header className={`${baseClass}__header`}>
|
||||
<div className={`${baseClass}__header-wrap`}>
|
||||
<div className={`${baseClass}__heading-with-error`}>
|
||||
<h3>{Label}</h3>
|
||||
<h3>
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
</h3>
|
||||
{fieldHasErrors && fieldErrorCount > 0 && (
|
||||
<ErrorPill count={fieldErrorCount} i18n={i18n} withMessage />
|
||||
)}
|
||||
@@ -239,7 +248,11 @@ export const BlocksField: React.FC<BlocksFieldProps> = (props) => {
|
||||
</ul>
|
||||
)}
|
||||
</div>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</header>
|
||||
<NullifyLocaleField fieldValue={value} localized={localized} path={path} />
|
||||
{(rows.length > 0 || (!valid && (showRequired || showMinRows))) && (
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
'use client'
|
||||
import type { LabelProps } from 'packages/payload/src/admin/types.js'
|
||||
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import React from 'react'
|
||||
|
||||
import { Check } from '../../icons/Check/index.js'
|
||||
@@ -7,11 +10,12 @@ import { Line } from '../../icons/Line/index.js'
|
||||
type Props = {
|
||||
AfterInput?: React.ReactNode
|
||||
BeforeInput?: React.ReactNode
|
||||
Label?: React.ReactNode
|
||||
CustomLabel?: React.ReactNode
|
||||
checked?: boolean
|
||||
className?: string
|
||||
id?: string
|
||||
inputRef?: React.RefObject<HTMLInputElement>
|
||||
labelProps?: LabelProps
|
||||
name?: string
|
||||
onToggle: (event: React.ChangeEvent<HTMLInputElement>) => void
|
||||
partialChecked?: boolean
|
||||
@@ -26,10 +30,11 @@ export const CheckboxInput: React.FC<Props> = ({
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Label,
|
||||
CustomLabel,
|
||||
checked,
|
||||
className,
|
||||
inputRef,
|
||||
labelProps,
|
||||
onToggle,
|
||||
partialChecked,
|
||||
readOnly,
|
||||
@@ -69,7 +74,7 @@ export const CheckboxInput: React.FC<Props> = ({
|
||||
</span>
|
||||
{AfterInput}
|
||||
</div>
|
||||
{Label}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
'use client'
|
||||
import type { ClientValidate } from 'payload/types'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import React, { useCallback } from 'react'
|
||||
|
||||
import type { CheckboxFieldProps } from './types.js'
|
||||
|
||||
import { useForm } from '../../forms/Form/context.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { generateFieldID } from '../../utilities/generateFieldID.js'
|
||||
@@ -24,13 +25,15 @@ const CheckboxField: React.FC<CheckboxFieldProps> = (props) => {
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
checked: checkedFromProps,
|
||||
className,
|
||||
descriptionProps,
|
||||
disableFormData,
|
||||
label,
|
||||
errorProps,
|
||||
labelProps,
|
||||
onChange: onChangeFromProps,
|
||||
partialChecked,
|
||||
path: pathFromProps,
|
||||
@@ -43,8 +46,6 @@ const CheckboxField: React.FC<CheckboxFieldProps> = (props) => {
|
||||
|
||||
const { uuid } = useForm()
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const memoizedValidate: ClientValidate = useCallback(
|
||||
(value, options) => {
|
||||
if (typeof validate === 'function') {
|
||||
@@ -88,21 +89,28 @@ const CheckboxField: React.FC<CheckboxFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<div className={`${baseClass}__error-wrap`}>{Error}</div>
|
||||
<div className={`${baseClass}__error-wrap`}>
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
</div>
|
||||
<CheckboxInput
|
||||
AfterInput={AfterInput}
|
||||
BeforeInput={BeforeInput}
|
||||
Label={Label}
|
||||
CustomLabel={CustomLabel}
|
||||
checked={checked}
|
||||
id={fieldID}
|
||||
inputRef={null}
|
||||
labelProps={labelProps}
|
||||
name={path}
|
||||
onToggle={onToggle}
|
||||
partialChecked={partialChecked}
|
||||
readOnly={readOnly}
|
||||
required={required}
|
||||
/>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,12 +2,14 @@
|
||||
'use client'
|
||||
import type { CodeField as CodeFieldType, FieldBase } from 'payload/types'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import React, { useCallback } from 'react'
|
||||
|
||||
import type { FormFieldBase } from '../shared/index.js'
|
||||
|
||||
import { CodeEditor } from '../../elements/CodeEditor/index.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { fieldBaseClass } from '../shared/index.js'
|
||||
@@ -34,12 +36,14 @@ const CodeField: React.FC<CodeFieldProps> = (props) => {
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
editorOptions = {},
|
||||
label,
|
||||
errorProps,
|
||||
labelProps,
|
||||
language = 'javascript',
|
||||
path: pathFromProps,
|
||||
readOnly,
|
||||
@@ -49,8 +53,6 @@ const CodeField: React.FC<CodeFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const memoizedValidate = useCallback(
|
||||
(value, options) => {
|
||||
if (typeof validate === 'function') {
|
||||
@@ -81,8 +83,8 @@ const CodeField: React.FC<CodeFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<div>
|
||||
{BeforeInput}
|
||||
<CodeEditor
|
||||
@@ -94,7 +96,7 @@ const CodeField: React.FC<CodeFieldProps> = (props) => {
|
||||
/>
|
||||
{AfterInput}
|
||||
</div>
|
||||
{Description}
|
||||
{CustomDescription ? CustomDescription : <FieldDescription {...(descriptionProps || {})} />}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import React, { Fragment, useCallback, useEffect, useState } from 'react'
|
||||
import { Collapsible as CollapsibleElement } from '../../elements/Collapsible/index.js'
|
||||
import { ErrorPill } from '../../elements/ErrorPill/index.js'
|
||||
import { useFieldProps } from '../../forms/FieldPropsProvider/index.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { RenderFields } from '../../forms/RenderFields/index.js'
|
||||
import { WatchChildErrors } from '../../forms/WatchChildErrors/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
@@ -22,6 +21,9 @@ const baseClass = 'collapsible-field'
|
||||
import type { FieldPermissions } from 'payload/auth'
|
||||
import type { FieldBase } from 'payload/types'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
|
||||
import type { FieldMap } from '../../providers/ComponentMap/buildComponentMap/types.js'
|
||||
import type { FormFieldBase } from '../shared/index.js'
|
||||
|
||||
@@ -36,18 +38,16 @@ export type CollapsibleFieldProps = FormFieldBase & {
|
||||
|
||||
const CollapsibleField: React.FC<CollapsibleFieldProps> = (props) => {
|
||||
const {
|
||||
Description,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
fieldMap,
|
||||
initCollapsed = false,
|
||||
label,
|
||||
labelProps,
|
||||
path: pathFromProps,
|
||||
required,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { path: pathFromContext, readOnly, schemaPath, siblingPermissions } = useFieldProps()
|
||||
const path = pathFromProps || pathFromContext
|
||||
|
||||
@@ -126,7 +126,7 @@ const CollapsibleField: React.FC<CollapsibleFieldProps> = (props) => {
|
||||
collapsibleStyle={fieldHasErrors ? 'error' : 'default'}
|
||||
header={
|
||||
<div className={`${baseClass}__row-label-wrap`}>
|
||||
{Label}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
{fieldHasErrors && <ErrorPill count={errorCount} i18n={i18n} withMessage />}
|
||||
</div>
|
||||
}
|
||||
@@ -143,7 +143,11 @@ const CollapsibleField: React.FC<CollapsibleFieldProps> = (props) => {
|
||||
schemaPath={schemaPath}
|
||||
/>
|
||||
</CollapsibleElement>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
</Fragment>
|
||||
)
|
||||
|
||||
@@ -3,9 +3,9 @@ import type { FormField } from 'payload/types'
|
||||
|
||||
import React, { useCallback } from 'react'
|
||||
|
||||
import { Error } from '../../forms/Error/index.js'
|
||||
import { FieldError } from '../../forms/FieldError/index.js'
|
||||
import { FieldLabel } from '../../forms/FieldLabel/index.js'
|
||||
import { useFormFields } from '../../forms/Form/context.js'
|
||||
import { Label } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import { fieldBaseClass } from '../shared/index.js'
|
||||
@@ -50,8 +50,8 @@ export const ConfirmPassword: React.FC<ConfirmPasswordFieldProps> = (props) => {
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
>
|
||||
<Error path={path} />
|
||||
<Label
|
||||
<FieldError path={path} />
|
||||
<FieldLabel
|
||||
htmlFor="field-confirm-password"
|
||||
label={t('authentication:confirmPassword')}
|
||||
required
|
||||
|
||||
@@ -6,7 +6,7 @@ import { getTranslation } from '@payloadcms/translations'
|
||||
import React, { useCallback } from 'react'
|
||||
|
||||
import { DatePickerField } from '../../elements/DatePicker/index.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { FieldLabel } from '../../forms/FieldLabel/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import { fieldBaseClass } from '../shared/index.js'
|
||||
@@ -16,6 +16,9 @@ const baseClass = 'date-time-field'
|
||||
|
||||
import type { DateField, FieldBase } from 'payload/types'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
|
||||
import type { FormFieldBase } from '../shared/index.js'
|
||||
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
@@ -34,12 +37,14 @@ const DateTimeField: React.FC<DateFieldProps> = (props) => {
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
date: datePickerProps,
|
||||
label,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
labelProps,
|
||||
path: pathFromProps,
|
||||
placeholder,
|
||||
readOnly,
|
||||
@@ -49,8 +54,6 @@ const DateTimeField: React.FC<DateFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
const memoizedValidate: ClientValidate = useCallback(
|
||||
@@ -83,8 +86,10 @@ const DateTimeField: React.FC<DateFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<div className={`${baseClass}__error-wrap`}>{Error}</div>
|
||||
{Label}
|
||||
<div className={`${baseClass}__error-wrap`}>
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
</div>
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<div className={`${baseClass}__input-wrapper`} id={`field-${path.replace(/\./g, '__')}`}>
|
||||
{BeforeInput}
|
||||
<DatePickerField
|
||||
@@ -98,7 +103,11 @@ const DateTimeField: React.FC<DateFieldProps> = (props) => {
|
||||
/>
|
||||
{AfterInput}
|
||||
</div>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,11 +3,13 @@ import type { ClientValidate } from 'payload/types'
|
||||
import type { EmailField as EmailFieldType, FieldBase } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import React, { useCallback } from 'react'
|
||||
|
||||
import type { FormFieldBase } from '../shared/index.js'
|
||||
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
@@ -28,12 +30,14 @@ const EmailField: React.FC<EmailFieldProps> = (props) => {
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
autoComplete,
|
||||
className,
|
||||
label,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
labelProps,
|
||||
path: pathFromProps,
|
||||
placeholder,
|
||||
readOnly,
|
||||
@@ -43,8 +47,6 @@ const EmailField: React.FC<EmailFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
const memoizedValidate: ClientValidate = useCallback(
|
||||
@@ -71,8 +73,8 @@ const EmailField: React.FC<EmailFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<div>
|
||||
{BeforeInput}
|
||||
<input
|
||||
@@ -87,7 +89,11 @@ const EmailField: React.FC<EmailFieldProps> = (props) => {
|
||||
/>
|
||||
{AfterInput}
|
||||
</div>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
import type { FieldPermissions } from 'payload/auth'
|
||||
import type { FieldBase } from 'payload/types'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import React, { Fragment } from 'react'
|
||||
|
||||
import type { FieldMap } from '../../providers/ComponentMap/buildComponentMap/types.js'
|
||||
@@ -10,7 +12,6 @@ import type { FormFieldBase } from '../shared/index.js'
|
||||
import { useCollapsible } from '../../elements/Collapsible/provider.js'
|
||||
import { ErrorPill } from '../../elements/ErrorPill/index.js'
|
||||
import { useFieldProps } from '../../forms/FieldPropsProvider/index.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { RenderFields } from '../../forms/RenderFields/index.js'
|
||||
import { WatchChildErrors } from '../../forms/WatchChildErrors/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
@@ -36,19 +37,17 @@ export type GroupFieldProps = FormFieldBase & {
|
||||
|
||||
const GroupField: React.FC<GroupFieldProps> = (props) => {
|
||||
const {
|
||||
Description,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
fieldMap,
|
||||
hideGutter,
|
||||
label,
|
||||
required,
|
||||
labelProps,
|
||||
style,
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { path, permissions, readOnly, schemaPath } = useFieldProps()
|
||||
const { i18n } = useTranslation()
|
||||
const isWithinCollapsible = useCollapsible()
|
||||
@@ -87,10 +86,14 @@ const GroupField: React.FC<GroupFieldProps> = (props) => {
|
||||
<GroupProvider>
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<div className={`${baseClass}__header`}>
|
||||
{(Label || Description) && (
|
||||
{(CustomLabel || CustomDescription) && (
|
||||
<header>
|
||||
{Label}
|
||||
{Description}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</header>
|
||||
)}
|
||||
{fieldHasErrors && <ErrorPill count={errorCount} i18n={i18n} withMessage />}
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
'use client'
|
||||
import React, { useEffect } from 'react'
|
||||
|
||||
import type { FormFieldBase } from '../index.js'
|
||||
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
|
||||
export type HiddenInputFieldProps = {
|
||||
export type HiddenInputFieldProps = FormFieldBase & {
|
||||
disableModifyingForm?: false
|
||||
name: string
|
||||
path?: string
|
||||
|
||||
@@ -4,7 +4,7 @@ import type { ClientValidate } from 'payload/types'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
import { CodeEditor } from '../../elements/CodeEditor/index.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { FieldLabel } from '../../forms/FieldLabel/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { fieldBaseClass } from '../shared/index.js'
|
||||
@@ -14,6 +14,9 @@ const baseClass = 'json-field'
|
||||
|
||||
import type { FieldBase, JSONField as JSONFieldType } from 'payload/types'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
|
||||
import type { FormFieldBase } from '../shared/index.js'
|
||||
|
||||
export type JSONFieldProps = FormFieldBase & {
|
||||
@@ -29,12 +32,14 @@ const JSONFieldComponent: React.FC<JSONFieldProps> = (props) => {
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
editorOptions,
|
||||
label,
|
||||
errorProps,
|
||||
labelProps,
|
||||
path: pathFromProps,
|
||||
readOnly,
|
||||
required,
|
||||
@@ -43,8 +48,6 @@ const JSONFieldComponent: React.FC<JSONFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const [stringValue, setStringValue] = useState<string>()
|
||||
const [jsonError, setJsonError] = useState<string>()
|
||||
const [hasLoadedValue, setHasLoadedValue] = useState(false)
|
||||
@@ -108,8 +111,8 @@ const JSONFieldComponent: React.FC<JSONFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<div>
|
||||
{BeforeInput}
|
||||
<CodeEditor
|
||||
@@ -121,7 +124,11 @@ const JSONFieldComponent: React.FC<JSONFieldProps> = (props) => {
|
||||
/>
|
||||
{AfterInput}
|
||||
</div>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
import type { FieldBase, NumberField as NumberFieldType } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import { isNumber } from 'payload/utilities'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
@@ -10,7 +13,6 @@ import type { Option } from '../../elements/ReactSelect/types.js'
|
||||
import type { FormFieldBase } from '../shared/index.js'
|
||||
|
||||
import { ReactSelect } from '../../elements/ReactSelect/index.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
@@ -36,12 +38,14 @@ const NumberFieldComponent: React.FC<NumberFieldProps> = (props) => {
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
hasMany = false,
|
||||
label,
|
||||
labelProps,
|
||||
max = Infinity,
|
||||
maxRows = Infinity,
|
||||
min = -Infinity,
|
||||
@@ -56,8 +60,6 @@ const NumberFieldComponent: React.FC<NumberFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { i18n, t } = useTranslation()
|
||||
|
||||
const memoizedValidate = useCallback(
|
||||
@@ -149,8 +151,8 @@ const NumberFieldComponent: React.FC<NumberFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{hasMany ? (
|
||||
<ReactSelect
|
||||
className={`field-${path.replace(/\./g, '__')}`}
|
||||
@@ -201,7 +203,11 @@ const NumberFieldComponent: React.FC<NumberFieldProps> = (props) => {
|
||||
{AfterInput}
|
||||
</div>
|
||||
)}
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,11 +1,12 @@
|
||||
'use client'
|
||||
import type { ClientValidate, Description, Validate } from 'payload/types'
|
||||
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import React, { useCallback } from 'react'
|
||||
|
||||
import type { FormFieldBase } from '../shared/index.js'
|
||||
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { fieldBaseClass } from '../shared/index.js'
|
||||
@@ -28,12 +29,13 @@ export type PasswordFieldProps = FormFieldBase & {
|
||||
export const PasswordField: React.FC<PasswordFieldProps> = (props) => {
|
||||
const {
|
||||
name,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
autoComplete,
|
||||
className,
|
||||
disabled,
|
||||
label,
|
||||
errorProps,
|
||||
labelProps,
|
||||
path: pathFromProps,
|
||||
required,
|
||||
style,
|
||||
@@ -41,8 +43,6 @@ export const PasswordField: React.FC<PasswordFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const memoizedValidate: ClientValidate = useCallback(
|
||||
(value, options) => {
|
||||
if (typeof validate === 'function') {
|
||||
@@ -67,8 +67,8 @@ export const PasswordField: React.FC<PasswordFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<input
|
||||
autoComplete={autoComplete}
|
||||
disabled={formProcessing || disabled}
|
||||
|
||||
@@ -5,7 +5,6 @@ import type { ClientValidate, FieldBase } from 'payload/types'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import React, { useCallback } from 'react'
|
||||
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
@@ -14,6 +13,10 @@ import './index.scss'
|
||||
|
||||
const baseClass = 'point'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
|
||||
import type { FormFieldBase } from '../shared/index.js'
|
||||
|
||||
export type PointFieldProps = FormFieldBase & {
|
||||
@@ -30,11 +33,13 @@ const PointField: React.FC<PointFieldProps> = (props) => {
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
label,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
labelProps,
|
||||
path: pathFromProps,
|
||||
placeholder,
|
||||
readOnly,
|
||||
@@ -45,8 +50,6 @@ const PointField: React.FC<PointFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
const memoizedValidate: ClientValidate = useCallback(
|
||||
@@ -97,10 +100,10 @@ const PointField: React.FC<PointFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
<ul className={`${baseClass}__wrap`}>
|
||||
<li>
|
||||
{Label}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<div className="input-wrapper">
|
||||
{BeforeInput}
|
||||
<input
|
||||
@@ -117,7 +120,7 @@ const PointField: React.FC<PointFieldProps> = (props) => {
|
||||
</div>
|
||||
</li>
|
||||
<li>
|
||||
{Label}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<div className="input-wrapper">
|
||||
{BeforeInput}
|
||||
<input
|
||||
@@ -134,7 +137,11 @@ const PointField: React.FC<PointFieldProps> = (props) => {
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -6,8 +6,8 @@ import type { FieldBase, Option } from 'payload/types'
|
||||
import { optionIsObject } from 'payload/types'
|
||||
import React, { useCallback } from 'react'
|
||||
|
||||
import { FieldLabel } from '../../forms/FieldLabel/index.js'
|
||||
import { useForm } from '../../forms/Form/context.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { fieldBaseClass } from '../shared/index.js'
|
||||
@@ -16,6 +16,9 @@ import './index.scss'
|
||||
|
||||
const baseClass = 'radio-group'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
|
||||
import type { FormFieldBase } from '../shared/index.js'
|
||||
|
||||
export type RadioFieldProps = FormFieldBase & {
|
||||
@@ -34,11 +37,13 @@ export type OnChange<T = string> = (value: T) => void
|
||||
const RadioGroupField: React.FC<RadioFieldProps> = (props) => {
|
||||
const {
|
||||
name,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
label,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
labelProps,
|
||||
layout = 'horizontal',
|
||||
onChange: onChangeFromProps,
|
||||
options = [],
|
||||
@@ -53,8 +58,6 @@ const RadioGroupField: React.FC<RadioFieldProps> = (props) => {
|
||||
|
||||
const { uuid } = useForm()
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const memoizedValidate = useCallback(
|
||||
(value, validationOptions) => {
|
||||
if (typeof validate === 'function')
|
||||
@@ -92,8 +95,10 @@ const RadioGroupField: React.FC<RadioFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
<div className={`${baseClass}__error-wrap`}>{Error}</div>
|
||||
{Label}
|
||||
<div className={`${baseClass}__error-wrap`}>
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
</div>
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<ul className={`${baseClass}--group`} id={`field-${path.replace(/\./g, '__')}`}>
|
||||
{options.map((option) => {
|
||||
let optionValue = ''
|
||||
@@ -130,7 +135,11 @@ const RadioGroupField: React.FC<RadioFieldProps> = (props) => {
|
||||
)
|
||||
})}
|
||||
</ul>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -2,6 +2,9 @@
|
||||
import type { PaginatedDocs } from 'payload/database'
|
||||
import type { Where } from 'payload/types'
|
||||
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import { wordBoundariesRegex } from 'payload/utilities'
|
||||
import qs from 'qs'
|
||||
import React, { useCallback, useEffect, useReducer, useRef, useState } from 'react'
|
||||
@@ -36,13 +39,16 @@ export { RelationshipFieldProps }
|
||||
const RelationshipField: React.FC<RelationshipFieldProps> = (props) => {
|
||||
const {
|
||||
name,
|
||||
Description,
|
||||
Error,
|
||||
Label,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
allowCreate = true,
|
||||
className,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
hasMany,
|
||||
isSortable = true,
|
||||
labelProps,
|
||||
path: pathFromProps,
|
||||
readOnly,
|
||||
relationTo,
|
||||
@@ -434,8 +440,8 @@ const RelationshipField: React.FC<RelationshipFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
{!errorLoading && (
|
||||
<div className={`${baseClass}__wrap`}>
|
||||
<ReactSelect
|
||||
@@ -527,7 +533,11 @@ const RelationshipField: React.FC<RelationshipFieldProps> = (props) => {
|
||||
</div>
|
||||
)}
|
||||
{errorLoading && <div className={`${baseClass}__error-loading`}>{errorLoading}</div>}
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,12 +3,14 @@
|
||||
import type { ClientValidate, FieldBase, Option, OptionObject } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import React, { useCallback, useState } from 'react'
|
||||
|
||||
import type { FormFieldBase } from '../shared/index.js'
|
||||
|
||||
import { ReactSelect } from '../../elements/ReactSelect/index.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
@@ -45,14 +47,16 @@ export const SelectField: React.FC<SelectFieldProps> = (props) => {
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
hasMany = false,
|
||||
isClearable = true,
|
||||
isSortable = true,
|
||||
label,
|
||||
labelProps,
|
||||
onChange: onChangeFromProps,
|
||||
options: optionsFromProps = [],
|
||||
path: pathFromProps,
|
||||
@@ -63,8 +67,6 @@ export const SelectField: React.FC<SelectFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
const [options] = useState(formatOptions(optionsFromProps))
|
||||
@@ -143,8 +145,8 @@ export const SelectField: React.FC<SelectFieldProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
<div>
|
||||
{BeforeInput}
|
||||
<ReactSelect
|
||||
@@ -162,7 +164,11 @@ export const SelectField: React.FC<SelectFieldProps> = (props) => {
|
||||
/>
|
||||
{AfterInput}
|
||||
</div>
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ import type { FieldPermissions } from 'payload/auth'
|
||||
import type { DocumentPreferences } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { toKebabCase } from 'payload/utilities'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
@@ -39,8 +40,9 @@ export type TabsFieldProps = FormFieldBase & {
|
||||
const TabsField: React.FC<TabsFieldProps> = (props) => {
|
||||
const {
|
||||
name,
|
||||
Description,
|
||||
CustomDescription,
|
||||
className,
|
||||
descriptionProps,
|
||||
forceRender = false,
|
||||
indexPath,
|
||||
path: pathFromProps,
|
||||
@@ -143,7 +145,11 @@ const TabsField: React.FC<TabsFieldProps> = (props) => {
|
||||
.filter(Boolean)
|
||||
.join(' ')}
|
||||
>
|
||||
{Description}
|
||||
{CustomDescription ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
<RenderFields
|
||||
fieldMap={activeTabConfig.fieldMap}
|
||||
forceRender={forceRender}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
'use client'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import React from 'react'
|
||||
|
||||
import type { TextInputProps } from './types.js'
|
||||
@@ -13,12 +16,15 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
|
||||
const {
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
hasMany,
|
||||
inputRef,
|
||||
labelProps,
|
||||
maxRows,
|
||||
onChange,
|
||||
onKeyDown,
|
||||
@@ -52,8 +58,8 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
{hasMany ? (
|
||||
<ReactSelect
|
||||
className={`field-${path.replace(/\./g, '__')}`}
|
||||
@@ -97,7 +103,11 @@ export const TextInput: React.FC<TextInputProps> = (props) => {
|
||||
{AfterInput}
|
||||
</div>
|
||||
)}
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import React, { useCallback, useEffect, useState } from 'react'
|
||||
import type { Option } from '../../elements/ReactSelect/types.js'
|
||||
import type { TextFieldProps, TextInputProps } from './types.js'
|
||||
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { useConfig } from '../../providers/Config/index.js'
|
||||
@@ -23,13 +22,15 @@ const TextField: React.FC<TextFieldProps> = (props) => {
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
hasMany,
|
||||
inputRef,
|
||||
label,
|
||||
labelProps,
|
||||
localized,
|
||||
maxLength,
|
||||
maxRows,
|
||||
@@ -44,8 +45,6 @@ const TextField: React.FC<TextFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const locale = useLocale()
|
||||
|
||||
const { localization: localizationConfig } = useConfig()
|
||||
@@ -115,12 +114,15 @@ const TextField: React.FC<TextFieldProps> = (props) => {
|
||||
<TextInput
|
||||
AfterInput={AfterInput}
|
||||
BeforeInput={BeforeInput}
|
||||
Description={Description}
|
||||
Error={Error}
|
||||
Label={Label}
|
||||
CustomDescription={CustomDescription}
|
||||
CustomError={CustomError}
|
||||
CustomLabel={CustomLabel}
|
||||
className={className}
|
||||
descriptionProps={descriptionProps}
|
||||
errorProps={errorProps}
|
||||
hasMany={hasMany}
|
||||
inputRef={inputRef}
|
||||
labelProps={labelProps}
|
||||
maxRows={maxRows}
|
||||
minRows={minRows}
|
||||
onChange={
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
'use client'
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import React from 'react'
|
||||
|
||||
import type { TextAreaInputProps } from './types.js'
|
||||
@@ -12,10 +15,13 @@ export const TextareaInput: React.FC<TextAreaInputProps> = (props) => {
|
||||
const {
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
labelProps,
|
||||
onChange,
|
||||
path,
|
||||
placeholder,
|
||||
@@ -46,8 +52,8 @@ export const TextareaInput: React.FC<TextAreaInputProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
{BeforeInput}
|
||||
<label className="textarea-outer" htmlFor={`field-${path.replace(/\./g, '__')}`}>
|
||||
<div className="textarea-inner">
|
||||
@@ -66,7 +72,11 @@ export const TextareaInput: React.FC<TextAreaInputProps> = (props) => {
|
||||
</div>
|
||||
</label>
|
||||
{AfterInput}
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import React, { useCallback } from 'react'
|
||||
|
||||
import type { TextAreaInputProps, TextareaFieldProps } from './types.js'
|
||||
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { withCondition } from '../../forms/withCondition/index.js'
|
||||
import { useConfig } from '../../providers/Config/index.js'
|
||||
@@ -23,11 +22,13 @@ const TextareaField: React.FC<TextareaFieldProps> = (props) => {
|
||||
name,
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
label,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
labelProps,
|
||||
locale,
|
||||
localized,
|
||||
maxLength,
|
||||
@@ -42,8 +43,6 @@ const TextareaField: React.FC<TextareaFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { i18n } = useTranslation()
|
||||
|
||||
const { localization } = useConfig()
|
||||
@@ -72,10 +71,13 @@ const TextareaField: React.FC<TextareaFieldProps> = (props) => {
|
||||
<TextareaInput
|
||||
AfterInput={AfterInput}
|
||||
BeforeInput={BeforeInput}
|
||||
Description={Description}
|
||||
Error={Error}
|
||||
Label={Label}
|
||||
CustomDescription={CustomDescription}
|
||||
CustomError={CustomError}
|
||||
CustomLabel={CustomLabel}
|
||||
className={className}
|
||||
descriptionProps={descriptionProps}
|
||||
errorProps={errorProps}
|
||||
labelProps={labelProps}
|
||||
onChange={(e) => {
|
||||
setValue(e.target.value)
|
||||
}}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
import type { ClientCollectionConfig, FilterOptionsResult, UploadField } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import { FieldError } from '@payloadcms/ui/forms/FieldError'
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import React, { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
import type { DocumentDrawerProps } from '../../elements/DocumentDrawer/types.js'
|
||||
@@ -13,7 +16,6 @@ import { Button } from '../../elements/Button/index.js'
|
||||
import { useDocumentDrawer } from '../../elements/DocumentDrawer/index.js'
|
||||
import { FileDetails } from '../../elements/FileDetails/index.js'
|
||||
import { useListDrawer } from '../../elements/ListDrawer/index.js'
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import { fieldBaseClass } from '../shared/index.js'
|
||||
import './index.scss'
|
||||
@@ -33,14 +35,17 @@ export type UploadInputProps = Omit<UploadFieldProps, 'filterOptions'> & {
|
||||
|
||||
export const UploadInput: React.FC<UploadInputProps> = (props) => {
|
||||
const {
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
api = '/api',
|
||||
className,
|
||||
collection,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
filterOptions,
|
||||
label,
|
||||
labelProps,
|
||||
onChange,
|
||||
readOnly,
|
||||
relationTo,
|
||||
@@ -52,8 +57,6 @@ export const UploadInput: React.FC<UploadInputProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const { i18n, t } = useTranslation()
|
||||
|
||||
const [file, setFile] = useState(undefined)
|
||||
@@ -130,8 +133,8 @@ export const UploadInput: React.FC<UploadInputProps> = (props) => {
|
||||
width,
|
||||
}}
|
||||
>
|
||||
{Error}
|
||||
{Label}
|
||||
{CustomError !== undefined ? CustomError : <FieldError {...(errorProps || {})} />}
|
||||
{CustomLabel !== undefined ? CustomLabel : <FieldLabel {...(labelProps || {})} />}
|
||||
{collection?.upload && (
|
||||
<React.Fragment>
|
||||
{file && !missingFile && (
|
||||
@@ -166,7 +169,11 @@ export const UploadInput: React.FC<UploadInputProps> = (props) => {
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
{Description}
|
||||
{CustomDescription !== undefined ? (
|
||||
CustomDescription
|
||||
) : (
|
||||
<FieldDescription {...(descriptionProps || {})} />
|
||||
)}
|
||||
</React.Fragment>
|
||||
)}
|
||||
{!readOnly && <DocumentDrawer onSave={onSave} />}
|
||||
|
||||
@@ -4,7 +4,6 @@ import React, { useCallback } from 'react'
|
||||
import type { UploadInputProps } from './Input.js'
|
||||
import type { UploadFieldProps } from './types.js'
|
||||
|
||||
import { Label as LabelComp } from '../../forms/Label/index.js'
|
||||
import { useField } from '../../forms/useField/index.js'
|
||||
import { useConfig } from '../../providers/Config/index.js'
|
||||
import { UploadInput } from './Input.js'
|
||||
@@ -15,11 +14,14 @@ export type { UploadInputProps }
|
||||
|
||||
export const Upload: React.FC<UploadFieldProps> = (props) => {
|
||||
const {
|
||||
Description,
|
||||
Error,
|
||||
Label: LabelFromProps,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
className,
|
||||
descriptionProps,
|
||||
errorProps,
|
||||
label,
|
||||
labelProps,
|
||||
path: pathFromProps,
|
||||
readOnly,
|
||||
relationTo,
|
||||
@@ -29,8 +31,6 @@ export const Upload: React.FC<UploadFieldProps> = (props) => {
|
||||
width,
|
||||
} = props
|
||||
|
||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||
|
||||
const {
|
||||
collections,
|
||||
routes: { api },
|
||||
@@ -64,13 +64,16 @@ export const Upload: React.FC<UploadFieldProps> = (props) => {
|
||||
if (collection.upload) {
|
||||
return (
|
||||
<UploadInput
|
||||
Description={Description}
|
||||
Error={Error}
|
||||
Label={Label}
|
||||
CustomDescription={CustomDescription}
|
||||
CustomError={CustomError}
|
||||
CustomLabel={CustomLabel}
|
||||
api={api}
|
||||
className={className}
|
||||
collection={collection}
|
||||
descriptionProps={descriptionProps}
|
||||
errorProps={errorProps}
|
||||
filterOptions={filterOptions}
|
||||
labelProps={labelProps}
|
||||
onChange={onChange}
|
||||
path={path}
|
||||
readOnly={readOnly}
|
||||
|
||||
@@ -1,18 +1,23 @@
|
||||
import type { User } from 'payload/auth'
|
||||
import type { Locale, SanitizedLocalizationConfig } from 'payload/config'
|
||||
import type { DocumentPreferences, Validate } from 'payload/types'
|
||||
import type { DocumentPreferences, ErrorProps, LabelProps, Validate } from 'payload/types'
|
||||
|
||||
import type { FieldDescriptionProps } from '../../forms/FieldDescription/types.js'
|
||||
|
||||
export const fieldBaseClass = 'field-type'
|
||||
|
||||
export type FormFieldBase = {
|
||||
AfterInput?: React.ReactNode
|
||||
BeforeInput?: React.ReactNode
|
||||
Description?: React.ReactNode
|
||||
Error?: React.ReactNode
|
||||
Label?: React.ReactNode
|
||||
CustomDescription?: React.ReactNode
|
||||
CustomError?: React.ReactNode
|
||||
CustomLabel?: React.ReactNode
|
||||
className?: string
|
||||
descriptionProps?: FieldDescriptionProps
|
||||
disabled?: boolean
|
||||
docPreferences?: DocumentPreferences
|
||||
errorProps?: ErrorProps
|
||||
labelProps?: LabelProps
|
||||
locale?: Locale
|
||||
localized?: boolean
|
||||
path?: string
|
||||
|
||||
@@ -2,17 +2,17 @@
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import React from 'react'
|
||||
|
||||
import type { Props } from './types.js'
|
||||
import type { FieldDescriptionProps } from './types.js'
|
||||
|
||||
import { useTranslation } from '../../providers/Translation/index.js'
|
||||
import { useFieldProps } from '../FieldPropsProvider/index.js'
|
||||
import './index.scss'
|
||||
|
||||
export { Props as FieldDescriptionProps }
|
||||
export { FieldDescriptionProps }
|
||||
|
||||
const baseClass = 'field-description'
|
||||
|
||||
export const FieldDescription: React.FC<Props> = (props) => {
|
||||
export const FieldDescription: React.FC<FieldDescriptionProps> = (props) => {
|
||||
const { className, description, marginPlacement } = props
|
||||
|
||||
const { path } = useFieldProps()
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
export type Props = {
|
||||
export type FieldDescriptionProps = {
|
||||
className?: string
|
||||
description?: Record<string, string> | string
|
||||
marginPlacement?: 'bottom' | 'top'
|
||||
|
||||
@@ -11,7 +11,7 @@ import './index.scss'
|
||||
|
||||
const baseClass = 'field-error'
|
||||
|
||||
export const Error: React.FC<ErrorProps> = (props) => {
|
||||
export const FieldError: React.FC<ErrorProps> = (props) => {
|
||||
const {
|
||||
alignCaret = 'right',
|
||||
message: messageFromProps,
|
||||
@@ -10,7 +10,7 @@ import { useFieldProps } from '../FieldPropsProvider/index.js'
|
||||
import { useForm } from '../Form/context.js'
|
||||
import './index.scss'
|
||||
|
||||
export const Label: React.FC<LabelProps> = (props) => {
|
||||
export const FieldLabel: React.FC<LabelProps> = (props) => {
|
||||
const { htmlFor: htmlForFromProps, label: labelFromProps, required = false } = props
|
||||
const { uuid } = useForm()
|
||||
const { path } = useFieldProps()
|
||||
@@ -30,6 +30,7 @@ export const buildComponentMap = (args: {
|
||||
}
|
||||
|
||||
const editViewFromConfig = collectionConfig?.admin?.components?.views?.Edit
|
||||
|
||||
const listViewFromConfig = collectionConfig?.admin?.components?.views?.List
|
||||
|
||||
const CustomEditView =
|
||||
@@ -52,6 +53,7 @@ export const buildComponentMap = (args: {
|
||||
: undefined
|
||||
|
||||
const Edit = (CustomEditView as React.FC<EditViewProps>) || DefaultEditView
|
||||
|
||||
const List = CustomListView || DefaultListView
|
||||
|
||||
const beforeList = collectionConfig?.admin?.components?.BeforeList
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { FieldDescriptionProps } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import type { CellProps, Field, FieldWithPath, LabelProps, SanitizedConfig } from 'payload/types'
|
||||
|
||||
import { fieldAffectsData, fieldIsPresentationalOnly } from 'payload/types'
|
||||
@@ -25,7 +26,6 @@ import type { TextFieldProps } from '../../../fields/Text/types.js'
|
||||
import type { TextareaFieldProps } from '../../../fields/Textarea/types.js'
|
||||
import type { UploadFieldProps } from '../../../fields/Upload/types.js'
|
||||
import type { FormFieldBase } from '../../../fields/shared/index.js'
|
||||
import type { Props as FieldDescription } from '../../../forms/FieldDescription/types.js'
|
||||
import type {
|
||||
FieldComponentProps,
|
||||
FieldMap,
|
||||
@@ -34,11 +34,7 @@ import type {
|
||||
ReducedBlock,
|
||||
} from './types.js'
|
||||
|
||||
import { RenderCustomComponent } from '../../../elements/RenderCustomComponent/index.js'
|
||||
import { HiddenInput } from '../../../fields/HiddenInput/index.js'
|
||||
import { Error as DefaultError } from '../../../forms/Error/index.js'
|
||||
import { FieldDescription as DefaultDescription } from '../../../forms/FieldDescription/index.js'
|
||||
import { Label as DefaultLabel } from '../../../forms/Label/index.js'
|
||||
|
||||
export const mapFields = (args: {
|
||||
config: SanitizedConfig
|
||||
@@ -89,7 +85,7 @@ export const mapFields = (args: {
|
||||
required: 'required' in field ? field.required : undefined,
|
||||
}
|
||||
|
||||
const descriptionProps: FieldDescription = {
|
||||
const descriptionProps: FieldDescriptionProps = {
|
||||
description:
|
||||
field.admin &&
|
||||
'description' in field.admin &&
|
||||
@@ -111,75 +107,83 @@ export const mapFields = (args: {
|
||||
readOnly: readOnlyOverride,
|
||||
})
|
||||
|
||||
const AfterInput = 'admin' in field &&
|
||||
'components' in field.admin &&
|
||||
'afterInput' in field.admin.components &&
|
||||
Array.isArray(field.admin?.components?.afterInput) && (
|
||||
<Fragment>
|
||||
{field.admin.components.afterInput.map((Component, i) => (
|
||||
<Component key={i} />
|
||||
))}
|
||||
</Fragment>
|
||||
)
|
||||
const AfterInput =
|
||||
('admin' in field &&
|
||||
'components' in field.admin &&
|
||||
'afterInput' in field.admin.components &&
|
||||
Array.isArray(field.admin?.components?.afterInput) && (
|
||||
<Fragment>
|
||||
{field.admin.components.afterInput.map((Component, i) => (
|
||||
<Component key={i} />
|
||||
))}
|
||||
</Fragment>
|
||||
)) ||
|
||||
null
|
||||
|
||||
const BeforeInput = 'admin' in field &&
|
||||
field.admin?.components &&
|
||||
'beforeInput' in field.admin.components &&
|
||||
Array.isArray(field.admin.components.beforeInput) && (
|
||||
<Fragment>
|
||||
{field.admin.components.beforeInput.map((Component, i) => (
|
||||
<Component key={i} />
|
||||
))}
|
||||
</Fragment>
|
||||
)
|
||||
const BeforeInput =
|
||||
('admin' in field &&
|
||||
field.admin?.components &&
|
||||
'beforeInput' in field.admin.components &&
|
||||
Array.isArray(field.admin.components.beforeInput) && (
|
||||
<Fragment>
|
||||
{field.admin.components.beforeInput.map((Component, i) => (
|
||||
<Component key={i} />
|
||||
))}
|
||||
</Fragment>
|
||||
)) ||
|
||||
null
|
||||
|
||||
const Description = (
|
||||
<RenderCustomComponent
|
||||
CustomComponent={
|
||||
field.admin &&
|
||||
'description' in field.admin &&
|
||||
field.admin.description &&
|
||||
typeof field.admin.description === 'function' &&
|
||||
(field.admin.description as React.FC<any>)
|
||||
}
|
||||
DefaultComponent={DefaultDescription}
|
||||
componentProps={descriptionProps}
|
||||
/>
|
||||
)
|
||||
const CustomDescriptionComponent =
|
||||
(field.admin &&
|
||||
'description' in field.admin &&
|
||||
field.admin.description &&
|
||||
typeof field.admin.description === 'function' &&
|
||||
(field.admin.description as React.FC<any>)) ||
|
||||
undefined
|
||||
|
||||
const Error = (
|
||||
<RenderCustomComponent
|
||||
CustomComponent={
|
||||
'admin' in field &&
|
||||
field.admin.components &&
|
||||
'Error' in field.admin.components &&
|
||||
field.admin?.components?.Error
|
||||
}
|
||||
DefaultComponent={DefaultError}
|
||||
componentProps={{ path }}
|
||||
/>
|
||||
)
|
||||
const CustomDescription =
|
||||
CustomDescriptionComponent !== undefined ? (
|
||||
<CustomDescriptionComponent {...(descriptionProps || {})} />
|
||||
) : undefined
|
||||
|
||||
const Label = (
|
||||
<RenderCustomComponent
|
||||
CustomComponent={
|
||||
'admin' in field &&
|
||||
field.admin?.components &&
|
||||
'Label' in field.admin.components &&
|
||||
field.admin?.components?.Label
|
||||
}
|
||||
DefaultComponent={DefaultLabel}
|
||||
componentProps={labelProps}
|
||||
/>
|
||||
)
|
||||
const CustomErrorComponent =
|
||||
('admin' in field &&
|
||||
field.admin?.components &&
|
||||
'Error' in field.admin.components &&
|
||||
field.admin?.components?.Error) ||
|
||||
undefined
|
||||
|
||||
const errorProps = {
|
||||
path,
|
||||
}
|
||||
|
||||
const CustomError =
|
||||
CustomErrorComponent !== undefined ? (
|
||||
<CustomErrorComponent {...(errorProps || {})} />
|
||||
) : undefined
|
||||
|
||||
const CustomLabelComponent =
|
||||
('admin' in field &&
|
||||
field.admin?.components &&
|
||||
'Label' in field.admin.components &&
|
||||
field.admin?.components?.Label) ||
|
||||
undefined
|
||||
|
||||
const CustomLabel =
|
||||
CustomLabelComponent !== undefined ? (
|
||||
<CustomLabelComponent {...(labelProps || {})} />
|
||||
) : undefined
|
||||
|
||||
const baseFieldProps: FormFieldBase = {
|
||||
AfterInput,
|
||||
BeforeInput,
|
||||
Description,
|
||||
Error,
|
||||
Label,
|
||||
CustomDescription,
|
||||
CustomError,
|
||||
CustomLabel,
|
||||
descriptionProps,
|
||||
disabled: 'admin' in field && 'disabled' in field.admin ? field.admin?.disabled : false,
|
||||
errorProps,
|
||||
labelProps,
|
||||
path,
|
||||
required: 'required' in field ? field.required : undefined,
|
||||
}
|
||||
@@ -324,7 +328,7 @@ export const mapFields = (args: {
|
||||
|
||||
const collapsibleField: Omit<CollapsibleFieldProps, 'indexPath' | 'permissions'> = {
|
||||
...baseFieldProps,
|
||||
Label: CollapsibleLabel,
|
||||
CustomLabel: CollapsibleLabel,
|
||||
className: field.admin?.className,
|
||||
disabled: field.admin?.disabled,
|
||||
fieldMap: nestedFieldMap,
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { HiddenInputFieldProps } from '@payloadcms/ui/fields/HiddenInput'
|
||||
import type { FieldTypes } from 'payload/config'
|
||||
import type {
|
||||
BlockField,
|
||||
@@ -50,6 +51,7 @@ export type FieldComponentProps =
|
||||
| DateFieldProps
|
||||
| EmailFieldProps
|
||||
| GroupFieldProps
|
||||
| HiddenInputFieldProps
|
||||
| JSONFieldProps
|
||||
| NumberFieldProps
|
||||
| PointFieldProps
|
||||
|
||||
@@ -154,4 +154,4 @@
|
||||
".next/types/**/*.ts",
|
||||
"scripts/**/*.ts"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user