chore: properly types cell components (#5474)
This commit is contained in:
@@ -36,5 +36,9 @@ export const CreatedAtCell: React.FC<CreatedAtCellProps> = ({
|
||||
|
||||
if (globalSlug) to = `${admin}/globals/${globalSlug}/versions/${versionID}`
|
||||
|
||||
return <Link href={to}>{cellData && formatDate(cellData, dateFormat, i18n.language)}</Link>
|
||||
return (
|
||||
<Link href={to}>
|
||||
{cellData && formatDate(cellData as Date | number | string, dateFormat, i18n.language)}
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -4,5 +4,5 @@ import React, { Fragment } from 'react'
|
||||
|
||||
export const IDCell: React.FC = () => {
|
||||
const { cellData } = useTableCell()
|
||||
return <Fragment>{cellData}</Fragment>
|
||||
return <Fragment>{cellData as number | string}</Fragment>
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ import type {
|
||||
SelectField,
|
||||
} from '../../fields/config/types.js'
|
||||
|
||||
export type CellProps = {
|
||||
export type RowData = Record<string, any>
|
||||
|
||||
export type CellComponentProps = {
|
||||
/**
|
||||
* A custom component to override the default cell component. If this is not set, the React component will be
|
||||
* taken from cellComponents based on the field type.
|
||||
@@ -32,19 +34,18 @@ export type CellProps = {
|
||||
onClick?: (args: {
|
||||
cellData: unknown
|
||||
collectionSlug: SanitizedCollectionConfig['slug']
|
||||
rowData: Record<string, unknown>
|
||||
rowData: RowData
|
||||
}) => void
|
||||
options?: SelectField['options']
|
||||
relationTo?: RelationshipField['relationTo']
|
||||
richTextComponentMap?: Map<string, React.ReactNode> // any should be MappedField
|
||||
}
|
||||
|
||||
export type CellComponentProps<Data = unknown> = {
|
||||
cellData: Data
|
||||
export type DefaultCellComponentProps<T = any> = CellComponentProps & {
|
||||
cellData: T
|
||||
customCellContext?: {
|
||||
collectionSlug?: SanitizedCollectionConfig['slug']
|
||||
uploadConfig?: SanitizedCollectionConfig['upload']
|
||||
}
|
||||
richTextComponentMap?: Map<string, React.ReactNode>
|
||||
rowData?: Record<string, unknown>
|
||||
rowData: RowData
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
export type { RichTextAdapter, RichTextFieldProps } from './RichText.js'
|
||||
export type { CellComponentProps, CellProps } from './elements/Cell.js'
|
||||
export type { CellComponentProps, DefaultCellComponentProps } from './elements/Cell.js'
|
||||
export type { ConditionalDateProps } from './elements/DatePicker.js'
|
||||
export type { DayPickerProps, SharedProps, TimePickerProps } from './elements/DatePicker.js'
|
||||
export type { DefaultPreviewButtonProps } from './elements/PreviewButton.js'
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use client'
|
||||
import type { CellComponentProps } from 'payload/types'
|
||||
import type { DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
export const RichTextCell: React.FC<CellComponentProps<any[]>> = ({ cellData }) => {
|
||||
export const RichTextCell: React.FC<DefaultCellComponentProps<any[]>> = ({ cellData }) => {
|
||||
const flattenedText = cellData?.map((i) => i?.children?.map((c) => c.text)).join(' ')
|
||||
|
||||
// Limiting the number of characters shown is done in a CSS rule
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
'use client'
|
||||
import type { CellComponentProps, CellProps } from 'payload/types'
|
||||
import type { CellComponentProps, DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
||||
import React from 'react'
|
||||
|
||||
export interface ArrayCellProps extends CellComponentProps<Record<string, unknown>[]> {
|
||||
labels: CellProps['labels']
|
||||
export interface ArrayCellProps extends DefaultCellComponentProps<Record<string, unknown>[]> {
|
||||
labels: CellComponentProps['labels']
|
||||
}
|
||||
|
||||
export const ArrayCell: React.FC<ArrayCellProps> = ({ cellData, labels }) => {
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
'use client'
|
||||
import type { CellComponentProps, CellProps } from 'payload/types'
|
||||
import type { CellComponentProps, DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
||||
import React from 'react'
|
||||
|
||||
export interface BlocksCellProps extends CellComponentProps<any> {
|
||||
blocks: CellProps['blocks']
|
||||
labels: CellProps['labels']
|
||||
export interface BlocksCellProps extends DefaultCellComponentProps<any> {
|
||||
blocks: CellComponentProps['blocks']
|
||||
labels: CellComponentProps['labels']
|
||||
}
|
||||
|
||||
export const BlocksCell: React.FC<BlocksCellProps> = ({ blocks, cellData, labels }) => {
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
'use client'
|
||||
import type { CellComponentProps } from 'payload/types'
|
||||
import type { DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
export const CheckboxCell: React.FC<CellComponentProps<boolean>> = ({ cellData }) => (
|
||||
export const CheckboxCell: React.FC<DefaultCellComponentProps<boolean>> = ({ cellData }) => (
|
||||
<code className="bool-cell">
|
||||
<span>{JSON.stringify(cellData)}</span>
|
||||
</code>
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
import type { CellComponentProps } from 'payload/types'
|
||||
import type { DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
export interface CodeCellProps extends CellComponentProps<string> {
|
||||
export interface CodeCellProps extends DefaultCellComponentProps<string> {
|
||||
nowrap?: boolean
|
||||
}
|
||||
|
||||
|
||||
@@ -1,16 +1,15 @@
|
||||
'use client'
|
||||
import type { CellComponentProps, CellProps } from 'payload/types'
|
||||
import type { DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import { useConfig } from '@payloadcms/ui/providers/Config'
|
||||
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
||||
import { formatDate } from '@payloadcms/ui/utilities/formatDate'
|
||||
import React from 'react'
|
||||
|
||||
export interface DateCellProps extends CellComponentProps<string> {
|
||||
dateDisplayFormat?: CellProps['dateDisplayFormat']
|
||||
}
|
||||
|
||||
export const DateCell: React.FC<DateCellProps> = ({ cellData, dateDisplayFormat }) => {
|
||||
export const DateCell: React.FC<DefaultCellComponentProps<Date | number | string>> = ({
|
||||
cellData,
|
||||
dateDisplayFormat,
|
||||
}) => {
|
||||
const {
|
||||
admin: { dateFormat: dateFormatFromConfig },
|
||||
} = useConfig()
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import type { CellComponentProps } from 'payload/types'
|
||||
import type { DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import { Thumbnail } from '@payloadcms/ui/elements/Thumbnail'
|
||||
import React from 'react'
|
||||
@@ -8,7 +8,7 @@ import './index.scss'
|
||||
|
||||
const baseClass = 'file'
|
||||
|
||||
export interface FileCellProps extends CellComponentProps<any> {}
|
||||
export interface FileCellProps extends DefaultCellComponentProps<any> {}
|
||||
|
||||
export const FileCell: React.FC<FileCellProps> = ({ cellData, customCellContext, rowData }) => {
|
||||
const { collectionSlug, uploadConfig } = customCellContext
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
'use client'
|
||||
import type { CellComponentProps } from 'payload/types'
|
||||
import type { DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
import './index.scss'
|
||||
|
||||
export const JSONCell: React.FC<CellComponentProps<string>> = ({ cellData }) => {
|
||||
export const JSONCell: React.FC<DefaultCellComponentProps<string>> = ({ cellData }) => {
|
||||
const textToShow = cellData.length > 100 ? `${cellData.substring(0, 100)}\u2026` : cellData
|
||||
|
||||
return (
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import type { CellComponentProps, CellProps } from 'payload/types'
|
||||
import type { CellComponentProps, DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { useIntersect } from '@payloadcms/ui/hooks/useIntersect'
|
||||
@@ -16,9 +16,9 @@ type Value = { relationTo: string; value: number | string }
|
||||
const baseClass = 'relationship-cell'
|
||||
const totalToShow = 3
|
||||
|
||||
export interface RelationshipCellProps extends CellComponentProps<any> {
|
||||
label: CellProps['label']
|
||||
relationTo: CellProps['relationTo']
|
||||
export interface RelationshipCellProps extends DefaultCellComponentProps<any> {
|
||||
label: CellComponentProps['label']
|
||||
relationTo: CellComponentProps['relationTo']
|
||||
}
|
||||
|
||||
export const RelationshipCell: React.FC<RelationshipCellProps> = ({
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
'use client'
|
||||
import type { CellComponentProps, CellProps, OptionObject } from 'payload/types'
|
||||
import type { CellComponentProps, DefaultCellComponentProps, OptionObject } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { useTranslation } from '@payloadcms/ui/providers/Translation'
|
||||
import { optionsAreObjects } from 'payload/types'
|
||||
import React from 'react'
|
||||
|
||||
export interface SelectCellProps extends CellComponentProps<any> {
|
||||
options: CellProps['options']
|
||||
export interface SelectCellProps extends DefaultCellComponentProps<any> {
|
||||
options: CellComponentProps['options']
|
||||
}
|
||||
|
||||
export const SelectCell: React.FC<SelectCellProps> = ({ cellData, options }) => {
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
'use client'
|
||||
import type { CellComponentProps } from 'payload/types'
|
||||
import type { DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
export const TextareaCell: React.FC<CellComponentProps<string>> = ({ cellData }) => {
|
||||
export const TextareaCell: React.FC<DefaultCellComponentProps<string>> = ({ cellData }) => {
|
||||
const textToShow = cellData?.length > 100 ? `${cellData.substr(0, 100)}\u2026` : cellData
|
||||
return <span>{textToShow}</span>
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
import LinkImport from 'next/link.js'
|
||||
import React from 'react' // TODO: abstract this out to support all routers
|
||||
|
||||
import type { CellProps } from 'payload/types'
|
||||
import type { CellComponentProps, DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import { getTranslation } from '@payloadcms/translations'
|
||||
import { TableCellProvider, useTableCell } from '@payloadcms/ui/elements/Table'
|
||||
@@ -14,7 +14,7 @@ import { cellComponents } from './fields/index.js'
|
||||
|
||||
const Link = (LinkImport.default || LinkImport) as unknown as typeof LinkImport.default
|
||||
|
||||
export const DefaultCell: React.FC<CellProps> = (props) => {
|
||||
export const DefaultCell: React.FC<CellComponentProps> = (props) => {
|
||||
const {
|
||||
name,
|
||||
CellComponentOverride,
|
||||
@@ -77,12 +77,12 @@ export const DefaultCell: React.FC<CellProps> = (props) => {
|
||||
if (name === 'id') {
|
||||
return (
|
||||
<WrapElement {...wrapElementProps}>
|
||||
<CodeCell cellData={`ID: ${cellData}`} nowrap />
|
||||
<CodeCell cellData={`ID: ${cellData}`} name={name} nowrap rowData={rowData} />
|
||||
</WrapElement>
|
||||
)
|
||||
}
|
||||
|
||||
const DefaultCellComponent = cellComponents[fieldType]
|
||||
const DefaultCellComponent: React.FC<DefaultCellComponentProps> = cellComponents[fieldType]
|
||||
|
||||
let CellComponent: React.ReactNode =
|
||||
cellData &&
|
||||
|
||||
@@ -1,27 +1,27 @@
|
||||
'use client'
|
||||
import type { CellComponentProps, CellProps } from 'payload/types'
|
||||
import type { CellComponentProps, DefaultCellComponentProps } from 'payload/types'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
export type ITableCellContext = {
|
||||
cellData: any
|
||||
cellProps?: Partial<CellProps>
|
||||
cellData: DefaultCellComponentProps['cellData']
|
||||
cellProps?: Partial<CellComponentProps>
|
||||
columnIndex?: number
|
||||
customCellContext: CellComponentProps['customCellContext']
|
||||
richTextComponentMap?: CellComponentProps['richTextComponentMap']
|
||||
rowData: any
|
||||
customCellContext: DefaultCellComponentProps['customCellContext']
|
||||
richTextComponentMap?: DefaultCellComponentProps['richTextComponentMap']
|
||||
rowData: DefaultCellComponentProps['rowData']
|
||||
}
|
||||
|
||||
const TableCellContext = React.createContext<ITableCellContext>({} as ITableCellContext)
|
||||
|
||||
export const TableCellProvider: React.FC<{
|
||||
cellData?: any
|
||||
cellProps?: Partial<CellProps>
|
||||
cellData?: DefaultCellComponentProps['cellData']
|
||||
cellProps?: Partial<CellComponentProps>
|
||||
children: React.ReactNode
|
||||
columnIndex?: number
|
||||
customCellContext?: CellComponentProps['customCellContext']
|
||||
richTextComponentMap?: CellComponentProps['richTextComponentMap']
|
||||
rowData?: any
|
||||
customCellContext?: DefaultCellComponentProps['customCellContext']
|
||||
richTextComponentMap?: DefaultCellComponentProps['richTextComponentMap']
|
||||
rowData?: DefaultCellComponentProps['rowData']
|
||||
}> = (props) => {
|
||||
const {
|
||||
cellData,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import type { CellProps, FieldBase } from 'payload/types'
|
||||
import type { CellComponentProps, FieldBase } from 'payload/types'
|
||||
|
||||
import React from 'react'
|
||||
|
||||
@@ -11,12 +11,14 @@ import { useTableColumns } from '../TableColumns/index.js'
|
||||
import { TableCellProvider } from './TableCellProvider/index.js'
|
||||
import './index.scss'
|
||||
|
||||
export { TableCellProvider }
|
||||
|
||||
const baseClass = 'table'
|
||||
|
||||
export type Column = {
|
||||
accessor: string
|
||||
active: boolean
|
||||
cellProps?: Partial<CellProps>
|
||||
cellProps?: Partial<CellComponentProps>
|
||||
components: {
|
||||
Cell: React.ReactNode
|
||||
Heading: React.ReactNode
|
||||
@@ -28,7 +30,7 @@ export type Column = {
|
||||
export type Props = {
|
||||
columns?: Column[]
|
||||
customCellContext?: Record<string, unknown>
|
||||
data: unknown[]
|
||||
data: Record<string, unknown>[]
|
||||
fieldMap: FieldMap
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { FieldLabel } from '@payloadcms/ui/forms/FieldLabel'
|
||||
import { type CellProps, type SanitizedCollectionConfig } from 'payload/types'
|
||||
import { type CellComponentProps, type SanitizedCollectionConfig } from 'payload/types'
|
||||
import React from 'react'
|
||||
|
||||
import type { FieldMap, MappedField } from '../../providers/ComponentMap/buildComponentMap/types.js'
|
||||
@@ -15,7 +15,7 @@ import { DefaultCell } from '../Table/DefaultCell/index.js'
|
||||
const fieldIsPresentationalOnly = (field: MappedField): boolean => field.type === 'ui'
|
||||
|
||||
export const buildColumns = (args: {
|
||||
cellProps: Partial<CellProps>[]
|
||||
cellProps: Partial<CellComponentProps>[]
|
||||
columnPreferences: ColumnPreferences
|
||||
defaultColumns?: string[]
|
||||
enableRowSelections: boolean
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use client'
|
||||
import type { SanitizedCollectionConfig } from 'payload/types'
|
||||
import type { CellProps } from 'payload/types'
|
||||
import type { CellComponentProps } from 'payload/types'
|
||||
|
||||
import React, { createContext, useCallback, useContext, useEffect, useReducer, useRef } from 'react'
|
||||
|
||||
@@ -31,7 +31,7 @@ export type ListPreferences = {
|
||||
}
|
||||
|
||||
type Props = {
|
||||
cellProps?: Partial<CellProps>[]
|
||||
cellProps?: Partial<CellComponentProps>[]
|
||||
children: React.ReactNode
|
||||
collectionSlug: string
|
||||
enableRowSelections?: boolean
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { FieldDescriptionProps } from '@payloadcms/ui/forms/FieldDescription'
|
||||
import type {
|
||||
CellProps,
|
||||
CellComponentProps,
|
||||
Field,
|
||||
FieldWithPath,
|
||||
LabelProps,
|
||||
@@ -189,7 +189,7 @@ export const mapFields = (args: {
|
||||
|
||||
let fieldComponentProps: FieldComponentProps
|
||||
|
||||
const cellComponentProps: CellProps = {
|
||||
const cellComponentProps: CellComponentProps = {
|
||||
name: 'name' in field ? field.name : undefined,
|
||||
fieldType: field.type,
|
||||
isFieldAffectingData,
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { HiddenInputFieldProps } from '@payloadcms/ui/fields/HiddenInput'
|
||||
import type { FieldTypes } from 'payload/config'
|
||||
import type {
|
||||
BlockField,
|
||||
CellProps,
|
||||
CellComponentProps,
|
||||
SanitizedCollectionConfig,
|
||||
SanitizedGlobalConfig,
|
||||
TabsField,
|
||||
@@ -67,7 +67,7 @@ export type FieldComponentProps =
|
||||
export type MappedField = {
|
||||
CustomCell?: React.ReactNode
|
||||
CustomField?: React.ReactNode
|
||||
cellComponentProps: CellProps
|
||||
cellComponentProps: CellComponentProps
|
||||
disableBulkEdit?: boolean
|
||||
disabled?: boolean
|
||||
fieldComponentProps: FieldComponentProps
|
||||
|
||||
@@ -2,6 +2,7 @@ import type { CollectionConfig } from 'payload/types'
|
||||
|
||||
import { slateEditor } from '@payloadcms/richtext-slate'
|
||||
|
||||
import { CustomCell } from '../components/CustomCell/index.js'
|
||||
import { DemoUIFieldCell } from '../components/DemoUIField/Cell.js'
|
||||
import { DemoUIField } from '../components/DemoUIField/Field.js'
|
||||
import {
|
||||
@@ -82,6 +83,15 @@ export const Posts: CollectionConfig = {
|
||||
},
|
||||
relationTo: 'posts',
|
||||
},
|
||||
{
|
||||
name: 'customCell',
|
||||
type: 'text',
|
||||
admin: {
|
||||
components: {
|
||||
Cell: CustomCell,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'sidebarField',
|
||||
type: 'text',
|
||||
|
||||
10
test/admin/components/CustomCell/index.tsx
Normal file
10
test/admin/components/CustomCell/index.tsx
Normal file
@@ -0,0 +1,10 @@
|
||||
'use client'
|
||||
import type { CellComponentProps } from 'payload/types'
|
||||
|
||||
import { useTableCell } from '@payloadcms/ui/elements/Table'
|
||||
import React from 'react'
|
||||
|
||||
export const CustomCell: React.FC<CellComponentProps> = (props) => {
|
||||
const context = useTableCell()
|
||||
return <div>{`Custom cell: ${context.cellData || 'No data'}`}</div>
|
||||
}
|
||||
Reference in New Issue
Block a user