@graphcommerce/next-ui 10.0.0-canary.67 → 10.0.0-canary.72

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 (103) hide show
  1. package/ActionCard/ActionCard.tsx +30 -21
  2. package/ActionCard/ActionCardAccordion.tsx +2 -2
  3. package/ActionCard/ActionCardLayout.tsx +4 -3
  4. package/ActionCard/ActionCardList.tsx +13 -6
  5. package/Blog/BlogAuthor/BlogAuthor.tsx +9 -7
  6. package/Blog/BlogContent/BlogContent.tsx +7 -4
  7. package/Blog/BlogHeader/BlogHeader.tsx +7 -4
  8. package/Blog/BlogList/BlogList.tsx +4 -3
  9. package/Blog/BlogListItem/BlogListItem.tsx +6 -5
  10. package/Blog/BlogTags/BlogTag.tsx +2 -4
  11. package/Blog/BlogTitle/BlogTitle.tsx +2 -6
  12. package/Breadcrumbs/Breadcrumbs.tsx +24 -38
  13. package/Breadcrumbs/BreadcrumbsList.tsx +9 -9
  14. package/Button/Button.tsx +4 -4
  15. package/Button/LinkOrButton.tsx +8 -7
  16. package/CHANGELOG.md +26 -0
  17. package/ChipMenu/ChipMenu.tsx +5 -5
  18. package/Container/Container.tsx +4 -4
  19. package/Fab/Fab.tsx +1 -1
  20. package/Footer/Footer.tsx +5 -5
  21. package/Form/Form.tsx +6 -6
  22. package/Form/FormDivider.tsx +1 -1
  23. package/Form/InputCheckmark.tsx +2 -1
  24. package/FramerScroller/SidebarGallery.tsx +43 -34
  25. package/FullPageMessage/FullPageMessage.tsx +13 -4
  26. package/IconHeader/IconHeader.tsx +22 -8
  27. package/IconSvg/IconSvg.tsx +1 -1
  28. package/Layout/components/LayoutHeader.tsx +7 -6
  29. package/Layout/components/LayoutHeaderBack.tsx +0 -2
  30. package/Layout/components/LayoutHeaderContent.tsx +22 -18
  31. package/Layout/components/LayoutTitle.tsx +4 -3
  32. package/LayoutDefault/components/LayoutDefault.tsx +5 -4
  33. package/LayoutOverlay/components/LayoutOverlayHeader.tsx +4 -3
  34. package/LayoutOverlay/components/LayoutOverlayHeader2.tsx +3 -9
  35. package/LayoutParts/DesktopHeaderBadge.tsx +4 -3
  36. package/LayoutParts/DesktopNavBar.tsx +10 -11
  37. package/LayoutParts/DesktopNavBarItem.tsx +22 -16
  38. package/LayoutParts/GlobalHead.tsx +1 -1
  39. package/LayoutParts/Logo.tsx +2 -1
  40. package/LayoutParts/MenuFab.tsx +36 -14
  41. package/LayoutParts/MenuFabItem.tsx +2 -1
  42. package/LayoutParts/MenuFabSecondaryItem.tsx +6 -3
  43. package/LayoutParts/PlaceholderFab.tsx +2 -1
  44. package/LayoutParts/StickyBelowHeader.tsx +4 -3
  45. package/MediaQuery/MediaQuery.tsx +2 -4
  46. package/Navigation/components/NavigationFab.tsx +31 -11
  47. package/Navigation/components/NavigationItem.tsx +14 -10
  48. package/Navigation/components/NavigationOverlay.tsx +39 -20
  49. package/Overlay/components/Overlay.tsx +10 -3
  50. package/Overlay/components/OverlayBase.tsx +21 -23
  51. package/Overlay/components/OverlayContainer.tsx +40 -14
  52. package/Overlay/components/OverlayHeader.tsx +2 -1
  53. package/Overlay/components/OverlayStickyBottom.tsx +2 -5
  54. package/OverlayOrPopperChip/OverlayOrPopperChip.tsx +35 -31
  55. package/OverlayOrPopperChip/OverlayPanel.tsx +4 -5
  56. package/OverlayOrPopperChip/OverlayPanelActions.tsx +2 -1
  57. package/OverlayOrPopperChip/PopperPanelActions.tsx +2 -1
  58. package/Page/types.ts +1 -4
  59. package/Pagination/Pagination.tsx +9 -6
  60. package/Pagination/PaginationExtended.tsx +4 -3
  61. package/RenderType/RenderType.tsx +8 -5
  62. package/Row/ButtonLinkList/ButtonLinkList.tsx +14 -15
  63. package/Row/ButtonLinkList/ButtonLinkListItem.tsx +1 -1
  64. package/Row/ColumnThree/ColumnThree.tsx +4 -3
  65. package/Row/ColumnTwo/ColumnTwo.tsx +16 -5
  66. package/Row/ColumnTwoSpread/ColumnTwoSpread.tsx +15 -4
  67. package/Row/ColumnTwoWithTop/ColumnTwoWithTop.tsx +22 -6
  68. package/Row/ContentLinks/ContentLinks.tsx +4 -3
  69. package/Row/HeroBanner/HeroBanner.tsx +3 -7
  70. package/Row/IconBlocks/IconBlock.tsx +4 -3
  71. package/Row/IconBlocks/IconBlocks.tsx +2 -1
  72. package/Row/ImageText/ImageText.tsx +5 -5
  73. package/Row/ImageTextBoxed/ImageTextBoxed.tsx +2 -2
  74. package/Row/ParagraphWithSidebarSlide/ParagraphWithSidebarSlide.tsx +1 -1
  75. package/Row/RowLinks/variant/VariantImageLabelSwiper.tsx +4 -3
  76. package/Row/RowLinks/variant/VariantInline.tsx +2 -4
  77. package/Row/RowLinks/variant/VariantLogoSwiper.tsx +4 -3
  78. package/Row/RowLinks/variant/VariantUsps.tsx +4 -3
  79. package/Row/SpecialBanner/SpecialBanner.tsx +2 -2
  80. package/SectionContainer/SectionContainer.tsx +6 -5
  81. package/SectionHeader/SectionHeader.tsx +4 -3
  82. package/Separator/Separator.tsx +4 -3
  83. package/SkipLink/SkipLink.tsx +2 -2
  84. package/Snackbar/MessageSnackbarImpl.tsx +22 -10
  85. package/StarRatingField/StarRatingField.tsx +1 -1
  86. package/Stepper/Stepper.tsx +6 -5
  87. package/Styles/withTheme.tsx +11 -9
  88. package/Tabs/TabItem.tsx +4 -5
  89. package/TextInputNumber/TextInputNumber.tsx +76 -50
  90. package/Theme/DarkLightModeThemeProvider.tsx +41 -88
  91. package/Theme/MuiButton.ts +23 -22
  92. package/Theme/MuiChip.ts +12 -13
  93. package/Theme/MuiFab.ts +5 -5
  94. package/Theme/MuiSlider.ts +5 -5
  95. package/Theme/createTheme.ts +1 -3
  96. package/Theme/themeDefaults.ts +1 -1
  97. package/ToggleButton/ToggleButton.tsx +10 -11
  98. package/ToggleButtonGroup/ToggleButtonGroup.tsx +4 -3
  99. package/UspList/UspList.tsx +4 -3
  100. package/UspList/UspListItem.tsx +4 -3
  101. package/package.json +15 -15
  102. package/types.ts +1 -0
  103. package/utils/sxx.ts +1 -1
