### 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<TCellData = any, TField extends ClientField = ClientField> ``` New: ```ts type DefaultCellComponentProps<TField extends ClientField = ClientField, TCellData = undefined> ``` ### 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<DefaultCellComponentProps<,ClientField>> = () => 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.
48 lines
1.5 KiB
TypeScript
48 lines
1.5 KiB
TypeScript
'use client'
|
|
import type { BlocksFieldClient, DefaultCellComponentProps } from 'payload'
|
|
|
|
import { getTranslation } from '@payloadcms/translations'
|
|
import React from 'react'
|
|
|
|
import { useTranslation } from '../../../../../providers/Translation/index.js'
|
|
|
|
export interface BlocksCellProps extends DefaultCellComponentProps<BlocksFieldClient> {}
|
|
|
|
export const BlocksCell: React.FC<BlocksCellProps> = ({ cellData, field: { blocks, labels } }) => {
|
|
const { i18n } = useTranslation()
|
|
|
|
const selectedBlocks = Array.isArray(cellData) ? cellData.map(({ blockType }) => blockType) : []
|
|
|
|
const translatedBlockLabels = blocks?.map((b) => ({
|
|
slug: b.slug,
|
|
label: getTranslation(b.labels.singular, i18n),
|
|
}))
|
|
|
|
let label = `0 ${getTranslation(labels?.plural, i18n)}`
|
|
|
|
const formatBlockList = (blocks) =>
|
|
blocks
|
|
.map((b) => {
|
|
const filtered = translatedBlockLabels.filter((f) => f.slug === b)?.[0]
|
|
return filtered?.label
|
|
})
|
|
.join(', ')
|
|
|
|
const itemsToShow = 5
|
|
|
|
if (selectedBlocks.length > itemsToShow) {
|
|
const more = selectedBlocks.length - itemsToShow
|
|
label = `${selectedBlocks.length} ${getTranslation(labels?.plural, i18n)} - ${i18n.t(
|
|
'fields:itemsAndMore',
|
|
{ count: more, items: formatBlockList(selectedBlocks.slice(0, itemsToShow)) },
|
|
)}`
|
|
} else if (selectedBlocks.length > 0) {
|
|
label = `${selectedBlocks.length} ${getTranslation(
|
|
selectedBlocks.length === 1 ? labels?.singular : labels?.plural,
|
|
i18n,
|
|
)} - ${formatBlockList(selectedBlocks)}`
|
|
}
|
|
|
|
return <span>{label}</span>
|
|
}
|