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

Fix hardcoded TextField size prop #9554

Merged
merged 6 commits into from
Jan 23, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
154 changes: 86 additions & 68 deletions docs/AppTheme.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ title: "Application Theme"

If you want to override some styles across the entire application, you can use a custom theme, leveraging [the Material UI Theming support](https://mui.com/material-ui/customization/theming/). Custom themes let you override colors, fonts, spacing, and even the style of individual components.

The [e-commerce demo](https://marmelab.com/react-admin-demo/) contains a theme switcher, so you can test them in a real application.
The [e-commerce demo](https://marmelab.com/react-admin-demo/) contains a theme switcher, so you can test them in a real application.

<video controls autoplay playsinline muted loop>
<source src="./img/demo-themes.mp4" type="video/mp4"/>
Expand All @@ -20,12 +20,12 @@ You can override the style of the entire application by passing a custom `theme`

```jsx
import { Admin, defaultTheme } from 'react-admin';
import { deepmerge } from '@mui/utils';
import indigo from '@mui/material/colors/indigo';
import pink from '@mui/material/colors/pink';
import red from '@mui/material/colors/red';

const myTheme = {
...defaultTheme,
const myTheme = deepmerge(defaultTheme, {
palette: {
primary: indigo,
secondary: pink,
Expand All @@ -37,10 +37,10 @@ const myTheme = {
// Use the system font instead of the default Roboto font.
fontFamily: ['-apple-system', 'BlinkMacSystemFont', '"Segoe UI"', 'Arial', 'sans-serif'].join(','),
},
};
});

const App = () => (
<Admin theme={theme}>
<Admin theme={myTheme}>
// ...
</Admin>
);
Expand All @@ -52,7 +52,7 @@ Note that you don't need to call Material-UI's `createTheme` yourself. React-adm

## Light And Dark Themes

It's a common practice to support both a light theme and a dark theme in an application, and let users choose which one they prefer.
It's a common practice to support both a light theme and a dark theme in an application, and let users choose which one they prefer.

<video controls autoplay playsinline muted loop>
<source src="./img/ToggleThemeButton.webm" type="video/webm"/>
Expand All @@ -62,15 +62,16 @@ It's a common practice to support both a light theme and a dark theme in an appl

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.

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.
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.

You can override the dark theme by setting the `<Admin>`'s `darkTheme` prop with your own theme:

```tsx
import { Admin, defaultDarkTheme, defaultLightTheme } from 'react-admin';
import { deepmerge } from '@mui/utils';

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

const App = () => (
<Admin
Expand All @@ -91,15 +92,15 @@ const App = () => (
// ...
</Admin>
);
```
```

## Built-In Themes

React-admin comes with 4 built-in themes, each one having a light and a dark variant. You can use them as a starting point for your custom theme, or use them as-is.

### Default

The default theme is a good fit for every application, and works equally well on desktop and mobile.
The default theme is a good fit for every application, and works equally well on desktop and mobile.

[![Default light theme](./img/defaultLightTheme1.jpg)](./img/defaultLightTheme1.jpg)
[![Default light theme](./img/defaultLightTheme2.jpg)](./img/defaultLightTheme2.jpg)
Expand All @@ -110,7 +111,7 @@ You don't need to configure anything to use the default theme - it comes out of

### Nano

A dense theme with minimal chrome, ideal for complex apps. It uses a small font size, reduced spacing, text buttons, standard variant inputs, pale colors. Only fit for desktop apps.
A dense theme with minimal chrome, ideal for complex apps. It uses a small font size, reduced spacing, text buttons, standard variant inputs, pale colors. Only fit for desktop apps.

[![Nano light theme](./img/nanoLightTheme1.jpg)](./img/nanoLightTheme1.jpg)
[![Nano light theme](./img/nanoLightTheme2.jpg)](./img/nanoLightTheme2.jpg)
Expand Down Expand Up @@ -231,11 +232,10 @@ For instance, to create a custom theme that overrides the style of the `<Datagri

```jsx
import { defaultTheme } from 'react-admin';
import { deepmerge } from '@mui/utils';

const theme = {
...defaultTheme,
const theme = deepmerge(defaultTheme, {
components: {
...defaultTheme.components,
RaDatagrid: {
styleOverrides: {
root: {
Expand All @@ -247,7 +247,7 @@ const theme = {
}
}
}
};
});

const App = () => (
<Admin theme={theme}>
Expand All @@ -271,11 +271,10 @@ You can use this technique to override not only styles, but also defaults for co

```jsx
import { defaultTheme } from 'react-admin';
import { deepmerge } from '@mui/utils';

const theme = {
...defaultTheme,
const theme = deepmerge(defaultTheme, {
components: {
...defaultTheme.components,
MuiTextField: {
defaultProps: {
variant: 'outlined',
Expand All @@ -287,18 +286,17 @@ const theme = {
},
},
}
};
});
```

**Tip**: TypeScript will be picky when overriding the `variant` `defaultProp`. To avoid compilation errors, type the `variant` value as `const`:

```ts
import { defaultTheme } from 'react-admin';
import { deepmerge } from '@mui/utils';

const theme = {
...defaultTheme,
const theme = deepmerge(defaultTheme, {
components: {
...defaultTheme.components,
MuiTextField: {
defaultProps: {
variant: 'outlined' as const,
Expand All @@ -310,7 +308,7 @@ const theme = {
},
},
}
};
});
```

## Customizing The Sidebar Width
Expand All @@ -319,14 +317,14 @@ You can specify the `Sidebar` width by setting the `width` and `closedWidth` pro

```jsx
import { defaultTheme } from 'react-admin';
import { deepmerge } from '@mui/utils';

const theme = {
...defaultTheme,
const theme = deepmerge(defaultTheme, {
sidebar: {
width: 300, // The default value is 240
closedWidth: 70, // The default value is 55
},
};
});

const App = () => (
<Admin theme={theme} dataProvider={...}>
Expand Down Expand Up @@ -425,15 +423,14 @@ const App = () => (
);
```

You can write a custom theme from scratch, or start from the [default theme](#default-theme) and override some values:
You can write a custom theme from scratch, or start from the [default theme](#default-theme) and override some values, using the Material UI's utility function deepmerge:
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved

```jsx
import { deepmerge } from '@mui/utils';
import { defaultTheme } from 'react-admin';

const theme = {
...defaultTheme,
const theme = deepmerge(defaultTheme, {
components: {
...defaultTheme.components,
RaDatagrid: {
styleOverrides: {
root: {
Expand All @@ -445,7 +442,7 @@ const theme = {
}
}
}
};
});
```

## Default Theme
Expand All @@ -454,22 +451,23 @@ React-admin provides a theme that customizes a few Material-UI settings. You can

```jsx
import { defaultTheme } from 'react-admin';
import { deepmerge } from '@mui/utils';

const myTheme = {
...defaultTheme,
const myTheme = deepmerge(defaultTheme, {
palette: {
...defaultTheme.palette,
secondary: {
main: '#11cb5f',
},
},
};
});
```

Here is the default theme:

```tsx
import { RaThemeOptions } from './layout/Theme';
import { RaThemeOptions } from './types';
import { createTheme } from '@mui/material';
import { deepmerge } from '@mui/utils';

const defaultThemeInvariants = {
typography: {
Expand All @@ -482,12 +480,30 @@ const defaultThemeInvariants = {
closedWidth: 50,
},
components: {
MuiAutocomplete: {
variants: [
{
props: {},
style: ({ theme }) => ({
[theme.breakpoints.down('sm')]: { width: '100%' },
}),
},
],
},
MuiTextField: {
defaultProps: {
variant: 'filled' as const,
margin: 'dense' as const,
size: 'small' as const,
},
variants: [
{
props: {},
style: ({ theme }) => ({
[theme.breakpoints.down('sm')]: { width: '100%' },
}),
},
],
},
MuiFormControl: {
defaultProps: {
Expand All @@ -499,46 +515,48 @@ const defaultThemeInvariants = {
},
};

export const defaultLightTheme: RaThemeOptions = {
palette: {
background: {
default: '#fafafb',
},
secondary: {
light: '#6ec6ff',
main: '#2196f3',
dark: '#0069c0',
contrastText: '#fff',
export const defaultLightTheme: RaThemeOptions = createTheme(
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved
deepmerge(defaultThemeInvariants, {
palette: {
background: {
default: '#fafafb',
},
secondary: {
light: '#6ec6ff',
main: '#2196f3',
dark: '#0069c0',
contrastText: '#fff',
},
},
},
...defaultThemeInvariants,
components: {
...defaultThemeInvariants.components,
MuiFilledInput: {
styleOverrides: {
root: {
backgroundColor: 'rgba(0, 0, 0, 0.04)',
'&$disabled': {
components: {
MuiFilledInput: {
styleOverrides: {
root: {
backgroundColor: 'rgba(0, 0, 0, 0.04)',
'&$disabled': {
backgroundColor: 'rgba(0, 0, 0, 0.04)',
},
},
},
},
},
},
};
})
);

export const defaultDarkTheme: RaThemeOptions = {
palette: {
mode: 'dark',
primary: {
main: '#90caf9',
},
background: {
default: '#313131',
export const defaultDarkTheme: RaThemeOptions = createTheme(
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved
deepmerge(defaultThemeInvariants, {
palette: {
mode: 'dark',
primary: {
main: '#90caf9',
},
background: {
default: '#313131',
},
},
},
...defaultThemeInvariants,
};
})
);

export const defaultTheme = defaultLightTheme;

```
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,6 @@ export const ResettableTextField = forwardRef(
variant={variant}
margin={margin}
className={className}
size="small"
PedroPerpetua marked this conversation as resolved.
Show resolved Hide resolved
{...rest}
onFocus={handleFocus}
onBlur={handleBlur}
Expand Down
6 changes: 1 addition & 5 deletions packages/ra-ui-materialui/src/theme/ThemeProvider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,7 @@ export const ThemeProvider = ({
const themeValue = useMemo(() => {
try {
return createTheme(
typeof mode === 'object'
? mode // FIXME: legacy useTheme, to be removed in v5
fzaninotto marked this conversation as resolved.
Show resolved Hide resolved
: mode === 'dark'
? darkTheme
: lightTheme || themeOverride
mode === 'dark' ? darkTheme : lightTheme || themeOverride
);
} catch (e) {
console.warn('Failed to reuse custom theme from store', e);
Expand Down
Loading