@mui/material 7.2.0 → 7.3.0

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 (86) 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 +76 -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.js +7 -8
  21. package/Radio/Radio.js +2 -3
  22. package/Select/SelectInput.js +66 -21
  23. package/Skeleton/Skeleton.js +1 -1
  24. package/Slider/Slider.js +6 -15
  25. package/Snackbar/Snackbar.js +2 -8
  26. package/SpeedDial/SpeedDial.js +20 -6
  27. package/Switch/Switch.js +6 -4
  28. package/TableCell/TableCell.js +1 -2
  29. package/TableRow/TableRow.js +2 -3
  30. package/ToggleButton/ToggleButton.js +7 -8
  31. package/Tooltip/Tooltip.js +2 -3
  32. package/esm/Accordion/Accordion.d.ts +11 -0
  33. package/esm/Accordion/Accordion.js +19 -5
  34. package/esm/Alert/Alert.js +2 -3
  35. package/esm/Autocomplete/Autocomplete.js +4 -4
  36. package/esm/Button/Button.js +5 -6
  37. package/esm/ButtonGroup/ButtonGroup.js +3 -4
  38. package/esm/Checkbox/Checkbox.js +2 -3
  39. package/esm/Chip/Chip.js +10 -11
  40. package/esm/Divider/Divider.js +1 -2
  41. package/esm/FilledInput/FilledInput.js +1 -1
  42. package/esm/IconButton/IconButton.js +2 -3
  43. package/esm/Input/Input.js +1 -1
  44. package/esm/LinearProgress/LinearProgress.js +1 -2
  45. package/esm/Link/Link.js +11 -4
  46. package/esm/Link/getTextDecoration.js +5 -0
  47. package/esm/ListItemButton/ListItemButton.js +4 -5
  48. package/esm/MenuItem/MenuItem.js +4 -5
  49. package/esm/OutlinedInput/OutlinedInput.js +2 -2
  50. package/esm/PaginationItem/PaginationItem.js +7 -8
  51. package/esm/Radio/Radio.js +2 -3
  52. package/esm/Select/SelectInput.js +66 -21
  53. package/esm/Skeleton/Skeleton.js +2 -2
  54. package/esm/Slider/Slider.js +6 -15
  55. package/esm/Snackbar/Snackbar.js +2 -8
  56. package/esm/SpeedDial/SpeedDial.js +20 -6
  57. package/esm/Switch/Switch.js +6 -4
  58. package/esm/TableCell/TableCell.js +1 -2
  59. package/esm/TableRow/TableRow.js +2 -3
  60. package/esm/ToggleButton/ToggleButton.js +7 -8
  61. package/esm/Tooltip/Tooltip.js +2 -3
  62. package/esm/index.js +1 -1
  63. package/esm/styles/createColorScheme.d.ts +3 -1
  64. package/esm/styles/createColorScheme.js +6 -1
  65. package/esm/styles/createPalette.js +29 -2
  66. package/esm/styles/createTheme.d.ts +1 -1
  67. package/esm/styles/createThemeNoVars.d.ts +3 -0
  68. package/esm/styles/createThemeNoVars.js +59 -1
  69. package/esm/styles/createThemeWithVars.d.ts +4 -0
  70. package/esm/styles/createThemeWithVars.js +98 -69
  71. package/esm/useAutocomplete/useAutocomplete.d.ts +1 -0
  72. package/esm/useAutocomplete/useAutocomplete.js +21 -3
  73. package/esm/version/index.js +2 -2
  74. package/index.js +1 -1
  75. package/package.json +9 -11
  76. package/styles/createColorScheme.d.ts +3 -1
  77. package/styles/createColorScheme.js +6 -1
  78. package/styles/createPalette.js +30 -2
  79. package/styles/createTheme.d.ts +1 -1
  80. package/styles/createThemeNoVars.d.ts +3 -0
  81. package/styles/createThemeNoVars.js +59 -1
  82. package/styles/createThemeWithVars.d.ts +4 -0
  83. package/styles/createThemeWithVars.js +98 -69
  84. package/useAutocomplete/useAutocomplete.d.ts +1 -0
  85. package/useAutocomplete/useAutocomplete.js +22 -3
  86. package/version/index.js +2 -2
