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

Introduce default dark theme #9479

Merged
merged 24 commits into from
Dec 4, 2023
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b03ba63
doc: introduce documentation (wip)
adguernier Nov 28, 2023
360bba8
add the default darktheme in <Admin>
adguernier Nov 28, 2023
a62a03f
add a story to demonstrate a custome light and dark theme
adguernier Nov 29, 2023
7c8ef33
add JSdoc to explain priority
adguernier Nov 29, 2023
735395f
JSdoc precisions about theme priorities
adguernier Nov 29, 2023
5dbd8eb
doc: enhance documentation about darktheme
adguernier Nov 29, 2023
ad6f74d
fix a typo
adguernier Nov 29, 2023
d1441cf
doc: add a section to upgrade guide about default dark theme
adguernier Nov 29, 2023
a535fd3
apply reviews
adguernier Nov 29, 2023
690448c
Fix props table
fzaninotto Nov 29, 2023
73f31b5
remove confusing lightTheme documentation
adguernier Dec 4, 2023
5b6a0fd
doc: default value for the theme to defaultLightTheme
adguernier Dec 4, 2023
3a7b3cc
doc: correct sentence
adguernier Dec 4, 2023
f713d26
improve upgrade guide for default dark theme
adguernier Dec 4, 2023
fb00163
remove JSDoc
adguernier Dec 4, 2023
6de9973
doc: remove them priorities
adguernier Dec 4, 2023
67a6ed6
remove useless darkTheme usage in stories
adguernier Dec 4, 2023
017ea11
update AdminContext spec
adguernier Dec 4, 2023
7873995
add a spec to test main theme priority
adguernier Dec 4, 2023
b19144b
Merge branch 'introduce-default-dark-theme-2' of github.com:marmelab/…
adguernier Dec 4, 2023
457eefc
Merge branch 'next' into introduce-default-dark-theme-2
adguernier Dec 4, 2023
ab9b129
Small edit
fzaninotto Dec 4, 2023
e44f99e
Default stories to light theme
fzaninotto Dec 4, 2023
c65b7c5
[no ci] Simplify upgrade guide
fzaninotto Dec 4, 2023
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
70 changes: 64 additions & 6 deletions docs/Admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,11 +145,12 @@ Here are all the props accepted by the component:
| `basename` | Optional | `string` | - | The base path for all URLs |
| `catchAll` | Optional | `Component` | `NotFound` | The fallback component for unknown routes |
| `dashboard` | Optional | `Component` | - | The content of the dashboard page |
| `darkTheme` | Optional | `object` | - | The dark theme configuration |
| `darkTheme` | Optional | `object` | `defaultDarkTheme` (the default built-in dark theme) | The dark theme configuration |
adguernier marked this conversation as resolved.
Show resolved Hide resolved
| `defaultTheme` | Optional | `boolean` | `false` | Flag to default to the light theme |
| `disableTelemetry` | Optional | `boolean` | `false` | Set to `true` to disable telemetry collection |
| `i18nProvider` | Optional | `I18NProvider` | - | The internationalization provider for translations |
| `layout` | Optional | `Component` | `Layout` | The content of the layout |
| `lightTheme` | Optional | `object` | `defaultLightTheme` (the default built-in light theme) | The light theme configuration |
adguernier marked this conversation as resolved.
Show resolved Hide resolved
| `loginPage` | Optional | `Component` | `LoginPage` | The content of the login page |
| `notification` | Optional | `Component` | `Notification` | The notification component |
| `queryClient` | Optional | `QueryClient` | - | The react-query client |
Expand Down Expand Up @@ -433,29 +434,48 @@ const App = () => (

## `darkTheme`

If you want to support both light and dark mode, you can provide a `darkTheme` in addition to the `theme` prop. The app will use the `darkTheme` by default for users who prefer the dark mode at the OS level, and users will be able to switch from light to dark mode using a new app bar button leveraging [the `<ToggleThemeButton>` component](./ToggleThemeButton.md).
React-admin provides a [built-in dark theme](./AppTheme.md#default). The app will use the `darkTheme` by default for users who prefer the dark mode at the OS level, and users will be able to switch from light to dark mode using [the `<ToggleThemeButton>` component](./ToggleThemeButton.md).

<video controls autoplay muted loop>
<source src="./img/ToggleThemeButton.webm" type="video/webm"/>
Your browser does not support the video tag.
</video>

If you want to override it, you can provide your own `darkTheme` in addition to the `theme` prop:

```tsx
import { Admin } from 'react-admin';
import { dataProvider } from './dataProvider';
import { darkTheme, lightTheme } from './themes';
import { myDarkTheme } from './themes';

const App = () => (
<Admin
dataProvider={dataProvider}
theme={lightTheme}
darkTheme={darkTheme}
darkTheme={myDarkTheme}
>
...
</Admin>
);
```

If you want to remove the user's ability to switch to dark theme, you can set `darkTheme` to `null`, therefore the `<ToggleThemeButton>` component won't be shown:

```tsx
import { Admin } from 'react-admin';
import { dataProvider } from './dataProvider';

const App = () => (
<Admin
dataProvider={dataProvider}
darkTheme={null}
>
...
</Admin>
);
```

If the `theme` prop is provided and the `darkTheme` prop is not, the dark theme is disabled.

**Tip**: To disable OS preference detection and always use one theme by default, see the [`defaultTheme`](#defaulttheme) prop.

## `defaultTheme`
Expand Down Expand Up @@ -600,6 +620,36 @@ Refer to each layout component documentation to understand the props it accepts.

Finally, you can also pass a custom component as the `layout` prop. It must contain a `{children}` placeholder, where react-admin will render the page content. Check [the custom layout documentation](./Layout.md#writing-a-layout-from-scratch) for examples, and use the [default `<Layout>`](https://github.com/marmelab/react-admin/blob/master/packages/ra-ui-materialui/src/layout/Layout.tsx) as a starting point.

## `lightTheme`
adguernier marked this conversation as resolved.
Show resolved Hide resolved

React-admin provides a [built-in light theme](./AppTheme.md#default). The app will use the `lightTheme` by default for users who prefer the light mode at the OS / browser level, and users will be able to switch from light to dark mode using [the `<ToggleThemeButton>` component](./ToggleThemeButton.md) if the `darkTheme` prop is provided or leaved by default.

<video controls autoplay muted loop>
<source src="./img/ToggleThemeButton.webm" type="video/webm"/>
Your browser does not support the video tag.
</video>

If you want to override it, you can provide your own `lightTheme`:

```tsx
import { Admin } from 'react-admin';
import { dataProvider } from './dataProvider';
import { mylightTheme } from './themes';

const App = () => (
<Admin
dataProvider={dataProvider}
lightTheme={mylightTheme}
>
...
</Admin>
);
```

If the `theme` prop is provided, the `lightTheme` prop is ignored.

**Tip**: To disable OS preference detection and always use one theme by default, see the [`defaultTheme`](#defaulttheme) prop.

## `loginPage`

If you want to customize the Login page, or switch to another authentication strategy than a username/password form, pass a component of your own as the `loginPage` prop. React-admin will display this component whenever the `/login` route is called.
Expand Down Expand Up @@ -843,7 +893,15 @@ const App = () => (

You can also [write your own theme](./AppTheme.md#writing-a-custom-theme) to fit your company branding. For more details on predefined and custom themes, refer to [the Application Theme chapter](./AppTheme.md).

If you want to support both a light and a dark theme, check out [the `<Admin darkTheme>` prop](#darktheme).
React-admin provides a [built-in dark theme by default](./AppTheme.md#default). If you want to override it, check out [the `<Admin darkTheme>` prop](#darktheme).

### Theme Priorities

The following priorities are applied depending on whether the `theme` prop is provided or not:

- if `theme` is not provided, the default light and dark theme are used;
- if `theme` is provided the `lightTheme` prop is ignored;
adguernier marked this conversation as resolved.
Show resolved Hide resolved
- if `theme` is provided and `darkTheme` prop is not, `darkTheme` is ignored and disabled;

## `title`

Expand Down
2 changes: 1 addition & 1 deletion docs/AppBar.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ By default, the `<AppBar>` component displays:
- a hamburger icon to toggle the sidebar width,
- the page title,
- a button to change locales (if the application uses [i18n](./Translation.md)),
- a button to change the theme (if the application uses a [dark theme](./Admin.md#darktheme)),
- a button to change the theme (if the [dark theme](./Admin.md#darktheme) is not disabled),
adguernier marked this conversation as resolved.
Show resolved Hide resolved
- a loading indicator,
- a button to display the user menu.

Expand Down
23 changes: 16 additions & 7 deletions docs/AppTheme.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,14 +60,17 @@ It's a common practice to support both a light theme and a dark theme in an appl
Your browser does not support the video tag.
</video>

React-admin provides a [built-in dark theme by default](#default), the default application theme depends on the user's system settings. If the user has chosen a dark mode in their OS, react-admin will use the dark theme. Otherwise, it will use the light theme.

React-admin's `<Admin>` component accepts a `darkTheme` prop in addition to the `theme` prop.
In addition, users can switch from one theme to the other using [the `<ToggleThemeButton>` component](./ToggleThemeButton.md), that appears in the AppBar as soon as you define a `darkTheme` prop.

```jsx
import { Admin, defaultTheme } from 'react-admin';
You can override the dark theme by setting the `<Admin>`'s `darkTheme` prop with your own theme:

const lightTheme = defaultTheme;
const darkTheme = { ...defaultTheme, palette: { mode: 'dark' } };
```tsx
import { Admin, defaultDarkTheme, defaultLightTheme } from 'react-admin';

const lightTheme = defaultLightTheme;
const darkTheme = { ...defaultDarkTheme, palette: { mode: 'dark' } };

const App = () => (
<Admin
Expand All @@ -80,9 +83,15 @@ const App = () => (
);
```

With this setup, the default application theme depends on the user's system settings. If the user has chosen a dark mode in their OS, react-admin will use the dark theme. Otherwise, it will use the light theme.
**Tip**: If you don't need the default dark theme, you can set the `<Admin>`'s `darkTheme` prop to `null`:

In addition, users can switch from one theme to the other using [the `<ToggleThemeButton>` component](./ToggleThemeButton.md), which appears in the AppBar as soon as you define a `darkTheme` prop.
```tsx
const App = () => (
<Admin darkTheme={null}>
// ...
</Admin>
);
```

## Built-In Themes

Expand Down
25 changes: 20 additions & 5 deletions docs/ToggleThemeButton.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ The `<ToggleThemeButton>` component lets users switch from light to dark mode, a
Your browser does not support the video tag.
</video>

It is enabled by default in the `<AppBar>` as soon as you define a dark theme via [the `<Admin darkTheme>` prop](./Admin.md#darktheme).
It is enabled by default in the `<AppBar>` as React-admin provides a [built-in dark theme](./AppTheme.md#default).

## Usage

Expand Down Expand Up @@ -52,10 +52,23 @@ const App = () => (

## Removing The Button From The AppBar

The `<ToggleThemeButton>` appears by default in the `<AppBar>` if the `<Admin darkTheme>` prop is defined. If you want to remove it, you need to set a custom [`<AppBar toolbar>` prop](./AppBar.md#toolbar):
The `<ToggleThemeButton>` appears by default in the `<AppBar>`. If you want to remove it, you have two solutions:

```jsx
// in src/MyAppBar.js
- you can set the `<Admin>` `darkTheme` prop to `null`:

```tsx
// in src/App.tsx
const App = () => (
<Admin darkTheme={null}>
// ...
</Admin>
);
```

- or you can set a custom [`<AppBar toolbar>` prop](./AppBar.md#toolbar):

```tsx
// in src/MyAppBar.tsx
import { AppBar, LocalesMenuButton, RefreshIconButton } from 'react-admin';

export const MyAppBar = () => (
Expand All @@ -71,7 +84,9 @@ export const MyAppBar = () => (

## Creating A Dark Theme

For this button to work, you must provide a dark theme to the `<Admin>` component. The `darkTheme` should be a JSON object that follows the [Material UI theme specification](https://material-ui.com/customization/theming/).
For this button to work, you must provide a dark theme to the `<Admin>` component. React-admin provides a [built-in dark theme](./AppTheme.md#default), but you can override it according to your needs.

The `darkTheme` should be a JSON object that follows the [Material UI theme specification](https://material-ui.com/customization/theming/).

You can create such a theme from scratch:

Expand Down
18 changes: 18 additions & 0 deletions docs/Upgrade.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,24 @@ If you previously relied on the fact that the rows were not clickable by default
</Datagrid>
```

## A `darkTheme` is now provided by default
adguernier marked this conversation as resolved.
Show resolved Hide resolved

If themes are not configured using the `<Admin>` component props, React-admin enables the [dark mode feature](https://marmelab.com/react-admin/AppTheme.html#light-and-dark-themes).
adguernier marked this conversation as resolved.
Show resolved Hide resolved

If you don't need the dark mode feature, you'll have to explicitly disable it:
```diff
-<Admin>
+<Admin darkTheme={null}>
...
</Admin>
```

adguernier marked this conversation as resolved.
Show resolved Hide resolved
Here are the priorities applied depending on whether the `theme` prop is provided or not:

- if `theme` is not provided, the [default light and dark theme](https://marmelab.com/react-admin/AppTheme.html#default) are used;
- if `theme` is provided the `lightTheme` prop is ignored (no change from before);
- if `theme` is provided and `darkTheme` prop is not, `darkTheme` is ignored and disabled;
adguernier marked this conversation as resolved.
Show resolved Hide resolved

## Upgrading to v4

If you are on react-admin v3, follow the [Upgrading to v4](https://marmelab.com/react-admin/doc/4.16/Upgrade.html) guide before upgrading to v5.
16 changes: 14 additions & 2 deletions packages/ra-ui-materialui/src/AdminContext.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
ThemesContext,
RaThemeOptions,
defaultLightTheme,
defaultDarkTheme,
} from './theme';

export const AdminContext = (props: AdminContextProps) => {
Expand All @@ -22,7 +23,12 @@ export const AdminContext = (props: AdminContextProps) => {
<ThemesContext.Provider
value={{
lightTheme: theme || lightTheme,
darkTheme,
darkTheme:
theme && !darkTheme
? null
: !darkTheme && darkTheme !== null
? defaultDarkTheme
: darkTheme,
defaultTheme,
}}
>
Expand All @@ -35,6 +41,9 @@ export const AdminContext = (props: AdminContextProps) => {
export interface AdminContextProps extends CoreAdminContextProps {
/**
* The material-UI theme to customize the UI
* If not provided, the default light and dark theme and are used
* If provided the the lightTheme prop is ignored
adguernier marked this conversation as resolved.
Show resolved Hide resolved
* If provided and darkTheme prop is not, darkTheme is ignored
*
* @see https://marmelab.com/react-admin/Admin.html#theme
* @example
Expand All @@ -56,13 +65,16 @@ export interface AdminContextProps extends CoreAdminContextProps {

/**
* The material-UI theme to customize the UI. Prefer the theme prop.
* If not provided, the default light theme is used.
*
* @see https://marmelab.com/react-admin/Admin.html#theme
*/
lightTheme?: RaThemeOptions;

/**
* The material-UI theme to apply to the UI when the dark mode is activated.
* If not provided, the default dark theme is used.
* If set to null, the dark mode is disabled.
*
* @see https://marmelab.com/react-admin/Admin.html#darktheme
* @example
Expand All @@ -80,7 +92,7 @@ export interface AdminContextProps extends CoreAdminContextProps {
* </Admin>
* );
*/
darkTheme?: RaThemeOptions;
darkTheme?: RaThemeOptions | null;

/**
* The default theme to use when the user hasn't chosen a theme yet.
Expand Down
3 changes: 0 additions & 3 deletions packages/ra-ui-materialui/src/theme/defaultTheme.stories.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import { AdminContext } from '../AdminContext';
import { AdminUI } from '../AdminUI';
import { ListGuesser } from '../list';
import { EditGuesser } from '../detail';
import { defaultLightTheme, defaultDarkTheme } from './defaultTheme';
import { testData } from './testData';

export default {
Expand All @@ -18,8 +17,6 @@ export default {
export const Default = () => (
<AdminContext
dataProvider={fakerestDataProvider(testData)}
lightTheme={defaultLightTheme}
darkTheme={defaultDarkTheme}
defaultTheme="light"
i18nProvider={polyglotI18nProvider(() => englishTranslations, 'en')}
>
Expand Down
Loading
Loading