Skip to content

Commit 78dc346

Browse files
committed
add renderprops to List component
1 parent dd28619 commit 78dc346

File tree

5 files changed

+74
-2
lines changed

5 files changed

+74
-2
lines changed

docs/List.md

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@ You can find more advanced examples of `<List>` usage in the [demos](./Demos.md)
5555

5656
| Prop | Required | Type | Default | Description |
5757
|---------------------------|----------|----------------|----------------|----------------------------------------------------------------------------------------------|
58-
| `children` | Required | `ReactNode` | - | The components rendering the list of records. |
58+
| `children` | Required if no render | `ReactNode` | - | The components rendering the list of records. |
59+
| `render` | Required if no children | `(listContext) => ReactNode` | - | The components rendering the list of records. |
5960
| `actions` | Optional | `ReactElement` | - | The actions to display in the toolbar. |
6061
| `aside` | Optional | `ReactElement` | - | The component to display on the side of the list. |
6162
| `component` | Optional | `Component` | `Card` | The component to render as the root element. |
@@ -79,6 +80,33 @@ You can find more advanced examples of `<List>` usage in the [demos](./Demos.md)
7980

8081
Additional props are passed down to the root component (a MUI `<Card>` by default).
8182

83+
## `render`
84+
85+
Alternatively to children you can pass a render prop to `<List>`. The render prop will receive the list context as its argument, allowing to inline the render logic for both the list content.
86+
When receiving a render prop the `<List>` component will ignore the children property.
87+
88+
{% raw %}
89+
```tsx
90+
<List
91+
render={({ error, isPending }) => {
92+
if (isPending) {
93+
return <div>Loading...</div>;
94+
}
95+
if (error) {
96+
return <div>Error: {error.message}</div>;
97+
}
98+
return (
99+
<SimpleList
100+
primaryText="%{title} (%{year})"
101+
secondaryText="%{summary}"
102+
tertiaryText={record => record.year}
103+
/>
104+
);
105+
}}
106+
/>
107+
```
108+
{% endraw %}
109+
82110
## `actions`
83111

84112
By default, the `<List>` view displays a toolbar on top of the list. It contains:

packages/ra-ui-materialui/src/list/List.spec.tsx

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
Default,
2424
SelectAllLimit,
2525
Themed,
26+
WithRenderProp,
2627
} from './List.stories';
2728

2829
const theme = createTheme(defaultTheme);
@@ -325,6 +326,19 @@ describe('<List />', () => {
325326
});
326327
});
327328

329+
it('should render a list page using render prop', async () => {
330+
render(<WithRenderProp />);
331+
expect(screen.getByText('Loading...')).toBeDefined();
332+
333+
await waitFor(() => {
334+
screen.getByText('1-10 of 13');
335+
});
336+
screen.getByText('War and Peace (1869)');
337+
screen.getByText(
338+
'A historical novel that intertwines the lives of Russian aristocrats with the events of the Napoleonic wars.'
339+
);
340+
});
341+
328342
describe('title', () => {
329343
it('should display by default the title of the resource', async () => {
330344
render(<Basic />);

packages/ra-ui-materialui/src/list/List.stories.tsx

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -844,3 +844,32 @@ export const Themed = () => (
844844
</Admin>
845845
</TestMemoryRouter>
846846
);
847+
848+
export const WithRenderProp = () => (
849+
<TestMemoryRouter initialEntries={['/books']}>
850+
<Admin dataProvider={defaultDataProvider}>
851+
<Resource
852+
name="books"
853+
list={() => (
854+
<List
855+
render={({ error, isPending }) => {
856+
if (isPending) {
857+
return <div>Loading...</div>;
858+
}
859+
if (error) {
860+
return <div>Error: {error.message}</div>;
861+
}
862+
return (
863+
<SimpleList
864+
primaryText="%{title} (%{year})"
865+
secondaryText="%{summary}"
866+
tertiaryText={record => record.year}
867+
/>
868+
);
869+
}}
870+
/>
871+
)}
872+
/>
873+
</Admin>
874+
</TestMemoryRouter>
875+
);

packages/ra-ui-materialui/src/list/List.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import { Loading } from '../layout';
2020
* - actions
2121
* - aside: Side Component
2222
* - children: List Layout
23+
* - render: alternative to children Function to render the List Layout, receive the list context as argument
2324
* - component
2425
* - disableAuthentication
2526
* - disableSyncWithLocation

packages/ra-ui-materialui/src/list/ListView.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ export interface ListViewProps<RecordType extends RaRecord = any> {
195195
* </List>
196196
* );
197197
*/
198-
children: ReactNode;
198+
children?: ReactNode;
199199

200200
/**
201201
* A function rendering the list of records. Take the list controller as argument.

0 commit comments

Comments
 (0)