@sanity/ui 2.9.0-canary.6 → 2.10.0-corel.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 (75) hide show
  1. package/dist/_chunks-cjs/getTheme_v2.js +54 -84
  2. package/dist/_chunks-cjs/getTheme_v2.js.map +1 -1
  3. package/dist/_chunks-es/getTheme_v2.mjs +54 -84
  4. package/dist/_chunks-es/getTheme_v2.mjs.map +1 -1
  5. package/dist/_legacy/getTheme_v2.esm.js +54 -84
  6. package/dist/_legacy/getTheme_v2.esm.js.map +1 -1
  7. package/dist/index.d.mts +21 -14
  8. package/dist/index.d.ts +21 -14
  9. package/dist/index.esm.js +3150 -3805
  10. package/dist/index.esm.js.map +1 -1
  11. package/dist/index.js +3148 -3802
  12. package/dist/index.js.map +1 -1
  13. package/dist/index.mjs +3150 -3805
  14. package/dist/index.mjs.map +1 -1
  15. package/dist/theme.d.mts +22 -28
  16. package/dist/theme.d.ts +22 -28
  17. package/dist/theme.esm.js +630 -1318
  18. package/dist/theme.esm.js.map +1 -1
  19. package/dist/theme.js +630 -1318
  20. package/dist/theme.js.map +1 -1
  21. package/dist/theme.mjs +630 -1318
  22. package/dist/theme.mjs.map +1 -1
  23. package/package.json +1 -2
  24. package/src/core/__workshop__/constants.ts +13 -13
  25. package/src/core/components/autocomplete/autocomplete.tsx +31 -42
  26. package/src/core/components/breadcrumbs/__workshop__/buttons.tsx +58 -0
  27. package/src/core/components/breadcrumbs/__workshop__/example.tsx +3 -1
  28. package/src/core/components/breadcrumbs/__workshop__/index.ts +5 -0
  29. package/src/core/components/breadcrumbs/breadcrumbs.styles.ts +1 -13
  30. package/src/core/components/breadcrumbs/breadcrumbs.tsx +70 -50
  31. package/src/core/components/dialog/dialog.tsx +3 -5
  32. package/src/core/components/menu/menu.tsx +11 -15
  33. package/src/core/components/menu/menuButton.tsx +36 -14
  34. package/src/core/components/menu/menuGroup.tsx +1 -2
  35. package/src/core/components/menu/menuItem.tsx +2 -4
  36. package/src/core/components/menu/useMenuController.ts +21 -18
  37. package/src/core/components/tab/tabList.tsx +11 -3
  38. package/src/core/components/toast/toastProvider.tsx +6 -5
  39. package/src/core/components/tree/treeItem.tsx +15 -18
  40. package/src/core/constants.ts +1 -1
  41. package/src/core/hooks/useArrayProp.ts +9 -14
  42. package/src/core/hooks/useMatchMedia.ts +22 -12
  43. package/src/core/primitives/avatar/avatarStack.tsx +5 -2
  44. package/src/core/primitives/button/__workshop__/props.tsx +1 -1
  45. package/src/core/primitives/button/button.tsx +11 -6
  46. package/src/core/primitives/button/styles.ts +1 -1
  47. package/src/core/primitives/flex/flex.tsx +5 -1
  48. package/src/core/primitives/heading/heading.tsx +1 -1
  49. package/src/core/primitives/popover/popover.tsx +139 -74
  50. package/src/core/primitives/popover/popoverCard.tsx +4 -1
  51. package/src/core/primitives/text/styles.ts +1 -0
  52. package/src/core/primitives/text/text.tsx +4 -2
  53. package/src/core/primitives/tooltip/tooltip.tsx +17 -47
  54. package/src/core/styles/card/_cardColorStyle.ts +8 -0
  55. package/src/core/styles/flex/flexStyle.ts +18 -0
  56. package/src/core/styles/flex/types.ts +2 -0
  57. package/src/core/theme/themeProvider.tsx +6 -4
  58. package/src/core/utils/elementQuery/elementQuery.tsx +17 -16
  59. package/src/core/utils/layer/layerProvider.tsx +1 -1
  60. package/src/core/utils/portal/portalProvider.tsx +5 -5
  61. package/src/theme/build/_deprecated/color/factory.ts +1 -1
  62. package/src/theme/build/_deprecated/color/muted/createMuted.ts +2 -2
  63. package/src/theme/build/buildColorTheme.ts +45 -39
  64. package/src/theme/build/renderColorTheme.ts +239 -65
  65. package/src/theme/build/resolveColorTokens.ts +51 -115
  66. package/src/theme/config/tokens/color/types.ts +4 -18
  67. package/src/theme/defaults/colorTokens.ts +19 -11
  68. package/src/theme/getScopedTheme.ts +9 -2
  69. package/src/theme/system/color/_constants.ts +8 -0
  70. package/src/theme/system/color/badge.ts +3 -7
  71. package/src/theme/system/v0/color/_system.ts +8 -4
  72. package/src/theme/system/v0/color/color.ts +3 -2
  73. package/src/theme/versioning/themeColor_v0_v2.ts +26 -0
  74. package/src/theme/versioning/v0_v2.ts +4 -0
  75. package/src/core/components/toast/toastState.ts +0 -6
