/**
* WordPress dependencies
*/
import {
useState,
useMemo,
createInterpolateElement,
} from '@wordpress/element';
import {
__experimentalHeading as Heading,
__experimentalText as Text,
Button,
} from '@wordpress/components';
import { __, _n } from '@wordpress/i18n';
// TODO: enable in the ESlint rule once we complete
// https://github.com/WordPress/gutenberg/issues/76135.
// eslint-disable-next-line @wordpress/use-recommended-components
import { Card, Stack } from '@wordpress/ui';
/**
* Internal dependencies
*/
import DataViews from '../index';
import filterSortAndPaginate from '../../utils/filter-sort-and-paginate';
import type { View } from '../../types';
import { actions, data, fields, type SpaceObject } from './fixtures';
import { LAYOUT_TABLE } from '../../constants';
/**
* Custom composition example
*/
function PlanetOverview( { planets }: { planets: SpaceObject[] } ) {
const moons = planets.reduce( ( sum, item ) => sum + item.satellites, 0 );
return (
<>
{ __( 'Solar System numbers' ) }
{ createInterpolateElement(
_n(
' planet',
' planets',
planets.length
),
{
PlanetsNumber: (
{ planets.length }{ ' ' }
),
}
) }
{ createInterpolateElement(
_n(
' moon',
' moons',
moons
),
{
SatellitesNumber: (
{ moons }
),
}
) }
>
);
}
/**
* Demonstrates how to build a custom layout using DataViews sub-components.
*
* Instead of using the default DataViews UI, this story shows how to:
* - Use `` as a context provider (wrapping custom children)
* - Compose your own layout with built-in sub-components:
* - `` - Search input
* - `` - Button to show/hide filters
* - `` - The filter UI itself
* - `` - Page navigation
* - `` - View settings (columns, density, etc.)
* - `` - Switch between table/grid/list views
* - `` - Actions for selected items
* - `` - The data display (table, grid, etc.)
*
* This pattern is useful when you need full control over the UI layout
* while still leveraging DataViews' data management and state handling.
*/
export const FreeCompositionComponent = () => {
const [ view, setView ] = useState< View >( {
type: LAYOUT_TABLE,
search: '',
page: 1,
perPage: 20,
layout: {
enableMoving: false,
},
filters: [],
fields: [ 'categories' ],
titleField: 'title',
descriptionField: 'description',
mediaField: 'image',
} );
const { data: processedData, paginationInfo } = useMemo( () => {
return filterSortAndPaginate( data, view, fields );
}, [ view ] );
const planets = processedData.filter( ( item ) =>
item.categories.includes( 'Planet' )
);
return (
item.id.toString() }
paginationInfo={ paginationInfo }
data={ processedData }
view={ view }
fields={ fields }
actions={ actions }
onChangeView={ setView }
defaultLayouts={ {
table: {},
grid: {},
} }
empty={
No planets
{ `Try a different search because “${ view.search }” returned no results.` }
}
>
);
};
export default FreeCompositionComponent;