@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,5 +1,6 @@
1
1
  /* eslint-disable @typescript-eslint/no-explicit-any */
2
2
  import {
3
+ Middleware,
3
4
  RootBoundary,
4
5
  arrow,
5
6
  autoUpdate,
@@ -20,10 +21,8 @@ import {
20
21
  useCallback,
21
22
  useEffect,
22
23
  useImperativeHandle,
23
- useLayoutEffect,
24
24
  useMemo,
25
25
  useRef,
26
- useState,
27
26
  } from 'react'
28
27
  import {useArrayProp, useElementSize, useMediaIndex, usePrefersReducedMotion} from '../../hooks'
29
28
  import {origin} from '../../middleware/origin'
@@ -127,14 +126,15 @@ export const Popover = memo(
127
126
  __unstable_margins: margins = DEFAULT_POPOVER_MARGINS,
128
127
  animate: _animate = false,
129
128
  arrow: arrowProp = false,
130
- boundaryElement: _boundaryElement,
129
+ boundaryElement = boundaryElementContext.element,
131
130
  children: childProp,
132
131
  constrainSize = false,
133
132
  content,
134
133
  disabled,
135
- fallbackPlacements: _fallbackPlacements,
134
+ fallbackPlacements = props.fallbackPlacements ??
135
+ DEFAULT_FALLBACK_PLACEMENTS[props.placement ?? 'bottom'],
136
136
  matchReferenceWidth,
137
- floatingBoundary: _floatingBoundary,
137
+ floatingBoundary = props.boundaryElement ?? boundaryElementContext.element,
138
138
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
139
139
  onActivate,
140
140
  open,
@@ -144,23 +144,16 @@ export const Popover = memo(
144
144
  portal,
145
145
  preventOverflow = true,
146
146
  radius: radiusProp = 3,
147
- referenceBoundary: _referenceBoundary,
147
+ referenceBoundary = props.boundaryElement ?? boundaryElementContext.element,
148
148
  referenceElement,
149
149
  scheme,
150
150
  shadow: shadowProp = 3,
151
151
  tone = 'inherit',
152
152
  width: widthProp = 'auto',
153
- zOffset: _zOffsetProp,
153
+ zOffset: zOffsetProp = layer.popover.zOffset,
154
154
  updateRef,
155
155
  ...restProps
156
156
  } = props
157
- const boundaryElement = _boundaryElement ?? boundaryElementContext.element
158
- const fallbackPlacements =
159
- _fallbackPlacements ?? DEFAULT_FALLBACK_PLACEMENTS[props.placement ?? 'bottom']
160
- const floatingBoundary = _floatingBoundary ?? boundaryElement ?? boundaryElementContext.element
161
- const referenceBoundary =
162
- _referenceBoundary ?? boundaryElement ?? boundaryElementContext.element
163
- const zOffsetProp = _zOffsetProp ?? layer.popover.zOffset
164
157
  const prefersReducedMotion = usePrefersReducedMotion()
165
158
  const animate = prefersReducedMotion ? false : _animate
166
159
  const boundarySize = useElementSize(boundaryElement)?.border
@@ -170,7 +163,7 @@ export const Popover = memo(
170
163
  const widthArrayProp = useArrayProp(widthProp)
171
164
  const zOffset = useArrayProp(zOffsetProp)
172
165
  const ref = useRef<HTMLDivElement | null>(null)
173
- const [arrowElement, setArrowElement] = useState<HTMLDivElement | null>(null)
166
+ const arrowRef = useRef<HTMLDivElement | null>(null)
174
167
  const rootBoundary: RootBoundary = 'viewport'
175
168
 
176
169
  useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(
@@ -181,70 +174,94 @@ export const Popover = memo(
181
174
  const mediaIndex = useMediaIndex()
182
175
  const boundaryWidth = constrainSize || preventOverflow ? boundarySize?.width : undefined
183
176
 
177
+ // Update width when
178
+ // - media index changes
179
+ // - `width` property changes
180
+ const width = calcCurrentWidth({
181
+ container,
182
+ mediaIndex,
183
+ width: widthArrayProp,
184
+ })
185
+ const widthRef = useRef(width)
186
+
187
+ useEffect(() => {
188
+ widthRef.current = width
189
+ }, [width])
190
+
191
+ // Update max width when
192
+ // - boundary width changes
193
+ // - `width` property changes
194
+ const maxWidth = calcMaxWidth({boundaryWidth, currentWidth: width})
195
+ const maxWidthRef = useRef(maxWidth)
196
+
197
+ useEffect(() => {
198
+ maxWidthRef.current = maxWidth
199
+ }, [maxWidth])
200
+
201
+ // Keep track of reference element width (see `size` middleware below)
202
+ const referenceWidthRef = useRef<number>()
203
+
184
204
  // Force apply width & max width to floating element
185
- useLayoutEffect(() => {
205
+ useEffect(() => {
186
206
  const floatingElement = ref.current
187
207
 
188
- // If constrainSize or matchReferenceWidth is true, then the styles are set by the `size` middleware
189
- if (!open || !floatingElement || constrainSize || matchReferenceWidth) return
208
+ if (!open || !floatingElement) return
190
209
 
191
- const currentWidth = calcCurrentWidth({
192
- container,
193
- mediaIndex,
194
- width: widthArrayProp,
195
- })
196
- const maxWidth = calcMaxWidth({boundaryWidth, currentWidth})
210
+ const referenceWidth = referenceWidthRef.current
197
211
 
198
- if (currentWidth !== undefined) {
199
- floatingElement.style.width = `${currentWidth}px`
212
+ if (matchReferenceWidth) {
213
+ if (referenceWidth !== undefined) {
214
+ floatingElement.style.width = `${referenceWidth}px`
215
+ }
216
+ } else if (width !== undefined) {
217
+ floatingElement.style.width = `${width}px`
200
218
  }
201
219
 
202
220
  if (typeof maxWidth === 'number') {
203
221
  floatingElement.style.maxWidth = `${maxWidth}px`
204
222
  }
205
- }, [
206
- boundaryWidth,
207
- constrainSize,
208
- container,
209
- matchReferenceWidth,
210
- mediaIndex,
211
- open,
212
- widthArrayProp,
213
- ])
223
+ }, [width, matchReferenceWidth, maxWidth, open])
214
224
 
215
- const {x, y, middlewareData, placement, refs, strategy, update} = useFloating({
216
- middleware: [
217
- // Flip the floating element when leaving the boundary box
218
- (constrainSize || preventOverflow) &&
225
+ const middleware = useMemo(() => {
226
+ const ret: Middleware[] = []
227
+
228
+ // Flip the floating element when leaving the boundary box
229
+ if (constrainSize || preventOverflow) {
230
+ ret.push(
219
231
  flip({
220
232
  boundary: floatingBoundary || undefined,
221
233
  fallbackPlacements,
222
234
  padding: DEFAULT_POPOVER_PADDING,
223
235
  rootBoundary,
224
236
  }),
225
- // Define distance between reference and floating element
226
- offset({mainAxis: DEFAULT_POPOVER_DISTANCE}),
227
- // Track sizes
228
- (constrainSize || matchReferenceWidth) &&
237
+ )
238
+ }
239
+
240
+ // Define distance between reference and floating element
241
+ ret.push(offset({mainAxis: DEFAULT_POPOVER_DISTANCE}))
242
+
243
+ // Track sizes
244
+ if (constrainSize || matchReferenceWidth) {
245
+ ret.push(
229
246
  size({
230
247
  apply({availableWidth, availableHeight, elements, referenceWidth}) {
231
- const currentWidth = calcCurrentWidth({
232
- container,
233
- mediaIndex,
234
- width: widthArrayProp,
235
- })
236
- const maxWidth = calcMaxWidth({boundaryWidth, currentWidth})
248
+ // not fresh, so use refs
249
+
250
+ referenceWidthRef.current = referenceWidth
251
+
252
+ const _currentWidth = widthRef.current
253
+ const _maxWidth = maxWidthRef.current
237
254
 
238
255
  if (matchReferenceWidth) {
239
256
  elements.floating.style.width = `${referenceWidth}px`
240
- } else if (currentWidth !== undefined) {
241
- elements.floating.style.width = `${currentWidth}px`
257
+ } else if (_currentWidth !== undefined) {
258
+ elements.floating.style.width = `${_currentWidth}px`
242
259
  }
243
260
 
244
261
  if (constrainSize) {
245
262
  elements.floating.style.maxWidth = `${Math.min(
246
263
  availableWidth,
247
- maxWidth ?? Infinity,
264
+ _maxWidth ?? Infinity,
248
265
  )}px`
249
266
 
250
267
  elements.floating.style.maxHeight = `${availableHeight}px`
@@ -256,28 +273,59 @@ export const Popover = memo(
256
273
  matchReferenceWidth,
257
274
  padding: DEFAULT_POPOVER_PADDING,
258
275
  }),
259
- // Shift the popover so its sits within the boundary element
260
- preventOverflow &&
276
+ )
277
+ }
278
+
279
+ // Shift the popover so its sits within the boundary element
280
+ if (preventOverflow) {
281
+ ret.push(
261
282
  shift({
262
283
  boundary: floatingBoundary || undefined,
263
284
  rootBoundary,
264
285
  padding: DEFAULT_POPOVER_PADDING,
265
286
  }),
266
- // Place arrow
267
- arrowProp &&
287
+ )
288
+ }
289
+
290
+ // Place arrow
291
+ if (arrowProp) {
292
+ ret.push(
268
293
  arrow({
269
- element: arrowElement,
294
+ element: arrowRef,
270
295
  padding: DEFAULT_POPOVER_PADDING,
271
296
  }),
272
- // Determine the origin to scale from.
273
- // Must be placed after `@sanity/ui/size` and `shift` middleware.
274
- animate && origin,
297
+ )
298
+ }
299
+
300
+ // Determine the origin to scale from.
301
+ // Must be placed after `@sanity/ui/size` and `shift` middleware.
302
+ if (animate) {
303
+ ret.push(origin)
304
+ }
305
+
306
+ ret.push(
275
307
  hide({
276
308
  boundary: referenceBoundary || undefined,
277
309
  padding: DEFAULT_POPOVER_PADDING,
278
310
  strategy: 'referenceHidden',
279
311
  }),
280
- ],
312
+ )
313
+
314
+ return ret
315
+ }, [
316
+ animate,
317
+ arrowProp,
318
+ constrainSize,
319
+ fallbackPlacements,
320
+ floatingBoundary,
321
+ margins,
322
+ matchReferenceWidth,
323
+ preventOverflow,
324
+ referenceBoundary,
325
+ ])
326
+
327
+ const {x, y, middlewareData, placement, refs, strategy, update} = useFloating({
328
+ middleware,
281
329
  placement: placementProp,
282
330
  whileElementsMounted: autoUpdate,
283
331
  })
@@ -290,6 +338,10 @@ export const Popover = memo(
290
338
  const originX = middlewareData['@sanity/ui/origin']?.originX
291
339
  const originY = middlewareData['@sanity/ui/origin']?.originY
292
340
 
341
+ const setArrow = useCallback((arrowEl: HTMLDivElement | null) => {
342
+ arrowRef.current = arrowEl
343
+ }, [])
344
+
293
345
  const setFloating = useCallback(
294
346
  (node: HTMLDivElement | null) => {
295
347
  ref.current = node
@@ -298,28 +350,41 @@ export const Popover = memo(
298
350
  [refs],
299
351
  )
300
352
 
301
- const [childElement, setChildElement] = useState<HTMLElement | null>(null)
302
353
  const setReference = useCallback(
303
354
  (node: HTMLElement | null) => {
304
355
  refs.setReference(node)
305
- setChildElement(node)
356
+
357
+ const childRef = getElementRef(childProp as any)
358
+
359
+ if (typeof childRef === 'function') {
360
+ childRef(node)
361
+ } else if (childRef) {
362
+ childRef.current = node
363
+ }
306
364
  },
307
- [refs],
365
+ [childProp, refs],
308
366
  )
309
367
 
310
- useImperativeHandle(getElementRef(childProp as any), () => childElement, [childElement])
311
-
312
368
  const child = useMemo(() => {
313
- if (!childProp || referenceElement) return null
369
+ if (!childProp) return null
314
370
 
315
- return cloneElement(childProp, {ref: setReference})
371
+ return cloneElement(childProp, {ref: referenceElement ? undefined : setReference})
316
372
  }, [childProp, referenceElement, setReference])
317
373
 
318
- useImperativeHandle(updateRef, () => update, [update])
374
+ useEffect(() => {
375
+ if (updateRef) {
376
+ if (typeof updateRef === 'function') {
377
+ updateRef(update)
378
+ } else if (updateRef) {
379
+ updateRef.current = update
380
+ }
381
+ }
382
+ }, [update, updateRef])
319
383
 
320
384
  useEffect(() => {
321
- if (child) return
322
- refs.setReference(referenceElement || null)
385
+ if (referenceElement) {
386
+ refs.setReference(referenceElement)
387
+ }
323
388
  }, [referenceElement, refs, child])
324
389
 
325
390
  if (disabled) {
@@ -333,7 +398,7 @@ export const Popover = memo(
333
398
  __unstable_margins={margins}
334
399
  animate={animate}
335
400
  arrow={arrowProp}
336
- arrowRef={setArrowElement}
401
+ arrowRef={setArrow}
337
402
  arrowX={arrowX}
338
403
  arrowY={arrowY}
339
404
  hidden={referenceHidden}
@@ -348,6 +413,7 @@ export const Popover = memo(
348
413
  originY={originY}
349
414
  strategy={strategy}
350
415
  tone={tone}
416
+ width={matchReferenceWidth ? referenceWidthRef.current : width}
351
417
  x={x}
352
418
  y={y}
353
419
  >
@@ -382,8 +448,7 @@ Popover.displayName = 'Memo(ForwardRef(Popover))'
382
448
  // https://github.com/facebook/react/pull/28348
383
449
  //
384
450
  // Access the ref using the method that doesn't yield a warning.
385
- function getElementRef(element?: React.ReactElement) {
386
- if (!element) return null
451
+ function getElementRef(element: React.ReactElement) {
387
452
  // React <=18 in DEV
388
453
  let getter = Object.getOwnPropertyDescriptor(element.props, 'ref')?.get
389
454
  let mayWarn = getter && 'isReactWarning' in getter && getter.isReactWarning
@@ -51,6 +51,7 @@ export const PopoverCard = memo(
51
51
  shadow?: number | number[]
52
52
  strategy: Strategy
53
53
  tone: CardTone
54
+ width: number | undefined
54
55
  x: number | null
55
56
  y: number | null
56
57
  } & Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'height' | 'width'>,
@@ -75,6 +76,7 @@ export const PopoverCard = memo(
75
76
  strategy,
76
77
  style,
77
78
  tone,
79
+ width,
78
80
  x: xProp,
79
81
  y: yProp,
80
82
  ...restProps
@@ -99,11 +101,12 @@ export const PopoverCard = memo(
99
101
  originY,
100
102
  position: strategy,
101
103
  top: y,
104
+ width,
102
105
  zIndex,
103
106
  willChange: animate ? 'transform' : undefined,
104
107
  ...style,
105
108
  }),
106
- [animate, originX, originY, strategy, style, x, y, zIndex],
109
+ [animate, originX, originY, strategy, style, width, x, y, zIndex],
107
110
  )
108
111
 
109
112
  const arrowStyle: CSSProperties = useMemo(
@@ -9,6 +9,7 @@ export function textBaseStyle(
9
9
  const {font} = getTheme_v2(props.theme)
10
10
 
11
11
  return css`
12
+ min-width: 0;
12
13
  color: var(--card-fg-color);
13
14
 
14
15
  ${$accent &&
@@ -25,7 +25,7 @@ export interface TextProps {
25
25
  * Use `textOverflow="ellipsis"` to render text as a single line which is concatenated with a `…` symbol.
26
26
  * @beta
27
27
  */
28
- textOverflow?: 'ellipsis'
28
+ textOverflow?: 'ellipsis' | 'none'
29
29
  weight?: ThemeFontWeightKey
30
30
  }
31
31
 
@@ -67,6 +67,8 @@ export const Text = forwardRef(function Text(
67
67
 
68
68
  if (textOverflow === 'ellipsis') {
69
69
  children = <SpanWithTextOverflow>{children}</SpanWithTextOverflow>
70
+ } else {
71
+ children = <span>{children}</span>
70
72
  }
71
73
 
72
74
  return (
@@ -80,7 +82,7 @@ export const Text = forwardRef(function Text(
80
82
  $size={useArrayProp(size)}
81
83
  $weight={weight}
82
84
  >
83
- <span>{children}</span>
85
+ {children}
84
86
  </Root>
85
87
  )
86
88
  })
@@ -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
- }
@@ -71,6 +71,14 @@ export function _cardColorStyle(
71
71
  '--card-badge-critical-dot-color': color.badge.critical.dot,
72
72
  '--card-badge-critical-fg-color': color.badge.critical.fg,
73
73
  '--card-badge-critical-icon-color': color.badge.critical.icon,
74
+ '--card-badge-prospect-bg-color': color.badge.prospect.bg,
75
+ '--card-badge-prospect-dot-color': color.badge.prospect.dot,
76
+ '--card-badge-prospect-fg-color': color.badge.prospect.fg,
77
+ '--card-badge-prospect-icon-color': color.badge.prospect.icon,
78
+ '--card-badge-explore-bg-color': color.badge.explore.bg,
79
+ '--card-badge-explore-dot-color': color.badge.explore.dot,
80
+ '--card-badge-explore-fg-color': color.badge.explore.fg,
81
+ '--card-badge-explore-icon-color': color.badge.explore.icon,
74
82
 
75
83
  '--card-code-bg-color': color.code.bg,
76
84
  '--card-code-fg-color': color.code.fg,
@@ -16,6 +16,8 @@ export function responsiveFlexStyle(): Array<
16
16
  BASE_STYLE,
17
17
  responsiveFlexAlignStyle,
18
18
  responsiveFlexGapStyle,
19
+ responsiveFlexGapXStyle,
20
+ responsiveFlexGapYStyle,
19
21
  responsiveFlexWrapStyle,
20
22
  responsiveFlexJustifyStyle,
21
23
  responsiveFlexDirectionStyle,
@@ -40,6 +42,22 @@ function responsiveFlexGapStyle(props: ResponsiveFlexStyleProps & ThemeProps) {
40
42
  }))
41
43
  }
42
44
 
45
+ function responsiveFlexGapXStyle(props: ResponsiveFlexStyleProps & ThemeProps) {
46
+ const {media, space} = getTheme_v2(props.theme)
47
+
48
+ return _responsive(media, props.$gapX, (gapX) => ({
49
+ columnGap: gapX ? rem(space[gapX]) : undefined,
50
+ }))
51
+ }
52
+
53
+ function responsiveFlexGapYStyle(props: ResponsiveFlexStyleProps & ThemeProps) {
54
+ const {media, space} = getTheme_v2(props.theme)
55
+
56
+ return _responsive(media, props.$gapY, (gapY) => ({
57
+ rowGap: gapY ? rem(space[gapY]) : undefined,
58
+ }))
59
+ }
60
+
43
61
  export function responsiveFlexWrapStyle(props: ResponsiveFlexStyleProps & ThemeProps): CSSObject[] {
44
62
  const {media} = getTheme_v2(props.theme)
45
63
 
@@ -7,6 +7,8 @@ export interface ResponsiveFlexStyleProps {
7
7
  $align: FlexAlign[]
8
8
  $direction: FlexDirection[]
9
9
  $gap: number[]
10
+ $gapX: number[]
11
+ $gapY: number[]
10
12
  $justify: FlexJustify[]
11
13
  $wrap: FlexWrap[]
12
14
  }
@@ -25,10 +25,12 @@ export interface ThemeProviderProps {
25
25
  */
26
26
  export function ThemeProvider(props: ThemeProviderProps): React.ReactElement {
27
27
  const parentTheme = useContext(ThemeContext)
28
- const {children} = props
29
- const scheme = props.scheme ?? (parentTheme?.scheme || 'light')
30
- const rootTheme = props.theme ?? (parentTheme?.theme || null)
31
- const tone = props.tone ?? (parentTheme?.tone || 'default')
28
+ const {
29
+ children,
30
+ scheme = parentTheme?.scheme || 'light',
31
+ theme: rootTheme = parentTheme?.theme || null,
32
+ tone = parentTheme?.tone || 'default',
33
+ } = props
32
34
 
33
35
  const themeContext: ThemeContextValue | null = useMemo(() => {
34
36
  if (!rootTheme) return null