@@ -1,4 +1,4 @@
1
- import {forwardRef, useImperativeHandle, useMemo, useState} from 'react'
1
+ import {forwardRef, useCallback, useImperativeHandle, useMemo, useRef, useState} from 'react'
2
2
  import {useElementSize} from '../../hooks'
3
3
  import {useTheme_v2} from '../../theme'
4
4
  import {findMaxBreakpoints, findMinBreakpoints} from './helpers'
@@ -21,30 +21,31 @@ export const ElementQuery = forwardRef(function ElementQuery(
21
21
  forwardedRef: React.ForwardedRef<HTMLDivElement>,
22
22
  ) {
23
23
  const theme = useTheme_v2()
24
- const {children, media: _media, ...restProps} = props
25
- const media = _media ?? theme.media
24
+ const {children, media = theme.media, ...restProps} = props
26
25
 
26
+ const ref = useRef<HTMLDivElement | null>(null)
27
27
  const [element, setElement] = useState<HTMLDivElement | null>(null)
28
28
  const elementSize = useElementSize(element)
29
29
  const width = useMemo(() => elementSize?.border.width ?? window.innerWidth, [elementSize])
30
30
 
31
- const max = useMemo(() => {
32
- const eq = findMaxBreakpoints(media, width)
31
+ const max = useMemo(() => findMaxBreakpoints(media, width), [media, width])
32
+ const min = useMemo(() => findMinBreakpoints(media, width), [media, width])
33
33
 
34
- return eq.length ? eq.join(' ') : undefined
35
- }, [media, width])
36
- const min = useMemo(() => {
37
- const eq = findMinBreakpoints(media, width)
34
+ useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(forwardedRef, () => ref.current)
38
35
 
39
- return eq.length ? eq.join(' ') : undefined
40
- }, [media, width])
41
-
42
- useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(forwardedRef, () => element, [
43
- element,
44
- ])
36
+ const setRef = useCallback((el: HTMLDivElement | null) => {
37
+ ref.current = el
38
+ setElement(el)
39
+ }, [])
45
40
 
46
41
  return (
47
- <div data-ui="ElementQuery" {...restProps} data-eq-max={max} data-eq-min={min} ref={setElement}>
42
+ <div
43
+ data-ui="ElementQuery"
44
+ {...restProps}
45
+ data-eq-max={max.length ? max.join(' ') : undefined}
46
+ data-eq-min={min.length ? min.join(' ') : undefined}
47
+ ref={setRef}
48
+ >
48
49
  {children}
49
50
  </div>
50
51
  )
@@ -85,7 +85,7 @@ export function LayerProvider(props: LayerProviderProps): React.ReactElement {
85
85
  parentDispose?.()
86
86
  }
87
87
  },
88
- [parentRegisterChild, setSize, setChildLayers],
88
+ [parentRegisterChild],
89
89
  )
90
90
 
91
91
  // Register this layer on mount
