fix: allow unnamed group fields to not set a label at all (#12580)
Technically you could already set `label: undefined` and it would be
supported by group fields but the types didn't reflect this.
So now you can create an unnamed group field like this:
```ts
{
type: 'group',
fields: [
{
type: 'text',
name: 'insideGroupWithNoLabel',
},
],
},
```
This will remove the label while still visually grouping the fields.

---------
Co-authored-by: Jacob Fletcher <jacobsfletch@gmail.com>
This commit is contained in:
@@ -37,7 +37,7 @@ export const MyGroupField: Field = {
|
|||||||
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| **`name`** | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
| **`name`** | To be used as the property name when stored and retrieved from the database. [More](/docs/fields/overview#field-names) |
|
||||||
| **`fields`** \* | Array of field types to nest within this Group. |
|
| **`fields`** \* | Array of field types to nest within this Group. |
|
||||||
| **`label`** | Used as a heading in the Admin Panel and to name the generated GraphQL type. Required when name is undefined, defaults to name converted to words. |
|
| **`label`** | Used as a heading in the Admin Panel and to name the generated GraphQL type. Defaults to the field name, if defined. |
|
||||||
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
| **`validate`** | Provide a custom validation function that will be executed on both the Admin Panel and the backend. [More](/docs/fields/overview#validation) |
|
||||||
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
| **`saveToJWT`** | If this field is top-level and nested in a config supporting [Authentication](/docs/authentication/overview), include its data in the user JWT. |
|
||||||
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
| **`hooks`** | Provide Field Hooks to control logic for this field. [More details](../hooks/fields). |
|
||||||
@@ -113,8 +113,7 @@ export const ExampleCollection: CollectionConfig = {
|
|||||||
|
|
||||||
## Presentational group fields
|
## Presentational group fields
|
||||||
|
|
||||||
You can also use the Group field to create a presentational group of fields. This is useful when you want to group fields together visually without affecting the data structure.
|
You can also use the Group field to only visually group fields without affecting the data structure. Not defining a label will render just the grouped fields.
|
||||||
The label will be required when a `name` is not provided.
|
|
||||||
|
|
||||||
```ts
|
```ts
|
||||||
import type { CollectionConfig } from 'payload'
|
import type { CollectionConfig } from 'payload'
|
||||||
|
|||||||
@@ -746,17 +746,6 @@ export type NamedGroupField = {
|
|||||||
|
|
||||||
export type UnnamedGroupField = {
|
export type UnnamedGroupField = {
|
||||||
interfaceName?: never
|
interfaceName?: never
|
||||||
/**
|
|
||||||
* Can be either:
|
|
||||||
* - A string, which will be used as the tab's label.
|
|
||||||
* - An object, where the key is the language code and the value is the label.
|
|
||||||
*/
|
|
||||||
label:
|
|
||||||
| {
|
|
||||||
[selectedLanguage: string]: string
|
|
||||||
}
|
|
||||||
| LabelFunction
|
|
||||||
| string
|
|
||||||
localized?: never
|
localized?: never
|
||||||
} & Omit<GroupBase, 'name' | 'virtual'>
|
} & Omit<GroupBase, 'name' | 'virtual'>
|
||||||
|
|
||||||
|
|||||||
@@ -119,5 +119,26 @@ describe('Group', () => {
|
|||||||
const unnamedNestedGroupField = page.locator(unnamedNestedGroupSelector)
|
const unnamedNestedGroupField = page.locator(unnamedNestedGroupSelector)
|
||||||
await expect(unnamedNestedGroupField).toBeVisible()
|
await expect(unnamedNestedGroupField).toBeVisible()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('should display with no label when label is undefined', async () => {
|
||||||
|
await page.goto(url.create)
|
||||||
|
|
||||||
|
// Makes sure the fields are rendered
|
||||||
|
await page.mouse.wheel(0, 2000)
|
||||||
|
|
||||||
|
const nolabelGroupSelector = `.field-type.group-field#field-_index-14 .group-field__header`
|
||||||
|
const nolabelGroupField = page.locator(nolabelGroupSelector)
|
||||||
|
|
||||||
|
await expect(nolabelGroupField).toBeHidden()
|
||||||
|
|
||||||
|
// Makes sure the fields are rendered
|
||||||
|
await page.mouse.wheel(0, 2000)
|
||||||
|
|
||||||
|
// Children should render even if the group has no label
|
||||||
|
const nolabelGroupChildSelector = `.field-type.group-field#field-_index-14 #field-insideGroupWithNoLabel`
|
||||||
|
const nolabelGroupChildField = page.locator(nolabelGroupChildSelector)
|
||||||
|
|
||||||
|
await expect(nolabelGroupChildField).toBeVisible()
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -314,6 +314,15 @@ const GroupFields: CollectionConfig = {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
type: 'group',
|
||||||
|
fields: [
|
||||||
|
{
|
||||||
|
type: 'text',
|
||||||
|
name: 'insideGroupWithNoLabel',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
{
|
{
|
||||||
type: 'group',
|
type: 'group',
|
||||||
label: 'Deeply nested group',
|
label: 'Deeply nested group',
|
||||||
|
|||||||
@@ -1082,6 +1082,7 @@ export interface GroupField {
|
|||||||
| null;
|
| null;
|
||||||
};
|
};
|
||||||
insideUnnamedGroup?: string | null;
|
insideUnnamedGroup?: string | null;
|
||||||
|
insideGroupWithNoLabel?: string | null;
|
||||||
deeplyNestedGroup?: {
|
deeplyNestedGroup?: {
|
||||||
insideNestedUnnamedGroup?: string | null;
|
insideNestedUnnamedGroup?: string | null;
|
||||||
};
|
};
|
||||||
@@ -2685,6 +2686,7 @@ export interface GroupFieldsSelect<T extends boolean = true> {
|
|||||||
email?: T;
|
email?: T;
|
||||||
};
|
};
|
||||||
insideUnnamedGroup?: T;
|
insideUnnamedGroup?: T;
|
||||||
|
insideGroupWithNoLabel?: T;
|
||||||
deeplyNestedGroup?:
|
deeplyNestedGroup?:
|
||||||
| T
|
| T
|
||||||
| {
|
| {
|
||||||
|
|||||||
Reference in New Issue
Block a user