Skip to content

Dataviews: Allow dataviews empty state to be customised #70867

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: trunk
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/dataviews/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

- Field API: `isValid` is now an object that contains `required` and `custom` validation rules. Additionally, fields should now opt-in into being a "required" field by setting `isValid.required` to `true` (all fields of type `email` and `integer` were required by default). [#70901](https://github.com/WordPress/gutenberg/pull/70901)

### Features
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There's now two "features" sections, we should combine them.


- `DataViews` empty state can be customized using the new `empty` prop.

### Bug Fixes

- Fix `filterSortAndPaginate` to handle searching fields that have a type of `array` ([#70785](https://github.com/WordPress/gutenberg/pull/70785)).
Expand Down
4 changes: 4 additions & 0 deletions packages/dataviews/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,10 @@ A list of numbers used to control the available item counts per page.

It's optional. Defaults to `[10, 20, 50, 100]`.

#### `empty`: React node

A message or element to be displayed instead of the dataview's default empty message.

### Composition modes

The `DataViews` component supports two composition modes:
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
/**
* External dependencies
*/
import type { ComponentProps, ReactElement } from 'react';
import type { ComponentProps, ReactElement, ReactNode } from 'react';

/**
* WordPress dependencies
Expand Down Expand Up @@ -55,6 +55,7 @@ type DataViewsContextType< Item > = {
isShowingFilter: boolean;
setIsShowingFilter: ( value: boolean ) => void;
perPageSizes?: [ number, number, number, number ];
empty?: ReactNode;
};

const DataViewsContext = createContext< DataViewsContextType< any > >( {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import type { ComponentType } from 'react';
* WordPress dependencies
*/
import { useContext } from '@wordpress/element';
import { __ } from '@wordpress/i18n';

/**
* Internal dependencies
Expand Down Expand Up @@ -35,6 +36,7 @@ export default function DataViewsLayout( { className }: DataViewsLayoutProps ) {
onClickItem,
isItemClickable,
renderItemLink,
empty = __( 'No results' ),
} = useContext( DataViewsContext );

const ViewComponent = VIEW_LAYOUTS.find( ( v ) => v.type === view.type )
Expand All @@ -57,6 +59,7 @@ export default function DataViewsLayout( { className }: DataViewsLayoutProps ) {
renderItemLink={ renderItemLink }
isItemClickable={ isItemClickable }
view={ view }
empty={ empty }
/>
);
}
3 changes: 3 additions & 0 deletions packages/dataviews/src/components/dataviews/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ type DataViewsProps< Item > = {
getItemLevel?: ( item: Item ) => number;
children?: ReactNode;
perPageSizes?: [ number, number, number, number ];
empty?: ReactNode;
} & ( Item extends ItemWithId
? { getItemId?: ( item: Item ) => string }
: { getItemId: ( item: Item ) => string } );
Expand Down Expand Up @@ -134,6 +135,7 @@ function DataViews< Item >( {
header,
children,
perPageSizes,
empty,
}: DataViewsProps< Item > ) {
const containerRef = useRef< HTMLDivElement | null >( null );
const [ containerWidth, setContainerWidth ] = useState( 0 );
Expand Down Expand Up @@ -199,6 +201,7 @@ function DataViews< Item >( {
isShowingFilter,
setIsShowingFilter,
perPageSizes,
empty,
} }
>
<div className="dataviews-wrapper" ref={ containerRef }>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
__experimentalText as Text,
__experimentalHStack as HStack,
__experimentalVStack as VStack,
Button,
} from '@wordpress/components';
import { __, _n } from '@wordpress/i18n';

Expand Down Expand Up @@ -110,6 +111,27 @@ export const Empty = () => {
);
};

export const CustomEmpty = () => {
const [ view, setView ] = useState< View >( {
...DEFAULT_VIEW,
fields: [ 'title', 'description', 'categories' ],
} );

return (
<DataViews
getItemId={ ( item ) => item.id.toString() }
paginationInfo={ { totalItems: 0, totalPages: 0 } }
data={ [] }
view={ view }
fields={ fields }
onChangeView={ setView }
actions={ actions }
defaultLayouts={ defaultLayouts }
empty={ view.search ? 'No sites found' : 'No sites' }
/>
);
};

export const FieldsNoSortableNoHidable = () => {
const [ view, setView ] = useState< View >( {
...DEFAULT_VIEW,
Expand Down Expand Up @@ -261,6 +283,19 @@ export const FreeComposition = () => {
table: {},
grid: {},
} }
empty={
<VStack
justify="space-around"
alignment="center"
className="free-composition-dataviews-empty"
>
<Text size={ 18 } as="p">
No planets
</Text>
<Text variant="muted">{ `Try a different search because “${ view.search }” returned no results.` }</Text>
<Button variant="secondary">Create new planet</Button>
</VStack>
}
>
<PlanetOverview planets={ planets } />
</DataViews>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,9 @@
.free-composition-dataviews-layout thead {
inset-block-start: 67px;
}

.free-composition-dataviews-empty {
border: 1px solid #000;
border-radius: 8px;
padding: 24px;
}
3 changes: 2 additions & 1 deletion packages/dataviews/src/dataviews-layouts/grid/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,7 @@ function ViewGrid< Item >( {
selection,
view,
className,
empty,
}: ViewGridProps< Item > ) {
const { resizeObserverRef } = useContext( DataViewsContext );
const titleField = fields.find(
Expand Down Expand Up @@ -446,7 +447,7 @@ function ViewGrid< Item >( {
'dataviews-no-results': ! isLoading,
} ) }
>
<p>{ isLoading ? <Spinner /> : __( 'No results' ) }</p>
<p>{ isLoading ? <Spinner /> : empty }</p>
</div>
)
}
Expand Down
5 changes: 2 additions & 3 deletions packages/dataviews/src/dataviews-layouts/list/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ export default function ViewList< Item >( props: ViewListProps< Item > ) {
selection,
view,
className,
empty,
} = props;
const baseId = useInstanceId( ViewList, 'view-list' );

Expand Down Expand Up @@ -491,9 +492,7 @@ export default function ViewList< Item >( props: ViewListProps< Item > ) {
'dataviews-no-results': ! hasData && ! isLoading,
} ) }
>
{ ! hasData && (
<p>{ isLoading ? <Spinner /> : __( 'No results' ) }</p>
) }
{ ! hasData && <p>{ isLoading ? <Spinner /> : empty }</p> }
</div>
);
}
Expand Down
5 changes: 2 additions & 3 deletions packages/dataviews/src/dataviews-layouts/table/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,7 @@ function ViewTable< Item >( {
renderItemLink,
view,
className,
empty,
}: ViewTableProps< Item > ) {
const { containerRef } = useContext( DataViewsContext );
const headerMenuRefs = useRef<
Expand Down Expand Up @@ -479,9 +480,7 @@ function ViewTable< Item >( {
} ) }
id={ tableNoticeId }
>
{ ! hasData && (
<p>{ isLoading ? <Spinner /> : __( 'No results' ) }</p>
) }
{ ! hasData && <p>{ isLoading ? <Spinner /> : empty }</p> }
</div>
</>
);
Expand Down
8 changes: 7 additions & 1 deletion packages/dataviews/src/types.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
/**
* External dependencies
*/
import type { ReactElement, ComponentType, ComponentProps } from 'react';
import type {
ReactElement,
ReactNode,
ComponentType,
ComponentProps,
} from 'react';

/**
* Internal dependencies
Expand Down Expand Up @@ -620,6 +625,7 @@ export interface ViewBaseProps< Item > {
) => ReactElement;
isItemClickable: ( item: Item ) => boolean;
view: View;
empty: ReactNode;
}

export interface ViewTableProps< Item > extends ViewBaseProps< Item > {
Expand Down
Loading