fix(ui): renders custom row labels

This commit is contained in:
Jacob Fletcher
2024-03-20 22:49:43 -04:00
parent 5ae537f23c
commit d956055795
10 changed files with 82 additions and 42 deletions

View File

@@ -32,7 +32,7 @@ import './index.scss'
const baseClass = 'array-field'
export type ArrayFieldProps = FormFieldBase & {
RowLabel?: React.ReactNode
CustomRowLabel?: React.ReactNode
fieldMap: FieldMap
forceRender?: boolean
indexPath: string
@@ -51,7 +51,7 @@ export const ArrayField: React.FC<ArrayFieldProps> = (props) => {
CustomDescription,
CustomError,
CustomLabel,
RowLabel,
CustomRowLabel,
className,
descriptionProps,
errorProps,
@@ -252,7 +252,7 @@ export const ArrayField: React.FC<ArrayFieldProps> = (props) => {
{(draggableSortableItemProps) => (
<ArrayRow
{...draggableSortableItemProps}
CustomRowLabel={RowLabel}
CustomRowLabel={CustomRowLabel}
addRow={addRow}
duplicateRow={duplicateRow}
fieldMap={fieldMap}

View File

@@ -14,7 +14,6 @@ import { Pill } from '../../elements/Pill/index.js'
import { useFormSubmitted } from '../../forms/Form/context.js'
import { RenderFields } from '../../forms/RenderFields/index.js'
import { useTranslation } from '../../providers/Translation/index.js'
import { HiddenInput } from '../HiddenInput/index.js'
import { RowActions } from './RowActions.js'
import { SectionTitle } from './SectionTitle/index.js'

View File

@@ -1,6 +1,5 @@
/* eslint-disable react/destructuring-assignment */
'use client'
import type { DocumentPreferences } from 'payload/types'
import type { DocumentPreferences, RowLabel } from 'payload/types'
import React, { Fragment, useCallback, useEffect, useState } from 'react'
@@ -19,7 +18,6 @@ import './index.scss'
const baseClass = 'collapsible-field'
import type { FieldPermissions } from 'payload/auth'
import type { FieldBase } from 'payload/types'
import { FieldDescription } from '@payloadcms/ui/forms/FieldDescription'
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
@@ -31,7 +29,7 @@ export type CollapsibleFieldProps = FormFieldBase & {
fieldMap: FieldMap
indexPath: string
initCollapsed?: boolean
label?: FieldBase['label']
label?: RowLabel
permissions: FieldPermissions
width?: string
}

View File

@@ -44,12 +44,10 @@ export const UploadInput: React.FC<UploadInputProps> = (props) => {
descriptionProps,
errorProps,
filterOptions,
label,
labelProps,
onChange,
readOnly,
relationTo,
required,
serverURL,
showError,
style,

View File

@@ -1,5 +1,12 @@
import type { FieldDescriptionProps } from '@payloadcms/ui/forms/FieldDescription'
import type { CellProps, Field, FieldWithPath, LabelProps, SanitizedConfig } from 'payload/types'
import type {
CellProps,
Field,
FieldWithPath,
LabelProps,
RowLabelComponent,
SanitizedConfig,
} from 'payload/types'
import { fieldAffectsData, fieldIsPresentationalOnly } from 'payload/types'
import { isPlainObject } from 'payload/utilities'
@@ -80,8 +87,7 @@ export const mapFields = (args: {
}`
const labelProps: LabelProps = {
// @ts-expect-error-next-line
label: 'label' in field ? field.label : null,
label: 'label' in field && typeof field.label !== 'function' ? field.label : null,
required: 'required' in field ? field.required : undefined,
}
@@ -204,23 +210,26 @@ export const mapFields = (args: {
switch (field.type) {
case 'array': {
let RowLabel: React.ReactNode
let CustomRowLabel: React.ReactNode
if (
'admin' in field &&
field.admin.components &&
'RowLabel' in field.admin.components &&
field.admin.components.RowLabel &&
!isPlainObject(field.admin.components.RowLabel)
(typeof field.admin.components.RowLabel === 'function' ||
// Do this to test for client components (`use client` directive) bc they import as empty objects
(typeof field.admin.components.RowLabel === 'object' &&
!isPlainObject(field.admin.components.RowLabel)))
) {
const CustomRowLabel = field.admin.components.RowLabel as React.ComponentType
RowLabel = <CustomRowLabel />
const CustomRowLabelComponent = field.admin.components.RowLabel as RowLabelComponent
CustomRowLabel = <CustomRowLabelComponent />
}
const arrayFieldProps: Omit<ArrayFieldProps, 'indexPath' | 'permissions'> = {
...baseFieldProps,
name: field.name,
RowLabel,
CustomRowLabel,
className: field.admin?.className,
disabled: field.admin?.disabled,
fieldMap: nestedFieldMap,
@@ -319,16 +328,20 @@ export const mapFields = (args: {
break
}
case 'collapsible': {
let CollapsibleLabel: React.ReactNode
let CustomCollapsibleLabel: React.ReactNode
if (typeof field.label === 'object' && !isPlainObject(field.label)) {
const LabelToRender = field.label as unknown as React.ComponentType
CollapsibleLabel = <LabelToRender />
if (
typeof field.label === 'function' ||
// Do this to test for client components (`use client` directive) bc they import as empty objects
(typeof field.label === 'object' && !isPlainObject(field.label))
) {
const CustomCollapsibleLabelComponent = field.label as RowLabelComponent
CustomCollapsibleLabel = <CustomCollapsibleLabelComponent />
}
const collapsibleField: Omit<CollapsibleFieldProps, 'indexPath' | 'permissions'> = {
...baseFieldProps,
CustomLabel: CollapsibleLabel,
CustomLabel: CustomCollapsibleLabel,
className: field.admin?.className,
disabled: field.admin?.disabled,
fieldMap: nestedFieldMap,
@@ -338,7 +351,7 @@ export const mapFields = (args: {
width: field.admin?.width,
}
fieldComponentProps = collapsibleField
fieldComponentProps = collapsibleField as CollapsibleFieldProps // TODO: dunno why this is needed
break
}
case 'date': {