@@ -153,12 +153,27 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
153
153
  });
154
154
  const inputRef = React.useRef(null);
155
155
  const displayRef = React.useRef(null);
156
+ const paperRef = React.useRef(null);
157
+ const didPointerDownRef = React.useRef(false);
156
158
  const [displayNode, setDisplayNode] = React.useState(null);
157
159
  const {
158
160
  current: isOpenControlled
159
161
  } = React.useRef(openProp != null);
160
162
  const [menuMinWidthState, setMenuMinWidthState] = React.useState();
163
+ const open = displayNode !== null && openState;
164
+ const ownerState = {
165
+ ...props,
166
+ variant,
167
+ value,
168
+ open,
169
+ error
170
+ };
171
+ const paperProps = {
172
+ ...MenuProps.PaperProps,
173
+ ...(typeof MenuProps.slotProps?.paper === 'function' ? MenuProps.slotProps.paper(ownerState) : MenuProps.slotProps?.paper)
174
+ };
161
175
  const handleRef = useForkRef(ref, inputRefProp);
176
+ const handlePaperRef = useForkRef(paperProps.ref, paperRef);
162
177
  const handleDisplayRef = React.useCallback(node => {
163
178
  displayRef.current = node;
164
179
  if (node) {
@@ -208,8 +223,8 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
208
223
  }
209
224
  return undefined;
210
225
  }, [labelId]);