@@ -1,6 +1,7 @@
1
+ import { sxx } from '@graphcommerce/next-ui'
1
2
  import { t } from '@lingui/core/macro'
2
3
  import type { SnackbarProps, SxProps, Theme } from '@mui/material'
3
- import { Box, Fab, lighten, Portal, Snackbar, SnackbarContent } from '@mui/material'
4
+ import { Box, Fab, Portal, Snackbar, SnackbarContent } from '@mui/material'
4
5
  import React, { useEffect, useState } from 'react'
5
6
  import { iconCheckmark, iconClose, iconSadFace } from '../icons'
6
7
  import iconInfo from '../icons/info.svg'
@@ -108,13 +109,13 @@ export default function MessageSnackbarImpl(props: MessageSnackbarProps) {
108
109
  open={showSnackbar}
109
110
  autoHideDuration={autoHide ? 5000 : null}
110
111
  className={classes.root}
111
- sx={[
112
+ sx={sxx(
112
113
  {
113
114
  pointerEvents: 'none',
114
115
  '& > *': { pointerEvents: 'auto' },
115
116
  },
116
- ...(Array.isArray(sx) ? sx : [sx]),
117
- ]}
117
+ sx,
118
+ )}
118
119
  onClose={hideSnackbar}
119
120
  >
120
121
  <SnackbarContent
@@ -122,8 +123,8 @@ export default function MessageSnackbarImpl(props: MessageSnackbarProps) {
122
123
  className={classes.content}
123
124
  sx={(theme) => ({
124
125
  '&.variantPill': {
125
- backgroundColor: theme.palette.background.paper,
126
- color: theme.palette.text.primary,
126
+ backgroundColor: theme.vars.palette.background.paper,
127
+ color: theme.vars.palette.text.primary,
127
128
  [theme.breakpoints.up('md')]: {
128
129
  ...breakpointVal(
129
130
  'borderRadius',
@@ -154,7 +155,6 @@ export default function MessageSnackbarImpl(props: MessageSnackbarProps) {
154
155
  gridArea: 'children',
155
156
  },
156
157
  },
157
-
158
158
  '&.disableIcon .MuiSnackbarContent-message': {
159
159
  gridTemplate: {
160
160
  xs: `"children close"
@@ -180,10 +180,22 @@ export default function MessageSnackbarImpl(props: MessageSnackbarProps) {
180
180
  message={
181
181
  <>
182
182
  {!disableIcon && <IconSvg src={icon2} size='large' />}
183
- <Box gridArea='children'>{children}</Box>
183
+ <Box
184
+ sx={{
185
+ gridArea: 'children',
186
+ }}
187
+ >
188
+ {children}
189
+ </Box>
184
190
  {/* </Box> */}
185
191
  {action && (
186
- <Box className={classes.actionButton} onClick={hideSnackbar} gridArea='action'>
192
+ <Box
193
+ className={classes.actionButton}
194
+ onClick={hideSnackbar}
195
+ sx={{
196
+ gridArea: 'action',
197
+ }}
198
+ >
187
199
  {action}
188
200
  </Box>
189
201
  )}
@@ -196,7 +208,7 @@ export default function MessageSnackbarImpl(props: MessageSnackbarProps) {
196
208
  onMouseDown={preventAnimationBubble}
197
209
  onTouchStart={preventAnimationBubble}
198
210
  sx={(theme) => ({
199
- backgroundColor: lighten(theme.palette.background.paper, 0.1),
211
+ backgroundColor: theme.lighten(theme.vars.palette.background.paper, 0.1),
200
212
  })}
201
213
  >
202
214
  <IconSvg src={iconClose} />
@@ -27,7 +27,7 @@ export function StarRatingField(props: StarRatingFieldProps) {
27
27
  src={iconStar}
28
28
  size='large'
29
29
  className={classes.starFull}
30
- sx={(theme) => ({ fill: theme.palette.divider, stroke: 'none', margin: '0 3px' })}
30
+ sx={(theme) => ({ fill: theme.vars.palette.divider, stroke: 'none', margin: '0 3px' })}
31
31
  />
32
32
  }
33
33
  icon={
@@ -1,3 +1,4 @@
1
+ import { sxx } from '@graphcommerce/next-ui'
1
2
  import type { SxProps, Theme } from '@mui/material'
2
3
  import { Box } from '@mui/material'
3
4
  import { extendableComponent } from '../Styles'
@@ -18,19 +19,19 @@ export function Stepper(props: StepperProps) {
18
19
  return (
19
20
  <Box
20
21
  className={classes.root}
21
- sx={[
22
+ sx={sxx(
22
23
  (theme) => ({
23
24
  marginTop: '-2px',
24
25
  display: 'grid',
25
26
  gridAutoFlow: 'column',
26
27
  gap: theme.spacings.xxs,
27
28
  }),
28
- ...(Array.isArray(sx) ? sx : [sx]),
29
- ]}
29
+ sx,
30
+ )}
30
31
  >
31
32
  {[...Array(steps).keys()].map((step: number) => (
32
33
  <Box
33
- sx={[
34
+ sx={sxx(
34
35
  {
35
36
  height: 2,
36
37
  bgcolor: 'divider',
@@ -38,7 +39,7 @@ export function Stepper(props: StepperProps) {
38
39
  currentStep - 1 >= step && {
39
40
  bgcolor: 'secondary.main',
40
41
  },
41
- ]}
42
+ )}
42
43
  className={`${classes.step} ${currentStep - 1 >= step ? classes.activeStep : ''}`}
43
44
  key={step}
44
45
  />
@@ -1,3 +1,4 @@
1
+ import { sxx } from '@graphcommerce/next-ui'
1
2
  import type { SxProps, Theme } from '@mui/material'
2
3
  import { ThemeProvider } from '@mui/material'
3
4
  import React from 'react'
@@ -43,21 +44,22 @@ export function withTheme<T>(
43
44
  Component: (value: T & WithSx) => React.ReactElement<any, any> | null,
44
45
  theme: Theme,
45
46
  ): React.FC<T & WithSx> {
46
- return (data: T & WithSx) => {
47
+ // eslint-disable-next-line react/function-component-definition
48
+ return function WithTheme(data: T & WithSx) {
47
49
  const { sx = [] } = data
48
50
  return (
49
51
  <ThemeProvider theme={theme}>
50
- <Component
51
- {...data}
52
- sx={[
52
+ {React.createElement(Component, {
53
+ ...data,
54
+ sx: sxx(
53
55
  {
54
56
  typography: 'body1',
55
- color: theme.palette.text.primary,
56
- backgroundColor: theme.palette.background.default,
57
+ color: theme.vars.palette.text.primary,
58
+ backgroundColor: theme.vars.palette.background.default,
57
59
  },
58
- ...(Array.isArray(sx) ? sx : [sx]),
59
- ]}
60
- />
60
+ sx,
61
+ ),
62
+ })}
61
63
  </ThemeProvider>
62
64
  )
63
65
  }
package/Tabs/TabItem.tsx CHANGED
@@ -1,5 +1,5 @@
1
1
  import { Box, ButtonBase, type SxProps, type Theme } from '@mui/material'
2
- import { alpha, useTheme } from '@mui/material/styles'
2
+ import { useTheme } from '@mui/material/styles'
3
3
  import { forwardRef } from 'react'
4
4
  import { extendableComponent } from '../Styles/extendableComponent'
5
5
  import { responsiveVal } from '../Styles/responsiveVal'
@@ -46,7 +46,7 @@ export const TabItem = forwardRef<HTMLButtonElement, TabItemProps>((props, ref)
46
46
  sx,
47
47
  disableRipple = true,
48
48
  className,
49
- color = (theme) => theme.palette.background.default,
49
+ color = (theme) => theme.vars.palette.background.default,
50
50
  variant = 'chrome',
51
51
  ...other
52
52
  } = props
@@ -74,12 +74,11 @@ export const TabItem = forwardRef<HTMLButtonElement, TabItemProps>((props, ref)
74
74
  pb: spacing,
75
75
  mx: `calc(${spacing} / 2)`,
76
76
  transition: 'background-color 0.2s ease-in-out',
77
-
78
77
  '&:hover:not(.selected) .TabItem-content': {
79
- bgcolor: alpha(color(theme), 0.5),
78
+ bgcolor: theme.alpha(color(theme), 0.5),
80
79
  },
81
80
  '&:focus:not(.selected) .TabItem-content': {
82
- bgcolor: alpha(color(theme), 0.5),
81
+ bgcolor: theme.alpha(color(theme), 0.5),
83
82
  },
84
83
  '&::before': {
85
84
  opacity: 0,
@@ -1,3 +1,4 @@
1
+ import { sxx } from '@graphcommerce/next-ui'
1
2
  import { t } from '@lingui/core/macro'
2
3
  import type { IconButtonProps, SxProps, TextFieldProps, Theme } from '@mui/material'
3
4
  import {
@@ -95,7 +96,7 @@ export function TextInputNumber(props: TextInputNumberProps) {
95
96
  variant={variant}
96
97
  inputRef={forkRef}
97
98
  className={`${textFieldProps.className ?? ''} ${classes.quantity}`}
98
- sx={[
99
+ sx={sxx(
99
100
  {
100
101
  width: responsiveVal(90, 120),
101
102
  },
@@ -117,61 +118,86 @@ export function TextInputNumber(props: TextInputNumberProps) {
117
118
  display: 'none',
118
119
  },
119
120
  },
120
- ...(Array.isArray(sx) ? sx : [sx]),
121
- ]}
121
+ sx,
122
+ )}
122
123
  autoComplete='off'
123
- InputProps={{
124
- ...textFieldProps.InputProps,
125
- startAdornment: (
126
- <Box>
127
- <Fab
128
- aria-label={t`Decrease`}
129
- size='smaller'
130
- sx={{ boxShadow: variant === 'standard' ? 4 : 0, minHeight: '30px' }}
131
- onPointerDown={() => setDirection('down')}
132
- onPointerUp={stop}
133
- tabIndex={-1}
134
- {...DownProps}
135
- className={`${classes.button} ${DownProps.className ?? ''}`}
136
- >
137
- {DownProps.children ?? <IconSvg src={iconMin} size='small' />}
138
- </Fab>
139
- </Box>
140
- ),
141
- endAdornment: (
142
- <Box>
143
- <Fab
144
- aria-label={t`Increase`}
145
- size='smaller'
146
- sx={{ boxShadow: variant === 'standard' ? 4 : 0, minHeight: '30px' }}
147
- onPointerDown={() => setDirection('up')}
148
- onPointerUp={() => setDirection(null)}
149
- tabIndex={-1}
150
- {...UpProps}
151
- className={`${classes.button} ${UpProps.className ?? ''}`}
152
- >
153
- {UpProps.children ?? <IconSvg src={iconPlus} size='small' />}
154
- </Fab>
155
- </Box>
156
- ),
157
- }}
158
124
  onChange={(e: ChangeEvent<HTMLInputElement>) => {
159
125
  if (textFieldProps.onChange) textFieldProps.onChange(e)
160
126
  updateDisabled(e.target)
161
127
  }}
162
- inputProps={{
163
- 'aria-label': t`Number`,
164
- ...inputProps,
165
- sx: [
166
- {
167
- typography: 'body1',
168
- textAlign: 'center',
169
- '&::-webkit-inner-spin-button,&::-webkit-outer-spin-button': {
170
- appearance: 'none',
128
+ slotProps={{
129
+ input: {
130
+ ...textFieldProps.InputProps,
131
+ startAdornment: (
132
+ <Box>
133
+ <Fab
134
+ aria-label={t`Decrease`}
135
+ size='smaller'
136
+ sx={sxx(
137
+ {
138
+ minHeight: '30px',
139
+ },
140
+ variant === 'standard'
141
+ ? {
142
+ boxShadow: 4,
143
+ }
144
+ : {
145
+ boxShadow: 0,
146
+ },
147
+ )}
148
+ onPointerDown={() => setDirection('down')}
149
+ onPointerUp={stop}
150
+ tabIndex={-1}
151
+ {...DownProps}
152
+ className={`${classes.button} ${DownProps.className ?? ''}`}
153
+ >
154
+ {DownProps.children ?? <IconSvg src={iconMin} size='small' />}
155
+ </Fab>
156
+ </Box>
157
+ ),
158
+ endAdornment: (
159
+ <Box>
160
+ <Fab
161
+ aria-label={t`Increase`}
162
+ size='smaller'
163
+ sx={sxx(
164
+ {
165
+ minHeight: '30px',
166
+ },
167
+ variant === 'standard'
168
+ ? {
169
+ boxShadow: 4,
170
+ }
171
+ : {
172
+ boxShadow: 0,
173
+ },
174
+ )}
175
+ onPointerDown={() => setDirection('up')}
176
+ onPointerUp={() => setDirection(null)}
177
+ tabIndex={-1}
178
+ {...UpProps}
179
+ className={`${classes.button} ${UpProps.className ?? ''}`}
180
+ >
181
+ {UpProps.children ?? <IconSvg src={iconPlus} size='small' />}
182
+ </Fab>
183
+ </Box>
184
+ ),
185
+ },
186
+
187
+ htmlInput: {
188
+ 'aria-label': t`Number`,
189
+ ...inputProps,
190
+ sx: [
191
+ {
192
+ typography: 'body1',
193
+ textAlign: 'center',
194
+ '&::-webkit-inner-spin-button,&::-webkit-outer-spin-button': {
195
+ appearance: 'none',
196
+ },
171
197
  },
172
- },
173
- ],
174
- className: `${inputProps?.className ?? ''} ${classes.quantityInput}`,
198
+ ],
199
+ className: `${inputProps?.className ?? ''} ${classes.quantityInput}`,
200
+ },
175
201
  }}
176
202
  />
177
203
  )
@@ -1,100 +1,41 @@
1
1
  import { Trans } from '@lingui/react/macro'
2
- import type { FabProps, ListItemButtonProps, Theme } from '@mui/material'
3
- import {
4
- Fab,
5
- ListItemButton,
6
- ListItemIcon,
7
- ListItemText,
8
- ThemeProvider, // eslint-disable-next-line @typescript-eslint/no-restricted-imports
9
- useMediaQuery,
10
- } from '@mui/material'
11
- import { useRouter } from 'next/router'
12
- import { createContext, useContext, useEffect, useMemo, useState } from 'react'
2
+ import type { FabProps, ListItemButtonProps } from '@mui/material'
3
+ import { Fab, ListItemButton, ListItemIcon, ListItemText } from '@mui/material'
4
+ import { useColorScheme } from '@mui/material/styles'
13
5
  import { iconMoon, iconSun } from '../icons'
14
6
  import { IconSvg } from '../IconSvg'
15
- import { getCssFlag, setCssFlag } from '../utils/cssFlags'
16
7
 
17
8
  type Mode = 'dark' | 'light'
18
- type UserMode = 'auto' | Mode
19
-
20
- type ColorModeContext = {
21
- userMode: UserMode
22
- browserMode: Mode
23
- currentMode: Mode
24
- isSingleMode: boolean
25
- toggle: () => void
26
- }
27
-
28
- /** @public */
29
- export const colorModeContext = createContext(undefined as unknown as ColorModeContext)
30
- colorModeContext.displayName = 'ColorModeContext'
31
-
32
- export type ThemeProviderProps = {
33
- children: React.ReactNode
34
- ssrMode?: Mode
35
- listenToBrowser?: boolean
36
- } & (
37
- | { light: Theme; dark?: undefined }
38
- | { light?: undefined; dark: Theme }
39
- | { light: Theme; dark: Theme }
40
- )
41
9
 
42
10
  /**
43
- * Wrapper around `import { ThemeProvider } from '@mui/material'`
11
+ * Hook to get and set the color mode. Uses MUI's useColorScheme() when CSS variables are enabled.
44
12
  *
45
- * The multi DarkLightModeThemeProvider allows switching between light and dark mode based on URL
46
- * and on user input.
13
+ * @public
47
14
  */
48
- export function DarkLightModeThemeProvider(props: ThemeProviderProps) {
49
- const { children, light, dark, ssrMode = 'light', listenToBrowser = true } = props
50
- const [configuredMode, setConfiguredMode] = useState<UserMode>(listenToBrowser ? 'auto' : ssrMode)
51
- const setThemeMode = (mode: UserMode) => {
52
- setConfiguredMode(mode)
53
- setCssFlag('color-scheme', mode)
15
+ export function useColorMode() {
16
+ const colorScheme = useColorScheme()
17
+
18
+ if (!colorScheme.mode) {
19
+ // CSS variables not enabled, return safe defaults
20
+ return {
21
+ userMode: 'light' as const,
22
+ browserMode: 'light' as Mode,
23
+ currentMode: 'light' as Mode,
24
+ isSingleMode: true,
25
+ toggle: () => {},
26
+ }
54
27
  }
55
28
 
56
- const browserMode: Mode = useMediaQuery('(prefers-color-scheme: dark)') ? 'dark' : 'light'
29
+ const { mode, setMode, systemMode } = colorScheme
30
+ const currentMode: Mode = mode === 'system' ? (systemMode ?? 'light') : mode
57
31
 
58
- // If the user has set a mode, use that. Otherwise, use the browser mode.
59
- const currentMode = configuredMode === 'auto' ? browserMode : configuredMode
60
-
61
- let theme: Theme = light || dark // Default
62
- if (light && currentMode === 'light') theme = light
63
- else if (dark) theme = dark
64
-
65
- useEffect(() => {
66
- const flag = getCssFlag('color-scheme') as Mode
67
- if (flag) setConfiguredMode(flag)
68
- }, [setConfiguredMode])
69
-
70
- // If a URL parameter is present, switch from auto to light or dark mode
71
- const { asPath } = useRouter()
72
- useEffect(() => {
73
- if (asPath.includes('darkmode')) setConfiguredMode('dark')
74
- }, [asPath])
75
-
76
- // Create the context
77
- const colorContext: ColorModeContext = useMemo(
78
- () => ({
79
- browserMode,
80
- userMode: configuredMode,
81
- currentMode,
82
- isSingleMode: !light || !dark,
83
- toggle: () => setThemeMode(currentMode === 'light' ? 'dark' : 'light'),
84
- }),
85
- [browserMode, configuredMode, currentMode, light, dark],
86
- )
87
-
88
- return (
89
- <colorModeContext.Provider value={colorContext}>
90
- <ThemeProvider theme={theme}>{children}</ThemeProvider>
91
- </colorModeContext.Provider>
92
- )
93
- }
94
-
95
- /** @public */
96
- export function useColorMode() {
97
- return useContext(colorModeContext)
32
+ return {
33
+ userMode: mode,
34
+ browserMode: (systemMode ?? 'light') as Mode,
35
+ currentMode,
36
+ isSingleMode: false,
37
+ toggle: () => setMode(currentMode === 'light' ? 'dark' : 'light'),
38
+ }
98
39
  }
99
40
 
100
41
  /** @public */
@@ -115,8 +56,6 @@ export function DarkLightModeToggleFab(props: Omit<FabProps, 'onClick'>) {
115
56
  /**
116
57
  * A button that switches between light and dark mode
117
58
  *
118
- * To disable this functionality
119
- *
120
59
  * @public
121
60
  */
122
61
  export function DarkLightModeMenuSecondaryItem(props: ListItemButtonProps) {
@@ -128,7 +67,7 @@ export function DarkLightModeMenuSecondaryItem(props: ListItemButtonProps) {
128
67
  }
129
68
 
130
69
  return (
131
- <ListItemButton {...props} sx={[{}, ...(Array.isArray(sx) ? sx : [sx])]} dense onClick={toggle}>
70
+ <ListItemButton {...props} sx={sx} dense onClick={toggle}>
132
71
  <ListItemIcon sx={{ minWidth: 'unset', paddingRight: '8px' }}>
133
72
  <IconSvg src={currentMode === 'light' ? iconMoon : iconSun} size='medium' />
134
73
  </ListItemIcon>
@@ -138,3 +77,17 @@ export function DarkLightModeMenuSecondaryItem(props: ListItemButtonProps) {
138
77
  </ListItemButton>
139
78
  )
140
79
  }
80
+
81
+ /**
82
+ * @deprecated Use ThemeProvider from @mui/material with cssVariables enabled instead. The
83
+ * dark/light mode toggle now uses MUI's built-in useColorScheme() hook.
84
+ */
85
+ export function DarkLightModeThemeProvider({ children }: { children: React.ReactNode }) {
86
+ console.warn(
87
+ 'DarkLightModeThemeProvider is deprecated. Use ThemeProvider from @mui/material with cssVariables enabled instead.',
88
+ )
89
+ return children
90
+ }
91
+
92
+ /** @deprecated No longer needed, context is provided by MUI's ThemeProvider with cssVariables */
93
+ export const colorModeContext = null
@@ -1,8 +1,7 @@
1
1
  import type { ComponentsVariants, Theme } from '@mui/material'
2
- import { alpha, darken, lighten } from '@mui/material'
3
2
  import { responsiveVal } from '../Styles/responsiveVal'
4
3
 
5
- declare module '@mui/material/Button/Button' {
4
+ declare module '@mui/material/Button' {
6
5
  interface ButtonPropsVariantOverrides {
7
6
  pill: true
8
7
  inline: true
@@ -25,7 +24,7 @@ export const MuiButtonResponsive: ButtonVariants = [
25
24
  ...theme.typography.body2,
26
25
  padding: `${responsiveVal(3, 5)} ${responsiveVal(8, 15)}`,
27
26
  '&.MuiLoadingButton-loading:hover': {
28
- backgroundColor: theme.palette.action.disabledBackground,
27
+ backgroundColor: theme.vars.palette.action.disabledBackground,
29
28
  },
30
29
  '& .MuiLoadingButton-loadingIndicatorEnd': { right: responsiveVal(9, 15) },
31
30
  '& .MuiLoadingButton-loadingIndicatorStart': { left: responsiveVal(9, 15) },
@@ -37,7 +36,7 @@ export const MuiButtonResponsive: ButtonVariants = [
37
36
  ...theme.typography.body1,
38
37
  padding: `${responsiveVal(7, 9)} ${responsiveVal(15, 22)}`,
39
38
  '&.MuiLoadingButton-loading:hover': {
40
- backgroundColor: theme.palette.action.disabledBackground,
39
+ backgroundColor: theme.vars.palette.action.disabledBackground,
41
40
  },
42
41
  '& .MuiLoadingButton-loadingIndicatorEnd': { right: responsiveVal(16, 24) },
43
42
  '& .MuiLoadingButton-loadingIndicatorStart': { left: responsiveVal(16, 24) },
@@ -50,7 +49,7 @@ export const MuiButtonResponsive: ButtonVariants = [
50
49
  fontWeight: theme.typography.fontWeightBold,
51
50
  padding: `${responsiveVal(10, 15)} ${responsiveVal(28, 58)}`,
52
51
  '&.MuiLoadingButton-loading:hover': {
53
- backgroundColor: theme.palette.action.disabledBackground,
52
+ backgroundColor: theme.vars.palette.action.disabledBackground,
54
53
  },
55
54
  '& .MuiLoadingButton-loadingIndicatorEnd': { right: responsiveVal(30, 60) },
56
55
  '& .MuiLoadingButton-loadingIndicatorStart': { left: responsiveVal(30, 60) },
@@ -112,36 +111,36 @@ export const MuiButtonPill: ButtonVariants = [
112
111
  {
113
112
  props: { variant: 'pill', color: 'primary' },
114
113
  style: ({ theme }) => ({
115
- backgroundColor: theme.palette.primary.main,
116
- color: theme.palette.primary.contrastText,
117
- '&:hover:not(.Mui-disabled)': { backgroundColor: theme.palette.primary.dark },
114
+ backgroundColor: theme.vars.palette.primary.main,
115
+ color: theme.vars.palette.primary.contrastText,
116
+ '&:hover:not(.Mui-disabled)': { backgroundColor: theme.vars.palette.primary.dark },
118
117
  }),
119
118
  },
120
119
  {
121
120
  props: { variant: 'pill', color: 'secondary' },
122
121
  style: ({ theme }) => ({
123
- backgroundColor: theme.palette.secondary.main,
124
- color: theme.palette.secondary.contrastText,
125
- '&:hover:not(.Mui-disabled)': { backgroundColor: theme.palette.secondary.dark },
122
+ backgroundColor: theme.vars.palette.secondary.main,
123
+ color: theme.vars.palette.secondary.contrastText,
124
+ '&:hover:not(.Mui-disabled)': { backgroundColor: theme.vars.palette.secondary.dark },
126
125
  }),
127
126
  },
128
127
  {
129
128
  props: { variant: 'pill', color: 'inherit' },
130
129
  style: ({ theme }) => ({
131
- backgroundColor: theme.palette.background.paper,
130
+ backgroundColor: theme.vars.palette.background.paper,
132
131
  '&:hover:not(.Mui-disabled)': {
133
- backgroundColor:
134
- theme.palette.mode === 'light'
135
- ? darken(theme.palette.background.default, 0.05)
136
- : lighten(theme.palette.background.default, 0.2),
132
+ backgroundColor: theme.darken(theme.vars.palette.background.default, 0.05),
133
+ ...theme.applyStyles('dark', {
134
+ backgroundColor: theme.lighten(theme.vars.palette.background.default, 0.2),
135
+ }),
137
136
  },
138
137
  }),
139
138
  },
140
139
  {
141
140
  props: { variant: 'pill', disabled: true },
142
141
  style: ({ theme }) => ({
143
- backgroundColor: theme.palette.action.disabledBackground,
144
- color: theme.palette.action.disabled,
142
+ backgroundColor: theme.vars.palette.action.disabledBackground,
143
+ color: theme.vars.palette.action.disabled,
145
144
  }),
146
145
  },
147
146
  ]
@@ -150,16 +149,18 @@ export const MuiButtonInline: ButtonVariants = [
150
149
  {
151
150
  props: { variant: 'inline', color: 'primary' },
152
151
  style: ({ theme }) => ({
153
- color: theme.palette.primary.main,
154
- '&:hover:not(.Mui-disabled)': { backgroundColor: alpha(theme.palette.primary.main, 0.19) },
152
+ color: theme.vars.palette.primary.main,
153
+ '&:hover:not(.Mui-disabled)': {
154
+ backgroundColor: theme.alpha(theme.vars.palette.primary.main, 0.19),
155
+ },
155
156
  }),
156
157
  },
157
158
  {
158
159
  props: { variant: 'inline', color: 'secondary' },
159
160
  style: ({ theme }) => ({
160
- color: theme.palette.secondary.main,
161
+ color: theme.vars.palette.secondary.main,
161
162
  '&:hover:not(.Mui-disabled)': {
162
- backgroundColor: theme.palette.secondary.light,
163
+ backgroundColor: theme.vars.palette.secondary.light,
163
164
  },
164
165
  }),
165
166
  },
package/Theme/MuiChip.ts CHANGED
@@ -1,8 +1,7 @@
1
1
  import type { ComponentsVariants, Theme } from '@mui/material'
2
- import { darken } from '@mui/material'
3
2
  import { responsiveVal } from '../Styles'
4
3
 
5
- declare module '@mui/material/Chip/Chip' {
4
+ declare module '@mui/material/Chip' {
6
5
  interface ChipPropsSizeOverrides {
7
6
  responsive: true
8
7
  }
@@ -54,36 +53,36 @@ export const MuiChip: ChipVariants = [
54
53
  {
55
54
  props: { variant: 'outlined' },
56
55
  style: ({ theme }) => ({
57
- borderColor: theme.palette.divider,
58
- backgroundColor: theme.palette.background.default,
56
+ borderColor: theme.vars.palette.divider,
57
+ backgroundColor: theme.vars.palette.background.default,
59
58
  '&:active': {
60
59
  boxShadow: 'none',
61
60
  },
62
61
  '& .MuiChip-deleteIcon': {
63
- color: theme.palette.text.primary,
62
+ color: theme.vars.palette.text.primary,
64
63
  },
65
64
  '&.MuiChip-clickable:hover': {
66
- backgroundColor: darken(theme.palette.background.default, 0.05),
65
+ backgroundColor: theme.darken(theme.vars.palette.background.default, 0.05),
67
66
  },
68
67
  '& .MuiChip-deleteIcon:hover': {
69
- color: theme.palette.text.primary,
68
+ color: theme.vars.palette.text.primary,
70
69
  },
71
70
  }),
72
71
  },
73
72
  {
74
73
  props: { color: 'primary' },
75
74
  style: ({ theme }) => ({
76
- borderColor: theme.palette.text.primary,
77
- color: theme.palette.text.primary,
75
+ borderColor: theme.vars.palette.text.primary,
76
+ color: theme.vars.palette.text.primary,
78
77
  '&:hover': {
79
- background: `${theme.palette.background.default} !important`,
80
- borderColor: `${theme.palette.divider} !important`,
78
+ background: `${theme.vars.palette.background.default} !important`,
79
+ borderColor: `${theme.vars.palette.divider} !important`,
81
80
  },
82
81
  '&:focus': {
83
- background: `${theme.palette.background.paper} !important`,
82
+ background: `${theme.vars.palette.background.paper} !important`,
84
83
  },
85
84
  '& .MuiChip-deleteIcon:hover': {
86
- color: theme.palette.text.primary,
85
+ color: theme.vars.palette.text.primary,
87
86
  },
88
87
  }),
89
88
  },