diff --git a/packages/dataviews/CHANGELOG.md b/packages/dataviews/CHANGELOG.md
index cc6f4df9428b09..d51cf9c969016d 100644
--- a/packages/dataviews/CHANGELOG.md
+++ b/packages/dataviews/CHANGELOG.md
@@ -2,7 +2,13 @@
## Unreleased
-- The "move left/move right" controls in the table layout (popup displayed on cliking header) are always visible. ([#64646](https://github.com/WordPress/gutenberg/pull/64646)). Before this, its visibility depending on filters, enableSorting, and enableHiding.
+## New features
+
+- Support using a component for field headers or names by providing a `header` property in the field object. The string `label` property (or `id`) is still mandatory. ([#64642](https://github.com/WordPress/gutenberg/pull/64642)).
+
+## Internal
+
+- The "move left/move right" controls in the table layout (popup displayed on cliking header) are always visible. ([#64646](https://github.com/WordPress/gutenberg/pull/64646)). Before this, its visibility depending on filters, enableSorting, and enableHiding.
## 4.1.0 (2024-08-07)
diff --git a/packages/dataviews/src/components/dataviews/stories/fixtures.js b/packages/dataviews/src/components/dataviews/stories/fixtures.js
index f89cea81e6f15d..50401d97b026b5 100644
--- a/packages/dataviews/src/components/dataviews/stories/fixtures.js
+++ b/packages/dataviews/src/components/dataviews/stories/fixtures.js
@@ -1,7 +1,7 @@
/**
* WordPress dependencies
*/
-import { trash } from '@wordpress/icons';
+import { trash, image, Icon, category } from '@wordpress/icons';
import {
Button,
__experimentalText as Text,
@@ -173,6 +173,12 @@ export const fields = [
{
label: 'Image',
id: 'image',
+ header: (
+
+
+ Image
+
+ ),
render: ( { item } ) => {
return (
@@ -217,6 +223,12 @@ export const fields = [
{
label: 'Categories',
id: 'categories',
+ header: (
+
+
+ Categories
+
+ ),
elements: [
{ value: 'Space', label: 'Space' },
{ value: 'NASA', label: 'NASA' },
diff --git a/packages/dataviews/src/components/dataviews/stories/index.story.js b/packages/dataviews/src/components/dataviews/stories/index.story.js
index 9ce1c29573e55c..376b14a464666c 100644
--- a/packages/dataviews/src/components/dataviews/stories/index.story.js
+++ b/packages/dataviews/src/components/dataviews/stories/index.story.js
@@ -8,7 +8,7 @@ import { useState, useMemo } from '@wordpress/element';
*/
import DataViews from '../index';
import { DEFAULT_VIEW, actions, data, fields } from './fixtures';
-import { LAYOUT_GRID, LAYOUT_TABLE } from '../../../constants';
+import { LAYOUT_GRID, LAYOUT_LIST, LAYOUT_TABLE } from '../../../constants';
import { filterSortAndPaginate } from '../../../filter-and-sort-data-view';
const meta = {
@@ -61,5 +61,11 @@ Default.args = {
primaryField: 'title',
},
},
+ [ LAYOUT_LIST ]: {
+ layout: {
+ mediaField: 'image',
+ primaryField: 'title',
+ },
+ },
},
};
diff --git a/packages/dataviews/src/dataviews-layouts/grid/index.tsx b/packages/dataviews/src/dataviews-layouts/grid/index.tsx
index c8cac31bf7db81..230ffe0dc50b5c 100644
--- a/packages/dataviews/src/dataviews-layouts/grid/index.tsx
+++ b/packages/dataviews/src/dataviews-layouts/grid/index.tsx
@@ -145,7 +145,7 @@ function GridItem< Item >( {
>
<>
- { field.label }
+ { field.header }
(
);
const index = view.fields?.indexOf( fieldId ) as number;
if ( !! combinedField ) {
- return combinedField.label;
+ return combinedField.header || combinedField.label;
}
const field = fields.find( ( f ) => f.id === fieldId );
if ( ! field ) {
@@ -102,7 +102,7 @@ const _HeaderMenu = forwardRef( function HeaderMenu< Item >(
ref={ ref }
variant="tertiary"
>
- { field.label }
+ { field.header }
{ view.sort && isSorted && (
{ sortArrows[ view.sort.direction ] }
diff --git a/packages/dataviews/src/normalize-fields.ts b/packages/dataviews/src/normalize-fields.ts
index f9f95b5b8140dc..5f0baec12c4df2 100644
--- a/packages/dataviews/src/normalize-fields.ts
+++ b/packages/dataviews/src/normalize-fields.ts
@@ -55,6 +55,7 @@ export function normalizeFields< Item >(
return {
...field,
label: field.label || field.id,
+ header: field.header || field.label || field.id,
getValue,
render,
sort,
diff --git a/packages/dataviews/src/types.ts b/packages/dataviews/src/types.ts
index fa5cec8d7d0320..ca55442f6529a5 100644
--- a/packages/dataviews/src/types.ts
+++ b/packages/dataviews/src/types.ts
@@ -87,6 +87,12 @@ export type Field< Item > = {
*/
label?: string;
+ /**
+ * The header of the field. Defaults to the label.
+ * It allows the usage of a React Element to render the field labels.
+ */
+ header?: string | ReactElement;
+
/**
* A description of the field.
*/
@@ -151,6 +157,7 @@ export type Field< Item > = {
export type NormalizedField< Item > = Field< Item > & {
label: string;
+ header: string | ReactElement;
getValue: ( args: { item: Item } ) => any;
render: ComponentType< { item: Item } >;
Edit: ComponentType< DataFormControlProps< Item > >;
@@ -289,6 +296,8 @@ export interface CombinedField {
label: string;
+ header?: string | ReactElement;
+
/**
* The fields to use as columns.
*/