@mui/material 7.2.0 → 7.3.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. package/Accordion/Accordion.d.ts +11 -0
  2. package/Accordion/Accordion.js +19 -5
  3. package/Alert/Alert.js +2 -3
  4. package/Autocomplete/Autocomplete.js +4 -4
  5. package/Button/Button.js +5 -6
  6. package/ButtonGroup/ButtonGroup.js +3 -4
  7. package/CHANGELOG.md +91 -0
  8. package/Checkbox/Checkbox.js +2 -3
  9. package/Chip/Chip.js +10 -11
  10. package/Divider/Divider.js +1 -2
  11. package/FilledInput/FilledInput.js +1 -1
  12. package/IconButton/IconButton.js +2 -3
  13. package/Input/Input.js +1 -1
  14. package/LinearProgress/LinearProgress.js +1 -2
  15. package/Link/Link.js +11 -4
  16. package/Link/getTextDecoration.js +5 -0
  17. package/ListItemButton/ListItemButton.js +4 -5
  18. package/MenuItem/MenuItem.js +4 -5
  19. package/OutlinedInput/OutlinedInput.js +2 -2
  20. package/PaginationItem/PaginationItem.d.ts +1 -0
  21. package/PaginationItem/PaginationItem.js +7 -8
  22. package/Radio/Radio.js +2 -3
  23. package/Select/SelectInput.js +2 -2
  24. package/Skeleton/Skeleton.js +1 -1
  25. package/Slider/Slider.js +6 -15
  26. package/Snackbar/Snackbar.js +2 -8
  27. package/SpeedDial/SpeedDial.js +20 -6
  28. package/Switch/Switch.js +6 -4
  29. package/TableCell/TableCell.js +1 -2
  30. package/TableRow/TableRow.js +2 -3
  31. package/ToggleButton/ToggleButton.js +7 -8
  32. package/Tooltip/Tooltip.js +2 -3
  33. package/esm/Accordion/Accordion.d.ts +11 -0
  34. package/esm/Accordion/Accordion.js +19 -5
  35. package/esm/Alert/Alert.js +2 -3
  36. package/esm/Autocomplete/Autocomplete.js +4 -4
  37. package/esm/Button/Button.js +5 -6
  38. package/esm/ButtonGroup/ButtonGroup.js +3 -4
  39. package/esm/Checkbox/Checkbox.js +2 -3
  40. package/esm/Chip/Chip.js +10 -11
  41. package/esm/Divider/Divider.js +1 -2
  42. package/esm/FilledInput/FilledInput.js +1 -1
  43. package/esm/IconButton/IconButton.js +2 -3
  44. package/esm/Input/Input.js +1 -1
  45. package/esm/LinearProgress/LinearProgress.js +1 -2
  46. package/esm/Link/Link.js +11 -4
  47. package/esm/Link/getTextDecoration.js +5 -0
  48. package/esm/ListItemButton/ListItemButton.js +4 -5
  49. package/esm/MenuItem/MenuItem.js +4 -5
  50. package/esm/OutlinedInput/OutlinedInput.js +2 -2
  51. package/esm/PaginationItem/PaginationItem.d.ts +1 -0
  52. package/esm/PaginationItem/PaginationItem.js +7 -8
  53. package/esm/Radio/Radio.js +2 -3
  54. package/esm/Select/SelectInput.js +2 -2
  55. package/esm/Skeleton/Skeleton.js +2 -2
  56. package/esm/Slider/Slider.js +6 -15
  57. package/esm/Snackbar/Snackbar.js +2 -8
  58. package/esm/SpeedDial/SpeedDial.js +20 -6
  59. package/esm/Switch/Switch.js +6 -4
  60. package/esm/TableCell/TableCell.js +1 -2
  61. package/esm/TableRow/TableRow.js +2 -3
  62. package/esm/ToggleButton/ToggleButton.js +7 -8
  63. package/esm/Tooltip/Tooltip.js +2 -3
  64. package/esm/index.js +1 -1
  65. package/esm/styles/createColorScheme.d.ts +3 -1
  66. package/esm/styles/createColorScheme.js +6 -1
  67. package/esm/styles/createPalette.js +29 -2
  68. package/esm/styles/createTheme.d.ts +1 -1
  69. package/esm/styles/createThemeNoVars.d.ts +3 -0
  70. package/esm/styles/createThemeNoVars.js +59 -1
  71. package/esm/styles/createThemeWithVars.d.ts +4 -0
  72. package/esm/styles/createThemeWithVars.js +98 -69
  73. package/esm/useAutocomplete/useAutocomplete.d.ts +1 -0
  74. package/esm/useAutocomplete/useAutocomplete.js +21 -3
  75. package/esm/version/index.js +3 -3
  76. package/index.js +1 -1
  77. package/package.json +9 -11
  78. package/styles/createColorScheme.d.ts +3 -1
  79. package/styles/createColorScheme.js +6 -1
  80. package/styles/createPalette.js +30 -2
  81. package/styles/createTheme.d.ts +1 -1
  82. package/styles/createThemeNoVars.d.ts +3 -0
  83. package/styles/createThemeNoVars.js +59 -1
  84. package/styles/createThemeWithVars.d.ts +4 -0
  85. package/styles/createThemeWithVars.js +98 -69
  86. package/useAutocomplete/useAutocomplete.d.ts +1 -0
  87. package/useAutocomplete/useAutocomplete.js +22 -3
  88. package/version/index.js +3 -3
