@sanity/ui 2.9.0-canary.6 → 2.9.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 (84) hide show
  1. package/dist/_chunks-cjs/getTheme_v2.js +26 -0
  2. package/dist/_chunks-cjs/getTheme_v2.js.map +1 -1
  3. package/dist/_chunks-es/getTheme_v2.mjs +26 -0
  4. package/dist/_chunks-es/getTheme_v2.mjs.map +1 -1
  5. package/dist/_legacy/getTheme_v2.esm.js +26 -0
  6. package/dist/_legacy/getTheme_v2.esm.js.map +1 -1
  7. package/dist/index.esm.js +652 -1048
  8. package/dist/index.esm.js.map +1 -1
  9. package/dist/index.js +651 -1047
  10. package/dist/index.js.map +1 -1
  11. package/dist/index.mjs +652 -1048
  12. package/dist/index.mjs.map +1 -1
  13. package/dist/theme.d.mts +22 -28
  14. package/dist/theme.d.ts +22 -28
  15. package/dist/theme.esm.js +124 -260
  16. package/dist/theme.esm.js.map +1 -1
  17. package/dist/theme.js +124 -260
  18. package/dist/theme.js.map +1 -1
  19. package/dist/theme.mjs +124 -260
  20. package/dist/theme.mjs.map +1 -1
  21. package/package.json +60 -53
  22. package/src/core/__workshop__/constants.ts +27 -31
  23. package/src/core/components/autocomplete/autocomplete.tsx +31 -42
  24. package/src/core/components/breadcrumbs/breadcrumbs.tsx +47 -35
  25. package/src/core/components/dialog/dialog.tsx +1 -1
  26. package/src/core/components/menu/__workshop__/tones.tsx +5 -6
  27. package/src/core/components/menu/useMenuController.ts +21 -18
  28. package/src/core/components/toast/__workshop__/hook.tsx +1 -1
  29. package/src/core/components/toast/toast.tsx +2 -2
  30. package/src/core/components/tree/treeItem.tsx +15 -18
  31. package/src/core/hooks/useElementRect/__workshop__/example.tsx +2 -2
  32. package/src/core/hooks/useMatchMedia.ts +22 -12
  33. package/src/core/primitives/badge/__workshop__/tones.tsx +6 -13
  34. package/src/core/primitives/button/__workshop__/custom.tsx +4 -3
  35. package/src/core/primitives/card/__workshop__/allTones.tsx +6 -8
  36. package/src/core/primitives/card/__workshop__/asButton.tsx +42 -24
  37. package/src/core/primitives/card/__workshop__/asComponent.tsx +1 -1
  38. package/src/core/primitives/card/__workshop__/checkered.tsx +17 -7
  39. package/src/core/primitives/card/__workshop__/interactive.tsx +10 -3
  40. package/src/core/primitives/card/__workshop__/listNavigation.tsx +5 -3
  41. package/src/core/primitives/card/__workshop__/props.tsx +7 -5
  42. package/src/core/primitives/card/__workshop__/selected.tsx +4 -1
  43. package/src/core/primitives/checkbox/__workshop__/tones.tsx +6 -0
  44. package/src/core/primitives/code/__workshop__/props.tsx +1 -1
  45. package/src/core/primitives/container/__workshop__/example.tsx +1 -1
  46. package/src/core/primitives/flex/__workshop__/example.tsx +3 -3
  47. package/src/core/primitives/grid/__workshop__/responsive.tsx +12 -12
  48. package/src/core/primitives/heading/__workshop__/opticalAlignment.tsx +13 -25
  49. package/src/core/primitives/inline/__workshop__/plain.tsx +3 -3
  50. package/src/core/primitives/label/__workshop__/opticalAlignment.tsx +6 -6
  51. package/src/core/primitives/popover/__workshop__/AlignedStory.tsx +1 -1
  52. package/src/core/primitives/popover/__workshop__/MatchReferenceWidthStory.tsx +3 -3
  53. package/src/core/primitives/popover/__workshop__/OpenOnMountStory.tsx +1 -1
  54. package/src/core/primitives/popover/__workshop__/PlainStory.tsx +1 -1
  55. package/src/core/primitives/popover/popover.tsx +140 -74
  56. package/src/core/primitives/popover/popoverCard.tsx +4 -1
  57. package/src/core/primitives/radio/__workshop__/plain.tsx +2 -2
  58. package/src/core/primitives/select/__workshop__/readOnly.tsx +1 -1
  59. package/src/core/primitives/text/__workshop__/example.tsx +6 -6
  60. package/src/core/primitives/text/__workshop__/opticalAlignment.tsx +11 -21
  61. package/src/core/primitives/textArea/__workshop__/plain.tsx +1 -1
  62. package/src/core/primitives/textInput/__workshop__/index.ts +0 -5
  63. package/src/core/primitives/textInput/__workshop__/plain.tsx +1 -2
  64. package/src/core/primitives/textInput/__workshop__/readOnly.tsx +6 -2
  65. package/src/core/primitives/textInput/__workshop__/tones.tsx +38 -0
  66. package/src/core/primitives/tooltip/tooltip.tsx +17 -47
  67. package/src/core/styles/card/_cardColorStyle.ts +8 -0
  68. package/src/core/theme/__workshop__/debug/story.tsx +18 -11
  69. package/src/core/utils/portal/portalProvider.tsx +5 -5
  70. package/src/theme/build/_deprecated/color/factory.ts +1 -1
  71. package/src/theme/build/_deprecated/color/muted/createMuted.ts +2 -2
  72. package/src/theme/build/buildColorTheme.ts +47 -37
  73. package/src/theme/build/renderColorTheme.ts +26 -30
  74. package/src/theme/build/resolveColorTokens.ts +51 -115
  75. package/src/theme/config/tokens/color/types.ts +4 -18
  76. package/src/theme/defaults/colorTokens.ts +8 -5
  77. package/src/theme/getScopedTheme.ts +9 -2
  78. package/src/theme/system/color/_constants.ts +6 -2
  79. package/src/theme/system/color/badge.ts +3 -7
  80. package/src/theme/system/v0/color/_system.ts +8 -4
  81. package/src/theme/system/v0/color/color.ts +3 -2
  82. package/src/theme/versioning/themeColor_v0_v2.ts +26 -0
  83. package/src/theme/versioning/v0_v2.ts +4 -0
  84. package/src/core/primitives/textInput/__workshop__/multipleTones.tsx +0 -20
