diff --git a/packages/ra-ui-materialui/src/list/List.stories.tsx b/packages/ra-ui-materialui/src/list/List.stories.tsx index 25ac0dcb43..2a4cef62c5 100644 --- a/packages/ra-ui-materialui/src/list/List.stories.tsx +++ b/packages/ra-ui-materialui/src/list/List.stories.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { Admin, AutocompleteInput } from 'react-admin'; +import { Admin, AutocompleteInput, Pagination } from 'react-admin'; import { CustomRoutes, Resource, @@ -10,6 +10,8 @@ import { import fakeRestDataProvider from 'ra-data-fakerest'; import { Box, Card, Typography, Button, Link as MuiLink } from '@mui/material'; +import { Empty as DefaultEmpty } from './Empty'; +import { Pagination as DefaultPagination } from './pagination'; import { List } from './List'; import { SimpleList } from './SimpleList'; import { ListActions } from './ListActions'; @@ -284,6 +286,23 @@ export const TitleElement = () => ( ); +const TitleSpan = () => Custom list title; + +export const TitleComponent = () => ( + + + ( + + + + )} + /> + + +); + export const TitleFalse = () => ( @@ -314,15 +333,30 @@ export const HasCreate = () => ( ); -const AsideComponent = () => Aside; +const AsideBlock = () => Aside; + +export const AsideElement = () => ( + + + ( + }> + + + )} + /> + + +); -export const Aside = () => ( +export const AsideComponent = () => ( ( - }> + )} @@ -404,6 +438,22 @@ export const Empty = () => ( ); +export const EmptyComponent = () => ( + + + ( + + + + )} + create={() => } + /> + + +); + export const EmptyPartialPagination = () => ( ( ); +export const PaginationComponent = () => ( + + + ( + + + + )} + /> + + +); + export const SX = () => ( diff --git a/packages/ra-ui-materialui/src/list/ListView.tsx b/packages/ra-ui-materialui/src/list/ListView.tsx index 242bae4739..b739d9b1b6 100644 --- a/packages/ra-ui-materialui/src/list/ListView.tsx +++ b/packages/ra-ui-materialui/src/list/ListView.tsx @@ -62,16 +62,18 @@ export const ListView = ( )} {children} - {!error && pagination !== false && pagination} + {!error && pagination !== false && getElement(pagination)} ); const renderEmpty = () => - empty !== false &&
{empty}
; + empty !== false && ( +
{getElement(empty)}
+ ); const shouldRenderEmptyPage = !error && @@ -93,34 +95,42 @@ export const ListView = ( {title !== false && ( )} {shouldRenderEmptyPage ? renderEmpty() : renderList()} - {aside} + {aside ? getElement(aside) : null} </Root> ); }; -const getElement = ( - ElementOrComponent: React.ComponentType<any> | ReactElement | false -) => { - if (ElementOrComponent === false) { +const getTitleElement = (title: ListViewProps['title']) => { + if (typeof title === 'string' || !title) { + return title; + } + return getElement(title); +}; + +const getActionsElement = (actions: ListViewProps['actions']) => { + if (!actions) { return; } + return getElement(actions); +}; +const getElement = (ElementOrComponent: ComponentType | ReactElement) => { if (isValidElement(ElementOrComponent)) { - console.log(`We have an element`); return ElementOrComponent; } - if (isValidElementType(ElementOrComponent)) { - console.log(`We have a component`); - const Element = ElementOrComponent as ComponentType<any>; + const Element = ElementOrComponent as ComponentType; return <Element />; } + throw new Error( + 'the value prop should be a valid ReactElement or a valid React Component' + ); }; export interface ListViewProps { @@ -157,7 +167,7 @@ export interface ListViewProps { * </List> * ); */ - actions?: ReactElement | React.ComponentType | false; + actions?: ReactElement | ComponentType | false; /** * The content to render as a sidebar. @@ -185,7 +195,7 @@ export interface ListViewProps { * </List> * ); */ - aside?: ReactElement; + aside?: ReactElement | ComponentType; /** * A class name to apply to the root div element @@ -256,7 +266,7 @@ export interface ListViewProps { * </List> * ); */ - empty?: ReactElement | false; + empty?: ReactElement | ComponentType | false; /** * Set to true to return null while the list is loading. @@ -309,7 +319,7 @@ export interface ListViewProps { * </List> * ); */ - pagination?: ReactElement | false; + pagination?: ReactElement | ComponentType | false; /** * The page title (main title) to display above the data. Defaults to the humanized resource name. @@ -324,7 +334,7 @@ export interface ListViewProps { * </List> * ); */ - title?: string | ReactElement | false; + title?: string | ReactElement | ComponentType | false; /** * The CSS styles to apply to the component.