Skip to content

Commit

Permalink
Merge pull request #9836 from markyao6275/mark/nonconfigurable-title
Browse files Browse the repository at this point in the history
Allow <Title /> to be nonConfigurable
  • Loading branch information
slax57 committed Jun 28, 2024
2 parents a3bd5a6 + 7f73bfb commit 3a9de0c
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 30 deletions.
12 changes: 12 additions & 0 deletions docs/Title.md
Original file line number Diff line number Diff line change
Expand Up @@ -121,3 +121,15 @@ const CustomPage = () => (
);
```

If you want to disable configuring the page title even while in [Configurable mode](./AppBar.md#configurable), you can pass `preferenceKey=false`.

```jsx
import { Title } from 'react-admin';

const CustomPageWithNonConfigurableTitle = () => (
<>
<Title title="My Custom Page" preferenceKey={false} />
<div>Content</div>
</>
);
```
13 changes: 2 additions & 11 deletions packages/ra-ui-materialui/src/layout/PageTitle.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,10 @@
import * as React from 'react';
import { useRecordContext, useTranslate, usePreference } from 'ra-core';
import { useTranslate } from 'ra-core';

export const PageTitle = ({ title, defaultTitle, className, ...rest }: any) => {
const [titleFromPreferences] = usePreference();
const translate = useTranslate();
const record = useRecordContext();

return titleFromPreferences ? (
<span className={className} {...rest}>
{translate(titleFromPreferences, {
...record,
_: titleFromPreferences,
})}
</span>
) : (
return (
<span className={className}>
{!title ? (
<span {...rest}>{defaultTitle}</span>
Expand Down
39 changes: 36 additions & 3 deletions packages/ra-ui-materialui/src/layout/PageTitleConfigurable.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import * as React from 'react';
import { useLocation } from 'react-router-dom';
import { usePreferenceInput } from 'ra-core';
import {
usePreferenceInput,
usePreference,
useRecordContext,
useTranslate,
} from 'ra-core';
import { TextField } from '@mui/material';

import { Configurable } from '../preferences';
Expand All @@ -22,7 +27,12 @@ export const PageTitleEditor = () => {
);
};

export const PageTitleConfigurable = ({ preferenceKey, ...props }) => {
export const PageTitleConfigurable = ({
preferenceKey,
title,
defaultTitle,
...props
}) => {
const { pathname } = useLocation();
return (
<Configurable
Expand All @@ -34,7 +44,30 @@ export const PageTitleConfigurable = ({ preferenceKey, ...props }) => {
},
}}
>
<PageTitle {...props} />
<PageTitleConfigurableInner
title={title}
defaultTitle={defaultTitle}
{...props}
/>
</Configurable>
);
};

const PageTitleConfigurableInner = ({ title, defaultTitle, ...props }) => {
const [titleFromPreferences] = usePreference();
const translate = useTranslate();
const record = useRecordContext();

return titleFromPreferences ? (
<span className={props.className} {...props}>
{translate(titleFromPreferences, {
...record,
_: titleFromPreferences,
})}
</span>
) : (
<>
<PageTitle title={title} defaultTitle={defaultTitle} {...props} />
</>
);
};
29 changes: 15 additions & 14 deletions packages/ra-ui-materialui/src/layout/Title.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { ReactElement } from 'react';
import { createPortal } from 'react-dom';
import { RaRecord, TitleComponent, warning } from 'ra-core';

import { PageTitle } from './PageTitle';
import { PageTitleConfigurable } from './PageTitleConfigurable';

export const Title = (props: TitleProps) => {
Expand Down Expand Up @@ -31,25 +32,25 @@ export const Title = (props: TitleProps) => {

warning(!defaultTitle && !title, 'Missing title prop in <Title> element');

return (
<>
{createPortal(
<PageTitleConfigurable
title={title}
defaultTitle={defaultTitle}
preferenceKey={preferenceKey}
{...rest}
/>,
container
)}
</>
);
const pageTitle =
preferenceKey === false ? (
<PageTitle title={title} defaultTitle={defaultTitle} {...rest} />
) : (
<PageTitleConfigurable
title={title}
defaultTitle={defaultTitle}
preferenceKey={preferenceKey}
{...rest}
/>
);

return <>{createPortal(pageTitle, container)}</>;
};

export interface TitleProps {
className?: string;
defaultTitle?: TitleComponent;
record?: Partial<RaRecord>;
title?: string | ReactElement;
preferenceKey?: string;
preferenceKey?: string | false;
}
31 changes: 29 additions & 2 deletions packages/ra-ui-materialui/src/layout/TitlePortal.stories.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import * as React from 'react';
import { TestMemoryRouter } from 'ra-core';
import { PreferencesEditorContextProvider } from 'ra-core';
import {
PreferencesEditorContextProvider,
RecordContextProvider,

Check warning on line 4 in packages/ra-ui-materialui/src/layout/TitlePortal.stories.tsx

View workflow job for this annotation

GitHub Actions / typecheck

'RecordContextProvider' is defined but never used. Allowed unused vars must match /^_/u
TestMemoryRouter,
} from 'ra-core';

import { TitlePortal } from './TitlePortal';
import { Title } from './Title';
import { InspectorButton } from '../preferences/InspectorButton';
import { Inspector } from '../preferences/Inspector';

export default {
title: 'ra-ui-materialui/layout/TitlePortal',
Expand Down Expand Up @@ -35,3 +40,25 @@ export const Sx = () => (
</PreferencesEditorContextProvider>
</TestMemoryRouter>
);

export const Configurable = () => (
<TestMemoryRouter>
<PreferencesEditorContextProvider>
<Inspector />
<InspectorButton />
<TitlePortal variant="body1" />
<Title title="Hello, world" />
</PreferencesEditorContextProvider>
</TestMemoryRouter>
);

export const NonConfigurable = () => (
<TestMemoryRouter>
<PreferencesEditorContextProvider>
<Inspector />
<InspectorButton />
<TitlePortal variant="body1" />
<Title title="Hello, world" preferenceKey={false} />
</PreferencesEditorContextProvider>
</TestMemoryRouter>
);

0 comments on commit 3a9de0c

Please sign in to comment.