@@ -1,4 +1,4 @@
1
- import {Card, Container, Text} from '@sanity/ui'
1
+ import {Container, Flex, Text} from '@sanity/ui'
2
2
  import {useBoolean, useSelect, useText} from '@sanity/ui-workshop'
3
3
  import {
4
4
  WORKSHOP_TEXT_ALIGN_OPTIONS,
@@ -11,7 +11,7 @@ export default function TextStory() {
11
11
  const accent = useBoolean('Accent', false, 'Props')
12
12
  const align = useSelect('Align', WORKSHOP_TEXT_ALIGN_OPTIONS, '', 'Props') || undefined
13
13
  const muted = useBoolean('Muted', false, 'Props')
14
- const size = useSelect('Size', WORKSHOP_TEXT_SIZE_OPTIONS, 2, 'Props')
14
+ const size = useSelect('Size', WORKSHOP_TEXT_SIZE_OPTIONS, 1, 'Props')
15
15
  const text = useText('Text', 'Hello, world', 'Props')
16
16
 
17
17
  const textOverflow =
@@ -20,8 +20,8 @@ export default function TextStory() {
20
20
  const weight = useSelect('Weight', WORKSHOP_TEXT_WEIGHT_OPTIONS, '', 'Props') || undefined
21
21
 
22
22
  return (
23
- <Container width={0}>
24
- <Card padding={4}>
23
+ <Flex align="center" height="fill" justify="center" padding={4} sizing="border">
24
+ <Container width={0}>
25
25
  <Text
26
26
  accent={accent}
27
27
  align={align}
@@ -32,7 +32,7 @@ export default function TextStory() {
32
32
  >
33
33
  {text}
34
34
  </Text>
35
- </Card>
36
- </Container>
35
+ </Container>
36
+ </Flex>
37
37
  )
38
38
  }
@@ -6,47 +6,37 @@ export default function OpticalAlignment() {
6
6
  <Box padding={[4, 5, 6]}>
7
7
  <Stack space={1}>
8
8
  <Flex>
9
- <Card padding={0} scheme="dark">
10
- <Text accent size={4}>
11
- Hamburgefonstiv M
12
- </Text>
9
+ <Card padding={0} tone="neutral">
10
+ <Text size={4}>Hamburgefonstiv M</Text>
13
11
  </Card>
14
12
  </Flex>
15
13
 
16
14
  <Flex>
17
- <Card padding={0} scheme="dark">
18
- <Text accent size={3}>
19
- Hamburgefonstiv M
20
- </Text>
15
+ <Card padding={0} tone="neutral">
16
+ <Text size={3}>Hamburgefonstiv M</Text>
21
17
  </Card>
22
18
  </Flex>
23
19
 
24
20
  <Flex>
25
- <Card padding={0} scheme="dark">
26
- <Text accent size={2}>
27
- Hamburgefonstiv M
28
- </Text>
21
+ <Card padding={0} tone="neutral">
22
+ <Text size={2}>Hamburgefonstiv M</Text>
29
23
  </Card>
30
24
  </Flex>
31
25
 
32
26
  <Flex>
33
- <Card padding={0} scheme="dark">
34
- <Text accent size={1}>
35
- Hamburgefonstiv M
36
- </Text>
27
+ <Card padding={0} tone="neutral">
28
+ <Text size={1}>Hamburgefonstiv M</Text>
37
29
  </Card>
38
30
  </Flex>
39
31
 
40
32
  <Flex>
41
- <Card padding={0} scheme="dark">
42
- <Text accent size={0}>
43
- Hamburgefonstiv M
44
- </Text>
33
+ <Card padding={0} tone="neutral">
34
+ <Text size={0}>Hamburgefonstiv M</Text>
45
35
  </Card>
46
36
  </Flex>
47
37
 
48
38
  <Flex>
49
- <Card padding={2} scheme="dark">
39
+ <Card padding={2} tone="neutral">
50
40
  <Text>
51
41
  <AddCircleIcon />
52
42
  </Text>
@@ -17,7 +17,7 @@ export default function PlainStory() {
17
17
  const fontSize = useSelect('Font size', WORKSHOP_TEXT_FONT_SIZE_OPTIONS, 2, 'Props')
18
18
  const padding = useSelect('Padding', WORKSHOP_SPACE_OPTIONS, 3, 'Props')
19
19
  const placeholder = useText('Placeholder', '', 'Props') || undefined
20
- const radius = useSelect('Radius', WORKSHOP_RADIUS_OPTIONS, 0, 'Props')
20
+ const radius = useSelect('Radius', WORKSHOP_RADIUS_OPTIONS, 2, 'Props')
21
21
  const readOnly = useBoolean('Read only', false, 'Props')
22
22
  const weight = useSelect('Weight', WORKSHOP_FONT_WEIGHT_OPTIONS, undefined, 'Props')
23
23
 
@@ -35,11 +35,6 @@ export default defineScope({
35
35
  title: 'Read only',
36
36
  component: lazy(() => import('./readOnly')),
37
37
  },
38
- {
39
- name: 'multiple-tones',
40
- title: 'Multiple tones',
41
- component: lazy(() => import('./multipleTones')),
42
- },
43
38
  {
44
39
  name: 'states',
45
40
  title: 'States',
@@ -57,7 +57,7 @@ function TextInputTest(props: {inputRef: React.Ref<HTMLInputElement>}) {
57
57
  const iconRight = useSelect(
58
58
  'Icon (right)',
59
59
  WORKSHOP_ICON_SYMBOL_OPTIONS,
60
- 'close',
60
+ 'cube',
61
61
  'Props',
62
62
  ) as IconSymbol
63
63
  const padding = useSelect('Padding', WORKSHOP_SPACE_OPTIONS, 3, 'Props')
@@ -83,7 +83,6 @@ function TextInputTest(props: {inputRef: React.Ref<HTMLInputElement>}) {
83
83
  icon={icon && icons[icon]}
84
84
  iconRight={iconRight && icons[iconRight]}
85
85
  id="text-input-example"
86
- name="email"
87
86
  onChange={handleChange}
88
87
  padding={padding}
89
88
  placeholder={placeholder}
@@ -1,5 +1,9 @@
1
- import {TextInput} from '@sanity/ui'
1
+ import {Flex, TextInput} from '@sanity/ui'
2
2
 
3
3
  export default function ReadOnlyStory() {
4
- return <TextInput id="text-input-example" readOnly />
4
+ return (
5
+ <Flex padding={4}>
6
+ <TextInput id="text-input-example" readOnly />
7
+ </Flex>
8
+ )
5
9
  }
@@ -3,7 +3,9 @@ import {useBoolean} from '@sanity/ui-workshop'
3
3
 
4
4
  export default function TonesStory() {
5
5
  const transparentTone = useBoolean('Transparent', true)
6
+ const neutralTone = useBoolean('Neutral', true)
6
7
  const primaryTone = useBoolean('Primary', true)
8
+ const suggestTone = useBoolean('Suggest', true)
7
9
  const positiveTone = useBoolean('Positive', true)
8
10
  const cautionTone = useBoolean('Caution', true)
9
11
  const criticalTone = useBoolean('Critical', true)
@@ -49,6 +51,24 @@ export default function TonesStory() {
49
51
  </Card>
50
52
  )}
51
53
 
54
+ {neutralTone && (
55
+ <Card padding={3} tone="neutral">
56
+ <TextInput
57
+ placeholder="neutral"
58
+ prefix={
59
+ <Box padding={3}>
60
+ <Text>prefix</Text>
61
+ </Box>
62
+ }
63
+ suffix={
64
+ <Box padding={3}>
65
+ <Text>suffix</Text>
66
+ </Box>
67
+ }
68
+ />
69
+ </Card>
70
+ )}
71
+
52
72
  {primaryTone && (
53
73
  <Card padding={3} tone="primary">
54
74
  <TextInput
@@ -67,6 +87,24 @@ export default function TonesStory() {
67
87
  </Card>
68
88
  )}
69
89
 
90
+ {suggestTone && (
91
+ <Card padding={3} tone="suggest">
92
+ <TextInput
93
+ placeholder="suggest"
94
+ prefix={
95
+ <Box padding={3}>
96
+ <Text>prefix</Text>
97
+ </Box>
98
+ }
99
+ suffix={
100
+ <Box padding={3}>
101
+ <Text>suffix</Text>
102
+ </Box>
103
+ }
104
+ />
105
+ </Card>
106
+ )}
107
+
70
108
  {positiveTone && (
71
109
  <Card padding={3} tone="positive">
72
110
  <TextInput
@@ -97,31 +97,28 @@ export const Tooltip = forwardRef(function Tooltip(
97
97
  const {
98
98
  animate: _animate = false,
99
99
  arrow: arrowProp = false,
100
- boundaryElement: _boundaryElement,
100
+ boundaryElement = boundaryElementContext?.element,
101
101
  children: childProp,
102
102
  content,
103
103
  disabled,
104
- fallbackPlacements: _fallbackPlacementsProp,
104
+ fallbackPlacements: fallbackPlacementsProp = props.fallbackPlacements ??
105
+ DEFAULT_FALLBACK_PLACEMENTS[props.placement ?? 'bottom'],
105
106
  padding = 2,
106
107
  placement: placementProp = 'bottom',
107
108
  portal: portalProp,
108
109
  radius = 2,
109
110
  scheme,
110
111
  shadow = 2,
111
- zOffset: _zOffset,
112
+ zOffset = layer.tooltip.zOffset,
112
113
  delay,
113
114
  ...restProps
114
115
  } = props
115
- const boundaryElement = _boundaryElement ?? boundaryElementContext?.element
116
- const fallbackPlacementsProp =
117
- _fallbackPlacementsProp ?? DEFAULT_FALLBACK_PLACEMENTS[props.placement ?? 'bottom']
118
- const zOffset = _zOffset ?? layer.tooltip.zOffset
119
116
  const prefersReducedMotion = usePrefersReducedMotion()
120
117
  const animate = prefersReducedMotion ? false : _animate
121
118
  const fallbackPlacements = useArrayProp(fallbackPlacementsProp)
122
119
  const ref = useRef<HTMLDivElement | null>(null)
123
120
  const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null)
124
- const [arrowElement, setArrowElement] = useState<HTMLDivElement | null>(null)
121
+ const arrowRef = useRef<HTMLDivElement | null>(null)
125
122
  const rootBoundary: RootBoundary = 'viewport'
126
123
  const [tooltipMaxWidth, setTooltipMaxWidth] = useState(0)
127
124
 
@@ -158,7 +155,7 @@ export const Tooltip = forwardRef(function Tooltip(
158
155
 
159
156
  // Place arrow
160
157
  if (arrowProp) {
161
- ret.push(arrow({element: arrowElement, padding: DEFAULT_TOOLTIP_PADDING}))
158
+ ret.push(arrow({element: arrowRef, padding: DEFAULT_TOOLTIP_PADDING}))
162
159
  }
163
160
 
164
161
  // Determine the origin to scale from.
@@ -168,7 +165,7 @@ export const Tooltip = forwardRef(function Tooltip(
168
165
  }
169
166
 
170
167
  return ret
171
- }, [animate, arrowElement, arrowProp, boundaryElement, fallbackPlacements])
168
+ }, [animate, arrowProp, boundaryElement, fallbackPlacements])
172
169
 
173
170
  const {floatingStyles, placement, middlewareData, refs, update} = useFloating({
174
171
  middleware,
@@ -226,42 +223,42 @@ export const Tooltip = forwardRef(function Tooltip(
226
223
  handleIsOpenChange(false)
227
224
  childProp?.props?.onBlur?.(e)
228
225
  },
229
- [childProp, handleIsOpenChange],
226
+ [childProp?.props, handleIsOpenChange],
230
227
  )
231
228
  const handleClick = useCallback(
232
229
  (e: MouseEvent) => {
233
230
  handleIsOpenChange(false, true)
234
231
  childProp?.props.onClick?.(e)
235
232
  },
236
- [childProp, handleIsOpenChange],
233
+ [childProp?.props, handleIsOpenChange],
237
234
  )
238
235
  const handleContextMenu = useCallback(
239
236
  (e: MouseEvent) => {
240
237
  handleIsOpenChange(false, true)
241
238
  childProp?.props.onContextMenu?.(e)
242
239
  },
243
- [childProp, handleIsOpenChange],
240
+ [childProp?.props, handleIsOpenChange],
244
241
  )
245
242
  const handleFocus = useCallback(
246
243
  (e: FocusEvent) => {
247
244
  handleIsOpenChange(true)
248
245
  childProp?.props?.onFocus?.(e)
249
246
  },
250
- [childProp, handleIsOpenChange],
247
+ [childProp?.props, handleIsOpenChange],
251
248
  )
252
249
  const handleMouseEnter = useCallback(
253
250
  (e: MouseEvent) => {
254
251
  handleIsOpenChange(true)
255
252
  childProp?.props?.onMouseEnter?.(e)
256
253
  },
257
- [childProp, handleIsOpenChange],
254
+ [childProp?.props, handleIsOpenChange],
258
255
  )
259
256
  const handleMouseLeave = useCallback(
260
257
  (e: MouseEvent) => {
261
258
  handleIsOpenChange(false)
262
259
  childProp?.props?.onMouseLeave?.(e)
263
260
  },
264
- [childProp, handleIsOpenChange],
261
+ [childProp?.props, handleIsOpenChange],
265
262
  )
266
263
 
267
264
  // Handle closing the tooltip when the mouse leaves the referenceElement
@@ -312,7 +309,7 @@ export const Tooltip = forwardRef(function Tooltip(
312
309
 
313
310
  const setArrow = useCallback(
314
311
  (arrowEl: HTMLDivElement | null) => {
315
- setArrowElement(arrowEl)
312
+ arrowRef.current = arrowEl
316
313
  update()
317
314
  },
318
315
  [update],
@@ -327,9 +324,9 @@ export const Tooltip = forwardRef(function Tooltip(
327
324
  )
328
325
 
329
326
  const childRef = useRef<HTMLElement | null>(null)
330
- const [childElement, setChildElement] = useState<HTMLElement | null>(null)
331
327
 
332
- useImperativeHandle(getElementRef(childProp as any), () => childElement, [childElement])
328
+ // Merge refs so that any ref we are overriding is called as well
329
+ useImperativeHandle((childProp as any)?.ref, () => childRef.current)
333
330
 
334
331
  const child = useMemo(() => {
335
332
  if (!childProp) return null
@@ -341,7 +338,7 @@ export const Tooltip = forwardRef(function Tooltip(
341
338
  onMouseLeave: handleMouseLeave,
342
339
  onClick: handleClick,
343
340
  onContextMenu: handleContextMenu,
344
- ref: setChildElement,
341
+ ref: childRef,
345
342
  })
346
343
  }, [
347
344
  childProp,
@@ -465,30 +462,3 @@ function useCloseOnMouseLeave({
465
462
  return () => window.removeEventListener('mousemove', handleMouseMove)
466
463
  }, [onMouseMove, showTooltip])
467
464
  }
468
-
469
- // Before React 19 accessing `element.props.ref` will throw a warning and suggest using `element.ref`
470
- // After React 19 accessing `element.ref` does the opposite.
471
- // https://github.com/facebook/react/pull/28348
472
- //
473
- // Access the ref using the method that doesn't yield a warning.
474
- function getElementRef(element?: React.ReactElement) {
475
- if (!element) return null
476
- // React <=18 in DEV
477
- let getter = Object.getOwnPropertyDescriptor(element.props, 'ref')?.get
478
- let mayWarn = getter && 'isReactWarning' in getter && getter.isReactWarning
479
-
480
- if (mayWarn) {
481
- return (element as any).ref
482
- }
483
-
484
- // React 19 in DEV
485
- getter = Object.getOwnPropertyDescriptor(element, 'ref')?.get
486
- mayWarn = getter && 'isReactWarning' in getter && getter.isReactWarning
487
-
488
- if (mayWarn) {
489
- return element.props.ref
490
- }
491
-
492
- // Not DEV
493
- return element.props.ref || (element as any).ref
494
- }
@@ -55,10 +55,18 @@ export function _cardColorStyle(
55
55
  '--card-badge-default-dot-color': color.badge.default.dot,
56
56
  '--card-badge-default-fg-color': color.badge.default.fg,
57
57
  '--card-badge-default-icon-color': color.badge.default.icon,
58
+ '--card-badge-neutral-bg-color': color.badge.neutral.bg,
59
+ '--card-badge-neutral-dot-color': color.badge.neutral.dot,
60
+ '--card-badge-neutral-fg-color': color.badge.neutral.fg,
61
+ '--card-badge-neutral-icon-color': color.badge.neutral.icon,
58
62
  '--card-badge-primary-bg-color': color.badge.primary.bg,
59
63
  '--card-badge-primary-dot-color': color.badge.primary.dot,
60
64
  '--card-badge-primary-fg-color': color.badge.primary.fg,
61
65
  '--card-badge-primary-icon-color': color.badge.primary.icon,
66
+ '--card-badge-suggest-bg-color': color.badge.suggest.bg,
67
+ '--card-badge-suggest-dot-color': color.badge.suggest.dot,
68
+ '--card-badge-suggest-fg-color': color.badge.suggest.fg,
69
+ '--card-badge-suggest-icon-color': color.badge.suggest.icon,
62
70
  '--card-badge-positive-bg-color': color.badge.positive.bg,
63
71
  '--card-badge-positive-dot-color': color.badge.positive.dot,
64
72
  '--card-badge-positive-fg-color': color.badge.positive.fg,
@@ -12,7 +12,7 @@ import {
12
12
  ThemeColorState_v2,
13
13
  } from '@sanity/ui/theme'
14
14
  import {useBoolean, useSelect} from '@sanity/ui-workshop'
15
- import {CSSProperties, useMemo} from 'react'
15
+ import {CSSProperties} from 'react'
16
16
  import {Badge, Box, Flex, KBD, Stack, Text} from '../../../primitives'
17
17
  import {useRootTheme} from '../../useRootTheme'
18
18
 
@@ -50,16 +50,13 @@ export default function DebugStory() {
50
50
  const button = useBoolean('Button', false, 'Props') || false
51
51
  const selectable = useBoolean('Selectable', false, 'Props') || false
52
52
 
53
- const features: Features = useMemo(
54
- () => ({
55
- base,
56
- button,
57
- schemes: scheme == 'all' ? ['light', 'dark'] : [scheme],
58
- selectable,
59
- tones: tone == 'all' ? ['transparent', 'default'] : [tone],
60
- }),
61
- [base, button, scheme, selectable, tone],
62
- )
53
+ const features: Features = {
54
+ base,
55
+ button,
56
+ schemes: scheme == 'all' ? ['light', 'dark'] : [scheme],
57
+ selectable,
58
+ tones: tone == 'all' ? ['transparent', 'default'] : [tone],
59
+ }
63
60
 
64
61
  return (
65
62
  <Flex>
@@ -352,11 +349,21 @@ function getStateVars(state: ThemeColorState_v2) {
352
349
  '--card-badge-default-fg-color': state.badge.default.fg,
353
350
  '--card-badge-default-icon-color': state.badge.default.icon,
354
351
 
352
+ '--card-badge-neutral-bg-color': state.badge.neutral.bg,
353
+ '--card-badge-neutral-dot-color': state.badge.neutral.dot,
354
+ '--card-badge-neutral-fg-color': state.badge.neutral.fg,
355
+ '--card-badge-neutral-icon-color': state.badge.neutral.icon,
356
+
355
357
  '--card-badge-primary-bg-color': state.badge.primary.bg,
356
358
  '--card-badge-primary-dot-color': state.badge.primary.dot,
357
359
  '--card-badge-primary-fg-color': state.badge.primary.fg,
358
360
  '--card-badge-primary-icon-color': state.badge.primary.icon,
359
361
 
362
+ '--card-badge-suggest-bg-color': state.badge.suggest.bg,
363
+ '--card-badge-suggest-dot-color': state.badge.suggest.dot,
364
+ '--card-badge-suggest-fg-color': state.badge.suggest.fg,
365
+ '--card-badge-suggest-icon-color': state.badge.suggest.icon,
366
+
360
367
  '--card-badge-positive-bg-color': state.badge.positive.bg,
361
368
  '--card-badge-positive-dot-color': state.badge.positive.dot,
362
369
  '--card-badge-positive-fg-color': state.badge.positive.fg,
@@ -1,4 +1,4 @@
1
- import {useMemo, useState, useSyncExternalStore} from 'react'
1
+ import {useMemo, useRef, useSyncExternalStore} from 'react'
2
2
  import {PortalContext} from './portalContext'
3
3
  import {PortalContextValue} from './types'
4
4
 
@@ -51,13 +51,13 @@ const emptySubscribe = () => () => {}
51
51
  * equality comparison (eg by identity), and only goes one level deep.
52
52
  */
53
53
  function useUnique<ValueType extends Comparable = Comparable>(value: ValueType): ValueType {
54
- const [cachedValue, setCachedValue] = useState(value)
54
+ const valueRef = useRef<ValueType>(value)
55
55
 
56
- if (!_isEqual(cachedValue, value)) {
57
- setCachedValue(value)
56
+ if (!_isEqual(valueRef.current, value)) {
57
+ valueRef.current = value
58
58
  }
59
59
 
60
- return cachedValue
60
+ return valueRef.current
61
61
  }
62
62
 
63
63
  function _isEqual(objA: Comparable, objB: Comparable): boolean {
@@ -34,7 +34,7 @@ export interface ThemeColorBuilderOpts {
34
34
  solid: (opts: {
35
35
  base: ThemeColorBase
36
36
  dark: boolean
37
- tone: ThemeColorToneKey
37
+ tone: ThemeColorName
38
38
  name: ThemeColorName
39
39
  state: 'enabled' | 'disabled' | 'hovered' | 'pressed' | 'selected'
40
40
  }) => ThemeColorGenericState
@@ -1,11 +1,11 @@
1
- import {ThemeColorBase, ThemeColorCardToneKey, ThemeColorMuted} from '../../../../system'
1
+ import {ThemeColorBase, ThemeColorMuted, ThemeColorName} from '../../../../system'
2
2
  import {ThemeColorBuilderOpts} from '../factory'
3
3
 
4
4
  export function createMutedTones(
5
5
  opts: ThemeColorBuilderOpts,
6
6
  base: ThemeColorBase,
7
7
  dark: boolean,
8
- name: ThemeColorCardToneKey,
8
+ name: ThemeColorName,
9
9
  ): ThemeColorMuted {
10
10
  return {
11
11
  default: {