Skip to content
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

Add ability to use a React element as Field label #4852

Merged
merged 1 commit into from
May 25, 2020
Merged
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
2 changes: 1 addition & 1 deletion docs/Fields.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ All field components accept the following props:
| ---|---|---|---|--- |
| `record` | Required | `Object` | - | Object containing the properties to display. `<Datagrid>`, `<SimpleForm>` and other components inject that prop to their children |
| `source` | Required | `string` | - | Name of the property to display |
| `label` | Optional | `string` | `source` | Used as a table header or an input label |
| `label` | Optional | `string | ReactElement` | `source` | Used as a table header or an input label |
| `sortable` | Optional | `boolean` | `true` | When used in a `List`, should the list be sortable using the `source` attribute? Setting it to `false` disables the click handler on the column header. |
| `sortBy` | Optional | `string` | `source` | When used in a `List`, specifies the actual `source` to be used for sorting when the user clicks the column header |
| `className` | Optional | `string` | - | A class name (usually generated by JSS) to customize the look and feel of the field element itself |
Expand Down
4 changes: 2 additions & 2 deletions docs/List.md
Original file line number Diff line number Diff line change
Expand Up @@ -1217,7 +1217,7 @@ Here are all the props accepted by the component:
* [`expand`](#expand)
* [`isRowSelectable`](#isrowselectable)

It renders as many columns as it receives `<Field>` children.
It renders as many columns as it receives `<Field>` children. It uses the field `label` as column header (or, for fields with not `label`, the field `source`).

```jsx
// in src/posts.js
Expand Down Expand Up @@ -1546,7 +1546,7 @@ For this kind of use case, you need to use a [custom datagrid body component](#b

### Performance

when displaying large pages of data, you might experience some performance issues.
When displaying large pages of data, you might experience some performance issues.
This is mostly due to the fact that we iterate over the `<Datagrid>` children and clone them.

In such cases, you can opt-in for an optimized version of the `<Datagrid>` by setting its `optimized` prop to `true`.
Expand Down
13 changes: 10 additions & 3 deletions packages/ra-core/src/util/FieldTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { FunctionComponent } from 'react';
import React, { FunctionComponent, ReactElement } from 'react';
import pure from 'recompose/pure';

import useTranslate from '../i18n/useTranslate';
Expand All @@ -8,7 +8,7 @@ interface Props {
isRequired?: boolean;
resource?: string;
source?: string;
label?: string;
label?: string | ReactElement;
}

export const FieldTitle: FunctionComponent<Props> = ({
Expand All @@ -18,10 +18,17 @@ export const FieldTitle: FunctionComponent<Props> = ({
isRequired,
}) => {
const translate = useTranslate();
if (label && typeof label !== 'string') {
return label;
}
return (
<span>
{translate(
...getFieldLabelTranslationArgs({ label, resource, source })
...getFieldLabelTranslationArgs({
label: label as string,
resource,
source,
})
)}
{isRequired && ' *'}
</span>
Expand Down
5 changes: 3 additions & 2 deletions packages/ra-ui-materialui/src/field/types.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { ReactElement } from 'react';
import { Record } from 'ra-core';
import PropTypes from 'prop-types';

Expand All @@ -8,7 +9,7 @@ export interface FieldProps {
sortBy?: string;
sortByOrder?: SortOrder;
source?: string;
label?: string;
label?: string | ReactElement;
sortable?: boolean;
className?: string;
cellClassName?: string;
Expand All @@ -28,7 +29,7 @@ export const fieldPropTypes = {
sortBy: PropTypes.string,
sortByOrder: PropTypes.oneOf<SortOrder>(['ASC', 'DESC']),
source: PropTypes.string,
label: PropTypes.string,
label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
sortable: PropTypes.bool,
className: PropTypes.string,
cellClassName: PropTypes.string,
Expand Down
4 changes: 2 additions & 2 deletions packages/ra-ui-materialui/src/input/Labeled.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ interface Props {
id: string;
input: any;
isRequired: boolean;
label?: string;
label?: string | ReactElement;
meta: any;
resource: string;
source: string;
Expand Down Expand Up @@ -119,7 +119,7 @@ Labeled.propTypes = {
id: PropTypes.string,
input: PropTypes.object,
isRequired: PropTypes.bool,
label: PropTypes.string,
label: PropTypes.oneOfType([PropTypes.string, PropTypes.element]),
meta: PropTypes.object,
onChange: PropTypes.func,
record: PropTypes.object,
Expand Down
19 changes: 19 additions & 0 deletions packages/ra-ui-materialui/src/list/DatagridHeaderCell.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,25 @@ import { DatagridHeaderCell } from './DatagridHeaderCell';
describe('<DatagridHeaderCell />', () => {
afterEach(cleanup);

it('should accept a React element as Field label', () => {
const Label = () => <>Label</>;
const Field = () => <div />;
const { getByText } = render(
<table>
<tbody>
<tr>
<DatagridHeaderCell
currentSort={{}}
field={<Field source="title" label={<Label />} />}
updateSort={() => true}
/>
</tr>
</tbody>
</table>
);
expect(getByText('Label')).toBeDefined();
});

describe('sorting on a column', () => {
const Field = () => <div />;
Field.defaultProps = {
Expand Down