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

[docs][joy-ui] Revise the theme color page #38402

Merged
merged 4 commits into from
Aug 22, 2023
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
34 changes: 24 additions & 10 deletions docs/data/joy/customization/theme-colors/PaletteThemeViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Sheet from '@mui/joy/Sheet';
import LightMode from '@mui/icons-material/LightModeOutlined';
import DarkMode from '@mui/icons-material/DarkModeOutlined';
import InfoOutlined from '@mui/icons-material/InfoOutlined';
import Check from '@mui/icons-material/Check';
import CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded';
import useClipboardCopy from 'docs/src/modules/utils/useClipboardCopy';

const defaultTheme = extendTheme();
Expand Down Expand Up @@ -37,17 +37,14 @@ const collator = new Intl.Collator(undefined, {
});

const Table = styled('table')(({ theme }) => ({
border: '1px solid',
borderColor: theme.vars.palette.divider,
borderRadius: theme.vars.radius.md,
borderCollapse: 'separate',
borderSpacing: 0,
display: 'block',
height: 500,
overflowY: 'scroll',
th: {
textAlign: 'left',
padding: '8px 6px',
padding: 8,
position: 'sticky',
top: 0,
zIndex: 1,
Expand Down Expand Up @@ -102,7 +99,18 @@ export default function PaletteThemeViewer() {
);

return (
<Box sx={{ width: '100%', overflow: 'hidden', position: 'relative' }}>
<Box
sx={{
marginBottom: '-9px',
width: '100%',
overflow: 'hidden',
position: 'relative',
border: '1px solid',
borderColor: 'divider',
borderTopLeftRadius: '12px',
borderTopRightRadius: '12px',
}}
>
<Sheet
variant="solid"
color="success"
Expand All @@ -115,13 +123,18 @@ export default function PaletteThemeViewer() {
})`,
transition: '0.3s',
p: 0.5,
px: 0.75,
borderRadius: 'xs',
boxShadow: 'sm',
pl: 0.5,
pr: 1,
borderRadius: 'xl',
boxShadow: 'md',
zIndex: 1,
}}
>
<Typography level="body-xs" textColor="inherit" startDecorator={<Check />}>
<Typography
level="body-xs"
textColor="inherit"
startDecorator={<CheckCircleRoundedIcon fontSize="small" />}
>
Copied
</Typography>
</Sheet>
Expand Down Expand Up @@ -164,6 +177,7 @@ export default function PaletteThemeViewer() {
color="neutral"
textColor="inherit"
fontSize="sm"
fontWeight="md"
textAlign="left"
onClick={() => copy(token)}
endDecorator={
Expand Down
34 changes: 24 additions & 10 deletions docs/data/joy/customization/theme-colors/PaletteThemeViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import Sheet from '@mui/joy/Sheet';
import LightMode from '@mui/icons-material/LightModeOutlined';
import DarkMode from '@mui/icons-material/DarkModeOutlined';
import InfoOutlined from '@mui/icons-material/InfoOutlined';
import Check from '@mui/icons-material/Check';
import CheckCircleRoundedIcon from '@mui/icons-material/CheckCircleRounded';
import useClipboardCopy from 'docs/src/modules/utils/useClipboardCopy';

const defaultTheme = extendTheme();
Expand Down Expand Up @@ -37,17 +37,14 @@ const collator = new Intl.Collator(undefined, {
});

const Table = styled('table')(({ theme }) => ({
border: '1px solid',
borderColor: theme.vars.palette.divider,
borderRadius: theme.vars.radius.md,
borderCollapse: 'separate',
borderSpacing: 0,
display: 'block',
height: 500,
overflowY: 'scroll',
th: {
textAlign: 'left',
padding: '8px 6px',
padding: 8,
position: 'sticky',
top: 0,
zIndex: 1,
Expand Down Expand Up @@ -101,7 +98,18 @@ export default function PaletteThemeViewer() {
/>
);
return (
<Box sx={{ width: '100%', overflow: 'hidden', position: 'relative' }}>
<Box
sx={{
marginBottom: '-9px',
width: '100%',
overflow: 'hidden',
position: 'relative',
border: '1px solid',
borderColor: 'divider',
borderTopLeftRadius: '12px',
borderTopRightRadius: '12px',
}}
>
<Sheet
variant="solid"
color="success"
Expand All @@ -114,13 +122,18 @@ export default function PaletteThemeViewer() {
})`,
transition: '0.3s',
p: 0.5,
px: 0.75,
borderRadius: 'xs',
boxShadow: 'sm',
pl: 0.5,
pr: 1,
borderRadius: 'xl',
boxShadow: 'md',
zIndex: 1,
}}
>
<Typography level="body-xs" textColor="inherit" startDecorator={<Check />}>
<Typography
level="body-xs"
textColor="inherit"
startDecorator={<CheckCircleRoundedIcon fontSize="small" />}
>
Copied
</Typography>
</Sheet>
Expand Down Expand Up @@ -163,6 +176,7 @@ export default function PaletteThemeViewer() {
color="neutral"
textColor="inherit"
fontSize="sm"
fontWeight="md"
textAlign="left"
onClick={() => copy(token)}
endDecorator={
Expand Down
149 changes: 72 additions & 77 deletions docs/data/joy/customization/theme-colors/theme-colors.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,33 @@

<p class="description">Learn about the default theme's color palette and how to customize it.</p>

## Default tokens
## Default color tokens

The table below lists all the default tokens and their values in light and dark color schemes.
Some tokens reuse values from other tokens using the [`var(--*)`](https://developer.mozilla.org/en-US/docs/Web/CSS/var) syntax.
Joy UI's default theme includes 5 built-in semantic color palettes, with light and dark mapping, to help you build great looking UIs quickly.

{{"demo": "PaletteThemeViewer.js", "bg": "inline"}}

:::info
Some tokens reuse color values from others using the [`var(--*)`](https://developer.mozilla.org/en-US/docs/Web/CSS/var) syntax.
:::

### Global variant tokens

One of Joy UI's main features is the four [global variants](/joy-ui/main-features/global-variants/) that are available in every component. They use the built-in color palettes following the format of **variant type | state | CSS property**. For example:

- `solidBg` refers to the solid variant's background color in its initial state.
- `outlinedHoverBorder` refers to the outlined variant's border color in its hover state.

### Channel tokens

The default tokens ending with `Channel` are automatically generated for each palette.
These tokens are useful for creating translucent colors (`rgba`).
The channel tokens helps creating translucent colors using (`rgba`).
The ones ending with `Channel` are automatically generated for each palette.

- `lightChannel`: is generated from the palette's `200` token.
- `mainChannel`: is generated from the palette's `500` token.
- `darkChannel`: is generated from the palette's `800` token.

The example usage is:
The code snippet below shows how to use them:

```js
import Typography from '@mui/joy/Typography';
Expand All @@ -30,24 +40,11 @@ import Typography from '@mui/joy/Typography';
>
```

### Global variant tokens

By default, Joy UI has four built-in [global variants](/joy-ui/main-features/global-variants/) tokens: `plain`, `outlined`, `soft`, and `solid`.
## Customizations

The global variant token is composed of three parts, in the format of **variant type | state | CSS property**.
### Changing the default values

For example:

- `solidBg` refers to the solid variant's background color in its initial state.
- `outlinedHoverBorder` refers to the outlined variant's border color in its hover state.

There are six palettes (`primary`, `neutral`, `danger`, `info`, `success`, and `warning`) that contain the global variant tokens as listed in the [table above](#default-tokens).

## Customizing the default palette

For each color scheme, the default colors are grouped within the `palette` node.

For example, the snippet below customizes the primary palette in dark mode:
To change the HEX code for each color while still following the palette pattern, extend the theme by accessing them through the `palette` node on the target mode (light or dark):

```js
import { extendTheme } from '@mui/joy/styles';
Expand Down Expand Up @@ -76,68 +73,30 @@ const theme = extendTheme({
// Then, pass it to `<CssVarsProvider theme={theme}>`.
```

## Customizing global variant tokens
### Changing the global variant tokens

We recommend using the [Button](/joy-ui/react-button/) component as a jumping-off point when customizing the global variants, because it gives you access to more of the interactive variants available than some other components.
A good way to start changing how color looks like with the built-in variants is by using the Button component as a jumping-off point.
For example, here's how you'd make the Joy UI Button match the colors of another system, such as [Bootstrap](https://getbootstrap.com/docs/5.2/components/buttons/#examples):

As an example, let's customize Joy UI's Button so to match the style of [Bootstrap](https://getbootstrap.com/docs/5.2/components/buttons/#examples):
{{"demo": "BootstrapVariantTokens.js"}}

- Bootstrap's default buttons are comparable to Joy UI's `solid` variant.
- Bootstrap's `secondary` variant uses a grey color, similar to Joy UI's `neutral`.
- Bootstrap's `btn-light` is similar to Joy UI's button using the `soft` variant and `neutral` color palette.
- Joy UI's defaults don't include anything similar to Bootstrap's `btn-dark`.
- We can recreate it using one of the three main customization approaches.

{{"demo": "BootstrapVariantTokens.js"}}

:::info
Customizing the global variant tokens affects all Joy UI components that support the `variant` prop.
:::
### Adding color tokens

## Removing the default tokens

To remove any default token, use `undefined` as a value.
This removes it from the `theme` object and prevents the corresponding CSS variable from being generated.

For example, all default global variant tokens comes with styles for the `:active` pseudo class.
Here's how you'd remove it from the solid variant.

```jsx
// ⚠️ If the value is `undefined`, it should be `undefined` for all color schemes.
const theme = extendTheme({
colorSchemes: {
light: {
palette: {
primary: {
solidActiveBg: undefined,
},
},
},
dark: {
palette: {
primary: {
solidActiveBg: undefined,
},
},
},
},
});
```

{{"demo": "RemoveActiveTokens.js"}}

## Adding more colors

Any custom tokens that you add to theme are available for use with both the `styled` and `sx` APIs.
To make any new color available through the `color` prop, insert them in the `colorSchemes` key of the extended theme.
You'll also be able to access them with both the `styled` and `sx` APIs.

```js
extendTheme({
colorSchemes: {
light: {
palette: {
// Example of new color tokens.
// We recommend to limit them to 3 levels deep-in this case:
// `palette.gradient.primary`.
// `gradient` is a new color token
gradient: {
primary: 'linear-gradient(to top, var(--joy-palette-primary-main), #000)',
},
Expand All @@ -150,9 +109,13 @@ extendTheme({
<Button sx={{ background: (theme) => theme.vars.palette.gradient.primary }} />;
```

### TypeScript
:::success
We recommend to limit them to 3 levels deep-in this case: `palette.gradient.primary`.
:::

When working in TypeScript, you must augment the theme's `Palette` interface to include the new tokens.
#### TypeScript

Augment the theme's `Palette` interface, when working in TypeScript, to include the new tokens.

```ts
// You can put this to any file that's included in your tsconfig
Expand All @@ -172,13 +135,9 @@ These tradeoffs mean that adding new tokens is usually only worthwhile when you
As an alternative, consider using [the `sx` prop](/joy-ui/customization/approaches/#sx-prop) for one-off customizations.
:::

## Adding more palettes

You can add your own palettes to your app's theme to pass custom color schemes to any components that accept the `color` prop.
### Adding new palettes

:::warning
Adding a new palette increases the HTML bundle size. The more tokens you added to the palette, the bigger the bundle size.
:::
To add entirely new color palettes, with any type of scale, and make them available through the `color` prop, insert them in the `colorSchemes` key of the extended theme.

The snippet below adds a custom `secondary` palette to the theme.

Expand Down Expand Up @@ -261,7 +220,7 @@ Then, you will be able to use `secondary` color on Joy UI components:
<Chip variant="soft" color="secondary">
```

### TypeScript
#### TypeScript

When working in TypeScript, you must augment the theme's interfaces to include the new palette.

Expand All @@ -282,3 +241,39 @@ declare module '@mui/joy/styles' {
}
}
```

:::warning
Note that adding new palettes increases the HTML bundle size.
:::

### Removing the default tokens

To remove any default token, use `undefined` as a value within the extended theme.
This removes them from the `theme` object and prevents the corresponding CSS variable from being generated.

For example, all default global variant color tokens comes with styles for the `:active` pseudo class.
Here's how you'd remove it from the solid variant.

```jsx
// ⚠️ If the value is `undefined`, it should be `undefined` for all color schemes.
const theme = extendTheme({
colorSchemes: {
light: {
palette: {
primary: {
solidActiveBg: undefined,
},
},
},
dark: {
palette: {
primary: {
solidActiveBg: undefined,
},
},
},
},
});
```

{{"demo": "RemoveActiveTokens.js"}}