211
- const update = (open, event) => {
212
- if (open) {
226
+ const update = (openParam, event) => {
227
+ if (openParam) {
213
228
  if (onOpen) {
214
229
  onOpen(event);
215
230
  }
@@ -218,7 +233,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
218
233
  }
219
234
  if (!isOpenControlled) {
220
235
  setMenuMinWidthState(autoWidth ? null : anchorElement.clientWidth);
221
- setOpenState(open);
236
+ setOpenState(openParam);
222
237
  }
223
238
  };
224
239
  const handleMouseDown = event => {
@@ -229,6 +244,31 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
229
244
  // Hijack the default focus behavior.
230
245
  event.preventDefault();
231
246
  displayRef.current.focus();
247
+ const doc = ownerDocument(event.currentTarget);
248
+ function handleMouseUp(mouseEvent) {
249
+ if (!displayRef.current) {
250
+ return;
251
+ }
252
+
253
+ // mouse is over the options/menuitem, don't close the menu
254
+ if (paperRef.current.contains(mouseEvent.target)) {
255
+ return;
256
+ }
257
+ const triggerElement = displayRef.current.getBoundingClientRect();
258
+
259
+ // mouse is inside the trigger, don't close the menu
260
+ if (mouseEvent.clientX >= triggerElement.left && mouseEvent.clientX <= triggerElement.right && mouseEvent.clientY >= triggerElement.top && mouseEvent.clientY <= triggerElement.bottom) {
261
+ return;
262
+ }
263
+
264
+ // close the menu
265
+ update(false, mouseEvent);
266
+ }
267
+
268
+ // `{ once: true }` to automatically remove the listener, see https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener#once
269
+ doc.addEventListener('mouseup', handleMouseUp, {
270
+ once: true
271
+ });
232
272
  update(true, event);
233
273
  };
234
274
  const handleClose = event => {
@@ -247,7 +287,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
247
287
  onChange(event, child);
248
288
  }
249
289
  };
250
- const handleItemClick = child => event => {
290
+ const handleItemSelect = child => event => {
251
291
  let newValue;
252
292
 
253
293
  // We use the tabindex attribute to signal the available options.
@@ -265,9 +305,6 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
265
305
  } else {
266
306
  newValue = child.props.value;
267
307
  }
268
- if (child.props.onClick) {
269
- child.props.onClick(event);
270
- }
271
308
  if (value !== newValue) {
272
309
  setValueState(newValue);
273
310
  if (onChange) {
@@ -303,7 +340,6 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
303
340
  }
304
341
  }
305
342
  };
306
- const open = displayNode !== null && openState;
307
343
  const handleBlur = event => {
308
344
  // if open event.stopImmediatePropagation
309
345
  if (!open && onBlur) {
@@ -364,7 +400,26 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
364
400
  }
365
401
  return /*#__PURE__*/React.cloneElement(child, {
366
402
  'aria-selected': selected ? 'true' : 'false',
367
- onClick: handleItemClick(child),
403
+ onPointerDown: () => {
404
+ didPointerDownRef.current = true;
405
+ },
406
+ onClick: event => {
407
+ didPointerDownRef.current = false;
408
+ if (child.props.onClick) {
409
+ child.props.onClick(event);
410
+ }
411
+ handleItemSelect(child)(event);
412
+ },
413
+ onMouseUp: event => {
414
+ if (didPointerDownRef.current) {
415
+ didPointerDownRef.current = false;
416
+ return;
417
+ }
418
+ if (child.props.onMouseUp) {
419
+ child.props.onMouseUp(event);
420
+ }
421
+ handleItemSelect(child)(event);
422
+ },
368
423
  onKeyUp: event => {
369
424
  if (event.key === ' ') {
370
425
  // otherwise our MenuItems dispatches a click event
@@ -423,21 +478,10 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
423
478
  tabIndex = disabled ? null : 0;
424
479
  }
425
480
  const buttonId = SelectDisplayProps.id || (name ? `mui-component-select-${name}` : undefined);
426
- const ownerState = {
427
- ...props,
428
- variant,
429
- value,
430
- open,
431
- error
432
- };
433
481
  const classes = useUtilityClasses(ownerState);
434
- const paperProps = {
435
- ...MenuProps.PaperProps,
436
- ...MenuProps.slotProps?.paper
437
- };
438
482
  const listProps = {
439
483
  ...MenuProps.MenuListProps,
440
- ...MenuProps.slotProps?.list
484
+ ...(typeof MenuProps.slotProps?.list === 'function' ? MenuProps.slotProps.list(ownerState) : MenuProps.slotProps?.list)
441
485
  };
442
486
  const listboxId = useId();
443
487
  return /*#__PURE__*/_jsxs(React.Fragment, {
@@ -515,6 +559,7 @@ const SelectInput = /*#__PURE__*/React.forwardRef(function SelectInput(props, re
515
559
  },
516
560
  paper: {
517
561
  ...paperProps,
562
+ ref: handlePaperRef,
518
563
  style: {
519
564
  minWidth: menuMinWidth,
520
565
  ...(paperProps != null ? paperProps.style : null)
@@ -4,7 +4,7 @@ import * as React from 'react';
4
4
  import clsx from 'clsx';
5
5
  import PropTypes from 'prop-types';
6
6
  import composeClasses from '@mui/utils/composeClasses';
7
- import { alpha, unstable_getUnit as getUnit, unstable_toUnitless as toUnitless } from "../styles/index.js";
7
+ import { unstable_getUnit as getUnit, unstable_toUnitless as toUnitless } from "../styles/index.js";
8
8
  import { keyframes, css, styled } from "../zero-styled/index.js";
9
9
  import memoTheme from "../utils/memoTheme.js";
10
10
  import { useDefaultProps } from "../DefaultPropsProvider/index.js";
@@ -80,7 +80,7 @@ const SkeletonRoot = styled('span', {
80
80
  return {
81
81
  display: 'block',
82
82
  // Create a "on paper" color with sufficient contrast retaining the color
83
- backgroundColor: theme.vars ? theme.vars.palette.Skeleton.bg : alpha(theme.palette.text.primary, theme.palette.mode === 'light' ? 0.11 : 0.13),
83
+ backgroundColor: theme.vars ? theme.vars.palette.Skeleton.bg : theme.alpha(theme.palette.text.primary, theme.palette.mode === 'light' ? 0.11 : 0.13),
84
84
  height: '1.2em',
85
85
  variants: [{
86
86
  props: {
@@ -5,7 +5,6 @@ import PropTypes from 'prop-types';
5
5
  import clsx from 'clsx';
6
6
  import chainPropTypes from '@mui/utils/chainPropTypes';
7
7
  import composeClasses from '@mui/utils/composeClasses';
8
- import { alpha, lighten, darken } from '@mui/system/colorManipulator';
9
8
  import { useRtl } from '@mui/system/RtlProvider';
10
9
  import useSlotProps from '@mui/utils/useSlotProps';
11
10
  import { useSlider, valueToPercent } from "./useSlider.js";
@@ -219,13 +218,13 @@ export const SliderTrack = styled('span', {
219
218
  backgroundColor: theme.vars.palette.Slider[`${color}Track`],
220
219
  borderColor: theme.vars.palette.Slider[`${color}Track`]
221
220
  } : {
222
- backgroundColor: lighten(theme.palette[color].main, 0.62),
223
- borderColor: lighten(theme.palette[color].main, 0.62),
221
+ backgroundColor: theme.lighten(theme.palette[color].main, 0.62),
222
+ borderColor: theme.lighten(theme.palette[color].main, 0.62),
224
223
  ...theme.applyStyles('dark', {
225
- backgroundColor: darken(theme.palette[color].main, 0.5)
224
+ backgroundColor: theme.darken(theme.palette[color].main, 0.5)
226
225
  }),
227
226
  ...theme.applyStyles('dark', {
228
- borderColor: darken(theme.palette[color].main, 0.5)
227
+ borderColor: theme.darken(theme.palette[color].main, 0.5)
229
228
  })
230
229
  })
231
230
  }
@@ -314,21 +313,13 @@ export const SliderThumb = styled('span', {
314
313
  },
315
314
  style: {
316
315
  [`&:hover, &.${sliderClasses.focusVisible}`]: {
317
- ...(theme.vars ? {
318
- boxShadow: `0px 0px 0px 8px rgba(${theme.vars.palette[color].mainChannel} / 0.16)`
319
- } : {
320
- boxShadow: `0px 0px 0px 8px ${alpha(theme.palette[color].main, 0.16)}`
321
- }),
316
+ boxShadow: `0px 0px 0px 8px ${theme.alpha((theme.vars || theme).palette[color].main, 0.16)}`,
322
317
  '@media (hover: none)': {
323
318
  boxShadow: 'none'
324
319
  }
325
320
  },
326
321
  [`&.${sliderClasses.active}`]: {
327
- ...(theme.vars ? {
328
- boxShadow: `0px 0px 0px 14px rgba(${theme.vars.palette[color].mainChannel} / 0.16)`
329
- } : {
330
- boxShadow: `0px 0px 0px 14px ${alpha(theme.palette[color].main, 0.16)}`
331
- })
322
+ boxShadow: `0px 0px 0px 14px ${theme.alpha((theme.vars || theme).palette[color].main, 0.16)}`
332
323
  }
333
324
  }
334
325
  }))]
@@ -373,14 +373,8 @@ process.env.NODE_ENV !== "production" ? Snackbar.propTypes /* remove-proptypes *
373
373
  * The props used for each slot inside.
374
374
  * @default {}
375
375
  */
376
- slotProps: PropTypes.shape({
377
- clickAwayListener: PropTypes.oneOfType([PropTypes.func, PropTypes.shape({
378
- children: PropTypes.element.isRequired,
379
- disableReactTree: PropTypes.bool,
380
- mouseEvent: PropTypes.oneOf(['onClick', 'onMouseDown', 'onMouseUp', 'onPointerDown', 'onPointerUp', false]),
381
- onClickAway: PropTypes.func,
382
- touchEvent: PropTypes.oneOf(['onTouchEnd', 'onTouchStart', false])
383
- })]),
376
+ slotProps: PropTypes /* @typescript-to-proptypes-ignore */.shape({
377
+ clickAwayListener: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
384
378
  content: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
385
379
  root: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
386
380
  transition: PropTypes.oneOfType([PropTypes.func, PropTypes.object])
@@ -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.0
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
  /**