From 77c99c2f496d4428073cd07e389cf8f0ee96709c Mon Sep 17 00:00:00 2001 From: Jarrod Flesch <30633324+JarrodMFlesch@users.noreply.github.com> Date: Thu, 14 Nov 2024 12:31:42 -0500 Subject: [PATCH] feat!: re-order DefaultCellComponentProps generics (#9207) ### What? Changes the order of the `DefaultCellComponentProps` generic type, allowing us to infer the type of cellData when a ClientField type is passed as the first generic argument. You can override the cellData type by passing the second generic. Previously: ```ts type DefaultCellComponentProps ``` New: ```ts type DefaultCellComponentProps ``` ### Why? Changing the ClientField type to be the first argument allows us to infer the cellData value type based on the type of field. I could have kept the same signature but the usage would look like: ```ts // Not very DX friendly const MyCellComponent> = () => null ``` ### How? The changes made [here](https://github.com/payloadcms/payload/compare/chore/beta/simplify-DefaultCellComponentProps?expand=1#diff-24f3c92e546c2be3fed0bab305236bba83001309a7239c20a3e3dbd6f5f71dc6R29-R73) allow this. You can override the type by passing in the second argument to the generic. --- packages/payload/src/admin/elements/Cell.ts | 73 +++++++++++++++++-- packages/richtext-lexical/src/types.ts | 4 +- .../Table/DefaultCell/fields/Array/index.tsx | 3 +- .../Table/DefaultCell/fields/Blocks/index.tsx | 2 +- .../DefaultCell/fields/Checkbox/index.tsx | 2 +- .../Table/DefaultCell/fields/Code/index.tsx | 2 +- .../Table/DefaultCell/fields/Date/index.tsx | 7 +- .../Table/DefaultCell/fields/File/index.tsx | 2 +- .../Table/DefaultCell/fields/JSON/index.tsx | 4 +- .../DefaultCell/fields/Relationship/index.tsx | 1 - .../Table/DefaultCell/fields/Select/index.tsx | 2 +- .../DefaultCell/fields/Textarea/index.tsx | 2 +- 12 files changed, 81 insertions(+), 23 deletions(-) diff --git a/packages/payload/src/admin/elements/Cell.ts b/packages/payload/src/admin/elements/Cell.ts index 3c6936413..bc181361d 100644 --- a/packages/payload/src/admin/elements/Cell.ts +++ b/packages/payload/src/admin/elements/Cell.ts @@ -2,14 +2,75 @@ import type { I18nClient } from '@payloadcms/translations' import type { ClientCollectionConfig } from '../../collections/config/client.js' import type { SanitizedCollectionConfig } from '../../collections/config/types.js' -import type { ClientField } from '../../fields/config/client.js' -import type { Field } from '../../fields/config/types.js' +import type { + ArrayFieldClient, + BlocksFieldClient, + CheckboxFieldClient, + ClientField, + CodeFieldClient, + DateFieldClient, + EmailFieldClient, + Field, + GroupFieldClient, + JSONFieldClient, + NumberFieldClient, + PointFieldClient, + RadioFieldClient, + RelationshipFieldClient, + SelectFieldClient, + TextareaFieldClient, + TextFieldClient, + UploadFieldClient, +} from '../../fields/config/types.js' import type { Payload } from '../../types/index.js' export type RowData = Record -export type DefaultCellComponentProps = { - readonly cellData: TCellData +export type DefaultCellComponentProps< + TField extends ClientField = ClientField, + TCellData = undefined, +> = { + readonly cellData: TCellData extends undefined + ? TField extends RelationshipFieldClient + ? number | Record | string + : TField extends NumberFieldClient + ? TField['hasMany'] extends true + ? number[] + : number + : TField extends TextFieldClient + ? TField['hasMany'] extends true + ? string[] + : string + : TField extends + | CodeFieldClient + | EmailFieldClient + | JSONFieldClient + | RadioFieldClient + | TextareaFieldClient + ? string + : TField extends BlocksFieldClient + ? { + [key: string]: any + blockType: string + }[] + : TField extends CheckboxFieldClient + ? boolean + : TField extends DateFieldClient + ? Date | number | string + : TField extends GroupFieldClient + ? Record + : TField extends UploadFieldClient + ? File | string + : TField extends ArrayFieldClient + ? Record[] + : TField extends SelectFieldClient + ? TField['hasMany'] extends true + ? string[] + : string + : TField extends PointFieldClient + ? { x: number; y: number } + : any + : TCellData readonly className?: string readonly collectionConfig: ClientCollectionConfig readonly columnIndex?: number @@ -25,10 +86,10 @@ export type DefaultCellComponentProps = { field: Field i18n: I18nClient payload: Payload -} & Omit, 'field'> +} & Omit, 'field'> diff --git a/packages/richtext-lexical/src/types.ts b/packages/richtext-lexical/src/types.ts index 21037a61a..a0a96fbb4 100644 --- a/packages/richtext-lexical/src/types.ts +++ b/packages/richtext-lexical/src/types.ts @@ -100,8 +100,8 @@ export type LexicalRichTextFieldProps = { RichTextFieldClientProps export type LexicalRichTextCellProps = DefaultCellComponentProps< - SerializedEditorState, - RichTextFieldClient + RichTextFieldClient, + SerializedEditorState > export type AdapterProps = { diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/Array/index.tsx b/packages/ui/src/elements/Table/DefaultCell/fields/Array/index.tsx index 36f33b5d2..0732a6308 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/Array/index.tsx +++ b/packages/ui/src/elements/Table/DefaultCell/fields/Array/index.tsx @@ -6,8 +6,7 @@ import React from 'react' import { useTranslation } from '../../../../../providers/Translation/index.js' -export interface ArrayCellProps - extends DefaultCellComponentProps[], ArrayFieldClient> {} +export interface ArrayCellProps extends DefaultCellComponentProps {} export const ArrayCell: React.FC = ({ cellData, field: { labels } }) => { const { i18n } = useTranslation() diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/Blocks/index.tsx b/packages/ui/src/elements/Table/DefaultCell/fields/Blocks/index.tsx index 2d3bfa13d..75e246f31 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/Blocks/index.tsx +++ b/packages/ui/src/elements/Table/DefaultCell/fields/Blocks/index.tsx @@ -6,7 +6,7 @@ import React from 'react' import { useTranslation } from '../../../../../providers/Translation/index.js' -export interface BlocksCellProps extends DefaultCellComponentProps {} +export interface BlocksCellProps extends DefaultCellComponentProps {} export const BlocksCell: React.FC = ({ cellData, field: { blocks, labels } }) => { const { i18n } = useTranslation() diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/Checkbox/index.tsx b/packages/ui/src/elements/Table/DefaultCell/fields/Checkbox/index.tsx index 33f0c31e9..e4d238916 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/Checkbox/index.tsx +++ b/packages/ui/src/elements/Table/DefaultCell/fields/Checkbox/index.tsx @@ -6,7 +6,7 @@ import React from 'react' import { useTranslation } from '../../../../../providers/Translation/index.js' import './index.scss' -export const CheckboxCell: React.FC> = ({ +export const CheckboxCell: React.FC> = ({ cellData, }) => { const { t } = useTranslation() diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/Code/index.tsx b/packages/ui/src/elements/Table/DefaultCell/fields/Code/index.tsx index e9a3af77a..9804bea57 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/Code/index.tsx +++ b/packages/ui/src/elements/Table/DefaultCell/fields/Code/index.tsx @@ -5,7 +5,7 @@ import React from 'react' import './index.scss' -export interface CodeCellProps extends DefaultCellComponentProps { +export interface CodeCellProps extends DefaultCellComponentProps { readonly nowrap?: boolean } diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/Date/index.tsx b/packages/ui/src/elements/Table/DefaultCell/fields/Date/index.tsx index 8c0cb6882..4dfd56f6b 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/Date/index.tsx +++ b/packages/ui/src/elements/Table/DefaultCell/fields/Date/index.tsx @@ -7,9 +7,10 @@ import { useConfig } from '../../../../../providers/Config/index.js' import { useTranslation } from '../../../../../providers/Translation/index.js' import { formatDate } from '../../../../../utilities/formatDate.js' -export const DateCell: React.FC< - DefaultCellComponentProps -> = ({ cellData, field: { admin: { date } = {} } }) => { +export const DateCell: React.FC> = ({ + cellData, + field: { admin: { date } = {} }, +}) => { const { config: { admin: { dateFormat: dateFormatFromRoot }, diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/File/index.tsx b/packages/ui/src/elements/Table/DefaultCell/fields/File/index.tsx index 2ba65164a..e2bfbb353 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/File/index.tsx +++ b/packages/ui/src/elements/Table/DefaultCell/fields/File/index.tsx @@ -9,7 +9,7 @@ import './index.scss' const baseClass = 'file' export interface FileCellProps - extends DefaultCellComponentProps {} + extends DefaultCellComponentProps {} export const FileCell: React.FC = ({ cellData: filename, diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/JSON/index.tsx b/packages/ui/src/elements/Table/DefaultCell/fields/JSON/index.tsx index 842c62c52..938f02bd8 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/JSON/index.tsx +++ b/packages/ui/src/elements/Table/DefaultCell/fields/JSON/index.tsx @@ -5,9 +5,7 @@ import React from 'react' import './index.scss' -export const JSONCell: React.FC> = ({ - cellData, -}) => { +export const JSONCell: React.FC> = ({ cellData }) => { const textToShow = cellData?.length > 100 ? `${cellData.substring(0, 100)}\u2026` : cellData return ( diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/Relationship/index.tsx b/packages/ui/src/elements/Table/DefaultCell/fields/Relationship/index.tsx index 1caf14cdc..e4d218aec 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/Relationship/index.tsx +++ b/packages/ui/src/elements/Table/DefaultCell/fields/Relationship/index.tsx @@ -24,7 +24,6 @@ const baseClass = 'relationship-cell' const totalToShow = 3 export type RelationshipCellProps = DefaultCellComponentProps< - any, JoinFieldClient | RelationshipFieldClient | UploadFieldClient > diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/Select/index.tsx b/packages/ui/src/elements/Table/DefaultCell/fields/Select/index.tsx index 293f3bd14..c1a8bfdf5 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/Select/index.tsx +++ b/packages/ui/src/elements/Table/DefaultCell/fields/Select/index.tsx @@ -7,7 +7,7 @@ import React from 'react' import { useTranslation } from '../../../../../providers/Translation/index.js' -export interface SelectCellProps extends DefaultCellComponentProps {} +export interface SelectCellProps extends DefaultCellComponentProps {} export const SelectCell: React.FC = ({ cellData, field: { options } }) => { const { i18n } = useTranslation() diff --git a/packages/ui/src/elements/Table/DefaultCell/fields/Textarea/index.tsx b/packages/ui/src/elements/Table/DefaultCell/fields/Textarea/index.tsx index af3ef63ce..4ae194891 100644 --- a/packages/ui/src/elements/Table/DefaultCell/fields/Textarea/index.tsx +++ b/packages/ui/src/elements/Table/DefaultCell/fields/Textarea/index.tsx @@ -3,7 +3,7 @@ import type { DefaultCellComponentProps, TextareaFieldClient } from 'payload' import React from 'react' -export const TextareaCell: React.FC> = ({ +export const TextareaCell: React.FC> = ({ cellData, }) => { const textToShow = cellData?.length > 100 ? `${cellData.substring(0, 100)}\u2026` : cellData