Skip to content

Commit b6dc572

Browse files
authored
Merge pull request #9172 from marmelab/simplelist-no-primary-text
Add ability to use SimpleList without `primaryText`
2 parents f0431ef + d3dfe79 commit b6dc572

File tree

6 files changed

+190
-136
lines changed

6 files changed

+190
-136
lines changed

docs/Datagrid.md

+95-93
Original file line numberDiff line numberDiff line change
@@ -38,24 +38,24 @@ The `<Datagrid>` is an **iterator** component: it gets an array of records from
3838

3939
## Props
4040

41-
Here are all the props accepted by the component:
42-
43-
* [`body`](#body)
44-
* [`bulkActionButtons`](#bulkactionbuttons)
45-
* [`children`](#children)
46-
* [`empty`](#empty)
47-
* [`expand`](#expand)
48-
* [`expandSingle`](#expandsingle)
49-
* [`header`](#header)
50-
* [`hover`](#hover)
51-
* [`isRowExpandable`](#isrowexpandable)
52-
* [`isRowSelectable`](#isrowselectable)
53-
* [`optimized`](#optimized-better-performance-for-large-tables)
54-
* [`rowStyle`](#rowstyle)
55-
* [`rowSx`](#rowsx)
56-
* [`rowClick`](#rowclick)
57-
* [`size`](#size)
58-
* [`sx`](#sx-css-api)
41+
| Prop | Required | Type | Default | Description |
42+
| --- | --- | --- | --- | --- |
43+
| `children` | Required | Element | n/a | The list of `<Field>` components to render as columns. |
44+
| `body` | Optional | Element | `<Datagrid Body>` | The component used to render the body of the table. |
45+
| `bulkActionButtons` | Optional | Element | `<BulkDelete Button>` | The component used to render the bulk action buttons. |
46+
| `empty` | Optional | Element | `<Empty>` | The component used to render the empty table. |
47+
| `expand` | Optional | Element | | The component used to render the expand panel for each row. |
48+
| `expandSingle` | Optional | Boolean | `false` | Whether to allow only one expanded row at a time. |
49+
| `header` | Optional | Element | `<Datagrid Header>` | The component used to render the table header. |
50+
| `hover` | Optional | Boolean | `true` | Whether to highlight the row under the mouse. |
51+
| `isRowExpandable` | Optional | Function | `() => true` | A function that returns whether a row is expandable. |
52+
| `isRowSelectable` | Optional | Function | `() => true` | A function that returns whether a row is selectable. |
53+
| `optimized` | Optional | Boolean | `false` | Whether to optimize the rendering of the table. |
54+
| `rowClick` | Optional | mixed | | The action to trigger when the user clicks on a row. |
55+
| `rowStyle` | Optional | Function | | A function that returns the style to apply to a row. |
56+
| `rowSx` | Optional | Function | | A function that returns the sx prop to apply to a row. |
57+
| `size` | Optional | `'small'` or `'medium'` | `'small'` | The size of the table. |
58+
| `sx` | Optional | Object | | The sx prop passed down to the Material UI `<Table>` element. |
5959

6060
Additional props are passed down to [the Material UI `<Table>` element](https://mui.com/material-ui/api/table/).
6161

@@ -107,39 +107,6 @@ const PostList = () => (
107107
export default PostList;
108108
```
109109

110-
## `children`
111-
112-
`<Datagrid>` accepts a list of Field components as children. It inspects each child's `source` and/or `label` props to determine the name of the column.
113-
114-
What's a Field component? Simply a component that reads the record (via `useRecordContext`) and renders a value. React-admin includes many Field components that you can use as children of `<Datagrid>` (`<TextField>`, `<NumberField>`, `<DateField>`, `<ReferenceField>`, and many more). Check [the Fields documentation](./Fields.md) for more information.
115-
116-
You can even create your own field components.
117-
118-
```jsx
119-
// in src/posts.js
120-
import * as React from 'react';
121-
import { useRecordContext, List, Datagrid, TextField, DateField } from 'react-admin';
122-
123-
const FullNameField = () => {
124-
const record = useRecordContext();
125-
return <span>{record.firstName} {record.lastName}</span>;
126-
}
127-
128-
export const UserList = () => (
129-
<List>
130-
<Datagrid rowclick="edit">
131-
<FullNameField source="last_name" label="Name" />
132-
<DateField source="dob" />
133-
<TextField source="city" />
134-
</Datagrid>
135-
</List>
136-
);
137-
```
138-
139-
`<Datagrid>` also inspects its children for `headerClassName` and `cellClassName` props, and gives the class names to the headers and the cells of that column.
140-
141-
Finally, `<Datagrid>` inspects children for props that indicate how it should be sorted (see [the Customizing The Sort Order For Columns section](#customizing-column-sort)) below.
142-
143110
## `bulkActionButtons`
144111

145112
<video controls autoplay playsinline muted loop>
@@ -377,6 +344,39 @@ const CustomResetViewsButton = () => {
377344
};
378345
```
379346

347+
## `children`
348+
349+
`<Datagrid>` accepts a list of Field components as children. It inspects each child's `source` and/or `label` props to determine the name of the column.
350+
351+
What's a Field component? Simply a component that reads the record (via `useRecordContext`) and renders a value. React-admin includes many Field components that you can use as children of `<Datagrid>` (`<TextField>`, `<NumberField>`, `<DateField>`, `<ReferenceField>`, and many more). Check [the Fields documentation](./Fields.md) for more information.
352+
353+
You can even create your own field components.
354+
355+
```jsx
356+
// in src/users.js
357+
import * as React from 'react';
358+
import { useRecordContext, List, Datagrid, TextField, DateField } from 'react-admin';
359+
360+
const FullNameField = () => {
361+
const record = useRecordContext();
362+
return <span>{record.firstName} {record.lastName}</span>;
363+
}
364+
365+
export const UserList = () => (
366+
<List>
367+
<Datagrid rowclick="edit">
368+
<FullNameField source="last_name" label="Name" />
369+
<DateField source="dob" />
370+
<TextField source="city" />
371+
</Datagrid>
372+
</List>
373+
);
374+
```
375+
376+
`<Datagrid>` also inspects its children for `headerClassName` and `cellClassName` props, and gives the class names to the headers and the cells of that column.
377+
378+
Finally, `<Datagrid>` inspects children for props that indicate how it should be sorted (see [the Customizing The Sort Order For Columns section](#customizing-column-sort)) below.
379+
380380
## `empty`
381381

382382
It's possible that a Datagrid will have no records to display. If the Datagrid's parent component does not handle the empty state, the Datagrid will display a message indicating there are no results. This message is translatable and its key is `ra.navigation.no_results`.
@@ -606,7 +606,7 @@ export const PostList = () => (
606606
```
607607
{% endraw %}
608608

609-
## `optimized`: Better Performance For Large Tables
609+
## `optimized`
610610

611611
When displaying large pages of data, you might experience some performance issues.
612612
This is mostly due to the fact that we iterate over the `<Datagrid>` children and clone them.
@@ -628,90 +628,92 @@ const PostList = () => (
628628
);
629629
```
630630

631-
## `rowStyle`
632-
633-
You can customize the `<Datagrid>` row style (applied to the `<tr>` element) based on the record, thanks to the `rowStyle` prop, which expects a function. React-admin calls this function for each row, passing the current record and index as arguments. The function should return a style object, which react-admin uses as a `<tr style>` prop.
631+
## `rowClick`
634632

635-
For instance, this allows to apply a custom background to the entire row if one value of the record - like its number of views - passes a certain threshold.
633+
You can catch clicks on rows to redirect to the show or edit view by setting the `rowClick` prop:
636634

637635
```jsx
638636
import { List, Datagrid } from 'react-admin';
639637

640-
const postRowStyle = (record, index) => ({
641-
backgroundColor: record.nb_views >= 500 ? '#efe' : 'white',
642-
});
643638
export const PostList = () => (
644639
<List>
645-
<Datagrid rowStyle={postRowStyle}>
640+
<Datagrid rowClick="edit">
646641
...
647642
</Datagrid>
648643
</List>
649644
);
650645
```
651646

652-
## `rowSx`
647+
`rowClick` accepts the following values:
653648

654-
You can customize the styles of rows and cells in `<Datagrid>` (applied to the `<DatagridRow>` element) based on the record, thanks to the `rowSx` prop, which expects a function. React-admin calls this function for each row, passing the current record and index as arguments. The function should return a Material UI [`sx`](https://mui.com/system/getting-started/the-sx-prop/), which react-admin uses as a `<TableRow sx>` prop.
649+
* "edit" to redirect to the edition view
650+
* "show" to redirect to the show view
651+
* "expand" to open the `expand` panel
652+
* "toggleSelection" to trigger the `onToggleItem` function
653+
* `false` to do nothing
654+
* a function `(id, resource, record) => path` that may return any of the above values or a custom path
655+
656+
**Tip**: If you pass a function, it can return `'edit'`, `'show'`, `false` or a router path. This allows to redirect to either the Edit or Show view after checking a condition on the record. For example:
657+
658+
```js
659+
const postRowClick = (id, resource, record) => record.editable ? 'edit' : 'show';
660+
```
661+
662+
**Tip**: If you pass a function, it can also return a promise allowing you to check an external API before returning a path. For example:
663+
664+
```js
665+
import fetchUserRights from './fetchUserRights';
666+
667+
const getPermissions = useGetPermissions();
668+
const postRowClick = (id, resource, record) =>
669+
useGetPermissions()
670+
.then(permissions => permissions === 'admin' ? 'edit' : 'show');
671+
```
672+
673+
## `rowStyle`
674+
675+
*Deprecated - use [`rowSx`](#rowsx) instead.*
676+
677+
You can customize the `<Datagrid>` row style (applied to the `<tr>` element) based on the record, thanks to the `rowStyle` prop, which expects a function. React-admin calls this function for each row, passing the current record and index as arguments. The function should return a style object, which react-admin uses as a `<tr style>` prop.
655678

656679
For instance, this allows to apply a custom background to the entire row if one value of the record - like its number of views - passes a certain threshold.
657680

658681
```jsx
659682
import { List, Datagrid } from 'react-admin';
660683

661-
const postRowSx = (record, index) => ({
684+
const postRowStyle = (record, index) => ({
662685
backgroundColor: record.nb_views >= 500 ? '#efe' : 'white',
663686
});
664687
export const PostList = () => (
665688
<List>
666-
<Datagrid rowSx={postRowSx}>
689+
<Datagrid rowStyle={postRowStyle}>
667690
...
668691
</Datagrid>
669692
</List>
670693
);
671694
```
672695

673-
## `rowClick`
696+
## `rowSx`
674697

675-
You can catch clicks on rows to redirect to the show or edit view by setting the `rowClick` prop:
698+
You can customize the styles of rows and cells in `<Datagrid>` (applied to the `<DatagridRow>` element) based on the record, thanks to the `rowSx` prop, which expects a function. React-admin calls this function for each row, passing the current record and index as arguments. The function should return a Material UI [`sx`](https://mui.com/system/getting-started/the-sx-prop/), which react-admin uses as a `<TableRow sx>` prop.
699+
700+
For instance, this allows to apply a custom background to the entire row if one value of the record - like its number of views - passes a certain threshold.
676701

677702
```jsx
678703
import { List, Datagrid } from 'react-admin';
679704

705+
const postRowSx = (record, index) => ({
706+
backgroundColor: record.nb_views >= 500 ? '#efe' : 'white',
707+
});
680708
export const PostList = () => (
681709
<List>
682-
<Datagrid rowClick="edit">
710+
<Datagrid rowSx={postRowSx}>
683711
...
684712
</Datagrid>
685713
</List>
686714
);
687715
```
688716

689-
`rowClick` accepts the following values:
690-
691-
* "edit" to redirect to the edition vue
692-
* "show" to redirect to the show vue
693-
* "expand" to open the `expand` panel
694-
* "toggleSelection" to trigger the `onToggleItem` function
695-
* `false` to do nothing
696-
* a function `(id, resource, record) => path` that may return any of the above values or a custom path
697-
698-
**Tip**: If you pass a function, it can return `'edit'`, `'show'`, `false` or a router path. This allows to redirect to either the Edit or Show view after checking a condition on the record. For example:
699-
700-
```js
701-
const postRowClick = (id, resource, record) => record.editable ? 'edit' : 'show';
702-
```
703-
704-
**Tip**: If you pass a function, it can also return a promise allowing you to check an external API before returning a path. For example:
705-
706-
```js
707-
import fetchUserRights from './fetchUserRights';
708-
709-
const getPermissions = useGetPermissions();
710-
const postRowClick = (id, resource, record) =>
711-
useGetPermissions()
712-
.then(permissions => permissions === 'admin' ? 'edit' : 'show');
713-
```
714-
715717
## `size`
716718

717719
The `<Datagrid>` is designed for a high density of content, so the row padding is low. If you want to add more margin to each cell, set the `size` prop to `medium`.

docs/SimpleList.md

+50-35
Original file line numberDiff line numberDiff line change
@@ -37,19 +37,40 @@ export const PostList = () => (
3737

3838
`<SimpleList>` executes the functions passed as `primaryText`, `secondaryText`, and `tertiaryText` on render, passing the current `record` as parameter. It uses the result to render each List item.
3939

40-
It accepts the following props:
41-
42-
* [`primaryText`](#primarytext) (required)
43-
* [`secondaryText`](#secondarytext)
44-
* [`tertiaryText`](#tertiarytext)
45-
* [`linkType`](#linktype)
46-
* [`leftAvatar`](#leftavatar)
47-
* [`leftIcon`](#lefticon)
48-
* [`rightAvatar`](#rightavatar)
49-
* [`rightIcon`](#righticon)
50-
* [`rowStyle`](#rowstyle)
51-
* [`rowSx`](#rowsx)
52-
* [`empty`](#empty)
40+
## Props
41+
42+
| Prop | Required | Type | Default | Description |
43+
| --- | --- | --- | --- | --- |
44+
| `primaryText` | Optional | mixed | record representation | The primary text to display. |
45+
| `secondaryText` | Optional | mixed | | The secondary text to display. |
46+
| `tertiaryText` | Optional | mixed | | The tertiary text to display. |
47+
| `linkType` | Optional |mixed | `"edit"` | The target of each item click. |
48+
| `leftAvatar` | Optional | function | | A function returning an `<Avatar>` component to display before the primary text. |
49+
| `leftIcon` | Optional | function | | A function returning an `<Icon>` component to display before the primary text. |
50+
| `rightAvatar` | Optional | function | | A function returning an `<Avatar>` component to display after the primary text. |
51+
| `rightIcon` | Optional | function | | A function returning an `<Icon>` component to display after the primary text. |
52+
| `rowStyle` | Optional | function | | A function returning a style object to apply to each row. |
53+
| `rowSx` | Optional | function | | A function returning a sx object to apply to each row. |
54+
| `empty` | Optional | ReactElement | | A ReactElement to display instead of the list when the data is empty. |
55+
56+
## `empty`
57+
58+
It's possible that a `<SimpleList>` will have no records to display. If the `<SimpleList>`'s parent component does not handle the empty state, the `<SimpleList>` will display a message indicating there are no results. This message is translatable with the key `ra.navigation.no_results`.
59+
60+
You can customize the empty state by passing a component to the `empty` prop:
61+
62+
```jsx
63+
const CustomEmpty = () => <div>No books found</div>;
64+
65+
const PostList = () => (
66+
<List>
67+
<SimpleList
68+
primaryText={record => record.title}
69+
empty={<CustomEmpty />}
70+
/>
71+
</List>
72+
);
73+
```
5374

5475
## `leftAvatar`
5576

@@ -78,22 +99,20 @@ export const PostList = () => (
7899
);
79100
```
80101

81-
82102
`linkType` accepts the following values:
83103

84104
* `linkType="edit"`: links to the edit page. This is the default behavior.
85105
* `linkType="show"`: links to the show page.
86106
* `linkType={false}`: does not create any link.
87107

88-
89-
90108
## `primaryText`
91109

92-
The `primaryText`, `secondaryText` and `tertiaryText` props can accept 3 types of values:
110+
The `primaryText`, `secondaryText` and `tertiaryText` props can accept 4 types of values:
93111

94112
1. a function returning a string,
95113
2. a string,
96114
3. a React element.
115+
4. `undefined` (the default)
97116

98117
If it's a **function**, react-admin passes the current record as parameter:
99118

@@ -151,6 +170,18 @@ export const PostList = () => (
151170

152171
`<SimpleList>` creates a `RecordContext` for each list item. This allows Field components to grab the current record using [`useRecordContext`](./useRecordContext.md).
153172

173+
If it's **undefined**, react-admin uses the [`recordRepresentation`](./Resource.md#recordrepresentation) for the current Resource. This is the default value.
174+
175+
```jsx
176+
import { List, SimpleList } from 'react-admin';
177+
178+
export const PostList = () => (
179+
<List>
180+
<SimpleList />
181+
</List>
182+
);
183+
```
184+
154185
## `rightAvatar`
155186

156187
This prop should be a function returning an `<Avatar>` component. When present, the `<ListItem>` renders a `<ListItemAvatar>` after the `<ListItemText>`
@@ -161,6 +192,8 @@ This prop should be a function returning an `<Icon>` component. When present, th
161192

162193
## `rowStyle`
163194

195+
*Deprecated - use [`rowSx`](#rowsx) instead.*
196+
164197
This optional prop should be a function, which gets called for each row. It receives the current record and index as arguments, and should return a style object. The style object is applied to the `<ListItem>` styles prop.
165198

166199
```jsx
@@ -203,24 +236,6 @@ See [`primaryText`](#primarytext)
203236

204237
See [`primaryText`](#primarytext)
205238

206-
## `empty`
207-
208-
It's possible that a SimpleList will have no records to display. If the SimpleList's parent component does not handle the empty state, the SimpleList will display a message indicating there are no results. This message is translatable and its key is `ra.navigation.no_results`.
209-
210-
You can customize the empty state by passing a component to the `empty` prop:
211-
212-
```jsx
213-
const CustomEmpty = () => <div>No books found</div>;
214-
215-
const PostList = () => (
216-
<List>
217-
<SimpleList
218-
primaryText={record => record.title}
219-
empty={<CustomEmpty />}
220-
/>
221-
</List>
222-
);
223-
```
224239

225240
## Using `<SimpleList>` On Small Screens
226241

0 commit comments

Comments
 (0)