chore(ui): strictly types fields (#5344)
This commit is contained in:
@@ -50,10 +50,11 @@ export const SetStepNav: React.FC<{
|
|||||||
|
|
||||||
if (mostRecentDoc) {
|
if (mostRecentDoc) {
|
||||||
if (useAsTitle !== 'id') {
|
if (useAsTitle !== 'id') {
|
||||||
const titleField = fieldMap.find(
|
const titleField = fieldMap.find((f) => {
|
||||||
({ name: fieldName, isFieldAffectingData }) =>
|
const { isFieldAffectingData } = f
|
||||||
isFieldAffectingData && fieldName === useAsTitle,
|
const fieldName = 'name' in f ? f.name : undefined
|
||||||
) as FieldAffectingData
|
return isFieldAffectingData && fieldName === useAsTitle
|
||||||
|
}) as FieldAffectingData
|
||||||
|
|
||||||
if (titleField && mostRecentDoc[useAsTitle]) {
|
if (titleField && mostRecentDoc[useAsTitle]) {
|
||||||
if (titleField.localized) {
|
if (titleField.localized) {
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ const Iterable: React.FC<Props> = ({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={baseClass}>
|
<div className={baseClass}>
|
||||||
{field.label && (
|
{'label' in field && field.label && (
|
||||||
<Label>
|
<Label>
|
||||||
{locale && <span className={`${baseClass}__locale-label`}>{locale}</span>}
|
{locale && <span className={`${baseClass}__locale-label`}>{locale}</span>}
|
||||||
{getTranslation(field.label, i18n)}
|
{getTranslation(field.label, i18n)}
|
||||||
@@ -40,12 +40,12 @@ const Iterable: React.FC<Props> = ({
|
|||||||
const versionRow = version?.[i] || {}
|
const versionRow = version?.[i] || {}
|
||||||
const comparisonRow = comparison?.[i] || {}
|
const comparisonRow = comparison?.[i] || {}
|
||||||
|
|
||||||
let subFields: MappedField[] = []
|
let fieldMap: MappedField[] = []
|
||||||
|
|
||||||
if (field.type === 'array') subFields = field.subfields
|
if (field.type === 'array' && 'fieldMap' in field) fieldMap = field.fieldMap
|
||||||
|
|
||||||
if (field.type === 'blocks') {
|
if (field.type === 'blocks') {
|
||||||
subFields = [
|
fieldMap = [
|
||||||
// {
|
// {
|
||||||
// name: 'blockType',
|
// name: 'blockType',
|
||||||
// label: i18n.t('fields:blockType'),
|
// label: i18n.t('fields:blockType'),
|
||||||
@@ -54,25 +54,28 @@ const Iterable: React.FC<Props> = ({
|
|||||||
]
|
]
|
||||||
|
|
||||||
if (versionRow?.blockType === comparisonRow?.blockType) {
|
if (versionRow?.blockType === comparisonRow?.blockType) {
|
||||||
const matchedBlock = field.blocks.find(
|
const matchedBlock = ('blocks' in field &&
|
||||||
(block) => block.slug === versionRow?.blockType,
|
field.blocks?.find((block) => block.slug === versionRow?.blockType)) || {
|
||||||
) || { subfields: [] }
|
fieldMap: [],
|
||||||
|
}
|
||||||
|
|
||||||
subFields = [...subFields, ...matchedBlock.subfields]
|
fieldMap = [...fieldMap, ...matchedBlock.fieldMap]
|
||||||
} else {
|
} else {
|
||||||
const matchedVersionBlock = field.blocks.find(
|
const matchedVersionBlock = ('blocks' in field &&
|
||||||
(block) => block.slug === versionRow?.blockType,
|
field.blocks?.find((block) => block.slug === versionRow?.blockType)) || {
|
||||||
) || { subfields: [] }
|
fieldMap: [],
|
||||||
|
}
|
||||||
|
|
||||||
const matchedComparisonBlock = field.blocks.find(
|
const matchedComparisonBlock = ('blocks' in field &&
|
||||||
(block) => block.slug === comparisonRow?.blockType,
|
field.blocks?.find((block) => block.slug === comparisonRow?.blockType)) || {
|
||||||
) || { subfields: [] }
|
fieldMap: [],
|
||||||
|
}
|
||||||
|
|
||||||
subFields = getUniqueListBy<MappedField>(
|
fieldMap = getUniqueListBy<MappedField>(
|
||||||
[
|
[
|
||||||
...subFields,
|
...fieldMap,
|
||||||
...matchedVersionBlock.subfields,
|
...matchedVersionBlock.fieldMap,
|
||||||
...matchedComparisonBlock.subfields,
|
...matchedComparisonBlock.fieldMap,
|
||||||
],
|
],
|
||||||
'name',
|
'name',
|
||||||
)
|
)
|
||||||
@@ -84,7 +87,7 @@ const Iterable: React.FC<Props> = ({
|
|||||||
<RenderFieldsToDiff
|
<RenderFieldsToDiff
|
||||||
comparison={comparisonRow}
|
comparison={comparisonRow}
|
||||||
diffComponents={diffComponents}
|
diffComponents={diffComponents}
|
||||||
fieldMap={subFields}
|
fieldMap={fieldMap}
|
||||||
fieldPermissions={permissions}
|
fieldPermissions={permissions}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
locales={locales}
|
locales={locales}
|
||||||
@@ -98,9 +101,10 @@ const Iterable: React.FC<Props> = ({
|
|||||||
{maxRows === 0 && (
|
{maxRows === 0 && (
|
||||||
<div className={`${baseClass}__no-rows`}>
|
<div className={`${baseClass}__no-rows`}>
|
||||||
{i18n.t('version:noRowsFound', {
|
{i18n.t('version:noRowsFound', {
|
||||||
label: field.labels?.plural
|
label:
|
||||||
? getTranslation(field.labels?.plural, i18n)
|
'labels' in field && field.labels?.plural
|
||||||
: i18n.t('general:rows'),
|
? getTranslation(field.labels?.plural, i18n)
|
||||||
|
: i18n.t('general:rows'),
|
||||||
})}
|
})}
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const Nested: React.FC<Props> = ({
|
|||||||
}) => {
|
}) => {
|
||||||
return (
|
return (
|
||||||
<div className={baseClass}>
|
<div className={baseClass}>
|
||||||
{field.label && (
|
{'label' in field && field.label && (
|
||||||
<Label>
|
<Label>
|
||||||
{locale && <span className={`${baseClass}__locale-label`}>{locale}</span>}
|
{locale && <span className={`${baseClass}__locale-label`}>{locale}</span>}
|
||||||
{getTranslation(field.label, i18n)}
|
{getTranslation(field.label, i18n)}
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ const Relationship: React.FC<Props> = ({ comparison, field, i18n, locale, versio
|
|||||||
let versionToRender = version
|
let versionToRender = version
|
||||||
let comparisonToRender = comparison
|
let comparisonToRender = comparison
|
||||||
|
|
||||||
if (field.hasMany) {
|
if ('hasMany' in field && field.hasMany) {
|
||||||
if (Array.isArray(version))
|
if (Array.isArray(version))
|
||||||
versionToRender = version
|
versionToRender = version
|
||||||
.map((val) => generateLabelFromValue(collections, field, locale, val))
|
.map((val) => generateLabelFromValue(collections, field, locale, val))
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
import type { I18n } from '@payloadcms/translations'
|
import type { I18n } from '@payloadcms/translations'
|
||||||
|
import type { SelectFieldProps } from 'packages/ui/src/forms/fields/Select/types.js'
|
||||||
|
import type { MappedFieldBase } from 'packages/ui/src/utilities/buildComponentMap/types.js'
|
||||||
import type { OptionObject, SelectField } from 'payload/types'
|
import type { OptionObject, SelectField } from 'payload/types'
|
||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
@@ -44,7 +46,11 @@ const getTranslatedOptions = (
|
|||||||
return typeof options === 'string' ? options : getTranslation(options.label, i18n)
|
return typeof options === 'string' ? options : getTranslation(options.label, i18n)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Select: React.FC<Props> = ({ comparison, diffMethod, field, i18n, locale, version }) => {
|
const Select: React.FC<
|
||||||
|
Omit<Props, 'field'> & {
|
||||||
|
field: MappedFieldBase & SelectFieldProps
|
||||||
|
}
|
||||||
|
> = ({ comparison, diffMethod, field, i18n, locale, version }) => {
|
||||||
let placeholder = ''
|
let placeholder = ''
|
||||||
|
|
||||||
if (version === comparison) placeholder = `[${i18n.t('general:noValue')}]`
|
if (version === comparison) placeholder = `[${i18n.t('general:noValue')}]`
|
||||||
@@ -63,7 +69,7 @@ const Select: React.FC<Props> = ({ comparison, diffMethod, field, i18n, locale,
|
|||||||
<div className={baseClass}>
|
<div className={baseClass}>
|
||||||
<Label>
|
<Label>
|
||||||
{locale && <span className={`${baseClass}__locale-label`}>{locale}</span>}
|
{locale && <span className={`${baseClass}__locale-label`}>{locale}</span>}
|
||||||
{getTranslation(field.label || '', i18n)}
|
{'label' in field && getTranslation(field.label || '', i18n)}
|
||||||
</Label>
|
</Label>
|
||||||
<DiffViewer
|
<DiffViewer
|
||||||
comparisonToRender={comparisonToRender}
|
comparisonToRender={comparisonToRender}
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
import type { TabsFieldProps } from 'packages/ui/src/forms/fields/Tabs/types.js'
|
||||||
|
import type { MappedFieldBase } from 'packages/ui/src/utilities/buildComponentMap/types.js'
|
||||||
|
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import type { Props } from '../types.js'
|
import type { Props } from '../types.js'
|
||||||
@@ -7,16 +10,11 @@ import Nested from '../Nested/index.js'
|
|||||||
|
|
||||||
const baseClass = 'tabs-diff'
|
const baseClass = 'tabs-diff'
|
||||||
|
|
||||||
const Tabs: React.FC<Props> = ({
|
const Tabs: React.FC<
|
||||||
comparison,
|
Omit<Props, 'field'> & {
|
||||||
diffComponents,
|
field: MappedFieldBase & TabsFieldProps
|
||||||
field,
|
}
|
||||||
i18n,
|
> = ({ comparison, diffComponents, field, i18n, locale, locales, permissions, version }) => {
|
||||||
locale,
|
|
||||||
locales,
|
|
||||||
permissions,
|
|
||||||
version,
|
|
||||||
}) => {
|
|
||||||
return (
|
return (
|
||||||
<div className={baseClass}>
|
<div className={baseClass}>
|
||||||
<div className={`${baseClass}__wrap`}>
|
<div className={`${baseClass}__wrap`}>
|
||||||
@@ -27,7 +25,7 @@ const Tabs: React.FC<Props> = ({
|
|||||||
comparison={comparison?.[tab.name]}
|
comparison={comparison?.[tab.name]}
|
||||||
diffComponents={diffComponents}
|
diffComponents={diffComponents}
|
||||||
field={field}
|
field={field}
|
||||||
fieldMap={tab.subfields}
|
fieldMap={tab.fieldMap}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
key={i}
|
key={i}
|
||||||
locale={locale}
|
locale={locale}
|
||||||
@@ -42,7 +40,7 @@ const Tabs: React.FC<Props> = ({
|
|||||||
<RenderFieldsToDiff
|
<RenderFieldsToDiff
|
||||||
comparison={comparison}
|
comparison={comparison}
|
||||||
diffComponents={diffComponents}
|
diffComponents={diffComponents}
|
||||||
fieldMap={tab.subfields}
|
fieldMap={tab.fieldMap}
|
||||||
fieldPermissions={permissions}
|
fieldPermissions={permissions}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
key={i}
|
key={i}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ const Text: React.FC<Props> = ({
|
|||||||
<div className={baseClass}>
|
<div className={baseClass}>
|
||||||
<Label>
|
<Label>
|
||||||
{locale && <span className={`${baseClass}__locale-label`}>{locale}</span>}
|
{locale && <span className={`${baseClass}__locale-label`}>{locale}</span>}
|
||||||
{getTranslation(field?.label || '', i18n)}
|
{'label' in field && getTranslation(field?.label || '', i18n)}
|
||||||
</Label>
|
</Label>
|
||||||
<DiffViewer
|
<DiffViewer
|
||||||
comparisonToRender={comparisonToRender}
|
comparisonToRender={comparisonToRender}
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
|||||||
return (
|
return (
|
||||||
<div className={baseClass}>
|
<div className={baseClass}>
|
||||||
{fieldMap?.map((field, i) => {
|
{fieldMap?.map((field, i) => {
|
||||||
if (field.name === 'id') return null
|
if ('name' in field && field.name === 'id') return null
|
||||||
|
|
||||||
const Component = diffComponents[field.type]
|
const Component = diffComponents[field.type]
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
|||||||
const diffMethod: DiffMethod = diffMethods[field.type] || 'CHARS'
|
const diffMethod: DiffMethod = diffMethods[field.type] || 'CHARS'
|
||||||
|
|
||||||
if (Component) {
|
if (Component) {
|
||||||
if (field.isFieldAffectingData) {
|
if (field.isFieldAffectingData && 'name' in field) {
|
||||||
const valueIsObject = field.type === 'code' || field.type === 'json'
|
const valueIsObject = field.type === 'code' || field.type === 'json'
|
||||||
|
|
||||||
const versionValue = valueIsObject
|
const versionValue = valueIsObject
|
||||||
@@ -53,7 +53,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
|||||||
diffComponents,
|
diffComponents,
|
||||||
diffMethod,
|
diffMethod,
|
||||||
field,
|
field,
|
||||||
fieldMap: 'subfields' in field ? field.subfields : fieldMap,
|
fieldMap: 'fieldMap' in field ? field.fieldMap : fieldMap,
|
||||||
fieldPermissions: subFieldPermissions,
|
fieldPermissions: subFieldPermissions,
|
||||||
i18n,
|
i18n,
|
||||||
isRichText,
|
isRichText,
|
||||||
@@ -93,7 +93,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (field.type === 'tabs') {
|
if (field.type === 'tabs' && 'fieldMap' in field) {
|
||||||
const Tabs = diffComponents.tabs
|
const Tabs = diffComponents.tabs
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -101,7 +101,7 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
|||||||
comparison={comparison}
|
comparison={comparison}
|
||||||
diffComponents={diffComponents}
|
diffComponents={diffComponents}
|
||||||
field={field}
|
field={field}
|
||||||
fieldMap={field.subfields}
|
fieldMap={field.fieldMap}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
key={i}
|
key={i}
|
||||||
locales={locales}
|
locales={locales}
|
||||||
@@ -111,14 +111,14 @@ const RenderFieldsToDiff: React.FC<Props> = ({
|
|||||||
}
|
}
|
||||||
|
|
||||||
// At this point, we are dealing with a `row`, etc
|
// At this point, we are dealing with a `row`, etc
|
||||||
if (field.subfields) {
|
if ('fieldMap' in field) {
|
||||||
return (
|
return (
|
||||||
<Nested
|
<Nested
|
||||||
comparison={comparison}
|
comparison={comparison}
|
||||||
diffComponents={diffComponents}
|
diffComponents={diffComponents}
|
||||||
disableGutter
|
disableGutter
|
||||||
field={field}
|
field={field}
|
||||||
fieldMap={field.subfields}
|
fieldMap={field.fieldMap}
|
||||||
i18n={i18n}
|
i18n={i18n}
|
||||||
key={i}
|
key={i}
|
||||||
locales={locales}
|
locales={locales}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ export const RichText: React.FC<
|
|||||||
editorConfig: SanitizedClientEditorConfig // With rendered features n stuff
|
editorConfig: SanitizedClientEditorConfig // With rendered features n stuff
|
||||||
name: string
|
name: string
|
||||||
richTextComponentMap: Map<string, React.ReactNode>
|
richTextComponentMap: Map<string, React.ReactNode>
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
> = (props) => {
|
> = (props) => {
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import type { FieldMap, FormFieldBase } from '@payloadcms/ui'
|
import type { FieldMap, FormFieldBase } from '@payloadcms/ui'
|
||||||
import type { ReducedBlock } from '@payloadcms/ui/types'
|
import type { ReducedBlock } from '@payloadcms/ui'
|
||||||
import type { FormState } from 'payload/types'
|
import type { FormState } from 'payload/types'
|
||||||
import type { Data } from 'payload/types'
|
import type { Data } from 'payload/types'
|
||||||
|
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'
|
|||||||
import { type BlockFields } from '../nodes/BlocksNode.js'
|
import { type BlockFields } from '../nodes/BlocksNode.js'
|
||||||
const baseClass = 'lexical-block'
|
const baseClass = 'lexical-block'
|
||||||
|
|
||||||
import type { ReducedBlock } from '@payloadcms/ui/types'
|
import type { ReducedBlock } from '@payloadcms/ui'
|
||||||
import type { FormState } from 'payload/types'
|
import type { FormState } from 'payload/types'
|
||||||
|
|
||||||
import { v4 as uuid } from 'uuid'
|
import { v4 as uuid } from 'uuid'
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
'use client'
|
'use client'
|
||||||
|
|
||||||
import type { ReducedBlock } from '@payloadcms/ui/types'
|
import type { ReducedBlock } from '@payloadcms/ui'
|
||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
|
|
||||||
|
|||||||
@@ -43,10 +43,10 @@ export const BlocksFeature: FeatureProviderProviderServer<
|
|||||||
for (const block of props.blocks) {
|
for (const block of props.blocks) {
|
||||||
clientProps.reducedBlocks.push({
|
clientProps.reducedBlocks.push({
|
||||||
slug: block.slug,
|
slug: block.slug,
|
||||||
|
fieldMap: [],
|
||||||
imageAltText: block.imageAltText,
|
imageAltText: block.imageAltText,
|
||||||
imageURL: block.imageURL,
|
imageURL: block.imageURL,
|
||||||
labels: block.labels,
|
labels: block.labels,
|
||||||
subfields: [],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import type { FormState } from 'payload/types'
|
|||||||
|
|
||||||
import {
|
import {
|
||||||
Drawer,
|
Drawer,
|
||||||
FieldPathProvider,
|
|
||||||
Form,
|
Form,
|
||||||
type FormProps,
|
type FormProps,
|
||||||
FormSubmit,
|
FormSubmit,
|
||||||
@@ -79,7 +78,6 @@ export const LinkDrawer: React.FC<Props> = ({ drawerSlug, handleModalSubmit, sta
|
|||||||
<Drawer className={baseClass} slug={drawerSlug} title={t('fields:editLink') ?? ''}>
|
<Drawer className={baseClass} slug={drawerSlug} title={t('fields:editLink') ?? ''}>
|
||||||
{initialState !== false && (
|
{initialState !== false && (
|
||||||
<Form
|
<Form
|
||||||
// @ts-expect-error // TODO: Fix this type. Is this correct?
|
|
||||||
fields={Array.isArray(fieldMap) ? fieldMap : []}
|
fields={Array.isArray(fieldMap) ? fieldMap : []}
|
||||||
initialState={initialState}
|
initialState={initialState}
|
||||||
onChange={[onChange]}
|
onChange={[onChange]}
|
||||||
|
|||||||
@@ -45,8 +45,10 @@ const RichTextField: React.FC<
|
|||||||
elements: EnabledFeatures['elements']
|
elements: EnabledFeatures['elements']
|
||||||
leaves: EnabledFeatures['leaves']
|
leaves: EnabledFeatures['leaves']
|
||||||
name: string
|
name: string
|
||||||
|
placeholder?: string
|
||||||
plugins: RichTextPlugin[]
|
plugins: RichTextPlugin[]
|
||||||
richTextComponentMap: Map<string, React.ReactNode>
|
richTextComponentMap: Map<string, React.ReactNode>
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
> = (props) => {
|
> = (props) => {
|
||||||
const {
|
const {
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ export const EditMany: React.FC<Props> = (props) => {
|
|||||||
const reducedFieldMap = []
|
const reducedFieldMap = []
|
||||||
fieldMap.map((field) => {
|
fieldMap.map((field) => {
|
||||||
selected.map((selectedField) => {
|
selected.map((selectedField) => {
|
||||||
if (field.name === selectedField.name) {
|
if ('name' in field && field.name === selectedField.name) {
|
||||||
reducedFieldMap.push(field)
|
reducedFieldMap.push(field)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -27,8 +27,8 @@ export const buildColumns = (args: {
|
|||||||
// sort the fields to the order of `defaultColumns` or `columnPreferences`
|
// sort the fields to the order of `defaultColumns` or `columnPreferences`
|
||||||
// TODO: flatten top level field, i.e. `flattenTopLevelField()` from `payload` but that is typed for `Field`, not `fieldMap`
|
// TODO: flatten top level field, i.e. `flattenTopLevelField()` from `payload` but that is typed for `Field`, not `fieldMap`
|
||||||
sortedFieldMap = fieldMap.sort((a, b) => {
|
sortedFieldMap = fieldMap.sort((a, b) => {
|
||||||
const aIndex = sortTo.findIndex((column) => column.accessor === a.name)
|
const aIndex = sortTo.findIndex((column) => 'name' in a && column.accessor === a.name)
|
||||||
const bIndex = sortTo.findIndex((column) => column.accessor === b.name)
|
const bIndex = sortTo.findIndex((column) => 'name' in b && column.accessor === b.name)
|
||||||
if (aIndex === -1 && bIndex === -1) return 0
|
if (aIndex === -1 && bIndex === -1) return 0
|
||||||
if (aIndex === -1) return 1
|
if (aIndex === -1) return 1
|
||||||
if (bIndex === -1) return -1
|
if (bIndex === -1) return -1
|
||||||
@@ -40,7 +40,7 @@ export const buildColumns = (args: {
|
|||||||
|
|
||||||
const sorted = sortedFieldMap.reduce((acc, field, index) => {
|
const sorted = sortedFieldMap.reduce((acc, field, index) => {
|
||||||
const columnPreference = columnPreferences?.find(
|
const columnPreference = columnPreferences?.find(
|
||||||
(preference) => preference.accessor === field.name,
|
(preference) => 'name' in field && preference.accessor === field.name,
|
||||||
)
|
)
|
||||||
|
|
||||||
let active = false
|
let active = false
|
||||||
@@ -48,7 +48,7 @@ export const buildColumns = (args: {
|
|||||||
if (columnPreference) {
|
if (columnPreference) {
|
||||||
active = columnPreference.active
|
active = columnPreference.active
|
||||||
} else if (defaultColumns && Array.isArray(defaultColumns) && defaultColumns.length > 0) {
|
} else if (defaultColumns && Array.isArray(defaultColumns) && defaultColumns.length > 0) {
|
||||||
active = defaultColumns.includes(field.name)
|
active = 'name' in field && defaultColumns.includes(field.name)
|
||||||
} else if (activeColumnsIndices.length < 4) {
|
} else if (activeColumnsIndices.length < 4) {
|
||||||
active = true
|
active = true
|
||||||
}
|
}
|
||||||
@@ -61,8 +61,8 @@ export const buildColumns = (args: {
|
|||||||
|
|
||||||
if (field) {
|
if (field) {
|
||||||
const column: Column = {
|
const column: Column = {
|
||||||
name: field.name,
|
name: 'name' in field ? field.name : undefined,
|
||||||
accessor: field.name,
|
accessor: 'name' in field ? field.name : undefined,
|
||||||
active,
|
active,
|
||||||
cellProps: {
|
cellProps: {
|
||||||
...cellProps?.[index],
|
...cellProps?.[index],
|
||||||
@@ -72,7 +72,7 @@ export const buildColumns = (args: {
|
|||||||
Cell: field.Cell,
|
Cell: field.Cell,
|
||||||
Heading: field.Heading,
|
Heading: field.Heading,
|
||||||
},
|
},
|
||||||
label: field.label,
|
label: 'label' in field ? field.label : undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
acc.push(column)
|
acc.push(column)
|
||||||
|
|||||||
@@ -23,31 +23,41 @@ export { default as FormSubmit } from '../forms/Submit/index.js'
|
|||||||
export { default as Submit } from '../forms/Submit/index.js'
|
export { default as Submit } from '../forms/Submit/index.js'
|
||||||
export { buildStateFromSchema } from '../forms/buildStateFromSchema/index.js'
|
export { buildStateFromSchema } from '../forms/buildStateFromSchema/index.js'
|
||||||
export type { BuildFormStateArgs } from '../forms/buildStateFromSchema/index.js'
|
export type { BuildFormStateArgs } from '../forms/buildStateFromSchema/index.js'
|
||||||
|
export type { ArrayFieldProps } from '../forms/fields/Array/types.js'
|
||||||
export { default as SectionTitle } from '../forms/fields/Blocks/SectionTitle/index.js'
|
export { default as SectionTitle } from '../forms/fields/Blocks/SectionTitle/index.js'
|
||||||
|
export type { BlocksFieldProps } from '../forms/fields/Blocks/types.js'
|
||||||
export { CheckboxInput } from '../forms/fields/Checkbox/Input.js'
|
export { CheckboxInput } from '../forms/fields/Checkbox/Input.js'
|
||||||
export { default as Checkbox } from '../forms/fields/Checkbox/index.js'
|
export { default as Checkbox } from '../forms/fields/Checkbox/index.js'
|
||||||
|
export type { CheckboxFieldProps } from '../forms/fields/Checkbox/types.js'
|
||||||
|
export type { CodeFieldProps } from '../forms/fields/Code/types.js'
|
||||||
export { default as ConfirmPassword } from '../forms/fields/ConfirmPassword/index.js'
|
export { default as ConfirmPassword } from '../forms/fields/ConfirmPassword/index.js'
|
||||||
|
export type { DateFieldProps } from '../forms/fields/DateTime/types.js'
|
||||||
export { default as Email } from '../forms/fields/Email/index.js'
|
export { default as Email } from '../forms/fields/Email/index.js'
|
||||||
|
export type { EmailFieldProps } from '../forms/fields/Email/types.js'
|
||||||
|
export type { GroupFieldProps } from '../forms/fields/Group/types.js'
|
||||||
export { default as HiddenInput } from '../forms/fields/HiddenInput/index.js'
|
export { default as HiddenInput } from '../forms/fields/HiddenInput/index.js'
|
||||||
|
export type { HiddenInputFieldProps } from '../forms/fields/HiddenInput/types.js'
|
||||||
|
export type { JSONFieldProps } from '../forms/fields/JSON/types.js'
|
||||||
export { default as Number } from '../forms/fields/Number/index.js'
|
export { default as Number } from '../forms/fields/Number/index.js'
|
||||||
|
|
||||||
|
export type { NumberFieldProps } from '../forms/fields/Number/types.js'
|
||||||
|
|
||||||
export { default as Password } from '../forms/fields/Password/index.js'
|
export { default as Password } from '../forms/fields/Password/index.js'
|
||||||
export { default as RadioGroupInput } from '../forms/fields/RadioGroup/index.js'
|
export { default as RadioGroupInput } from '../forms/fields/RadioGroup/index.js'
|
||||||
export type { OnChange } from '../forms/fields/RadioGroup/types.js'
|
export type { OnChange } from '../forms/fields/RadioGroup/types.js'
|
||||||
export { default as Select } from '../forms/fields/Select/index.js'
|
export { default as Select } from '../forms/fields/Select/index.js'
|
||||||
export { default as SelectInput } from '../forms/fields/Select/index.js'
|
export { default as SelectInput } from '../forms/fields/Select/index.js'
|
||||||
|
|
||||||
export { TextInput, type TextInputProps } from '../forms/fields/Text/Input.js'
|
export { TextInput, type TextInputProps } from '../forms/fields/Text/Input.js'
|
||||||
|
|
||||||
export { default as Text } from '../forms/fields/Text/index.js'
|
export { default as Text } from '../forms/fields/Text/index.js'
|
||||||
export type { Props as TextFieldProps } from '../forms/fields/Text/types.js'
|
|
||||||
export { type TextAreaInputProps, TextareaInput } from '../forms/fields/Textarea/Input.js'
|
export { type TextAreaInputProps, TextareaInput } from '../forms/fields/Textarea/Input.js'
|
||||||
export { default as Textarea } from '../forms/fields/Textarea/index.js'
|
export { default as Textarea } from '../forms/fields/Textarea/index.js'
|
||||||
|
|
||||||
export { UploadInput, type UploadInputProps } from '../forms/fields/Upload/Input.js'
|
export { UploadInput, type UploadInputProps } from '../forms/fields/Upload/Input.js'
|
||||||
|
|
||||||
export { default as UploadField } from '../forms/fields/Upload/index.js'
|
export { default as UploadField } from '../forms/fields/Upload/index.js'
|
||||||
export { fieldTypes } from '../forms/fields/index.js'
|
export { fieldTypes } from '../forms/fields/index.js'
|
||||||
export { fieldBaseClass } from '../forms/fields/shared.js'
|
export { fieldBaseClass } from '../forms/fields/shared.js'
|
||||||
export { useField } from '../forms/useField/index.js'
|
export { useField } from '../forms/useField/index.js'
|
||||||
export type { FieldType, Options } from '../forms/useField/types.js'
|
|
||||||
export { withCondition } from '../forms/withCondition/index.js'
|
export { withCondition } from '../forms/withCondition/index.js'
|
||||||
|
|
||||||
export { buildComponentMap } from '../utilities/buildComponentMap/index.js'
|
export { buildComponentMap } from '../utilities/buildComponentMap/index.js'
|
||||||
|
export type { ReducedBlock } from '../utilities/buildComponentMap/types.js'
|
||||||
|
|||||||
@@ -7,4 +7,3 @@ import type React from 'react'
|
|||||||
// import { Link } from 'next/link'
|
// import { Link } from 'next/link'
|
||||||
export type LinkType = React.ElementType
|
export type LinkType = React.ElementType
|
||||||
export type { FormFieldBase } from '../forms/fields/shared.js'
|
export type { FormFieldBase } from '../forms/fields/shared.js'
|
||||||
export type { ReducedBlock } from '../utilities/buildComponentMap/types.js'
|
|
||||||
|
|||||||
@@ -53,7 +53,11 @@ export const RenderFields: React.FC<Props> = (props) => {
|
|||||||
ref={intersectionRef}
|
ref={intersectionRef}
|
||||||
>
|
>
|
||||||
{hasRendered &&
|
{hasRendered &&
|
||||||
fieldMap?.map(({ name, Field, disabled, readOnly }, fieldIndex) => {
|
fieldMap?.map((f, fieldIndex) => {
|
||||||
|
const { Field, disabled, readOnly } = f
|
||||||
|
|
||||||
|
const name = 'name' in f ? f.name : undefined
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<RenderField
|
<RenderField
|
||||||
Field={Field}
|
Field={Field}
|
||||||
|
|||||||
@@ -2,24 +2,29 @@ import type { FieldMap } from '../../utilities/buildComponentMap/types.js'
|
|||||||
|
|
||||||
export const buildPathSegments = (parentPath: string, fieldMap: FieldMap): string[] => {
|
export const buildPathSegments = (parentPath: string, fieldMap: FieldMap): string[] => {
|
||||||
const pathNames = fieldMap.reduce((acc, subField) => {
|
const pathNames = fieldMap.reduce((acc, subField) => {
|
||||||
if (subField.subfields && subField.isFieldAffectingData) {
|
if ('fieldMap' in subField) {
|
||||||
// group, block, array
|
if (subField.fieldMap && subField.isFieldAffectingData) {
|
||||||
acc.push(parentPath ? `${parentPath}.${subField.name}.` : `${subField.name}.`)
|
// group, block, array
|
||||||
} else if (subField.subfields) {
|
const name = 'name' in subField ? subField.name : 'unnamed'
|
||||||
// rows, collapsibles, unnamed-tab
|
acc.push(parentPath ? `${parentPath}.${name}.` : `${name}.`)
|
||||||
acc.push(...buildPathSegments(parentPath, subField.subfields))
|
} else if (subField.fieldMap) {
|
||||||
} else if (subField.type === 'tabs') {
|
// rows, collapsibles, unnamed-tab
|
||||||
// tabs
|
acc.push(...buildPathSegments(parentPath, subField.fieldMap))
|
||||||
subField.tabs.forEach((tab) => {
|
} else if (subField.type === 'tabs') {
|
||||||
let tabPath = parentPath
|
// tabs
|
||||||
if ('name' in tab) {
|
'tabs' in subField &&
|
||||||
tabPath = parentPath ? `${parentPath}.${tab.name}` : tab.name
|
subField.tabs?.forEach((tab) => {
|
||||||
}
|
let tabPath = parentPath
|
||||||
acc.push(...buildPathSegments(tabPath, tab.subfields))
|
if ('name' in tab) {
|
||||||
})
|
tabPath = parentPath ? `${parentPath}.${tab.name}` : tab.name
|
||||||
} else if (subField.isFieldAffectingData) {
|
}
|
||||||
// text, number, date, etc.
|
acc.push(...buildPathSegments(tabPath, tab.fieldMap))
|
||||||
acc.push(parentPath ? `${parentPath}.${subField.name}` : subField.name)
|
})
|
||||||
|
} else if (subField.isFieldAffectingData) {
|
||||||
|
// text, number, date, etc.
|
||||||
|
const name = 'name' in subField ? subField.name : 'unnamed'
|
||||||
|
acc.push(parentPath ? `${parentPath}.${name}` : name)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return acc
|
return acc
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { ArrayFieldProps } from './types.js'
|
||||||
|
|
||||||
import Banner from '../../../elements/Banner/index.js'
|
import Banner from '../../../elements/Banner/index.js'
|
||||||
import { Button } from '../../../elements/Button/index.js'
|
import { Button } from '../../../elements/Button/index.js'
|
||||||
@@ -24,7 +24,7 @@ import './index.scss'
|
|||||||
|
|
||||||
const baseClass = 'array-field'
|
const baseClass = 'array-field'
|
||||||
|
|
||||||
const ArrayFieldType: React.FC<Props> = (props) => {
|
const ArrayFieldType: React.FC<ArrayFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
Description,
|
Description,
|
||||||
@@ -37,6 +37,8 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
|||||||
indexPath,
|
indexPath,
|
||||||
label,
|
label,
|
||||||
localized,
|
localized,
|
||||||
|
maxRows,
|
||||||
|
minRows,
|
||||||
path: pathFromProps,
|
path: pathFromProps,
|
||||||
permissions,
|
permissions,
|
||||||
readOnly,
|
readOnly,
|
||||||
@@ -46,9 +48,6 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
|||||||
|
|
||||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||||
|
|
||||||
const minRows = 'minRows' in props ? props?.minRows : 0
|
|
||||||
const maxRows = 'maxRows' in props ? props?.maxRows : undefined
|
|
||||||
|
|
||||||
const { setDocFieldPreferences } = useDocumentInfo()
|
const { setDocFieldPreferences } = useDocumentInfo()
|
||||||
const { addFieldRow, dispatchFields, setModified } = useForm()
|
const { addFieldRow, dispatchFields, setModified } = useForm()
|
||||||
const submitted = useFormSubmitted()
|
const submitted = useFormSubmitted()
|
||||||
@@ -66,7 +65,7 @@ const ArrayFieldType: React.FC<Props> = (props) => {
|
|||||||
})()
|
})()
|
||||||
|
|
||||||
// Handle labeling for Arrays, Global Arrays, and Blocks
|
// Handle labeling for Arrays, Global Arrays, and Blocks
|
||||||
const getLabels = (p: Props) => {
|
const getLabels = (p: ArrayFieldProps) => {
|
||||||
if ('labels' in p && p?.labels) return p.labels
|
if ('labels' in p && p?.labels) return p.labels
|
||||||
if ('label' in p && p?.label) return { plural: undefined, singular: p.label }
|
if ('label' in p && p?.label) return { plural: undefined, singular: p.label }
|
||||||
return { plural: t('general:rows'), singular: t('general:row') }
|
return { plural: t('general:rows'), singular: t('general:row') }
|
||||||
|
|||||||
@@ -1,11 +1,19 @@
|
|||||||
|
import type { FieldMap } from '@payloadcms/ui'
|
||||||
import type { FieldPermissions } from 'payload/auth'
|
import type { FieldPermissions } from 'payload/auth'
|
||||||
|
import type { ArrayField, FieldBase, RowLabel } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type ArrayFieldProps = FormFieldBase & {
|
||||||
|
RowLabel?: React.ReactNode
|
||||||
|
fieldMap: FieldMap
|
||||||
forceRender?: boolean
|
forceRender?: boolean
|
||||||
indexPath: string
|
indexPath: string
|
||||||
label: false | string
|
label?: FieldBase['label']
|
||||||
|
labels?: ArrayField['labels']
|
||||||
|
maxRows?: ArrayField['maxRows']
|
||||||
|
minRows?: ArrayField['minRows']
|
||||||
name?: string
|
name?: string
|
||||||
permissions: FieldPermissions
|
permissions: FieldPermissions
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ export const BlockRow: React.FC<BlockFieldProps> = ({
|
|||||||
blockType={row.blockType}
|
blockType={row.blockType}
|
||||||
blocks={blocks}
|
blocks={blocks}
|
||||||
duplicateRow={duplicateRow}
|
duplicateRow={duplicateRow}
|
||||||
fieldMap={block.subfields}
|
fieldMap={block.fieldMap}
|
||||||
hasMaxRows={hasMaxRows}
|
hasMaxRows={hasMaxRows}
|
||||||
labels={labels}
|
labels={labels}
|
||||||
moveRow={moveRow}
|
moveRow={moveRow}
|
||||||
@@ -135,7 +135,7 @@ export const BlockRow: React.FC<BlockFieldProps> = ({
|
|||||||
<HiddenInput name={`${path}.id`} value={row.id} />
|
<HiddenInput name={`${path}.id`} value={row.id} />
|
||||||
<RenderFields
|
<RenderFields
|
||||||
className={`${baseClass}__fields`}
|
className={`${baseClass}__fields`}
|
||||||
fieldMap={block.subfields}
|
fieldMap={block.fieldMap}
|
||||||
forceRender={forceRender}
|
forceRender={forceRender}
|
||||||
margins="small"
|
margins="small"
|
||||||
path={path}
|
path={path}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { Fragment, useCallback } from 'react'
|
import React, { Fragment, useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { BlocksFieldProps } from './types.js'
|
||||||
|
|
||||||
import Banner from '../../../elements/Banner/index.js'
|
import Banner from '../../../elements/Banner/index.js'
|
||||||
import { Button } from '../../../elements/Button/index.js'
|
import { Button } from '../../../elements/Button/index.js'
|
||||||
@@ -27,7 +27,7 @@ import './index.scss'
|
|||||||
|
|
||||||
const baseClass = 'blocks-field'
|
const baseClass = 'blocks-field'
|
||||||
|
|
||||||
const BlocksField: React.FC<Props> = (props) => {
|
const BlocksField: React.FC<BlocksFieldProps> = (props) => {
|
||||||
const { i18n, t } = useTranslation()
|
const { i18n, t } = useTranslation()
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -35,11 +35,15 @@ const BlocksField: React.FC<Props> = (props) => {
|
|||||||
Description,
|
Description,
|
||||||
Error,
|
Error,
|
||||||
Label: LabelFromProps,
|
Label: LabelFromProps,
|
||||||
|
blocks,
|
||||||
className,
|
className,
|
||||||
forceRender = false,
|
forceRender = false,
|
||||||
indexPath,
|
indexPath,
|
||||||
label,
|
label,
|
||||||
|
labels: labelsFromProps,
|
||||||
localized,
|
localized,
|
||||||
|
maxRows,
|
||||||
|
minRows,
|
||||||
path: pathFromProps,
|
path: pathFromProps,
|
||||||
readOnly,
|
readOnly,
|
||||||
required,
|
required,
|
||||||
@@ -48,11 +52,6 @@ const BlocksField: React.FC<Props> = (props) => {
|
|||||||
|
|
||||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||||
|
|
||||||
const minRows = 'minRows' in props ? props?.minRows : 0
|
|
||||||
const maxRows = 'maxRows' in props ? props?.maxRows : undefined
|
|
||||||
const blocks = 'blocks' in props ? props?.blocks : undefined
|
|
||||||
const labelsFromProps = 'labels' in props ? props?.labels : undefined
|
|
||||||
|
|
||||||
const { setDocFieldPreferences } = useDocumentInfo()
|
const { setDocFieldPreferences } = useDocumentInfo()
|
||||||
const { addFieldRow, dispatchFields, setModified } = useForm()
|
const { addFieldRow, dispatchFields, setModified } = useForm()
|
||||||
const { code: locale } = useLocale()
|
const { code: locale } = useLocale()
|
||||||
|
|||||||
@@ -1,10 +1,20 @@
|
|||||||
|
import type { FieldMap, ReducedBlock } from '@payloadcms/ui'
|
||||||
import type { FieldPermissions } from 'payload/auth'
|
import type { FieldPermissions } from 'payload/auth'
|
||||||
|
import type { BlockField, FieldBase } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type BlocksFieldProps = FormFieldBase & {
|
||||||
|
blocks?: ReducedBlock[]
|
||||||
|
fieldMap: FieldMap
|
||||||
forceRender?: boolean
|
forceRender?: boolean
|
||||||
indexPath: string
|
indexPath: string
|
||||||
|
label?: FieldBase['label']
|
||||||
|
labels?: BlockField['labels']
|
||||||
|
maxRows?: number
|
||||||
|
minRows?: number
|
||||||
name?: string
|
name?: string
|
||||||
permissions: FieldPermissions
|
permissions: FieldPermissions
|
||||||
|
slug?: string
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { ClientValidate } from 'payload/types'
|
|||||||
|
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { CheckboxFieldProps } from './types.js'
|
||||||
|
|
||||||
import { generateFieldID } from '../../../utilities/generateFieldID.js'
|
import { generateFieldID } from '../../../utilities/generateFieldID.js'
|
||||||
import { useForm } from '../../Form/context.js'
|
import { useForm } from '../../Form/context.js'
|
||||||
@@ -16,7 +16,7 @@ import './index.scss'
|
|||||||
|
|
||||||
const baseClass = 'checkbox'
|
const baseClass = 'checkbox'
|
||||||
|
|
||||||
const Checkbox: React.FC<Props> = (props) => {
|
const Checkbox: React.FC<CheckboxFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
|
|||||||
@@ -1,11 +1,15 @@
|
|||||||
|
import type { FieldBase } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type CheckboxFieldProps = FormFieldBase & {
|
||||||
checked?: boolean
|
checked?: boolean
|
||||||
disableFormData?: boolean
|
disableFormData?: boolean
|
||||||
id?: string
|
id?: string
|
||||||
|
label?: FieldBase['label']
|
||||||
name?: string
|
name?: string
|
||||||
onChange?: (val: boolean) => void
|
onChange?: (val: boolean) => void
|
||||||
partialChecked?: boolean
|
partialChecked?: boolean
|
||||||
path?: string
|
path?: string
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { CodeFieldProps } from './types.js'
|
||||||
|
|
||||||
import { CodeEditor } from '../../../elements/CodeEditor/index.js'
|
import { CodeEditor } from '../../../elements/CodeEditor/index.js'
|
||||||
import LabelComp from '../../Label/index.js'
|
import LabelComp from '../../Label/index.js'
|
||||||
@@ -18,7 +18,7 @@ const prismToMonacoLanguageMap = {
|
|||||||
|
|
||||||
const baseClass = 'code-field'
|
const baseClass = 'code-field'
|
||||||
|
|
||||||
const Code: React.FC<Props> = (props) => {
|
const Code: React.FC<CodeFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
AfterInput,
|
AfterInput,
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
|
import type { CodeField, FieldBase } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type CodeFieldProps = FormFieldBase & {
|
||||||
|
editorOptions?: CodeField['admin']['editorOptions']
|
||||||
|
label?: FieldBase['label']
|
||||||
|
language?: CodeField['admin']['language']
|
||||||
name?: string
|
name?: string
|
||||||
path?: string
|
path?: string
|
||||||
|
width: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { DocumentPreferences } from 'payload/types'
|
|||||||
|
|
||||||
import React, { Fragment, useCallback, useEffect, useState } from 'react'
|
import React, { Fragment, useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { CollapsibleFieldProps } from './types.js'
|
||||||
|
|
||||||
import { Collapsible } from '../../../elements/Collapsible/index.js'
|
import { Collapsible } from '../../../elements/Collapsible/index.js'
|
||||||
import { ErrorPill } from '../../../elements/ErrorPill/index.js'
|
import { ErrorPill } from '../../../elements/ErrorPill/index.js'
|
||||||
@@ -21,7 +21,7 @@ import './index.scss'
|
|||||||
|
|
||||||
const baseClass = 'collapsible-field'
|
const baseClass = 'collapsible-field'
|
||||||
|
|
||||||
const CollapsibleField: React.FC<Props> = (props) => {
|
const CollapsibleField: React.FC<CollapsibleFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
Description,
|
Description,
|
||||||
Label: LabelFromProps,
|
Label: LabelFromProps,
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
|
import type { FieldMap } from '@payloadcms/ui'
|
||||||
import type { FieldPermissions } from 'payload/auth'
|
import type { FieldPermissions } from 'payload/auth'
|
||||||
import type { FieldTypes } from 'payload/config'
|
import type { FieldTypes } from 'payload/config'
|
||||||
|
import type { FieldBase } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type CollapsibleFieldProps = FormFieldBase & {
|
||||||
|
fieldMap: FieldMap
|
||||||
fieldTypes: FieldTypes
|
fieldTypes: FieldTypes
|
||||||
indexPath: string
|
indexPath: string
|
||||||
|
initCollapsed?: boolean
|
||||||
|
label?: FieldBase['label']
|
||||||
permissions: FieldPermissions
|
permissions: FieldPermissions
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { FormField } from 'payload/types'
|
|||||||
|
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { ConfirmPasswordFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
import Error from '../../Error/index.js'
|
import Error from '../../Error/index.js'
|
||||||
@@ -13,7 +13,7 @@ import { useField } from '../../useField/index.js'
|
|||||||
import { fieldBaseClass } from '../shared.js'
|
import { fieldBaseClass } from '../shared.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
const ConfirmPassword: React.FC<Props> = (props) => {
|
const ConfirmPassword: React.FC<ConfirmPasswordFieldProps> = (props) => {
|
||||||
const { disabled } = props
|
const { disabled } = props
|
||||||
|
|
||||||
const password = useFormFields<FormField>(([fields]) => fields.password)
|
const password = useFormFields<FormField>(([fields]) => fields.password)
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
export type Props = {
|
export type ConfirmPasswordFieldProps = {
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,25 +5,27 @@ import type { ClientValidate } from 'payload/types'
|
|||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { DateFieldProps } from './types.js'
|
||||||
|
|
||||||
import { DatePickerField } from '../../../elements/DatePicker/index.js'
|
import { DatePickerField } from '../../../elements/DatePicker/index.js'
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
|
import LabelComp from '../../Label/index.js'
|
||||||
import { useField } from '../../useField/index.js'
|
import { useField } from '../../useField/index.js'
|
||||||
import { fieldBaseClass } from '../shared.js'
|
import { fieldBaseClass } from '../shared.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
const baseClass = 'date-time-field'
|
const baseClass = 'date-time-field'
|
||||||
|
|
||||||
const DateTime: React.FC<Props> = (props) => {
|
const DateTime: React.FC<DateFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
AfterInput,
|
AfterInput,
|
||||||
BeforeInput,
|
BeforeInput,
|
||||||
Description,
|
Description,
|
||||||
Error,
|
Error,
|
||||||
Label: LabelComp,
|
Label: LabelFromProps,
|
||||||
className,
|
className,
|
||||||
|
date: datePickerProps,
|
||||||
label,
|
label,
|
||||||
path: pathFromProps,
|
path: pathFromProps,
|
||||||
placeholder,
|
placeholder,
|
||||||
@@ -34,9 +36,7 @@ const DateTime: React.FC<Props> = (props) => {
|
|||||||
width,
|
width,
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const Label = LabelComp || label
|
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||||
|
|
||||||
const datePickerProps = 'date' in props ? props.date : {}
|
|
||||||
|
|
||||||
const { i18n } = useTranslation()
|
const { i18n } = useTranslation()
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
|
import type { DateField, FieldBase } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type DateFieldProps = FormFieldBase & {
|
||||||
|
date?: DateField['admin']['date']
|
||||||
|
label?: FieldBase['label']
|
||||||
name?: string
|
name?: string
|
||||||
path: string
|
path?: string
|
||||||
|
placeholder?: DateField['admin']['placeholder'] | string
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { ClientValidate } from 'payload/types'
|
|||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { EmailFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
import LabelComp from '../../Label/index.js'
|
import LabelComp from '../../Label/index.js'
|
||||||
@@ -13,7 +13,7 @@ import { withCondition } from '../../withCondition/index.js'
|
|||||||
import { fieldBaseClass } from '../shared.js'
|
import { fieldBaseClass } from '../shared.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
export const Email: React.FC<Props> = (props) => {
|
export const Email: React.FC<EmailFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
AfterInput,
|
AfterInput,
|
||||||
|
|||||||
@@ -1,7 +1,12 @@
|
|||||||
|
import type { EmailField, FieldBase } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type EmailFieldProps = FormFieldBase & {
|
||||||
autoComplete?: string
|
autoComplete?: string
|
||||||
|
label?: FieldBase['label']
|
||||||
name?: string
|
name?: string
|
||||||
path?: string
|
path?: string
|
||||||
|
placeholder?: EmailField['admin']['placeholder']
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import React, { Fragment } from 'react'
|
import React, { Fragment } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { GroupFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useCollapsible } from '../../../elements/Collapsible/provider.js'
|
import { useCollapsible } from '../../../elements/Collapsible/provider.js'
|
||||||
import { ErrorPill } from '../../../elements/ErrorPill/index.js'
|
import { ErrorPill } from '../../../elements/ErrorPill/index.js'
|
||||||
@@ -19,7 +19,7 @@ import { GroupProvider, useGroup } from './provider.js'
|
|||||||
|
|
||||||
const baseClass = 'group-field'
|
const baseClass = 'group-field'
|
||||||
|
|
||||||
const Group: React.FC<Props> = (props) => {
|
const Group: React.FC<GroupFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
Description,
|
Description,
|
||||||
Label: LabelFromProps,
|
Label: LabelFromProps,
|
||||||
|
|||||||
@@ -1,11 +1,16 @@
|
|||||||
|
import type { FieldMap } from '@payloadcms/ui'
|
||||||
import type { FieldPermissions } from 'payload/auth'
|
import type { FieldPermissions } from 'payload/auth'
|
||||||
|
import type { FieldBase } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type GroupFieldProps = FormFieldBase & {
|
||||||
|
fieldMap: FieldMap
|
||||||
forceRender?: boolean
|
forceRender?: boolean
|
||||||
hideGutter?: boolean
|
hideGutter?: boolean
|
||||||
indexPath: string
|
indexPath: string
|
||||||
|
label?: FieldBase['label']
|
||||||
name?: string
|
name?: string
|
||||||
permissions: FieldPermissions
|
permissions: FieldPermissions
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import React, { useEffect } from 'react'
|
import React, { useEffect } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { HiddenInputFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useField } from '../../useField/index.js'
|
import { useField } from '../../useField/index.js'
|
||||||
import { withCondition } from '../../withCondition/index.js'
|
import { withCondition } from '../../withCondition/index.js'
|
||||||
@@ -10,7 +10,7 @@ import { withCondition } from '../../withCondition/index.js'
|
|||||||
* This is mainly used to save a value on the form that is not visible to the user.
|
* This is mainly used to save a value on the form that is not visible to the user.
|
||||||
* For example, this sets the `ìd` property of a block in the Blocks field.
|
* For example, this sets the `ìd` property of a block in the Blocks field.
|
||||||
*/
|
*/
|
||||||
const HiddenInput: React.FC<Props> = (props) => {
|
const HiddenInput: React.FC<HiddenInputFieldProps> = (props) => {
|
||||||
const { name, disableModifyingForm = true, path: pathFromProps, value: valueFromProps } = props
|
const { name, disableModifyingForm = true, path: pathFromProps, value: valueFromProps } = props
|
||||||
|
|
||||||
const { path, setValue, value } = useField({
|
const { path, setValue, value } = useField({
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export type Props = {
|
export type HiddenInputFieldProps = {
|
||||||
disableModifyingForm?: false
|
disableModifyingForm?: false
|
||||||
name: string
|
name: string
|
||||||
path?: string
|
path?: string
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { ClientValidate } from 'payload/types'
|
|||||||
|
|
||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { JSONFieldProps } from './types.js'
|
||||||
|
|
||||||
import { CodeEditor } from '../../../elements/CodeEditor/index.js'
|
import { CodeEditor } from '../../../elements/CodeEditor/index.js'
|
||||||
import LabelComp from '../../Label/index.js'
|
import LabelComp from '../../Label/index.js'
|
||||||
@@ -14,7 +14,7 @@ import './index.scss'
|
|||||||
|
|
||||||
const baseClass = 'json-field'
|
const baseClass = 'json-field'
|
||||||
|
|
||||||
const JSONField: React.FC<Props> = (props) => {
|
const JSONField: React.FC<JSONFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
AfterInput,
|
AfterInput,
|
||||||
@@ -23,6 +23,7 @@ const JSONField: React.FC<Props> = (props) => {
|
|||||||
Error,
|
Error,
|
||||||
Label: LabelFromProps,
|
Label: LabelFromProps,
|
||||||
className,
|
className,
|
||||||
|
editorOptions,
|
||||||
label,
|
label,
|
||||||
path: pathFromProps,
|
path: pathFromProps,
|
||||||
readOnly,
|
readOnly,
|
||||||
@@ -34,9 +35,6 @@ const JSONField: React.FC<Props> = (props) => {
|
|||||||
|
|
||||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||||
|
|
||||||
// eslint-disable-next-line react/destructuring-assignment
|
|
||||||
const editorOptions = 'editorOptions' in props ? props.editorOptions : {}
|
|
||||||
|
|
||||||
const [stringValue, setStringValue] = useState<string>()
|
const [stringValue, setStringValue] = useState<string>()
|
||||||
const [jsonError, setJsonError] = useState<string>()
|
const [jsonError, setJsonError] = useState<string>()
|
||||||
const [hasLoadedValue, setHasLoadedValue] = useState(false)
|
const [hasLoadedValue, setHasLoadedValue] = useState(false)
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
|
import type { FieldBase, JSONField } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type JSONFieldProps = FormFieldBase & {
|
||||||
|
editorOptions?: JSONField['admin']['editorOptions']
|
||||||
|
label?: FieldBase['label']
|
||||||
name?: string
|
name?: string
|
||||||
path?: string
|
path?: string
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { isNumber } from 'payload/utilities'
|
|||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import type { Option } from '../../../elements/ReactSelect/types.js'
|
import type { Option } from '../../../elements/ReactSelect/types.js'
|
||||||
import type { Props } from './types.js'
|
import type { NumberFieldProps } from './types.js'
|
||||||
|
|
||||||
import ReactSelect from '../../../elements/ReactSelect/index.js'
|
import ReactSelect from '../../../elements/ReactSelect/index.js'
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
@@ -15,7 +15,7 @@ import { withCondition } from '../../withCondition/index.js'
|
|||||||
import { fieldBaseClass } from '../shared.js'
|
import { fieldBaseClass } from '../shared.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
const NumberField: React.FC<Props> = (props) => {
|
const NumberField: React.FC<NumberFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
AfterInput,
|
AfterInput,
|
||||||
@@ -24,12 +24,17 @@ const NumberField: React.FC<Props> = (props) => {
|
|||||||
Error,
|
Error,
|
||||||
Label: LabelFromProps,
|
Label: LabelFromProps,
|
||||||
className,
|
className,
|
||||||
|
hasMany = false,
|
||||||
label,
|
label,
|
||||||
|
max = Infinity,
|
||||||
|
maxRows = Infinity,
|
||||||
|
min = -Infinity,
|
||||||
onChange: onChangeFromProps,
|
onChange: onChangeFromProps,
|
||||||
path: pathFromProps,
|
path: pathFromProps,
|
||||||
placeholder,
|
placeholder,
|
||||||
readOnly,
|
readOnly,
|
||||||
required,
|
required,
|
||||||
|
step = 1,
|
||||||
style,
|
style,
|
||||||
validate,
|
validate,
|
||||||
width,
|
width,
|
||||||
@@ -37,12 +42,6 @@ const NumberField: React.FC<Props> = (props) => {
|
|||||||
|
|
||||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||||
|
|
||||||
const max = 'max' in props ? props.max : Infinity
|
|
||||||
const min = 'min' in props ? props.min : -Infinity
|
|
||||||
const step = 'step' in props ? props.step : 1
|
|
||||||
const hasMany = 'hasMany' in props ? props.hasMany : false
|
|
||||||
const maxRows = 'maxRows' in props ? props.maxRows : Infinity
|
|
||||||
|
|
||||||
const { i18n, t } = useTranslation()
|
const { i18n, t } = useTranslation()
|
||||||
|
|
||||||
const memoizedValidate = useCallback(
|
const memoizedValidate = useCallback(
|
||||||
|
|||||||
@@ -1,7 +1,17 @@
|
|||||||
|
import type { FieldBase, NumberField } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type NumberFieldProps = FormFieldBase & {
|
||||||
|
hasMany?: boolean
|
||||||
|
label?: FieldBase['label']
|
||||||
|
max?: number
|
||||||
|
maxRows?: number
|
||||||
|
min?: number
|
||||||
name?: string
|
name?: string
|
||||||
onChange?: (e: number) => void
|
onChange?: (e: number) => void
|
||||||
path?: string
|
path?: string
|
||||||
|
placeholder?: NumberField['admin']['placeholder']
|
||||||
|
step?: number
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import type { ClientValidate } from 'payload/types'
|
|||||||
|
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { PasswordFieldProps } from './types.js'
|
||||||
|
|
||||||
import LabelComp from '../../Label/index.js'
|
import LabelComp from '../../Label/index.js'
|
||||||
import { useField } from '../../useField/index.js'
|
import { useField } from '../../useField/index.js'
|
||||||
@@ -11,7 +11,7 @@ import { withCondition } from '../../withCondition/index.js'
|
|||||||
import { fieldBaseClass } from '../shared.js'
|
import { fieldBaseClass } from '../shared.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
export const Password: React.FC<Props> = (props) => {
|
export const Password: React.FC<PasswordFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
Error,
|
Error,
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type React from 'react'
|
|||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type PasswordFieldProps = FormFieldBase & {
|
||||||
autoComplete?: string
|
autoComplete?: string
|
||||||
className?: string
|
className?: string
|
||||||
description?: Description
|
description?: Description
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type { ClientValidate } from 'payload/types'
|
|||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { PointFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
import LabelComp from '../../Label/index.js'
|
import LabelComp from '../../Label/index.js'
|
||||||
@@ -16,7 +16,7 @@ import './index.scss'
|
|||||||
|
|
||||||
const baseClass = 'point'
|
const baseClass = 'point'
|
||||||
|
|
||||||
const PointField: React.FC<Props> = (props) => {
|
const PointField: React.FC<PointFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
AfterInput,
|
AfterInput,
|
||||||
@@ -30,6 +30,7 @@ const PointField: React.FC<Props> = (props) => {
|
|||||||
placeholder,
|
placeholder,
|
||||||
readOnly,
|
readOnly,
|
||||||
required,
|
required,
|
||||||
|
step,
|
||||||
style,
|
style,
|
||||||
validate,
|
validate,
|
||||||
width,
|
width,
|
||||||
@@ -39,8 +40,6 @@ const PointField: React.FC<Props> = (props) => {
|
|||||||
|
|
||||||
const { i18n } = useTranslation()
|
const { i18n } = useTranslation()
|
||||||
|
|
||||||
const step = 'step' in props ? props.step : 1
|
|
||||||
|
|
||||||
const memoizedValidate: ClientValidate = useCallback(
|
const memoizedValidate: ClientValidate = useCallback(
|
||||||
(value, options) => {
|
(value, options) => {
|
||||||
if (typeof validate === 'function') {
|
if (typeof validate === 'function') {
|
||||||
|
|||||||
@@ -1,6 +1,12 @@
|
|||||||
|
import type { FieldBase } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type PointFieldProps = FormFieldBase & {
|
||||||
|
label?: FieldBase['label']
|
||||||
name?: string
|
name?: string
|
||||||
path?: string
|
path?: string
|
||||||
|
placeholder?: string
|
||||||
|
step?: number
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
import { optionIsObject } from 'payload/types'
|
import { optionIsObject } from 'payload/types'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { RadioFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useForm } from '../../Form/context.js'
|
import { useForm } from '../../Form/context.js'
|
||||||
import LabelComp from '../../Label/index.js'
|
import LabelComp from '../../Label/index.js'
|
||||||
@@ -16,7 +16,7 @@ import './index.scss'
|
|||||||
|
|
||||||
const baseClass = 'radio-group'
|
const baseClass = 'radio-group'
|
||||||
|
|
||||||
const RadioGroup: React.FC<Props> = (props) => {
|
const RadioGroup: React.FC<RadioFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
Description,
|
Description,
|
||||||
@@ -24,7 +24,9 @@ const RadioGroup: React.FC<Props> = (props) => {
|
|||||||
Label: LabelFromProps,
|
Label: LabelFromProps,
|
||||||
className,
|
className,
|
||||||
label,
|
label,
|
||||||
|
layout = 'horizontal',
|
||||||
onChange: onChangeFromProps,
|
onChange: onChangeFromProps,
|
||||||
|
options = [],
|
||||||
path: pathFromProps,
|
path: pathFromProps,
|
||||||
readOnly,
|
readOnly,
|
||||||
required,
|
required,
|
||||||
@@ -38,10 +40,6 @@ const RadioGroup: React.FC<Props> = (props) => {
|
|||||||
|
|
||||||
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
const Label = LabelFromProps || <LabelComp label={label} required={required} />
|
||||||
|
|
||||||
const options = 'options' in props ? props.options : []
|
|
||||||
|
|
||||||
const layout = 'layout' in props ? props.layout : 'horizontal'
|
|
||||||
|
|
||||||
const memoizedValidate = useCallback(
|
const memoizedValidate = useCallback(
|
||||||
(value, validationOptions) => {
|
(value, validationOptions) => {
|
||||||
if (typeof validate === 'function')
|
if (typeof validate === 'function')
|
||||||
|
|||||||
@@ -1,10 +1,16 @@
|
|||||||
|
import type { FieldBase, Option } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type RadioFieldProps = FormFieldBase & {
|
||||||
|
label?: FieldBase['label']
|
||||||
|
layout?: 'horizontal' | 'vertical'
|
||||||
name?: string
|
name?: string
|
||||||
onChange?: OnChange
|
onChange?: OnChange
|
||||||
|
options?: Option[]
|
||||||
path?: string
|
path?: string
|
||||||
value?: string
|
value?: string
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OnChange<T = string> = (value: T) => void
|
export type OnChange<T = string> = (value: T) => void
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import qs from 'qs'
|
|||||||
import React, { useCallback, useEffect, useReducer, useRef, useState } from 'react'
|
import React, { useCallback, useEffect, useReducer, useRef, useState } from 'react'
|
||||||
|
|
||||||
import type { DocumentDrawerProps } from '../../../elements/DocumentDrawer/types.js'
|
import type { DocumentDrawerProps } from '../../../elements/DocumentDrawer/types.js'
|
||||||
import type { GetResults, Option, Props, Value } from './types.js'
|
import type { GetResults, Option, RelationshipFieldProps, Value } from './types.js'
|
||||||
|
|
||||||
import ReactSelect from '../../../elements/ReactSelect/index.js'
|
import ReactSelect from '../../../elements/ReactSelect/index.js'
|
||||||
import { useDebouncedCallback } from '../../../hooks/useDebouncedCallback.js'
|
import { useDebouncedCallback } from '../../../hooks/useDebouncedCallback.js'
|
||||||
@@ -31,7 +31,7 @@ const maxResultsPerRequest = 10
|
|||||||
|
|
||||||
const baseClass = 'relationship'
|
const baseClass = 'relationship'
|
||||||
|
|
||||||
const Relationship: React.FC<Props> = (props) => {
|
const Relationship: React.FC<RelationshipFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
Description,
|
Description,
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
import type { I18n } from '@payloadcms/translations'
|
import type { I18n } from '@payloadcms/translations'
|
||||||
import type { SanitizedCollectionConfig } from 'payload/types'
|
import type { RelationshipField, SanitizedCollectionConfig } from 'payload/types'
|
||||||
import type { SanitizedConfig } from 'payload/types'
|
import type { SanitizedConfig } from 'payload/types'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type RelationshipFieldProps = FormFieldBase & {
|
||||||
|
allowCreate?: RelationshipField['admin']['allowCreate']
|
||||||
|
hasMany?: boolean
|
||||||
|
isSortable?: boolean
|
||||||
name: string
|
name: string
|
||||||
|
relationTo?: RelationshipField['relationTo']
|
||||||
|
sortOptions?: RelationshipField['admin']['sortOptions']
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export type Option = {
|
export type Option = {
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import type React from 'react'
|
import type React from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { RichTextFieldProps } from './types.js'
|
||||||
|
|
||||||
const RichText: React.FC<Props> = (props) => {
|
const RichText: React.FC<RichTextFieldProps> = (props) => {
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,7 @@
|
|||||||
|
import type { MappedField } from '@payloadcms/ui'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase
|
export type RichTextFieldProps = FormFieldBase & {
|
||||||
|
richTextComponentMap?: Map<string, MappedField[] | React.ReactNode>
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { RowFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useFieldProps } from '../../FieldPropsProvider/index.js'
|
import { useFieldProps } from '../../FieldPropsProvider/index.js'
|
||||||
import { RenderFields } from '../../RenderFields/index.js'
|
import { RenderFields } from '../../RenderFields/index.js'
|
||||||
@@ -12,7 +12,7 @@ import { RowProvider } from './provider.js'
|
|||||||
|
|
||||||
const baseClass = 'row'
|
const baseClass = 'row'
|
||||||
|
|
||||||
const Row: React.FC<Props> = (props) => {
|
const Row: React.FC<RowFieldProps> = (props) => {
|
||||||
const { className, fieldMap, forceRender = false } = props
|
const { className, fieldMap, forceRender = false } = props
|
||||||
|
|
||||||
const { path, readOnly, schemaPath, siblingPermissions } = useFieldProps()
|
const { path, readOnly, schemaPath, siblingPermissions } = useFieldProps()
|
||||||
|
|||||||
@@ -1,12 +1,15 @@
|
|||||||
|
import type { FieldMap } from '@payloadcms/ui'
|
||||||
import type { FieldPermissions } from 'payload/auth'
|
import type { FieldPermissions } from 'payload/auth'
|
||||||
import type { FieldTypes } from 'payload/config'
|
import type { FieldTypes } from 'payload/config'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type RowFieldProps = FormFieldBase & {
|
||||||
|
fieldMap: FieldMap
|
||||||
fieldTypes: FieldTypes
|
fieldTypes: FieldTypes
|
||||||
forceRender?: boolean
|
forceRender?: boolean
|
||||||
indexPath: string
|
indexPath: string
|
||||||
path?: string
|
path?: string
|
||||||
permissions?: FieldPermissions
|
permissions?: FieldPermissions
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type { ClientValidate, Option, OptionObject } from 'payload/types'
|
|||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useCallback, useState } from 'react'
|
import React, { useCallback, useState } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { SelectFieldProps } from './types.js'
|
||||||
|
|
||||||
import ReactSelect from '../../../elements/ReactSelect/index.js'
|
import ReactSelect from '../../../elements/ReactSelect/index.js'
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
@@ -27,7 +27,7 @@ const formatOptions = (options: Option[]): OptionObject[] =>
|
|||||||
} as OptionObject
|
} as OptionObject
|
||||||
})
|
})
|
||||||
|
|
||||||
export const Select: React.FC<Props> = (props) => {
|
export const Select: React.FC<SelectFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
AfterInput,
|
AfterInput,
|
||||||
|
|||||||
@@ -1,8 +1,16 @@
|
|||||||
|
import type { FieldBase, Option } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type SelectFieldProps = FormFieldBase & {
|
||||||
|
hasMany?: boolean
|
||||||
|
isClearable?: boolean
|
||||||
|
isSortable?: boolean
|
||||||
|
label?: FieldBase['label']
|
||||||
name?: string
|
name?: string
|
||||||
onChange?: (e: string) => void
|
onChange?: (e: string) => void
|
||||||
|
options?: Option[]
|
||||||
path?: string
|
path?: string
|
||||||
value?: string
|
value?: string
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ export const TabComponent: React.FC<TabProps> = ({ isActive, parentPath, setIsAc
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<React.Fragment>
|
<React.Fragment>
|
||||||
<WatchChildErrors fieldMap={tab.subfields} path={path} setErrorCount={setErrorCount} />
|
<WatchChildErrors fieldMap={tab.fieldMap} path={path} setErrorCount={setErrorCount} />
|
||||||
<button
|
<button
|
||||||
className={[
|
className={[
|
||||||
baseClass,
|
baseClass,
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { getTranslation } from '@payloadcms/translations'
|
|||||||
import { toKebabCase } from 'payload/utilities'
|
import { toKebabCase } from 'payload/utilities'
|
||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { TabsFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useCollapsible } from '../../../elements/Collapsible/provider.js'
|
import { useCollapsible } from '../../../elements/Collapsible/provider.js'
|
||||||
import { useDocumentInfo } from '../../../providers/DocumentInfo/index.js'
|
import { useDocumentInfo } from '../../../providers/DocumentInfo/index.js'
|
||||||
@@ -21,7 +21,7 @@ import { TabsProvider } from './provider.js'
|
|||||||
|
|
||||||
const baseClass = 'tabs-field'
|
const baseClass = 'tabs-field'
|
||||||
|
|
||||||
const TabsField: React.FC<Props> = (props) => {
|
const TabsField: React.FC<TabsFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
Description,
|
Description,
|
||||||
@@ -130,7 +130,7 @@ const TabsField: React.FC<Props> = (props) => {
|
|||||||
>
|
>
|
||||||
{Description}
|
{Description}
|
||||||
<RenderFields
|
<RenderFields
|
||||||
fieldMap={activeTabConfig.subfields}
|
fieldMap={activeTabConfig.fieldMap}
|
||||||
forceRender={forceRender}
|
forceRender={forceRender}
|
||||||
key={
|
key={
|
||||||
activeTabConfig.label
|
activeTabConfig.label
|
||||||
|
|||||||
@@ -1,13 +1,15 @@
|
|||||||
import type { FieldPermissions } from 'payload/auth'
|
import type { FieldPermissions } from 'payload/auth'
|
||||||
|
|
||||||
import type { MappedTab } from '../../../utilities/buildComponentMap/types.js'
|
import type { FieldMap, MappedTab } from '../../../utilities/buildComponentMap/types.js'
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type TabsFieldProps = FormFieldBase & {
|
||||||
|
fieldMap: FieldMap
|
||||||
forceRender?: boolean
|
forceRender?: boolean
|
||||||
indexPath: string
|
indexPath: string
|
||||||
name?: string
|
name?: string
|
||||||
path?: string
|
path?: string
|
||||||
permissions: FieldPermissions
|
permissions: FieldPermissions
|
||||||
tabs?: MappedTab[]
|
tabs?: MappedTab[]
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,16 +2,18 @@
|
|||||||
import type { ChangeEvent } from 'react'
|
import type { ChangeEvent } from 'react'
|
||||||
|
|
||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
|
import { TextField } from 'payload/types.js'
|
||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
import type { Option } from '../../../elements/ReactSelect/types.js'
|
import type { Option } from '../../../elements/ReactSelect/types.js'
|
||||||
|
import type { TextareaFieldProps } from '../Textarea/types.js'
|
||||||
|
|
||||||
import ReactSelect from '../../../elements/ReactSelect/index.js'
|
import ReactSelect from '../../../elements/ReactSelect/index.js'
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
import { type FormFieldBase, fieldBaseClass } from '../shared.js'
|
import { fieldBaseClass } from '../shared.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
export type TextInputProps = Omit<FormFieldBase, 'type'> & {
|
export type TextInputProps = Omit<TextareaFieldProps, 'type'> & {
|
||||||
hasMany?: boolean
|
hasMany?: boolean
|
||||||
inputRef?: React.MutableRefObject<HTMLInputElement>
|
inputRef?: React.MutableRefObject<HTMLInputElement>
|
||||||
maxRows?: number
|
maxRows?: number
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import type { ClientValidate } from 'payload/types'
|
|||||||
import React, { useCallback, useEffect, useState } from 'react'
|
import React, { useCallback, useEffect, useState } from 'react'
|
||||||
|
|
||||||
import type { Option } from '../../../elements/ReactSelect/types.js'
|
import type { Option } from '../../../elements/ReactSelect/types.js'
|
||||||
import type { Props } from './types.js'
|
import type { TextFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useConfig } from '../../../providers/Config/index.js'
|
import { useConfig } from '../../../providers/Config/index.js'
|
||||||
import { useLocale } from '../../../providers/Locale/index.js'
|
import { useLocale } from '../../../providers/Locale/index.js'
|
||||||
@@ -15,7 +15,7 @@ import { isFieldRTL } from '../shared.js'
|
|||||||
import { TextInput } from './Input.js'
|
import { TextInput } from './Input.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
const Text: React.FC<Props> = (props) => {
|
const Text: React.FC<TextFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
AfterInput,
|
AfterInput,
|
||||||
|
|||||||
@@ -1,11 +1,18 @@
|
|||||||
|
import type { FieldBase, TextField } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type TextFieldProps = FormFieldBase & {
|
||||||
hasMany?: boolean
|
hasMany?: boolean
|
||||||
inputRef?: React.MutableRefObject<HTMLInputElement>
|
inputRef?: React.MutableRefObject<HTMLInputElement>
|
||||||
|
label?: FieldBase['label']
|
||||||
|
maxLength?: number
|
||||||
maxRows?: number
|
maxRows?: number
|
||||||
|
minLength?: number
|
||||||
minRows?: number
|
minRows?: number
|
||||||
name?: string
|
name?: string
|
||||||
onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>
|
onKeyDown?: React.KeyboardEventHandler<HTMLInputElement>
|
||||||
path?: string
|
path?: string
|
||||||
|
placeholder?: TextField['admin']['placeholder']
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,11 +2,13 @@
|
|||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { type ChangeEvent } from 'react'
|
import React, { type ChangeEvent } from 'react'
|
||||||
|
|
||||||
|
import type { TextareaFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
import { type FormFieldBase, fieldBaseClass } from '../shared.js'
|
import { fieldBaseClass } from '../shared.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
export type TextAreaInputProps = FormFieldBase & {
|
export type TextAreaInputProps = TextareaFieldProps & {
|
||||||
onChange?: (e: ChangeEvent<HTMLTextAreaElement>) => void
|
onChange?: (e: ChangeEvent<HTMLTextAreaElement>) => void
|
||||||
rows?: number
|
rows?: number
|
||||||
showError?: boolean
|
showError?: boolean
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import type { ClientValidate } from 'payload/types'
|
|||||||
import { getTranslation } from '@payloadcms/translations'
|
import { getTranslation } from '@payloadcms/translations'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { TextareaFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useConfig } from '../../../providers/Config/index.js'
|
import { useConfig } from '../../../providers/Config/index.js'
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
@@ -16,7 +16,7 @@ import { isFieldRTL } from '../shared.js'
|
|||||||
import { TextareaInput } from './Input.js'
|
import { TextareaInput } from './Input.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
const Textarea: React.FC<Props> = (props) => {
|
const Textarea: React.FC<TextareaFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
name,
|
name,
|
||||||
AfterInput,
|
AfterInput,
|
||||||
|
|||||||
@@ -1,6 +1,14 @@
|
|||||||
|
import type { FieldBase, TextareaField } from 'payload/types.js'
|
||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type TextareaFieldProps = FormFieldBase & {
|
||||||
|
label?: FieldBase['label']
|
||||||
|
maxLength?: number
|
||||||
|
minLength?: number
|
||||||
name?: string
|
name?: string
|
||||||
path?: string
|
path?: string
|
||||||
|
placeholder?: TextareaField['admin']['placeholder']
|
||||||
|
rows?: number
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import React, { useCallback, useEffect, useState } from 'react'
|
|||||||
|
|
||||||
import type { DocumentDrawerProps } from '../../../elements/DocumentDrawer/types.js'
|
import type { DocumentDrawerProps } from '../../../elements/DocumentDrawer/types.js'
|
||||||
import type { ListDrawerProps } from '../../../elements/ListDrawer/types.js'
|
import type { ListDrawerProps } from '../../../elements/ListDrawer/types.js'
|
||||||
|
import type { UploadFieldProps } from './types.js'
|
||||||
|
|
||||||
import { Button } from '../../../elements/Button/index.js'
|
import { Button } from '../../../elements/Button/index.js'
|
||||||
import { useDocumentDrawer } from '../../../elements/DocumentDrawer/index.js'
|
import { useDocumentDrawer } from '../../../elements/DocumentDrawer/index.js'
|
||||||
@@ -14,12 +15,12 @@ import FileDetails from '../../../elements/FileDetails/index.js'
|
|||||||
import { useListDrawer } from '../../../elements/ListDrawer/index.js'
|
import { useListDrawer } from '../../../elements/ListDrawer/index.js'
|
||||||
import { useTranslation } from '../../../providers/Translation/index.js'
|
import { useTranslation } from '../../../providers/Translation/index.js'
|
||||||
import LabelComp from '../../Label/index.js'
|
import LabelComp from '../../Label/index.js'
|
||||||
import { type FormFieldBase, fieldBaseClass } from '../shared.js'
|
import { fieldBaseClass } from '../shared.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
const baseClass = 'upload'
|
const baseClass = 'upload'
|
||||||
|
|
||||||
export type UploadInputProps = FormFieldBase & {
|
export type UploadInputProps = Omit<UploadFieldProps, 'filterOptions'> & {
|
||||||
api?: string
|
api?: string
|
||||||
collection?: SanitizedCollectionConfig
|
collection?: SanitizedCollectionConfig
|
||||||
filterOptions?: FilterOptionsResult
|
filterOptions?: FilterOptionsResult
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
'use client'
|
'use client'
|
||||||
import React, { useCallback } from 'react'
|
import React, { useCallback } from 'react'
|
||||||
|
|
||||||
import type { Props } from './types.js'
|
import type { UploadFieldProps } from './types.js'
|
||||||
|
|
||||||
import { useConfig } from '../../../providers/Config/index.js'
|
import { useConfig } from '../../../providers/Config/index.js'
|
||||||
import LabelComp from '../../Label/index.js'
|
import LabelComp from '../../Label/index.js'
|
||||||
@@ -9,7 +9,7 @@ import { useField } from '../../useField/index.js'
|
|||||||
import { UploadInput } from './Input.js'
|
import { UploadInput } from './Input.js'
|
||||||
import './index.scss'
|
import './index.scss'
|
||||||
|
|
||||||
const Upload: React.FC<Props> = (props) => {
|
const Upload: React.FC<UploadFieldProps> = (props) => {
|
||||||
const {
|
const {
|
||||||
Description,
|
Description,
|
||||||
Error,
|
Error,
|
||||||
|
|||||||
@@ -2,9 +2,11 @@ import type { UploadField } from 'payload/types'
|
|||||||
|
|
||||||
import type { FormFieldBase } from '../shared.js'
|
import type { FormFieldBase } from '../shared.js'
|
||||||
|
|
||||||
export type Props = FormFieldBase & {
|
export type UploadFieldProps = FormFieldBase & {
|
||||||
filterOptions?: UploadField['filterOptions']
|
filterOptions?: UploadField['filterOptions']
|
||||||
|
label?: UploadField['label']
|
||||||
name?: string
|
name?: string
|
||||||
path?: string
|
path?: string
|
||||||
relationTo?: UploadField['relationTo']
|
relationTo?: UploadField['relationTo']
|
||||||
|
width?: string
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,26 +1,6 @@
|
|||||||
import type { User } from 'payload/auth'
|
import type { User } from 'payload/auth'
|
||||||
import type { Locale, SanitizedLocalizationConfig } from 'payload/config'
|
import type { Locale, SanitizedLocalizationConfig } from 'payload/config'
|
||||||
import type {
|
import type { DocumentPreferences, FormState, Validate } from 'payload/types'
|
||||||
ArrayField,
|
|
||||||
BlockField,
|
|
||||||
CodeField,
|
|
||||||
DateField,
|
|
||||||
DocumentPreferences,
|
|
||||||
FormState,
|
|
||||||
JSONField,
|
|
||||||
RelationshipField,
|
|
||||||
RowLabel,
|
|
||||||
UploadField,
|
|
||||||
Validate,
|
|
||||||
} from 'payload/types'
|
|
||||||
import type { Option } from 'payload/types'
|
|
||||||
|
|
||||||
import type {
|
|
||||||
FieldMap,
|
|
||||||
MappedField,
|
|
||||||
MappedTab,
|
|
||||||
ReducedBlock,
|
|
||||||
} from '../../utilities/buildComponentMap/types.js'
|
|
||||||
|
|
||||||
export const fieldBaseClass = 'field-type'
|
export const fieldBaseClass = 'field-type'
|
||||||
|
|
||||||
@@ -30,99 +10,19 @@ export type FormFieldBase = {
|
|||||||
Description?: React.ReactNode
|
Description?: React.ReactNode
|
||||||
Error?: React.ReactNode
|
Error?: React.ReactNode
|
||||||
Label?: React.ReactNode
|
Label?: React.ReactNode
|
||||||
RowLabel?: React.ReactNode
|
|
||||||
className?: string
|
className?: string
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
docPreferences?: DocumentPreferences
|
docPreferences?: DocumentPreferences
|
||||||
fieldMap?: FieldMap
|
|
||||||
initialSubfieldState?: FormState
|
|
||||||
label?: string
|
|
||||||
locale?: Locale
|
locale?: Locale
|
||||||
localized?: boolean
|
localized?: boolean
|
||||||
maxLength?: number
|
|
||||||
minLength?: number
|
|
||||||
path?: string
|
path?: string
|
||||||
placeholder?: Record<string, string> | string
|
|
||||||
readOnly?: boolean
|
readOnly?: boolean
|
||||||
required?: boolean
|
required?: boolean
|
||||||
rtl?: boolean
|
rtl?: boolean
|
||||||
style?: React.CSSProperties
|
style?: React.CSSProperties
|
||||||
user?: User
|
user?: User
|
||||||
validate?: Validate
|
validate?: Validate
|
||||||
width?: string
|
}
|
||||||
} & (
|
|
||||||
| {
|
|
||||||
// For `array` fields
|
|
||||||
label?: RowLabel
|
|
||||||
labels?: ArrayField['labels']
|
|
||||||
maxRows?: ArrayField['maxRows']
|
|
||||||
minRows?: ArrayField['minRows']
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `blocks` fields
|
|
||||||
blocks?: ReducedBlock[]
|
|
||||||
labels?: BlockField['labels']
|
|
||||||
maxRows?: BlockField['maxRows']
|
|
||||||
minRows?: BlockField['minRows']
|
|
||||||
slug?: string
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `code` fields
|
|
||||||
editorOptions?: CodeField['admin']['editorOptions']
|
|
||||||
language?: CodeField['admin']['language']
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `collapsible` fields
|
|
||||||
initCollapsed?: boolean
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `date` fields
|
|
||||||
date?: DateField['admin']['date']
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `json` fields
|
|
||||||
editorOptions?: JSONField['admin']['editorOptions']
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `number` fields
|
|
||||||
hasMany?: boolean
|
|
||||||
max?: number
|
|
||||||
maxRows?: number
|
|
||||||
min?: number
|
|
||||||
step?: number
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `radio` fields
|
|
||||||
layout?: 'horizontal' | 'vertical'
|
|
||||||
options?: Option[]
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `relationship` fields
|
|
||||||
allowCreate?: RelationshipField['admin']['allowCreate']
|
|
||||||
relationTo?: RelationshipField['relationTo']
|
|
||||||
sortOptions?: RelationshipField['admin']['sortOptions']
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `richText` fields
|
|
||||||
richTextComponentMap?: Map<string, MappedField[] | React.ReactNode>
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `select` fields
|
|
||||||
isClearable?: boolean
|
|
||||||
isSortable?: boolean
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `textarea` fields
|
|
||||||
rows?: number
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
// For `upload` fields
|
|
||||||
relationTo?: UploadField['relationTo']
|
|
||||||
}
|
|
||||||
| {
|
|
||||||
tabs?: MappedTab[]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determines whether a field should be displayed as right-to-left (RTL) based on its configuration, payload's localization configuration and the adming user's currently enabled locale.
|
* Determines whether a field should be displayed as right-to-left (RTL) based on its configuration, payload's localization configuration and the adming user's currently enabled locale.
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ export const ComponentMapProvider: React.FC<{
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: better lookup for nested fields, etc.
|
// TODO: better lookup for nested fields, etc.
|
||||||
return fieldMap.find((field) => field.name === path)
|
return fieldMap.find((field) => 'name' in field && field.name === path)
|
||||||
},
|
},
|
||||||
[componentMap],
|
[componentMap],
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -5,8 +5,32 @@ import { isPlainObject } from 'payload/utilities'
|
|||||||
import React, { Fragment } from 'react'
|
import React, { Fragment } from 'react'
|
||||||
|
|
||||||
import type { Props as FieldDescription } from '../../forms/FieldDescription/types.js'
|
import type { Props as FieldDescription } from '../../forms/FieldDescription/types.js'
|
||||||
|
import type { ArrayFieldProps } from '../../forms/fields/Array/types.js'
|
||||||
|
import type { BlocksFieldProps } from '../../forms/fields/Blocks/types.js'
|
||||||
|
import type { CheckboxFieldProps } from '../../forms/fields/Checkbox/types.js'
|
||||||
|
import type { CodeFieldProps } from '../../forms/fields/Code/types.js'
|
||||||
|
import type { CollapsibleFieldProps } from '../../forms/fields/Collapsible/types.js'
|
||||||
|
import type { DateFieldProps } from '../../forms/fields/DateTime/types.js'
|
||||||
|
import type { EmailFieldProps } from '../../forms/fields/Email/types.js'
|
||||||
|
import type { GroupFieldProps } from '../../forms/fields/Group/types.js'
|
||||||
|
import type { JSONFieldProps } from '../../forms/fields/JSON/types.js'
|
||||||
|
import type { NumberFieldProps } from '../../forms/fields/Number/types.js'
|
||||||
|
import type { PointFieldProps } from '../../forms/fields/Point/types.js'
|
||||||
|
import type { RelationshipFieldProps } from '../../forms/fields/Relationship/types.js'
|
||||||
|
import type { RowFieldProps } from '../../forms/fields/Row/types.js'
|
||||||
|
import type { SelectFieldProps } from '../../forms/fields/Select/types.js'
|
||||||
|
import type { TabsFieldProps } from '../../forms/fields/Tabs/types.js'
|
||||||
|
import type { TextFieldProps } from '../../forms/fields/Text/types.js'
|
||||||
|
import type { TextareaFieldProps } from '../../forms/fields/Textarea/types.js'
|
||||||
|
import type { UploadFieldProps } from '../../forms/fields/Upload/types.js'
|
||||||
import type { FormFieldBase } from '../../forms/fields/shared.js'
|
import type { FormFieldBase } from '../../forms/fields/shared.js'
|
||||||
import type { FieldMap, MappedField, MappedTab, ReducedBlock } from './types.js'
|
import type {
|
||||||
|
FieldComponentProps,
|
||||||
|
FieldMap,
|
||||||
|
MappedField,
|
||||||
|
MappedTab,
|
||||||
|
ReducedBlock,
|
||||||
|
} from './types.js'
|
||||||
|
|
||||||
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
import { RenderCustomComponent } from '../../elements/RenderCustomComponent/index.js'
|
||||||
import { SortColumn } from '../../elements/SortColumn/index.js'
|
import { SortColumn } from '../../elements/SortColumn/index.js'
|
||||||
@@ -83,178 +107,83 @@ export const mapFields = (args: {
|
|||||||
readOnly: readOnlyOverride,
|
readOnly: readOnlyOverride,
|
||||||
})
|
})
|
||||||
|
|
||||||
// `tabs` fields require a field map of each of its tab's nested fields
|
const AfterInput = 'admin' in field &&
|
||||||
const tabs =
|
'components' in field.admin &&
|
||||||
'tabs' in field &&
|
'afterInput' in field.admin.components &&
|
||||||
field.tabs &&
|
Array.isArray(field.admin?.components?.afterInput) && (
|
||||||
Array.isArray(field.tabs) &&
|
<Fragment>
|
||||||
field.tabs.map((tab) => {
|
{field.admin.components.afterInput.map((Component, i) => (
|
||||||
const tabFieldMap = mapFields({
|
<Component key={i} />
|
||||||
DefaultCell,
|
))}
|
||||||
config,
|
</Fragment>
|
||||||
fieldSchema: tab.fields,
|
)
|
||||||
filter,
|
|
||||||
parentPath: path,
|
|
||||||
readOnly: readOnlyOverride,
|
|
||||||
})
|
|
||||||
|
|
||||||
const reducedTab: MappedTab = {
|
const BeforeInput = 'admin' in field &&
|
||||||
name: 'name' in tab ? tab.name : undefined,
|
field.admin?.components &&
|
||||||
label: tab.label,
|
'beforeInput' in field.admin.components &&
|
||||||
subfields: tabFieldMap,
|
Array.isArray(field.admin.components.beforeInput) && (
|
||||||
|
<Fragment>
|
||||||
|
{field.admin.components.beforeInput.map((Component, i) => (
|
||||||
|
<Component key={i} />
|
||||||
|
))}
|
||||||
|
</Fragment>
|
||||||
|
)
|
||||||
|
|
||||||
|
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}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
return reducedTab
|
const Error = (
|
||||||
})
|
<RenderCustomComponent
|
||||||
|
CustomComponent={
|
||||||
// `blocks` fields require a field map of each of its block's nested fields
|
'admin' in field &&
|
||||||
const blocks =
|
field.admin.components &&
|
||||||
'blocks' in field &&
|
'Error' in field.admin.components &&
|
||||||
field.blocks &&
|
field.admin?.components?.Error
|
||||||
Array.isArray(field.blocks) &&
|
|
||||||
field.blocks.map((block) => {
|
|
||||||
const blockFieldMap = mapFields({
|
|
||||||
DefaultCell,
|
|
||||||
config,
|
|
||||||
fieldSchema: block.fields,
|
|
||||||
filter,
|
|
||||||
parentPath: `${path}.${block.slug}`,
|
|
||||||
readOnly: readOnlyOverride,
|
|
||||||
})
|
|
||||||
|
|
||||||
const reducedBlock: ReducedBlock = {
|
|
||||||
slug: block.slug,
|
|
||||||
imageAltText: block.imageAltText,
|
|
||||||
imageURL: block.imageURL,
|
|
||||||
labels: block.labels,
|
|
||||||
subfields: blockFieldMap,
|
|
||||||
}
|
}
|
||||||
|
DefaultComponent={DefaultError}
|
||||||
|
componentProps={{ path }}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
return reducedBlock
|
const Label = (
|
||||||
})
|
<RenderCustomComponent
|
||||||
|
CustomComponent={
|
||||||
|
'admin' in field &&
|
||||||
|
field.admin?.components &&
|
||||||
|
'Label' in field.admin.components &&
|
||||||
|
field.admin?.components?.Label
|
||||||
|
}
|
||||||
|
DefaultComponent={DefaultLabel}
|
||||||
|
componentProps={labelProps}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
let RowLabel: React.ReactNode
|
const baseFieldProps: FormFieldBase = {
|
||||||
|
AfterInput,
|
||||||
if (
|
BeforeInput,
|
||||||
'admin' in field &&
|
Description,
|
||||||
field.admin.components &&
|
Error,
|
||||||
'RowLabel' in field.admin.components &&
|
Label,
|
||||||
field.admin.components.RowLabel &&
|
disabled: 'admin' in field && 'disabled' in field.admin ? field.admin?.disabled : false,
|
||||||
!isPlainObject(field.admin.components.RowLabel)
|
path,
|
||||||
) {
|
required: 'required' in field ? field.required : undefined,
|
||||||
const CustomRowLabel = field.admin.components.RowLabel as React.ComponentType
|
|
||||||
RowLabel = <CustomRowLabel />
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: these types can get cleaned up
|
let fieldComponentProps: FieldComponentProps
|
||||||
// i.e. not all fields have `maxRows` or `min` or `max`
|
|
||||||
// but this is labor intensive and requires consuming components to be updated
|
|
||||||
const fieldComponentProps: FormFieldBase = {
|
|
||||||
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>
|
|
||||||
),
|
|
||||||
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>
|
|
||||||
),
|
|
||||||
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}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
Error: (
|
|
||||||
<RenderCustomComponent
|
|
||||||
CustomComponent={
|
|
||||||
'admin' in field &&
|
|
||||||
field.admin.components &&
|
|
||||||
'Error' in field.admin.components &&
|
|
||||||
field.admin?.components?.Error
|
|
||||||
}
|
|
||||||
DefaultComponent={DefaultError}
|
|
||||||
componentProps={{ path }}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
Label: (
|
|
||||||
<RenderCustomComponent
|
|
||||||
CustomComponent={
|
|
||||||
'admin' in field &&
|
|
||||||
field.admin?.components &&
|
|
||||||
'Label' in field.admin.components &&
|
|
||||||
field.admin?.components?.Label
|
|
||||||
}
|
|
||||||
DefaultComponent={DefaultLabel}
|
|
||||||
componentProps={labelProps}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
RowLabel,
|
|
||||||
blocks,
|
|
||||||
className:
|
|
||||||
'admin' in field && 'className' in field.admin ? field?.admin?.className : undefined,
|
|
||||||
date: 'admin' in field && 'date' in field.admin ? field.admin.date : undefined,
|
|
||||||
disabled: field?.admin && 'disabled' in field.admin ? field.admin?.disabled : false,
|
|
||||||
fieldMap: nestedFieldMap,
|
|
||||||
hasMany: 'hasMany' in field ? field.hasMany : undefined,
|
|
||||||
label: 'label' in field && typeof field.label === 'string' ? field.label : undefined,
|
|
||||||
max: 'max' in field ? field.max : undefined,
|
|
||||||
maxRows: 'maxRows' in field ? field.maxRows : undefined,
|
|
||||||
min: 'min' in field ? field.min : undefined,
|
|
||||||
options: 'options' in field ? field.options : undefined,
|
|
||||||
placeholder:
|
|
||||||
'admin' in field && 'placeholder' in field.admin
|
|
||||||
? field?.admin?.placeholder
|
|
||||||
: undefined,
|
|
||||||
readOnly:
|
|
||||||
'admin' in field && 'readOnly' in field.admin ? field.admin.readOnly : undefined,
|
|
||||||
relationTo: 'relationTo' in field ? field.relationTo : undefined,
|
|
||||||
richTextComponentMap: undefined,
|
|
||||||
step: 'admin' in field && 'step' in field.admin ? field.admin.step : undefined,
|
|
||||||
style: 'admin' in field && 'style' in field.admin ? field?.admin?.style : undefined,
|
|
||||||
tabs,
|
|
||||||
width: 'admin' in field && 'width' in field.admin ? field?.admin?.width : undefined,
|
|
||||||
}
|
|
||||||
|
|
||||||
if (
|
|
||||||
field.type === 'collapsible' &&
|
|
||||||
typeof field.label === 'object' &&
|
|
||||||
!isPlainObject(field.label)
|
|
||||||
) {
|
|
||||||
const CollapsibleLabel = field.label as unknown as React.ComponentType
|
|
||||||
fieldComponentProps.Label = <CollapsibleLabel />
|
|
||||||
}
|
|
||||||
|
|
||||||
let Field = <FieldComponent {...fieldComponentProps} />
|
|
||||||
|
|
||||||
const cellComponentProps: CellProps = {
|
const cellComponentProps: CellProps = {
|
||||||
name: 'name' in field ? field.name : undefined,
|
name: 'name' in field ? field.name : undefined,
|
||||||
blocks:
|
|
||||||
'blocks' in field &&
|
|
||||||
field.blocks.map((b) => ({
|
|
||||||
slug: b.slug,
|
|
||||||
labels: b.labels,
|
|
||||||
})),
|
|
||||||
dateDisplayFormat:
|
|
||||||
'admin' in field && 'date' in field.admin ? field.admin.date.displayFormat : undefined,
|
|
||||||
fieldType: field.type,
|
fieldType: field.type,
|
||||||
isFieldAffectingData,
|
isFieldAffectingData,
|
||||||
label:
|
label:
|
||||||
@@ -265,6 +194,418 @@ export const mapFields = (args: {
|
|||||||
options: 'options' in field ? field.options : undefined,
|
options: 'options' in field ? field.options : undefined,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch (field.type) {
|
||||||
|
case 'array': {
|
||||||
|
let RowLabel: React.ReactNode
|
||||||
|
|
||||||
|
if (
|
||||||
|
'admin' in field &&
|
||||||
|
field.admin.components &&
|
||||||
|
'RowLabel' in field.admin.components &&
|
||||||
|
field.admin.components.RowLabel &&
|
||||||
|
!isPlainObject(field.admin.components.RowLabel)
|
||||||
|
) {
|
||||||
|
const CustomRowLabel = field.admin.components.RowLabel as React.ComponentType
|
||||||
|
RowLabel = <CustomRowLabel />
|
||||||
|
}
|
||||||
|
|
||||||
|
const arrayFieldProps: Omit<ArrayFieldProps, 'indexPath' | 'permissions'> = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
RowLabel,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
fieldMap: nestedFieldMap,
|
||||||
|
label: field?.label || undefined,
|
||||||
|
labels: field.labels,
|
||||||
|
maxRows: field.maxRows,
|
||||||
|
minRows: field.minRows,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = arrayFieldProps
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'blocks': {
|
||||||
|
const blocks = field.blocks.map((block) => {
|
||||||
|
const blockFieldMap = mapFields({
|
||||||
|
DefaultCell,
|
||||||
|
config,
|
||||||
|
fieldSchema: block.fields,
|
||||||
|
filter,
|
||||||
|
parentPath: `${path}.${block.slug}`,
|
||||||
|
readOnly: readOnlyOverride,
|
||||||
|
})
|
||||||
|
|
||||||
|
const reducedBlock: ReducedBlock = {
|
||||||
|
slug: block.slug,
|
||||||
|
fieldMap: blockFieldMap,
|
||||||
|
imageAltText: block.imageAltText,
|
||||||
|
imageURL: block.imageURL,
|
||||||
|
labels: block.labels,
|
||||||
|
}
|
||||||
|
|
||||||
|
return reducedBlock
|
||||||
|
})
|
||||||
|
|
||||||
|
const blocksField: Omit<BlocksFieldProps, 'indexPath' | 'permissions'> = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
blocks,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
fieldMap: nestedFieldMap,
|
||||||
|
label: field?.label || undefined,
|
||||||
|
labels: field.labels,
|
||||||
|
maxRows: field.maxRows,
|
||||||
|
minRows: field.minRows,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = blocksField
|
||||||
|
|
||||||
|
cellComponentProps.blocks = field.blocks.map((b) => ({
|
||||||
|
slug: b.slug,
|
||||||
|
labels: b.labels,
|
||||||
|
}))
|
||||||
|
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'checkbox': {
|
||||||
|
const checkboxField: CheckboxFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
label: field.label,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = checkboxField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'code': {
|
||||||
|
const codeField: CodeFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
editorOptions: field.admin?.editorOptions,
|
||||||
|
label: field.label,
|
||||||
|
language: field.admin?.language,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = codeField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'collapsible': {
|
||||||
|
let CollapsibleLabel: React.ReactNode
|
||||||
|
|
||||||
|
if (typeof field.label === 'object' && !isPlainObject(field.label)) {
|
||||||
|
const LabelToRender = field.label as unknown as React.ComponentType
|
||||||
|
CollapsibleLabel = <LabelToRender />
|
||||||
|
}
|
||||||
|
|
||||||
|
const collapsibleField: Omit<CollapsibleFieldProps, 'indexPath' | 'permissions'> = {
|
||||||
|
...baseFieldProps,
|
||||||
|
Label: CollapsibleLabel,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
fieldMap: nestedFieldMap,
|
||||||
|
fieldTypes,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = collapsibleField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'date': {
|
||||||
|
const dateField: DateFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
date: field.admin?.date,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
label: field.label,
|
||||||
|
placeholder: field.admin?.placeholder,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = dateField
|
||||||
|
cellComponentProps.dateDisplayFormat = field.admin?.date?.displayFormat
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'email': {
|
||||||
|
const emailField: EmailFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
placeholder: field.admin?.placeholder,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = emailField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'group': {
|
||||||
|
const groupField: Omit<GroupFieldProps, 'indexPath' | 'permissions'> = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
fieldMap: nestedFieldMap,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = groupField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'json': {
|
||||||
|
const jsonField: JSONFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
editorOptions: field.admin?.editorOptions,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = jsonField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'number': {
|
||||||
|
const numberField: NumberFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
hasMany: field.hasMany,
|
||||||
|
max: field.max,
|
||||||
|
maxRows: field.maxRows,
|
||||||
|
min: field.min,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
step: field.admin?.step,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = numberField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'point': {
|
||||||
|
const pointField: PointFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = pointField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'relationship': {
|
||||||
|
const relationshipField: RelationshipFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
allowCreate: field.admin.allowCreate,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
hasMany: field.hasMany,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
relationTo: field.relationTo,
|
||||||
|
required: field.required,
|
||||||
|
sortOptions: field.admin.sortOptions,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = relationshipField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'richText': {
|
||||||
|
const richTextField = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = richTextField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'row': {
|
||||||
|
const rowField: Omit<RowFieldProps, 'indexPath' | 'permissions'> = {
|
||||||
|
...baseFieldProps,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
fieldMap: nestedFieldMap,
|
||||||
|
fieldTypes,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = rowField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'tabs': {
|
||||||
|
// `tabs` fields require a field map of each of its tab's nested fields
|
||||||
|
const tabs = field.tabs.map((tab) => {
|
||||||
|
const tabFieldMap = mapFields({
|
||||||
|
DefaultCell,
|
||||||
|
config,
|
||||||
|
fieldSchema: tab.fields,
|
||||||
|
filter,
|
||||||
|
parentPath: path,
|
||||||
|
readOnly: readOnlyOverride,
|
||||||
|
})
|
||||||
|
|
||||||
|
const reducedTab: MappedTab = {
|
||||||
|
name: 'name' in tab ? tab.name : undefined,
|
||||||
|
fieldMap: tabFieldMap,
|
||||||
|
label: tab.label,
|
||||||
|
}
|
||||||
|
|
||||||
|
return reducedTab
|
||||||
|
})
|
||||||
|
|
||||||
|
const tabsField: Omit<TabsFieldProps, 'indexPath' | 'permissions'> = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: 'name' in field ? (field.name as string) : undefined,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
fieldMap: nestedFieldMap,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
tabs,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = tabsField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'text': {
|
||||||
|
const textField: TextFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
maxLength: field.maxLength,
|
||||||
|
minLength: field.minLength,
|
||||||
|
placeholder: field.admin?.placeholder,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = textField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'textarea': {
|
||||||
|
const textareaField: TextareaFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
maxLength: field.maxLength,
|
||||||
|
minLength: field.minLength,
|
||||||
|
placeholder: field.admin?.placeholder,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
rows: field.admin?.rows,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = textareaField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'ui': {
|
||||||
|
fieldComponentProps = baseFieldProps
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'upload': {
|
||||||
|
const uploadField: UploadFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
filterOptions: field.filterOptions,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
relationTo: field.relationTo,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = uploadField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
case 'select': {
|
||||||
|
const selectField: SelectFieldProps = {
|
||||||
|
...baseFieldProps,
|
||||||
|
name: field.name,
|
||||||
|
className: field.admin?.className,
|
||||||
|
disabled: field.admin?.disabled,
|
||||||
|
hasMany: field.hasMany,
|
||||||
|
isClearable: field.admin?.isClearable,
|
||||||
|
options: field.options,
|
||||||
|
readOnly: field.admin?.readOnly,
|
||||||
|
required: field.required,
|
||||||
|
style: field.admin?.style,
|
||||||
|
width: field.admin?.width,
|
||||||
|
}
|
||||||
|
|
||||||
|
fieldComponentProps = selectField
|
||||||
|
break
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let Field = <FieldComponent {...fieldComponentProps} />
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handle RichText Field Components, Cell Components, and component maps
|
* Handle RichText Field Components, Cell Components, and component maps
|
||||||
*/
|
*/
|
||||||
@@ -288,49 +629,43 @@ export const mapFields = (args: {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const Cell = (
|
||||||
|
<RenderCustomComponent
|
||||||
|
CustomComponent={field.admin?.components?.Cell}
|
||||||
|
DefaultComponent={DefaultCell}
|
||||||
|
componentProps={cellComponentProps}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
|
const Heading = (
|
||||||
|
<SortColumn
|
||||||
|
disable={
|
||||||
|
('disableSort' in field && Boolean(field.disableSort)) ||
|
||||||
|
fieldIsPresentationalOnly(field) ||
|
||||||
|
undefined
|
||||||
|
}
|
||||||
|
label={
|
||||||
|
'label' in field && field.label && typeof field.label !== 'function'
|
||||||
|
? field.label
|
||||||
|
: 'name' in field
|
||||||
|
? field.name
|
||||||
|
: undefined
|
||||||
|
}
|
||||||
|
name={'name' in field ? field.name : undefined}
|
||||||
|
/>
|
||||||
|
)
|
||||||
|
|
||||||
const reducedField: MappedField = {
|
const reducedField: MappedField = {
|
||||||
name: 'name' in field ? field.name : '',
|
...fieldComponentProps,
|
||||||
type: field.type,
|
type: field.type,
|
||||||
Cell: (
|
Cell,
|
||||||
<RenderCustomComponent
|
|
||||||
CustomComponent={field.admin?.components?.Cell}
|
|
||||||
DefaultComponent={DefaultCell}
|
|
||||||
componentProps={cellComponentProps}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
Field,
|
Field,
|
||||||
Heading: (
|
Heading,
|
||||||
<SortColumn
|
|
||||||
disable={
|
|
||||||
('disableSort' in field && Boolean(field.disableSort)) ||
|
|
||||||
fieldIsPresentationalOnly(field) ||
|
|
||||||
undefined
|
|
||||||
}
|
|
||||||
label={
|
|
||||||
'label' in field && field.label && typeof field.label !== 'function'
|
|
||||||
? field.label
|
|
||||||
: 'name' in field
|
|
||||||
? field.name
|
|
||||||
: undefined
|
|
||||||
}
|
|
||||||
name={'name' in field ? field.name : undefined}
|
|
||||||
/>
|
|
||||||
),
|
|
||||||
blocks,
|
|
||||||
disabled: field?.admin && 'disabled' in field.admin ? field.admin?.disabled : false,
|
|
||||||
fieldIsPresentational,
|
fieldIsPresentational,
|
||||||
hasMany: 'hasMany' in field ? field.hasMany : undefined,
|
|
||||||
isFieldAffectingData,
|
isFieldAffectingData,
|
||||||
isSidebar: 'admin' in field && field.admin?.position === 'sidebar',
|
isSidebar:
|
||||||
label: 'label' in field && typeof field.label !== 'function' ? field.label : undefined,
|
'admin' in field && 'position' in field.admin && field.admin.position === 'sidebar',
|
||||||
labels: 'labels' in field ? field.labels : undefined,
|
|
||||||
localized: 'localized' in field ? field.localized : false,
|
localized: 'localized' in field ? field.localized : false,
|
||||||
options: 'options' in field ? field.options : undefined,
|
|
||||||
readOnly:
|
|
||||||
'admin' in field && 'readOnly' in field.admin ? field.admin.readOnly : undefined,
|
|
||||||
relationTo: 'relationTo' in field ? field.relationTo : undefined,
|
|
||||||
subfields: nestedFieldMap,
|
|
||||||
tabs,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (FieldComponent) {
|
if (FieldComponent) {
|
||||||
@@ -343,7 +678,7 @@ export const mapFields = (args: {
|
|||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
const hasID =
|
const hasID =
|
||||||
result.findIndex(({ name, isFieldAffectingData }) => isFieldAffectingData && name === 'id') > -1
|
result.findIndex((f) => 'name' in f && f.isFieldAffectingData && f.name === 'id') > -1
|
||||||
|
|
||||||
if (!disableAddingID && !hasID) {
|
if (!disableAddingID && !hasID) {
|
||||||
result.push({
|
result.push({
|
||||||
@@ -354,13 +689,8 @@ export const mapFields = (args: {
|
|||||||
Heading: <SortColumn label="ID" name="id" />,
|
Heading: <SortColumn label="ID" name="id" />,
|
||||||
fieldIsPresentational: false,
|
fieldIsPresentational: false,
|
||||||
isFieldAffectingData: true,
|
isFieldAffectingData: true,
|
||||||
isSidebar: false,
|
// label: 'ID',
|
||||||
label: 'ID',
|
|
||||||
labels: undefined,
|
|
||||||
localized: undefined,
|
localized: undefined,
|
||||||
readOnly: false,
|
|
||||||
subfields: [],
|
|
||||||
tabs: [],
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,67 +10,74 @@ import type {
|
|||||||
TabsField,
|
TabsField,
|
||||||
} from 'payload/types'
|
} from 'payload/types'
|
||||||
|
|
||||||
|
import type { ArrayFieldProps } from '../../forms/fields/Array/types.js'
|
||||||
|
import type { BlocksFieldProps } from '../../forms/fields/Blocks/types.js'
|
||||||
|
import type { CheckboxFieldProps } from '../../forms/fields/Checkbox/types.js'
|
||||||
|
import type { CodeFieldProps } from '../../forms/fields/Code/types.js'
|
||||||
|
import type { CollapsibleFieldProps } from '../../forms/fields/Collapsible/types.js'
|
||||||
|
import type { DateFieldProps } from '../../forms/fields/DateTime/types.js'
|
||||||
|
import type { EmailFieldProps } from '../../forms/fields/Email/types.js'
|
||||||
|
import type { GroupFieldProps } from '../../forms/fields/Group/types.js'
|
||||||
|
import type { JSONFieldProps } from '../../forms/fields/JSON/types.js'
|
||||||
|
import type { NumberFieldProps } from '../../forms/fields/Number/types.js'
|
||||||
|
import type { PointFieldProps } from '../../forms/fields/Point/types.js'
|
||||||
|
import type { RelationshipFieldProps } from '../../forms/fields/Relationship/types.js'
|
||||||
|
import type { RowFieldProps } from '../../forms/fields/Row/types.js'
|
||||||
|
import type { SelectFieldProps } from '../../forms/fields/Select/types.js'
|
||||||
|
import type { TabsFieldProps } from '../../forms/fields/Tabs/types.js'
|
||||||
|
import type { TextFieldProps } from '../../forms/fields/Text/types.js'
|
||||||
|
import type { TextareaFieldProps } from '../../forms/fields/Textarea/types.js'
|
||||||
|
import type { UploadFieldProps } from '../../forms/fields/Upload/types.js'
|
||||||
import type { fieldTypes } from '../../forms/fields/index.js'
|
import type { fieldTypes } from '../../forms/fields/index.js'
|
||||||
|
|
||||||
export type MappedTab = {
|
export type MappedTab = {
|
||||||
|
fieldMap?: FieldMap
|
||||||
label: TabsField['tabs'][0]['label']
|
label: TabsField['tabs'][0]['label']
|
||||||
name?: string
|
name?: string
|
||||||
subfields?: FieldMap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ReducedBlock = {
|
export type ReducedBlock = {
|
||||||
|
fieldMap: FieldMap
|
||||||
imageAltText?: string
|
imageAltText?: string
|
||||||
imageURL?: string
|
imageURL?: string
|
||||||
labels: BlockField['labels']
|
labels: BlockField['labels']
|
||||||
slug: string
|
slug: string
|
||||||
subfields: FieldMap
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export type MappedField = {
|
export type FieldComponentProps =
|
||||||
|
| ArrayFieldProps
|
||||||
|
| BlocksFieldProps
|
||||||
|
| CheckboxFieldProps
|
||||||
|
| CodeFieldProps
|
||||||
|
| CollapsibleFieldProps
|
||||||
|
| DateFieldProps
|
||||||
|
| EmailFieldProps
|
||||||
|
| GroupFieldProps
|
||||||
|
| JSONFieldProps
|
||||||
|
| NumberFieldProps
|
||||||
|
| PointFieldProps
|
||||||
|
| RelationshipFieldProps
|
||||||
|
| RowFieldProps
|
||||||
|
| SelectFieldProps
|
||||||
|
| TabsFieldProps
|
||||||
|
| TextFieldProps
|
||||||
|
| TextareaFieldProps
|
||||||
|
| UploadFieldProps
|
||||||
|
|
||||||
|
export type MappedFieldBase = {
|
||||||
Cell: React.ReactNode
|
Cell: React.ReactNode
|
||||||
Field: React.ReactNode
|
Field: React.ReactNode
|
||||||
Heading: React.ReactNode
|
Heading: React.ReactNode
|
||||||
/**
|
|
||||||
* On `block` fields only
|
|
||||||
*/
|
|
||||||
blocks?: ReducedBlock[]
|
|
||||||
disabled?: boolean
|
disabled?: boolean
|
||||||
/**
|
|
||||||
* On `richText` fields only
|
|
||||||
*/
|
|
||||||
editor?: RichTextField['editor']
|
|
||||||
fieldIsPresentational: boolean
|
fieldIsPresentational: boolean
|
||||||
fieldMap?: FieldMap
|
|
||||||
hasMany?: boolean
|
|
||||||
isFieldAffectingData: boolean
|
isFieldAffectingData: boolean
|
||||||
isSidebar: boolean
|
isSidebar?: boolean
|
||||||
label: FieldBase['label']
|
|
||||||
labels: Labels
|
|
||||||
localized: boolean
|
localized: boolean
|
||||||
name: string
|
|
||||||
/**
|
|
||||||
* On `select` fields only
|
|
||||||
*/
|
|
||||||
options?: Option[]
|
|
||||||
/**
|
|
||||||
* This is the `admin.readOnly` value from the field's config
|
|
||||||
*/
|
|
||||||
readOnly: boolean
|
|
||||||
/**
|
|
||||||
* On `relationship` fields only
|
|
||||||
*/
|
|
||||||
relationTo?: RelationshipField['relationTo']
|
|
||||||
/**
|
|
||||||
* On `array`, `group`, `collapsible`, and `tabs` fields only
|
|
||||||
*/
|
|
||||||
subfields?: FieldMap
|
|
||||||
/**
|
|
||||||
* On `tabs` fields only
|
|
||||||
*/
|
|
||||||
tabs?: MappedTab[]
|
|
||||||
type: keyof typeof fieldTypes
|
type: keyof typeof fieldTypes
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export type MappedField = FieldComponentProps & MappedFieldBase
|
||||||
|
|
||||||
export type FieldMap = MappedField[]
|
export type FieldMap = MappedField[]
|
||||||
|
|
||||||
export type ActionMap = {
|
export type ActionMap = {
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ export const PostsCollection: CollectionConfig = {
|
|||||||
name: 'text',
|
name: 'text',
|
||||||
type: 'text',
|
type: 'text',
|
||||||
},
|
},
|
||||||
{
|
// {
|
||||||
name: 'richText',
|
// name: 'richText',
|
||||||
type: 'richText',
|
// type: 'richText',
|
||||||
},
|
// },
|
||||||
{
|
{
|
||||||
name: 'relationship',
|
name: 'relationship',
|
||||||
type: 'relationship',
|
type: 'relationship',
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ describe('versions', () => {
|
|||||||
await expect(
|
await expect(
|
||||||
page.locator('.autosave:has-text("Last saved less than a minute ago")'),
|
page.locator('.autosave:has-text("Last saved less than a minute ago")'),
|
||||||
).toBeVisible()
|
).toBeVisible()
|
||||||
expect(await titleField.inputValue()).toBe('global title')
|
await expect(titleField).toHaveValue('global title')
|
||||||
|
|
||||||
// refresh the page and ensure value autosaved
|
// refresh the page and ensure value autosaved
|
||||||
await page.goto(url.global(autoSaveGlobalSlug))
|
await page.goto(url.global(autoSaveGlobalSlug))
|
||||||
@@ -339,7 +339,7 @@ describe('versions', () => {
|
|||||||
// change locale back to en
|
// change locale back to en
|
||||||
await changeLocale(page, en)
|
await changeLocale(page, en)
|
||||||
// verify en loads its own title
|
// verify en loads its own title
|
||||||
expect(await titleField.inputValue()).toEqual(title)
|
await expect(titleField).toHaveValue(title)
|
||||||
// change non-localized description field
|
// change non-localized description field
|
||||||
await descriptionField.fill(newDescription)
|
await descriptionField.fill(newDescription)
|
||||||
await wait(500)
|
await wait(500)
|
||||||
@@ -352,8 +352,8 @@ describe('versions', () => {
|
|||||||
// title should not be english title
|
// title should not be english title
|
||||||
// description should be new description
|
// description should be new description
|
||||||
await page.reload()
|
await page.reload()
|
||||||
expect(await titleField.inputValue()).toEqual(spanishTitle)
|
await expect(titleField).toHaveValue(spanishTitle)
|
||||||
expect(await descriptionField.inputValue()).toEqual(newDescription)
|
await expect(descriptionField).toHaveValue(newDescription)
|
||||||
})
|
})
|
||||||
|
|
||||||
test('should restore localized docs correctly', async () => {
|
test('should restore localized docs correctly', async () => {
|
||||||
|
|||||||
Reference in New Issue
Block a user