More control over array items' labels #1843
Replies: 8 comments 6 replies
-
👍🏻 If you don't plan to implement this, getting pointers on how to implement it would be helpful as well. |
Beta Was this translation helpful? Give feedback.
-
There's a labels |
Beta Was this translation helpful? Give feedback.
-
There is the following option, but I don't see how you get the actual title in there because it just gives you the id:
|
Beta Was this translation helpful? Give feedback.
-
How should this be done with Payload 3 beta? |
Beta Was this translation helpful? Give feedback.
-
The docs for the array field have a working example of how to change the label using another field. import { CollectionConfig } from 'payload/types'
import { RowLabelArgs } from 'payload/dist/admin/components/forms/RowLabel/types'
export const ExampleCollection: CollectionConfig = {
slug: 'example-collection',
fields: [
{
name: 'slider', // required
type: 'array', // required
label: 'Image Slider',
minRows: 2,
maxRows: 10,
interfaceName: 'CardSlider', // optional
labels: {
singular: 'Slide',
plural: 'Slides',
},
fields: [
// required
{
name: 'title',
type: 'text',
},
{
name: 'image',
type: 'upload',
relationTo: 'media',
required: true,
},
{
name: 'caption',
type: 'text',
},
],
admin: {
components: {
RowLabel: ({ data, index }: RowLabelArgs) => {
return data?.title || `Slide ${String(index).padStart(2, '0')}`
},
},
},
},
],
} |
Beta Was this translation helpful? Give feedback.
-
I have a very basic/simple working version for v3 beta.90: ArrayFieldTitle.tsx 'use client'
import type { Data } from 'payload'
import { useRowLabel } from '@payloadcms/ui'
function ArrayFieldTitle() {
const { data, rowNumber } = useRowLabel<Data>();
return (
<>
{`Component: ${ data?.componentTitle}` || `Component ${String(rowNumber).padStart(2, '0')}`}
</>
)
}
export default ArrayFieldTitle In this case my Array Field is declared as follows: {
name: 'myComponents',
type: 'array',
label: 'Components',
minRows: 1,
admin: {
components: {
RowLabel: 'src/components/shared/ArrayFieldTitle.tsx',
},
},
fields: [
{
type: 'row',
fields: [
{
name: 'componentTitle',
type: 'text',
label: 'Component Title',
},
],
},
{
type: 'row',
fields: [
{
name: 'parts',
type: 'textarea',
label: 'Parts',
},
],
},
{
type: 'row',
fields: [
{
name: 'steps',
type: 'textarea',
label: 'Steps to Build',
},
],
},
], Hope it helps. |
Beta Was this translation helpful? Give feedback.
-
I've implemented the following that handles multilingual support and relational fields. Here is the component: "use client";
import { getTranslation } from "@payloadcms/translations";
import { useRowLabel, useTranslation } from "@payloadcms/ui";
import { CollectionSlug, LabelFunction, StaticLabel } from "payload";
import { useEffect, useState } from "react";
const RowLabel = ({ defaultLabel, path, relationTo }: { defaultLabel: LabelFunction | StaticLabel; path: string; relationTo?: CollectionSlug }) => {
const [label, setLabel] = useState<string | null>(null);
const { i18n } = useTranslation()
const { data, rowNumber } = useRowLabel<any>();
useEffect(() => {
if (relationTo) {
const [field, property] = path.split(".");
fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}/api/${relationTo}/${data?.[field]}`).then((res) => res.json()).then((res) => {
setLabel(res[property]);
});
}
}, []);
if(label) return label;
let generated: any = data;
for (const segment of path.split(".")) {
generated = generated?.[segment];
}
if (generated) return generated;
return `${getTranslation(defaultLabel, i18n)} ${String(rowNumber).padStart(2, "0")}`;
};
export default RowLabel; The function I call on the fields: import type { CollectionSlug, LabelFunction, StaticLabel } from "payload";
export function createRowLabel({ defaultLabel, path, relationTo }: { defaultLabel: LabelFunction | StaticLabel; path: string; relationTo?: CollectionSlug }) {
return {
path: "@payload/components/row-label",
clientProps: {
defaultLabel: defaultLabel,
path: path,
relationTo: relationTo,
},
};
} And the way to use it: {
type: "array",
name: "menu",
label: "Menu",
labels: {
singular: {
fr: "Élément",
en: "Item",
},
plural: {
fr: "Éléments",
en: "Items",
},
},
admin: {
initCollapsed: true,
components: {
RowLabel: createRowLabel({
defaultLabel: {
fr: "Élément",
en: "Item",
},
path: "link.label",
}),
},
},
fields: [linkField()],
}, |
Beta Was this translation helpful? Give feedback.
-
I think this is really needed. Using blocks and arrays, these default labels are jarring. From a UX perspective, how can I arrange items if I don't see the specific name I gave that item? |
Beta Was this translation helpful? Give feedback.
-
It'd be great to have more control over the labels of an array field's items.
Consider the following screenshot, please.
UX would be so much better if there were a way to replace
Question 01
with the actual question title. Or maybe such a mechanism already exists and I just failed to find it?Beta Was this translation helpful? Give feedback.
All reactions