@@ -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, ThemeColorToneKey} 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: ThemeColorToneKey,
9
9
  ): ThemeColorMuted {
10
10
  return {
11
11
  default: {
@@ -24,6 +24,7 @@ import {
24
24
  ThemeColorInput_v2,
25
25
  ThemeColorInputMode_v2,
26
26
  ThemeColorInputState_v2,
27
+ THEME_COLOR_CARD_TONES,
27
28
  } from '../system'
28
29
  import {ColorTokenContext, resolveColorTokenValue as _color} from './colorToken'
29
30
  import {resolveColorTokens} from './resolveColorTokens'
@@ -46,14 +47,11 @@ function buildColorScheme(
46
47
  ): ThemeColorScheme_v2 {
47
48
  const {scheme} = options
48
49
 
49
- return {
50
- transparent: buildCardColorTheme({scheme, tone: 'transparent'}, config),
51
- default: buildCardColorTheme({scheme, tone: 'default'}, config),
52
- primary: buildCardColorTheme({scheme, tone: 'primary'}, config),
53
- positive: buildCardColorTheme({scheme, tone: 'positive'}, config),
54
- caution: buildCardColorTheme({scheme, tone: 'caution'}, config),
55
- critical: buildCardColorTheme({scheme, tone: 'critical'}, config),
56
- }
50
+ return THEME_COLOR_CARD_TONES.reduce((acc, tone) => {
51
+ acc[tone] = buildCardColorTheme({scheme, tone}, config)
52
+
53
+ return acc
54
+ }, {} as ThemeColorScheme_v2)
57
55
  }
58
56
 
59
57
  function buildCardColorTheme(
@@ -77,7 +75,7 @@ function buildCardColorTheme(
77
75
  badge: buildBadgeColorTheme(tokens?.badge, {scheme}, config),
78
76
  bg: _color(context, tokens?.bg),
79
77
  border: _color(context, tokens?.border),
80
- button: buildButtonColorTheme({scheme}, config),
78
+ button: buildButtonColorTheme({scheme, tone}, config),
81
79
  code: {
82
80
  bg: _color(context, tokens?.code?.bg),
83
81
  fg: _color(context, tokens?.code?.fg),
@@ -98,7 +96,7 @@ function buildCardColorTheme(
98
96
  bg: _color(context, tokens?.muted?.bg),
99
97
  fg: _color(context, tokens?.muted?.fg),
100
98
  },
101
- selectable: buildSelectableColorTheme({scheme}, config),
99
+ selectable: buildSelectableColorTheme({scheme, tone}, config),
102
100
  shadow: buildShadowColorTheme({scheme, tone}, config),
103
101
  skeleton: {
104
102
  from: _color(context, tokens?.skeleton?.from),
@@ -167,13 +165,11 @@ function buildBadgeColorTheme(
167
165
  ): ThemeColorBadge_v2 {
168
166
  const {scheme} = options
169
167
 
170
- return {
171
- default: _buildBadgeColorTheme(tokens, {scheme, tone: 'default'}, config),
172
- primary: _buildBadgeColorTheme(tokens, {scheme, tone: 'primary'}, config),
173
- positive: _buildBadgeColorTheme(tokens, {scheme, tone: 'positive'}, config),
174
- caution: _buildBadgeColorTheme(tokens, {scheme, tone: 'caution'}, config),
175
- critical: _buildBadgeColorTheme(tokens, {scheme, tone: 'critical'}, config),
176
- }
168
+ return THEME_COLOR_STATE_TONES.reduce((acc, tone) => {
169
+ acc[tone] = _buildBadgeColorTheme(tokens, {scheme, tone}, config)
170
+
171
+ return acc
172
+ }, {} as ThemeColorBadge_v2)
177
173
  }
178
174
 
179
175
  function _buildBadgeColorTheme(
@@ -195,15 +191,15 @@ function _buildBadgeColorTheme(
195
191
  }
196
192
 
197
193
  function buildButtonColorTheme(
198
- options: {scheme: ThemeColorSchemeKey},
194
+ options: {scheme: ThemeColorSchemeKey; tone: ThemeColorCardToneKey},
199
195
  config?: ThemeConfig,
200
196
  ): ThemeColorButton_v2 {
201
- const {scheme} = options
197
+ const {scheme, tone: cardTone} = options
202
198
 
203
199
  const modes: Partial<ThemeColorButton_v2> = {}
204
200
 
205
201
  for (const mode of THEME_COLOR_BUTTON_MODES) {
206
- modes[mode] = buildButtonTonesColorTheme({scheme, mode}, config)
202
+ modes[mode] = buildButtonTonesColorTheme({cardTone, scheme, mode}, config)
207
203
  }
208
204
 
209
205
  return modes as ThemeColorButton_v2
@@ -211,17 +207,18 @@ function buildButtonColorTheme(
211
207
 
212
208
  function buildButtonTonesColorTheme(
213
209
  options: {
210
+ cardTone: ThemeColorCardToneKey
214
211
  scheme: ThemeColorSchemeKey
215
212
  mode: ThemeColorButtonModeKey
216
213
  },
217
214
  config?: ThemeConfig,
218
215
  ): ThemeColorButtonMode_v2 {
219
- const {mode, scheme} = options
216
+ const {cardTone, mode, scheme} = options
220
217
 
221
218
  const tones: Partial<ThemeColorButtonMode_v2> = {}
222
219
 
223
220
  for (const tone of THEME_COLOR_STATE_TONES) {
224
- tones[tone] = buildButtonStatesColorTheme({mode, scheme, tone}, config)
221
+ tones[tone] = buildButtonStatesColorTheme({cardTone, mode, scheme, tone}, config)
225
222
  }
226
223
 
227
224
  return tones as ThemeColorButtonMode_v2
@@ -229,18 +226,19 @@ function buildButtonTonesColorTheme(
229
226
 
230
227
  function buildButtonStatesColorTheme(
231
228
  options: {
229
+ cardTone: ThemeColorCardToneKey
232
230
  mode: ThemeColorButtonModeKey
233
231
  scheme: ThemeColorSchemeKey
234
232
  tone: ThemeColorStateToneKey
235
233
  },
236
234
  config?: ThemeConfig,
237
235
  ): ThemeColorButtonTone_v2 {
238
- const {mode, scheme, tone} = options
236
+ const {cardTone, mode, scheme, tone} = options
239
237
 
240
238
  const states: Partial<ThemeColorButtonTone_v2> = {}
241
239
 
242
240
  for (const state of THEME_COLOR_STATES) {
243
- states[state] = buildButtonStateColorTheme({mode, tone, scheme, state}, config)
241
+ states[state] = buildButtonStateColorTheme({cardTone, mode, tone, scheme, state}, config)
244
242
  }
245
243
 
246
244
  return states as ThemeColorButtonTone_v2
@@ -248,6 +246,7 @@ function buildButtonStatesColorTheme(
248
246
 
249
247
  function buildButtonStateColorTheme(
250
248
  options: {
249
+ cardTone: ThemeColorCardToneKey
251
250
  mode: ThemeColorButtonModeKey
252
251
  tone: ThemeColorStateToneKey
253
252
  scheme: ThemeColorSchemeKey
@@ -255,9 +254,10 @@ function buildButtonStateColorTheme(
255
254
  },
256
255
  config?: ThemeConfig,
257
256
  ): ThemeColorState_v2 {
258
- const {mode, tone, scheme, state} = options
257
+ const {cardTone, mode, tone, scheme, state} = options
258
+ const cardTokens = config?.color?.base?.[cardTone]
259
259
  const tokens = config?.color?.button?.[mode]?.[tone]?.[state]
260
- const hue = tokens?._hue || 'gray'
260
+ const hue = tokens?._hue || cardTokens?._hue || 'gray'
261
261
  const blendMode = tokens?._blend || ['screen', 'multiply']
262
262
  const context: ColorTokenContext = {hue, scheme}
263
263
 
@@ -318,25 +318,26 @@ function buildInputStatesColorTheme(
318
318
  const {mode, scheme, tone} = options
319
319
 
320
320
  return {
321
- enabled: buildInputStateColorTheme({mode, scheme, state: 'enabled', tone}, config),
322
- hovered: buildInputStateColorTheme({mode, scheme, state: 'hovered', tone}, config),
323
- readOnly: buildInputStateColorTheme({mode, scheme, state: 'readOnly', tone}, config),
324
- disabled: buildInputStateColorTheme({mode, scheme, state: 'disabled', tone}, config),
321
+ enabled: buildInputStateColorTheme({mode, scheme, state: 'enabled', cardTone: tone}, config),
322
+ hovered: buildInputStateColorTheme({mode, scheme, state: 'hovered', cardTone: tone}, config),
323
+ readOnly: buildInputStateColorTheme({mode, scheme, state: 'readOnly', cardTone: tone}, config),
324
+ disabled: buildInputStateColorTheme({mode, scheme, state: 'disabled', cardTone: tone}, config),
325
325
  }
326
326
  }
327
327
 
328
328
  function buildInputStateColorTheme(
329
329
  options: {
330
+ cardTone: ThemeColorCardToneKey
330
331
  mode: 'default' | 'invalid'
331
332
  scheme: ThemeColorSchemeKey
332
333
  state: 'enabled' | 'hovered' | 'readOnly' | 'disabled'
333
- tone: ThemeColorCardToneKey
334
334
  },
335
335
  config?: ThemeConfig,
336
336
  ): ThemeColorInputState_v2 {
337
- const {mode, tone, scheme, state} = options
337
+ const {cardTone, mode, scheme, state} = options
338
+ const cardTokens = config?.color?.base?.[cardTone]
338
339
  const tokens = config?.color?.input?.[mode]?.[state]
339
- const hue = tokens?._hue || config?.color?.base?.[tone]?._hue || 'gray'
340
+ const hue = tokens?._hue || cardTokens?._hue || 'gray'
340
341
  const blendMode = tokens?._blend || ['screen', 'multiply']
341
342
  const context: ColorTokenContext = {hue, scheme}
342
343
 
@@ -355,15 +356,16 @@ function buildInputStateColorTheme(
355
356
  function buildSelectableColorTheme(
356
357
  options: {
357
358
  scheme: ThemeColorSchemeKey
359
+ tone: ThemeColorCardToneKey
358
360
  },
359
361
  config?: ThemeConfig,
360
362
  ): ThemeColorButtonMode_v2 {
361
- const {scheme} = options
363
+ const {scheme, tone: cardTone} = options
362
364
 
363
365
  const tones: Partial<ThemeColorButtonMode_v2> = {}
364
366
 
365
367
  for (const tone of THEME_COLOR_STATE_TONES) {
366
- tones[tone] = buildSelectableStatesColorTheme({scheme, tone}, config)
368
+ tones[tone] = buildSelectableStatesColorTheme({cardTone, scheme, tone}, config)
367
369
  }
368
370
 
369
371
  return tones as ThemeColorButtonMode_v2
@@ -371,17 +373,18 @@ function buildSelectableColorTheme(
371
373
 
372
374
  function buildSelectableStatesColorTheme(
373
375
  options: {
376
+ cardTone: ThemeColorCardToneKey
374
377
  scheme: ThemeColorSchemeKey
375
378
  tone: ThemeColorStateToneKey
376
379
  },
377
380
  config?: ThemeConfig,
378
381
  ): ThemeColorButtonTone_v2 {
379
- const {scheme, tone} = options
382
+ const {cardTone, scheme, tone} = options
380
383
 
381
384
  const states: Partial<ThemeColorButtonTone_v2> = {}
382
385
 
383
386
  for (const state of THEME_COLOR_STATES) {
384
- states[state] = buildSelectableStateColorTheme({tone, scheme, state}, config)
387
+ states[state] = buildSelectableStateColorTheme({cardTone, tone, scheme, state}, config)
385
388
  }
386
389
 
387
390
  return states as ThemeColorButtonTone_v2
@@ -389,15 +392,18 @@ function buildSelectableStatesColorTheme(
389
392
 
390
393
  function buildSelectableStateColorTheme(
391
394
  options: {
395
+ cardTone: ThemeColorCardToneKey
392
396
  scheme: ThemeColorSchemeKey
393
397
  state: ThemeColorStateKey
394
398
  tone: ThemeColorStateToneKey
395
399
  },
396
400
  config?: ThemeConfig,
397
401
  ): ThemeColorState_v2 {
398
- const {scheme, state, tone} = options
402
+ const {cardTone, scheme, state, tone} = options
403
+ const cardTokens = config?.color?.base?.[cardTone]
399
404
  const tokens = config?.color?.selectable?.[tone]?.[state]
400
- const hue = tokens?._hue || 'gray'
405
+
406
+ const hue = tokens?._hue || cardTokens?._hue || 'gray'
401
407
  const blendMode = tokens?._blend || ['screen', 'multiply']
402
408
  const context: ColorTokenContext = {hue, scheme}
403
409