@@ -220,13 +220,17 @@ const SpeedDial = /*#__PURE__*/React.forwardRef(function SpeedDial(inProps, ref)
220
220
  *
221
221
  * @param dialActionIndex {number}
222
222
  * @param origButtonRef {React.RefObject?}
223
+ * @param fabSlotOrigButtonRef {React.RefObject?}
223
224
  */
224
- const createHandleSpeedDialActionButtonRef = (dialActionIndex, origButtonRef) => {
225
+ const createHandleSpeedDialActionButtonRef = (dialActionIndex, origButtonRef, fabSlotOrigButtonRef) => {
225
226
  return buttonRef => {
226
227
  actions.current[dialActionIndex + 1] = buttonRef;
227
228
  if (origButtonRef) {
228
229
  origButtonRef(buttonRef);
229
230
  }
231
+ if (fabSlotOrigButtonRef) {
232
+ fabSlotOrigButtonRef(buttonRef);
233
+ }
230
234
  };
231
235
  };
232
236
  const handleKeyDown = event => {
@@ -342,16 +346,26 @@ const SpeedDial = /*#__PURE__*/React.forwardRef(function SpeedDial(inProps, ref)
342
346
  const children = allItems.map((child, index) => {
343
347
  const {
344
348
  FabProps: {
345
- ref: origButtonRef,
346
- ...ChildFabProps
349
+ ref: origButtonRef
347
350
  } = {},
351
+ slotProps: childSlotProps = {},
348
352
  tooltipPlacement: tooltipPlacementProp
349
353
  } = child.props;
354
+ const {
355
+ fab: {
356
+ ref: fabSlotOrigButtonRef,
357
+ ...fabSlotProps
358
+ } = {},
359
+ ...restOfSlotProps
360
+ } = childSlotProps;
350
361
  const tooltipPlacement = tooltipPlacementProp || (getOrientation(direction) === 'vertical' ? 'left' : 'top');
351
362
  return /*#__PURE__*/React.cloneElement(child, {
352
- FabProps: {
353
- ...ChildFabProps,
354
- ref: createHandleSpeedDialActionButtonRef(index, origButtonRef)
363
+ slotProps: {
364
+ fab: {
365
+ ...fabSlotProps,
366
+ ref: createHandleSpeedDialActionButtonRef(index, origButtonRef, fabSlotOrigButtonRef)
367
+ },
368
+ ...restOfSlotProps
355
369
  },
356
370
  delay: 30 * (open ? index : allItems.length - index),
357
371
  open,
@@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
6
6
  import clsx from 'clsx';
7
7
  import refType from '@mui/utils/refType';
8
8
  import composeClasses from '@mui/utils/composeClasses';
9
- import { alpha, darken, lighten } from '@mui/system/colorManipulator';
10
9
  import capitalize from "../utils/capitalize.js";
11
10
  import createSimplePaletteValueFilter from "../utils/createSimplePaletteValueFilter.js";
12
11
  import SwitchBase from "../internal/SwitchBase.js";
@@ -142,7 +141,7 @@ const SwitchSwitchBase = styled(SwitchBase, {
142
141
  theme
143
142
  }) => ({
144
143
  '&:hover': {
145
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette.action.activeChannel} / ${theme.vars.palette.action.hoverOpacity})` : alpha(theme.palette.action.active, theme.palette.action.hoverOpacity),
144
+ backgroundColor: theme.alpha((theme.vars || theme).palette.action.active, (theme.vars || theme).palette.action.hoverOpacity),
146
145
  // Reset on touch devices, it doesn't add specificity
147
146
  '@media (hover: none)': {
148
147
  backgroundColor: 'transparent'
@@ -157,13 +156,13 @@ const SwitchSwitchBase = styled(SwitchBase, {
157
156
  [`&.${switchClasses.checked}`]: {
158
157
  color: (theme.vars || theme).palette[color].main,
159
158
  '&:hover': {
160
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.hoverOpacity})` : alpha(theme.palette[color].main, theme.palette.action.hoverOpacity),
159
+ backgroundColor: theme.alpha((theme.vars || theme).palette[color].main, (theme.vars || theme).palette.action.hoverOpacity),
161
160
  '@media (hover: none)': {
162
161
  backgroundColor: 'transparent'
163
162
  }
164
163
  },
165
164
  [`&.${switchClasses.disabled}`]: {
166
- color: theme.vars ? theme.vars.palette.Switch[`${color}DisabledColor`] : `${theme.palette.mode === 'light' ? lighten(theme.palette[color].main, 0.62) : darken(theme.palette[color].main, 0.55)}`
165
+ color: theme.vars ? theme.vars.palette.Switch[`${color}DisabledColor`] : `${theme.palette.mode === 'light' ? theme.lighten(theme.palette[color].main, 0.62) : theme.darken(theme.palette[color].main, 0.55)}`
167
166
  }
168
167
  },
169
168
  [`&.${switchClasses.checked} + .${switchClasses.track}`]: {
@@ -275,6 +274,9 @@ const Switch = /*#__PURE__*/React.forwardRef(function Switch(inProps, ref) {
275
274
  ...(slotProps.switchBase && {
276
275
  root: typeof slotProps.switchBase === 'function' ? slotProps.switchBase(ownerState) : slotProps.switchBase
277
276
  }),
277
+ input: {
278
+ role: 'switch'
279
+ },
278
280
  ...(slotProps.input && {
279
281
  input: typeof slotProps.input === 'function' ? slotProps.input(ownerState) : slotProps.input
280
282
  })
@@ -4,7 +4,6 @@ import * as React from 'react';
4
4
  import PropTypes from 'prop-types';
5
5
  import clsx from 'clsx';
6
6
  import composeClasses from '@mui/utils/composeClasses';
7
- import { darken, alpha, lighten } from '@mui/system/colorManipulator';
8
7
  import capitalize from "../utils/capitalize.js";
9
8
  import TableContext from "../Table/TableContext.js";
10
9
  import Tablelvl2Context from "../Table/Tablelvl2Context.js";
@@ -45,7 +44,7 @@ const TableCellRoot = styled('td', {
45
44
  // Workaround for a rendering bug with spanned columns in Chrome 62.0.
46
45
  // Removes the alpha (sets it to 1), and lightens or darkens the theme color.
47
46
  borderBottom: theme.vars ? `1px solid ${theme.vars.palette.TableCell.border}` : `1px solid
48
- ${theme.palette.mode === 'light' ? lighten(alpha(theme.palette.divider, 1), 0.88) : darken(alpha(theme.palette.divider, 1), 0.68)}`,
47
+ ${theme.palette.mode === 'light' ? theme.lighten(theme.alpha(theme.palette.divider, 1), 0.88) : theme.darken(theme.alpha(theme.palette.divider, 1), 0.68)}`,
49
48
  textAlign: 'left',
50
49
  padding: 16,
51
50
  variants: [{
@@ -4,7 +4,6 @@ import * as React from 'react';
4
4
  import PropTypes from 'prop-types';
5
5
  import clsx from 'clsx';
6
6
  import composeClasses from '@mui/utils/composeClasses';
7
- import { alpha } from '@mui/system/colorManipulator';
8
7
  import Tablelvl2Context from "../Table/Tablelvl2Context.js";
9
8
  import { styled } from "../zero-styled/index.js";
10
9
  import memoTheme from "../utils/memoTheme.js";
@@ -45,9 +44,9 @@ const TableRowRoot = styled('tr', {
45
44
  backgroundColor: (theme.vars || theme).palette.action.hover
46
45
  },
47
46
  [`&.${tableRowClasses.selected}`]: {
48
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity),
47
+ backgroundColor: theme.alpha((theme.vars || theme).palette.primary.main, (theme.vars || theme).palette.action.selectedOpacity),
49
48
  '&:hover': {
50
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette.primary.mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha(theme.palette.primary.main, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity)
49
+ backgroundColor: theme.alpha((theme.vars || theme).palette.primary.main, `${(theme.vars || theme).palette.action.selectedOpacity} + ${(theme.vars || theme).palette.action.hoverOpacity}`)
51
50
  }
52
51
  }
53
52
  })));
@@ -6,7 +6,6 @@ import PropTypes from 'prop-types';
6
6
  import clsx from 'clsx';
7
7
  import resolveProps from '@mui/utils/resolveProps';
8
8
  import composeClasses from '@mui/utils/composeClasses';
9
- import { alpha } from '@mui/system/colorManipulator';
10
9
  import ButtonBase from "../ButtonBase/index.js";
11
10
  import capitalize from "../utils/capitalize.js";
12
11
  import { styled } from "../zero-styled/index.js";
@@ -56,7 +55,7 @@ const ToggleButtonRoot = styled(ButtonBase, {
56
55
  '&:hover': {
57
56
  textDecoration: 'none',
58
57
  // Reset on mouse devices
59
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.hoverOpacity})` : alpha(theme.palette.text.primary, theme.palette.action.hoverOpacity),
58
+ backgroundColor: theme.alpha((theme.vars || theme).palette.text.primary, (theme.vars || theme).palette.action.hoverOpacity),
60
59
  '@media (hover: none)': {
61
60
  backgroundColor: 'transparent'
62
61
  }
@@ -68,12 +67,12 @@ const ToggleButtonRoot = styled(ButtonBase, {
68
67
  style: {
69
68
  [`&.${toggleButtonClasses.selected}`]: {
70
69
  color: (theme.vars || theme).palette.text.primary,
71
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.text.primary, theme.palette.action.selectedOpacity),
70
+ backgroundColor: theme.alpha((theme.vars || theme).palette.text.primary, (theme.vars || theme).palette.action.selectedOpacity),
72
71
  '&:hover': {
73
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette.text.primaryChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha(theme.palette.text.primary, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
72
+ backgroundColor: theme.alpha((theme.vars || theme).palette.text.primary, `${(theme.vars || theme).palette.action.selectedOpacity} + ${(theme.vars || theme).palette.action.hoverOpacity}`),
74
73
  // Reset on touch devices, it doesn't add specificity
75
74
  '@media (hover: none)': {
76
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette.text.primaryChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette.text.primary, theme.palette.action.selectedOpacity)
75
+ backgroundColor: theme.alpha((theme.vars || theme).palette.text.primary, (theme.vars || theme).palette.action.selectedOpacity)
77
76
  }
78
77
  }
79
78
  }
@@ -85,12 +84,12 @@ const ToggleButtonRoot = styled(ButtonBase, {
85
84
  style: {
86
85
  [`&.${toggleButtonClasses.selected}`]: {
87
86
  color: (theme.vars || theme).palette[color].main,
88
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette[color].main, theme.palette.action.selectedOpacity),
87
+ backgroundColor: theme.alpha((theme.vars || theme).palette[color].main, (theme.vars || theme).palette.action.selectedOpacity),
89
88
  '&:hover': {
90
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / calc(${theme.vars.palette.action.selectedOpacity} + ${theme.vars.palette.action.hoverOpacity}))` : alpha(theme.palette[color].main, theme.palette.action.selectedOpacity + theme.palette.action.hoverOpacity),
89
+ backgroundColor: theme.alpha((theme.vars || theme).palette[color].main, `${(theme.vars || theme).palette.action.selectedOpacity} + ${(theme.vars || theme).palette.action.hoverOpacity}`),
91
90
  // Reset on touch devices, it doesn't add specificity
92
91
  '@media (hover: none)': {
93
- backgroundColor: theme.vars ? `rgba(${theme.vars.palette[color].mainChannel} / ${theme.vars.palette.action.selectedOpacity})` : alpha(theme.palette[color].main, theme.palette.action.selectedOpacity)
92
+ backgroundColor: theme.alpha((theme.vars || theme).palette[color].main, (theme.vars || theme).palette.action.selectedOpacity)
94
93
  }
95
94
  }
96
95
  }
@@ -6,7 +6,6 @@ import clsx from 'clsx';
6
6
  import useTimeout, { Timeout } from '@mui/utils/useTimeout';
7
7
  import elementAcceptingRef from '@mui/utils/elementAcceptingRef';
8
8
  import composeClasses from '@mui/utils/composeClasses';
9
- import { alpha } from '@mui/system/colorManipulator';
10
9
  import { useRtl } from '@mui/system/RtlProvider';
11
10
  import isFocusVisible from '@mui/utils/isFocusVisible';
12
11
  import getReactElementRef from '@mui/utils/getReactElementRef';
@@ -157,7 +156,7 @@ const TooltipTooltip = styled('div', {
157
156
  })(memoTheme(({
158
157
  theme
159
158
  }) => ({
160
- backgroundColor: theme.vars ? theme.vars.palette.Tooltip.bg : alpha(theme.palette.grey[700], 0.92),
159
+ backgroundColor: theme.vars ? theme.vars.palette.Tooltip.bg : theme.alpha(theme.palette.grey[700], 0.92),
161
160
  borderRadius: (theme.vars || theme).shape.borderRadius,
162
161
  color: (theme.vars || theme).palette.common.white,
163
162
  fontFamily: theme.typography.fontFamily,
@@ -278,7 +277,7 @@ const TooltipArrow = styled('span', {
278
277
  width: '1em',
279
278
  height: '0.71em' /* = width / sqrt(2) = (length of the hypotenuse) */,
280
279
  boxSizing: 'border-box',
281
- color: theme.vars ? theme.vars.palette.Tooltip.bg : alpha(theme.palette.grey[700], 0.9),
280
+ color: theme.vars ? theme.vars.palette.Tooltip.bg : theme.alpha(theme.palette.grey[700], 0.9),
282
281
  '&::before': {
283
282
  content: '""',
284
283
  margin: 'auto',
package/esm/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @mui/material v7.2.0
2
+ * @mui/material v7.3.1
3
3
  *
4
4
  * @license MIT
5
5
  * This source code is licensed under the MIT license found in the
@@ -6,4 +6,6 @@ export declare function getOpacity(mode: 'light' | 'dark'): {
6
6
  switchTrack: number;
7
7
  };
8
8
  export declare function getOverlays(mode: 'light' | 'dark'): string[];
9
- export default function createColorScheme(options: ColorSystemOptions): ColorSystemOptions;
9
+ export default function createColorScheme(options: ColorSystemOptions & {
10
+ colorSpace?: string;
11
+ }): ColorSystemOptions;
@@ -26,9 +26,14 @@ export default function createColorScheme(options) {
26
26
  // need to cast to avoid module augmentation test
27
27
  opacity,
28
28
  overlays,
29
+ colorSpace,
29
30
  ...rest
30
31
  } = options;
31
- const palette = createPalette(paletteInput);
32
+ // need to cast because `colorSpace` is considered internal at the moment.
33
+ const palette = createPalette({
34
+ ...paletteInput,
35
+ colorSpace
36
+ });
32
37
  return {
33
38
  palette,
34
39
  opacity: {
@@ -92,6 +92,19 @@ function addLightOrDark(intent, direction, shade, tonalOffset) {
92
92
  }
93
93
  }
94
94
  }
95
+ function mixLightOrDark(colorSpace, intent, direction, shade, tonalOffset) {
96
+ const tonalOffsetLight = tonalOffset.light || tonalOffset;
97
+ const tonalOffsetDark = tonalOffset.dark || tonalOffset * 1.5;
98
+ if (!intent[direction]) {
99
+ if (intent.hasOwnProperty(shade)) {
100
+ intent[direction] = intent[shade];
101
+ } else if (direction === 'light') {
102
+ intent.light = `color-mix(in ${colorSpace}, ${intent.main}, #fff ${(tonalOffsetLight * 100).toFixed(0)}%)`;
103
+ } else if (direction === 'dark') {
104
+ intent.dark = `color-mix(in ${colorSpace}, ${intent.main}, #000 ${(tonalOffsetDark * 100).toFixed(0)}%)`;
105
+ }
106
+ }
107
+ }
95
108
  function getDefaultPrimary(mode = 'light') {
96
109
  if (mode === 'dark') {
97
110
  return {
@@ -177,11 +190,17 @@ function getDefaultWarning(mode = 'light') {
177
190
  dark: orange[900]
178
191
  };
179
192
  }
193
+
194
+ // Use the same name as the experimental CSS `contrast-color` function.
195
+ export function contrastColor(background) {
196
+ return `oklch(from ${background} var(--__l) 0 h / var(--__a))`;
197
+ }
180
198
  export default function createPalette(palette) {
181
199
  const {
182
200
  mode = 'light',
183
201
  contrastThreshold = 3,
184
202
  tonalOffset = 0.2,
203
+ colorSpace,
185
204
  ...other
186
205
  } = palette;
187
206
  const primary = palette.primary || getDefaultPrimary(mode);
@@ -195,6 +214,9 @@ export default function createPalette(palette) {
195
214
  // Bootstrap: https://github.com/twbs/bootstrap/blob/1d6e3710dd447de1a200f29e8fa521f8a0908f70/scss/_functions.scss#L59
196
215
  // and material-components-web https://github.com/material-components/material-components-web/blob/ac46b8863c4dab9fc22c4c662dc6bd1b65dd652f/packages/mdc-theme/_functions.scss#L54
197
216
  function getContrastText(background) {
217
+ if (colorSpace) {
218
+ return contrastColor(background);
219
+ }
198
220
  const contrastText = getContrastRatio(background, dark.text.primary) >= contrastThreshold ? dark.text.primary : light.text.primary;
199
221
  if (process.env.NODE_ENV !== 'production') {
200
222
  const contrast = getContrastRatio(background, contrastText);
@@ -223,8 +245,13 @@ export default function createPalette(palette) {
223
245
  if (typeof color.main !== 'string') {
224
246
  throw new Error(process.env.NODE_ENV !== "production" ? `MUI: The color${name ? ` (${name})` : ''} provided to augmentColor(color) is invalid.\n` + `\`color.main\` should be a string, but \`${JSON.stringify(color.main)}\` was provided instead.\n` + '\n' + 'Did you intend to use one of the following approaches?\n' + '\n' + 'import { green } from "@mui/material/colors";\n' + '\n' + 'const theme1 = createTheme({ palette: {\n' + ' primary: green,\n' + '} });\n' + '\n' + 'const theme2 = createTheme({ palette: {\n' + ' primary: { main: green[500] },\n' + '} });' : _formatErrorMessage(12, name ? ` (${name})` : '', JSON.stringify(color.main)));
225
247
  }
226
- addLightOrDark(color, 'light', lightShade, tonalOffset);
227
- addLightOrDark(color, 'dark', darkShade, tonalOffset);
248
+ if (colorSpace) {
249
+ mixLightOrDark(colorSpace, color, 'light', lightShade, tonalOffset);
250
+ mixLightOrDark(colorSpace, color, 'dark', darkShade, tonalOffset);
251
+ } else {
252
+ addLightOrDark(color, 'light', lightShade, tonalOffset);
253
+ addLightOrDark(color, 'dark', darkShade, tonalOffset);
254
+ }
228
255
  if (!color.contrastText) {
229
256
  color.contrastText = getContrastText(color.main);
230
257
  }
@@ -8,7 +8,7 @@ export type { ThemeOptions, Theme, CssThemeVariables } from "./createThemeNoVars
8
8
  * @returns A complete, ready-to-use theme object.
9
9
  */
10
10
  export default function createTheme(options?: Omit<ThemeOptions, 'components'> & Pick<CssVarsThemeOptions, 'defaultColorScheme' | 'colorSchemes' | 'components'> & {
11
- cssVariables?: boolean | Pick<CssVarsThemeOptions, 'colorSchemeSelector' | 'rootSelector' | 'disableCssColorScheme' | 'cssVarPrefix' | 'shouldSkipGeneratingVar'>;
11
+ cssVariables?: boolean | Pick<CssVarsThemeOptions, 'colorSchemeSelector' | 'rootSelector' | 'disableCssColorScheme' | 'cssVarPrefix' | 'shouldSkipGeneratingVar' | 'nativeColor'>;
12
12
  },
13
13
  // cast type to skip module augmentation test
14
14
  ...args: object[]): Theme;
@@ -60,6 +60,9 @@ export interface Theme extends BaseTheme, CssVarsProperties {
60
60
  components?: Components<BaseTheme>;
61
61
  unstable_sx: (props: SxProps<Theme>) => CSSObject;
62
62
  unstable_sxConfig: SxConfig;
63
+ alpha: (color: string, value: number | string) => string;
64
+ lighten: (color: string, coefficient: number | string) => string;
65
+ darken: (color: string, coefficient: number | string) => string;
63
66
  }
64
67
 
65
68
  /**
@@ -2,6 +2,7 @@ import _formatErrorMessage from "@mui/utils/formatMuiErrorMessage";
2
2
  import deepmerge from '@mui/utils/deepmerge';
3
3
  import styleFunctionSx, { unstable_defaultSxConfig as defaultSxConfig } from '@mui/system/styleFunctionSx';
4
4
  import systemCreateTheme from '@mui/system/createTheme';
5
+ import { alpha as systemAlpha, lighten as systemLighten, darken as systemDarken } from '@mui/system/colorManipulator';
5
6
  import generateUtilityClass from '@mui/utils/generateUtilityClass';
6
7
  import createMixins from "./createMixins.js";
7
8
  import createPalette from "./createPalette.js";
@@ -10,6 +11,58 @@ import shadows from "./shadows.js";
10
11
  import createTransitions from "./createTransitions.js";
11
12
  import zIndex from "./zIndex.js";
12
13
  import { stringifyTheme } from "./stringifyTheme.js";
14
+ function coefficientToPercentage(coefficient) {
15
+ if (typeof coefficient === 'number') {
16
+ return `${(coefficient * 100).toFixed(0)}%`;
17
+ }
18
+ return `calc((${coefficient}) * 100%)`;
19
+ }
20
+
21
+ // This can be removed when moved to `color-mix()` entirely.
22
+ const parseAddition = str => {
23
+ if (!Number.isNaN(+str)) {
24
+ return +str;
25
+ }
26
+ const numbers = str.match(/\d*\.?\d+/g);
27
+ if (!numbers) {
28
+ return 0;
29
+ }
30
+ let sum = 0;
31
+ for (let i = 0; i < numbers.length; i += 1) {
32
+ sum += +numbers[i];
33
+ }
34
+ return sum;
35
+ };
36
+ function attachColorManipulators(theme) {
37
+ Object.assign(theme, {
38
+ alpha(color, coefficient) {
39
+ const obj = this || theme;
40
+ if (obj.colorSpace) {
41
+ return `oklch(from ${color} l c h / ${typeof coefficient === 'string' ? `calc(${coefficient})` : coefficient})`;
42
+ }
43
+ if (obj.vars) {
44
+ // To preserve the behavior of the CSS theme variables
45
+ // In the future, this could be replaced by `color-mix` (when https://caniuse.com/?search=color-mix reaches 95%).
46
+ return `rgba(${color.replace(/var\(--([^,\s)]+)(?:,[^)]+)?\)+/g, 'var(--$1Channel)')} / ${typeof coefficient === 'string' ? `calc(${coefficient})` : coefficient})`;
47
+ }
48
+ return systemAlpha(color, parseAddition(coefficient));
49
+ },
50
+ lighten(color, coefficient) {
51
+ const obj = this || theme;
52
+ if (obj.colorSpace) {
53
+ return `color-mix(in ${obj.colorSpace}, ${color}, #fff ${coefficientToPercentage(coefficient)})`;
54
+ }
55
+ return systemLighten(color, coefficient);
56
+ },
57
+ darken(color, coefficient) {
58
+ const obj = this || theme;
59
+ if (obj.colorSpace) {
60
+ return `color-mix(in ${obj.colorSpace}, ${color}, #000 ${coefficientToPercentage(coefficient)})`;
61
+ }
62
+ return systemDarken(color, coefficient);
63
+ }
64
+ });
65
+ }
13
66
  function createThemeNoVars(options = {}, ...args) {
14
67
  const {
15
68
  breakpoints: breakpointsInput,
@@ -19,6 +72,7 @@ function createThemeNoVars(options = {}, ...args) {
19
72
  transitions: transitionsInput = {},
20
73
  typography: typographyInput = {},
21
74
  shape: shapeInput,
75
+ colorSpace,
22
76
  ...other
23
77
  } = options;
24
78
  if (options.vars &&
@@ -29,7 +83,10 @@ function createThemeNoVars(options = {}, ...args) {
29
83
  // #host-reference
30
84
  'Please use another name or follow the [docs](https://mui.com/material-ui/customization/css-theme-variables/usage/) to enable the feature.' : _formatErrorMessage(20));
31
85
  }
32
- const palette = createPalette(paletteInput);
86
+ const palette = createPalette({
87
+ ...paletteInput,
88
+ colorSpace
89
+ });
33
90
  const systemTheme = systemCreateTheme(options);
34
91
  let muiTheme = deepmerge(systemTheme, {
35
92
  mixins: createMixins(systemTheme.breakpoints, mixinsInput),
@@ -86,6 +143,7 @@ function createThemeNoVars(options = {}, ...args) {
86
143
  };
87
144
  muiTheme.toRuntimeSource = stringifyTheme; // for Pigment CSS integration
88
145
 
146
+ attachColorManipulators(muiTheme);
89
147
  return muiTheme;
90
148
  }
91
149
  export default createThemeNoVars;
@@ -266,6 +266,10 @@ export interface CssVarsThemeOptions extends Omit<ThemeOptions, 'palette' | 'com
266
266
  * @default false
267
267
  */
268
268
  disableCssColorScheme?: boolean;
269
+ /**
270
+ * If `true`, the CSS relative color will be used.
271
+ */
272
+ nativeColor?: boolean;
269
273
  /**
270
274
  * A function to determine if the key, value should be attached as CSS Variable
271
275
  * `keys` is an array that represents the object path keys.