@sanity/ui 2.3.6-canary.5 → 2.3.6

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 (53) hide show
  1. package/dist/index.d.mts +1 -13
  2. package/dist/index.d.ts +1 -13
  3. package/dist/index.esm.js +2173 -2149
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +2179 -2155
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.mjs +2173 -2149
  8. package/dist/index.mjs.map +1 -1
  9. package/package.json +35 -31
  10. package/src/core/components/autocomplete/autocomplete.tsx +34 -31
  11. package/src/core/components/breadcrumbs/breadcrumbs.tsx +2 -3
  12. package/src/core/components/dialog/dialog.tsx +12 -23
  13. package/src/core/components/hotkeys/hotkeys.tsx +3 -3
  14. package/src/core/components/menu/menu.tsx +1 -5
  15. package/src/core/components/menu/menuButton.tsx +32 -17
  16. package/src/core/components/menu/menuGroup.tsx +5 -7
  17. package/src/core/components/menu/menuItem.tsx +6 -10
  18. package/src/core/components/skeleton/skeleton.tsx +11 -5
  19. package/src/core/components/skeleton/textSkeleton.tsx +7 -6
  20. package/src/core/components/toast/toastProvider.tsx +24 -26
  21. package/src/core/components/tree/treeItem.tsx +44 -31
  22. package/src/core/hooks/useArrayProp.ts +10 -11
  23. package/src/core/primitives/avatar/avatar.tsx +15 -11
  24. package/src/core/primitives/avatar/avatarCounter.tsx +17 -11
  25. package/src/core/primitives/avatar/avatarStack.tsx +7 -3
  26. package/src/core/primitives/badge/badge.tsx +4 -7
  27. package/src/core/primitives/box/box.tsx +27 -53
  28. package/src/core/primitives/button/button.tsx +12 -11
  29. package/src/core/primitives/card/card.tsx +9 -17
  30. package/src/core/primitives/code/code.tsx +3 -4
  31. package/src/core/primitives/container/container.tsx +11 -4
  32. package/src/core/primitives/flex/flex.tsx +7 -13
  33. package/src/core/primitives/grid/grid.tsx +10 -19
  34. package/src/core/primitives/heading/heading.tsx +4 -7
  35. package/src/core/primitives/inline/inline.tsx +2 -3
  36. package/src/core/primitives/kbd/kbd.tsx +3 -4
  37. package/src/core/primitives/label/label.tsx +4 -7
  38. package/src/core/primitives/popover/popover.tsx +49 -47
  39. package/src/core/primitives/select/select.tsx +6 -12
  40. package/src/core/primitives/stack/stack.tsx +3 -4
  41. package/src/core/primitives/text/text.tsx +4 -7
  42. package/src/core/primitives/textArea/textArea.tsx +6 -12
  43. package/src/core/primitives/textInput/textInput.tsx +5 -6
  44. package/src/core/primitives/tooltip/tooltip.tsx +11 -14
  45. package/src/core/theme/themeProvider.tsx +6 -4
  46. package/src/core/utils/elementQuery/elementQuery.tsx +3 -4
  47. package/src/core/utils/layer/getLayerContext.test.ts +4 -0
  48. package/src/core/utils/layer/layer.test.tsx +2 -0
  49. package/src/core/utils/layer/layerProvider.tsx +43 -35
  50. package/src/core/utils/layer/types.ts +1 -0
  51. package/dist/index.compiled.mjs +0 -7475
  52. package/dist/index.compiled.mjs.map +0 -1
  53. package/src/core/components/tree/treeItem.styles.ts +0 -21
@@ -1,6 +1,6 @@
1
- import {forwardRef, useMemo} from 'react'
1
+ import {forwardRef} from 'react'
2
2
  import {styled} from 'styled-components'
3
- import {_getArrayProp} from '../../styles'
3
+ import {useArrayProp} from '../../hooks'
4
4
  import {responsiveGridStyle, ResponsiveGridStyleProps} from '../../styles/internal'
5
5
  import {Box, BoxProps} from '../box'
6
6
  import {ResponsiveGridProps} from '../types'
@@ -24,28 +24,19 @@ export const Grid = forwardRef(function Grid(
24
24
  const {as, autoRows, autoCols, autoFlow, columns, gap, gapX, gapY, rows, children, ...restProps} =
25
25
  props
26
26
 
27
- const $autoRows = useMemo(() => _getArrayProp(autoRows), [autoRows])
28
- const $autoCols = useMemo(() => _getArrayProp(autoCols), [autoCols])
29
- const $autoFlow = useMemo(() => _getArrayProp(autoFlow), [autoFlow])
30
- const $columns = useMemo(() => _getArrayProp(columns), [columns])
31
- const $gap = useMemo(() => _getArrayProp(gap), [gap])
32
- const $gapX = useMemo(() => _getArrayProp(gapX), [gapX])
33
- const $gapY = useMemo(() => _getArrayProp(gapY), [gapY])
34
- const $rows = useMemo(() => _getArrayProp(rows), [rows])
35
-
36
27
  return (
37
28
  <Root
38
29
  data-as={typeof as === 'string' ? as : undefined}
39
30
  data-ui="Grid"
40
31
  {...restProps}
41
- $autoRows={$autoRows}
42
- $autoCols={$autoCols}
43
- $autoFlow={$autoFlow}
44
- $columns={$columns}
45
- $gap={$gap}
46
- $gapX={$gapX}
47
- $gapY={$gapY}
48
- $rows={$rows}
32
+ $autoRows={useArrayProp(autoRows)}
33
+ $autoCols={useArrayProp(autoCols)}
34
+ $autoFlow={useArrayProp(autoFlow)}
35
+ $columns={useArrayProp(columns)}
36
+ $gap={useArrayProp(gap)}
37
+ $gapX={useArrayProp(gapX)}
38
+ $gapY={useArrayProp(gapY)}
39
+ $rows={useArrayProp(rows)}
49
40
  forwardedAs={as}
50
41
  ref={ref}
51
42
  >
@@ -1,7 +1,7 @@
1
1
  import {ThemeFontWeightKey} from '@sanity/ui/theme'
2
- import {forwardRef, useMemo} from 'react'
2
+ import {forwardRef} from 'react'
3
3
  import {styled} from 'styled-components'
4
- import {_getArrayProp} from '../../styles'
4
+ import {useArrayProp} from '../../hooks'
5
5
  import {
6
6
  ResponsiveFontStyleProps,
7
7
  responsiveHeadingFont,
@@ -62,9 +62,6 @@ export const Heading = forwardRef(function Heading(
62
62
  ...restProps
63
63
  } = props
64
64
 
65
- const $size = useMemo(() => _getArrayProp(size), [size])
66
- const $align = useMemo(() => _getArrayProp(align), [align])
67
-
68
65
  let children = childrenProp
69
66
 
70
67
  if (textOverflow === 'ellipsis') {
@@ -76,9 +73,9 @@ export const Heading = forwardRef(function Heading(
76
73
  data-ui="Heading"
77
74
  {...restProps}
78
75
  $accent={accent}
79
- $align={$align}
80
- $size={$size}
76
+ $align={useArrayProp(align)}
81
77
  $muted={muted}
78
+ $size={useArrayProp(size)}
82
79
  $weight={weight}
83
80
  ref={ref}
84
81
  >
@@ -1,6 +1,6 @@
1
1
  import {forwardRef, useMemo, Children} from 'react'
2
2
  import {styled} from 'styled-components'
3
- import {_getArrayProp} from '../../styles'
3
+ import {useArrayProp} from '../../hooks'
4
4
  import {Box, BoxProps} from '../box'
5
5
  import {inlineBaseStyle, inlineSpaceStyle} from './styles'
6
6
  import {ResponsiveInlineSpaceStyleProps} from './types'
@@ -26,7 +26,6 @@ export const Inline = forwardRef(function Inline(
26
26
  ) {
27
27
  const {as, children: childrenProp, space, ...restProps} = props
28
28
 
29
- const $space = useMemo(() => _getArrayProp(space), [space])
30
29
  const children = useMemo(
31
30
  () => Children.map(childrenProp, (child) => child && <div>{child}</div>),
32
31
  [childrenProp],
@@ -36,7 +35,7 @@ export const Inline = forwardRef(function Inline(
36
35
  <Root
37
36
  data-ui="Inline"
38
37
  {...restProps}
39
- $space={$space}
38
+ $space={useArrayProp(space)}
40
39
  forwardedAs={as}
41
40
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
42
41
  ref={ref as any}
@@ -1,6 +1,6 @@
1
- import {forwardRef, useMemo} from 'react'
1
+ import {forwardRef} from 'react'
2
2
  import {styled, css} from 'styled-components'
3
- import {_getArrayProp} from '../../styles'
3
+ import {useArrayProp} from '../../hooks'
4
4
  import {responsiveRadiusStyle, ResponsiveRadiusStyleProps} from '../../styles/internal'
5
5
  import {Radius} from '../../types'
6
6
  import {Box} from '../box'
@@ -46,10 +46,9 @@ export const KBD = forwardRef(function KBD(
46
46
  ref: React.ForwardedRef<HTMLDivElement>,
47
47
  ) {
48
48
  const {children, fontSize = 0, padding = 1, radius = 2, ...restProps} = props
49
- const $radius = useMemo(() => _getArrayProp(radius), [radius])
50
49
 
51
50
  return (
52
- <Root data-ui="KBD" {...restProps} $radius={$radius} ref={ref}>
51
+ <Root data-ui="KBD" {...restProps} $radius={useArrayProp(radius)} ref={ref}>
53
52
  <Box as="span" padding={padding}>
54
53
  <Text as="span" size={fontSize} weight="semibold">
55
54
  {children}
@@ -1,7 +1,7 @@
1
1
  import {ThemeFontWeightKey} from '@sanity/ui/theme'
2
- import {forwardRef, useMemo} from 'react'
2
+ import {forwardRef} from 'react'
3
3
  import {styled} from 'styled-components'
4
- import {_getArrayProp} from '../../styles'
4
+ import {useArrayProp} from '../../hooks'
5
5
  import {responsiveLabelFont, responsiveTextAlignStyle} from '../../styles/internal'
6
6
  import {TextAlign} from '../../types'
7
7
  import {labelBaseStyle} from './styles'
@@ -59,9 +59,6 @@ export const Label = forwardRef(function Label(
59
59
  ...restProps
60
60
  } = props
61
61
 
62
- const $size = useMemo(() => _getArrayProp(size), [size])
63
- const $align = useMemo(() => _getArrayProp(align), [align])
64
-
65
62
  let children = childrenProp
66
63
 
67
64
  if (textOverflow === 'ellipsis') {
@@ -75,9 +72,9 @@ export const Label = forwardRef(function Label(
75
72
  data-ui="Label"
76
73
  {...restProps}
77
74
  $accent={accent}
78
- $align={$align}
79
- $size={$size}
75
+ $align={useArrayProp(align)}
80
76
  $muted={muted}
77
+ $size={useArrayProp(size)}
81
78
  $weight={weight}
82
79
  ref={ref}
83
80
  >
@@ -14,6 +14,7 @@ import {AnimatePresence} from 'framer-motion'
14
14
  import {
15
15
  MutableRefObject,
16
16
  RefCallback,
17
+ cloneElement,
17
18
  forwardRef,
18
19
  memo,
19
20
  useCallback,
@@ -22,9 +23,8 @@ import {
22
23
  useMemo,
23
24
  useRef,
24
25
  } from 'react'
25
- import {useElementSize, useMediaIndex, usePrefersReducedMotion} from '../../hooks'
26
+ import {useArrayProp, useElementSize, useMediaIndex, usePrefersReducedMotion} from '../../hooks'
26
27
  import {origin} from '../../middleware/origin'
27
- import {_getArrayProp} from '../../styles'
28
28
  import {useTheme_v2} from '../../theme'
29
29
  import {BoxOverflow, CardTone, Placement, PopoverMargins} from '../../types'
30
30
  import {
@@ -65,7 +65,6 @@ export interface PopoverProps
65
65
  arrow?: boolean
66
66
  /** @deprecated Use `floatingBoundary` and/or `referenceBoundary` instead */
67
67
  boundaryElement?: HTMLElement | null
68
- /** @deprecated Use `referenceElement` instead */
69
68
  children?: React.ReactElement
70
69
  /**
71
70
  * When `true`, prevent overflow within the current boundary:
@@ -132,14 +131,15 @@ export const Popover = memo(
132
131
  __unstable_margins: margins = DEFAULT_POPOVER_MARGINS,
133
132
  animate: _animate = false,
134
133
  arrow: arrowProp = false,
135
- boundaryElement: _boundaryElement,
136
- children,
134
+ boundaryElement = boundaryElementContext.element,
135
+ children: childProp,
137
136
  constrainSize = false,
138
137
  content,
139
138
  disabled,
140
- fallbackPlacements: _fallbackPlacements,
139
+ fallbackPlacements = props.fallbackPlacements ??
140
+ DEFAULT_FALLBACK_PLACEMENTS[props.placement ?? 'bottom'],
141
141
  matchReferenceWidth,
142
- floatingBoundary: _floatingBoundary,
142
+ floatingBoundary = props.boundaryElement ?? boundaryElementContext.element,
143
143
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
144
144
  onActivate,
145
145
  open,
@@ -149,32 +149,24 @@ export const Popover = memo(
149
149
  portal,
150
150
  preventOverflow = true,
151
151
  radius: radiusProp = 3,
152
- referenceBoundary: _referenceBoundary,
152
+ referenceBoundary = props.boundaryElement ?? boundaryElementContext.element,
153
153
  referenceElement,
154
154
  scheme,
155
155
  shadow: shadowProp = 3,
156
156
  tone = 'inherit',
157
157
  width: widthProp = 'auto',
158
- zOffset: _zOffset,
158
+ zOffset: zOffsetProp = layer.popover.zOffset,
159
159
  updateRef,
160
160
  ...restProps
161
161
  } = props
162
- const boundaryElement = _boundaryElement ?? boundaryElementContext.element
163
- const referenceBoundary =
164
- _referenceBoundary ?? props.boundaryElement ?? boundaryElementContext.element
165
- const floatingBoundary =
166
- _floatingBoundary ?? props.boundaryElement ?? boundaryElementContext.element
167
- const fallbackPlacements =
168
- _fallbackPlacements ?? DEFAULT_FALLBACK_PLACEMENTS[props.placement ?? 'bottom']
169
- const zOffsetProp = _zOffset ?? layer.popover.zOffset
170
162
  const prefersReducedMotion = usePrefersReducedMotion()
171
163
  const animate = prefersReducedMotion ? false : _animate
172
164
  const boundarySize = useElementSize(boundaryElement)?.border
173
- const padding = useMemo(() => _getArrayProp(paddingProp), [paddingProp])
174
- const radius = useMemo(() => _getArrayProp(radiusProp), [radiusProp])
175
- const shadow = useMemo(() => _getArrayProp(shadowProp), [shadowProp])
176
- const widthArrayProp = _getArrayProp(widthProp)
177
- const zOffset = useMemo(() => _getArrayProp(zOffsetProp), [zOffsetProp])
165
+ const padding = useArrayProp(paddingProp)
166
+ const radius = useArrayProp(radiusProp)
167
+ const shadow = useArrayProp(shadowProp)
168
+ const widthArrayProp = useArrayProp(widthProp)
169
+ const zOffset = useArrayProp(zOffsetProp)
178
170
  const ref = useRef<HTMLDivElement | null>(null)
179
171
  const arrowRef = useRef<HTMLDivElement | null>(null)
180
172
  const rootBoundary: RootBoundary = 'viewport'
@@ -363,15 +355,45 @@ export const Popover = memo(
363
355
  [refs],
364
356
  )
365
357
 
366
- useImperativeHandle(updateRef, () => update, [update])
358
+ const setReference = useCallback(
359
+ (node: HTMLElement | null) => {
360
+ refs.setReference(node)
361
+
362
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
363
+ const childRef = (childProp as any)?.ref
364
+
365
+ if (typeof childRef === 'function') {
366
+ childRef(node)
367
+ } else if (childRef) {
368
+ childRef.current = node
369
+ }
370
+ },
371
+ [childProp, refs],
372
+ )
373
+
374
+ const child = useMemo(() => {
375
+ if (!childProp || referenceElement) return null
376
+
377
+ return cloneElement(childProp, {ref: setReference})
378
+ }, [childProp, referenceElement, setReference])
367
379
 
368
380
  useEffect(() => {
369
- if (children) return
381
+ if (updateRef) {
382
+ if (typeof updateRef === 'function') {
383
+ updateRef(update)
384
+ } else if (updateRef) {
385
+ updateRef.current = update
386
+ }
387
+ }
388
+ }, [update, updateRef])
389
+
390
+ useEffect(() => {
391
+ if (child) return
370
392
  refs.setReference(referenceElement || null)
371
- }, [children, referenceElement, refs])
393
+ }, [referenceElement, refs, child])
372
394
 
373
395
  if (disabled) {
374
- return children || <></>
396
+ return childProp || <></>
375
397
  }
376
398
 
377
399
  const popover = (
@@ -427,30 +449,10 @@ export const Popover = memo(
427
449
  </ConditionalWrapper>
428
450
 
429
451
  {/* the referred element */}
430
- {children && !referenceElement && (
431
- <div
432
- ref={(node) => {
433
- logDeprecatedWarning()
434
- refs.setReference(node)
435
- }}
436
- style={{display: 'contents'}}
437
- >
438
- {children}
439
- </div>
440
- )}
452
+ {child}
441
453
  </>
442
454
  )
443
455
  }),
444
456
  )
445
457
 
446
458
  Popover.displayName = 'Popover'
447
-
448
- let didWarn = false
449
-
450
- function logDeprecatedWarning() {
451
- if (!didWarn) {
452
- // eslint-disable-next-line no-console
453
- console.warn('Popover: Please use the `referenceElement` prop instead of passing a children.')
454
- didWarn = true
455
- }
456
- }
@@ -1,8 +1,7 @@
1
1
  import {ChevronDownIcon} from '@sanity/icons'
2
- import {forwardRef, useImperativeHandle, useMemo, useRef} from 'react'
2
+ import {forwardRef, useImperativeHandle, useRef} from 'react'
3
3
  import {styled} from 'styled-components'
4
- import {useCustomValidity} from '../../hooks'
5
- import {_getArrayProp} from '../../styles'
4
+ import {useCustomValidity, useArrayProp} from '../../hooks'
6
5
  import {Radius} from '../../types'
7
6
  import {Box} from '../box'
8
7
  import {Text} from '../text'
@@ -60,21 +59,16 @@ export const Select = forwardRef(function Select(
60
59
 
61
60
  useCustomValidity(ref, customValidity)
62
61
 
63
- const $fontSize = useMemo(() => _getArrayProp(fontSize), [fontSize])
64
- const $padding = useMemo(() => _getArrayProp(padding), [padding])
65
- const $radius = useMemo(() => _getArrayProp(radius), [radius])
66
- const $space = useMemo(() => _getArrayProp(space), [space])
67
-
68
62
  return (
69
63
  <Root data-ui="Select">
70
64
  <Input
71
65
  data-read-only={!disabled && readOnly ? '' : undefined}
72
66
  data-ui="Select"
73
67
  {...restProps}
74
- $fontSize={$fontSize}
75
- $padding={$padding}
76
- $radius={$radius}
77
- $space={$space}
68
+ $fontSize={useArrayProp(fontSize)}
69
+ $padding={useArrayProp(padding)}
70
+ $radius={useArrayProp(radius)}
71
+ $space={useArrayProp(space)}
78
72
  disabled={disabled || readOnly}
79
73
  ref={ref}
80
74
  >
@@ -1,6 +1,6 @@
1
- import {forwardRef, useMemo} from 'react'
1
+ import {forwardRef} from 'react'
2
2
  import {styled} from 'styled-components'
3
- import {_getArrayProp} from '../../styles'
3
+ import {useArrayProp} from '../../hooks'
4
4
  import {Box, BoxProps} from '../box'
5
5
  import {stackBaseStyle, responsiveStackSpaceStyle, ResponsiveStackSpaceStyleProps} from './styles'
6
6
 
@@ -24,14 +24,13 @@ export const Stack = forwardRef(function Stack(
24
24
  ref: React.ForwardedRef<HTMLDivElement>,
25
25
  ) {
26
26
  const {as, space, ...restProps} = props
27
- const $space = useMemo(() => _getArrayProp(space), [space])
28
27
 
29
28
  return (
30
29
  <Root
31
30
  data-as={typeof as === 'string' ? as : undefined}
32
31
  data-ui="Stack"
33
32
  {...restProps}
34
- $space={$space}
33
+ $space={useArrayProp(space)}
35
34
  forwardedAs={as}
36
35
  ref={ref}
37
36
  />
@@ -1,7 +1,7 @@
1
1
  import {ThemeFontWeightKey} from '@sanity/ui/theme'
2
- import {forwardRef, useMemo} from 'react'
2
+ import {forwardRef} from 'react'
3
3
  import {styled} from 'styled-components'
4
- import {_getArrayProp} from '../../styles'
4
+ import {useArrayProp} from '../../hooks'
5
5
  import {
6
6
  ResponsiveFontStyleProps,
7
7
  responsiveTextAlignStyle,
@@ -63,9 +63,6 @@ export const Text = forwardRef(function Text(
63
63
  ...restProps
64
64
  } = props
65
65
 
66
- const $size = useMemo(() => _getArrayProp(size), [size])
67
- const $align = useMemo(() => _getArrayProp(align), [align])
68
-
69
66
  let children = childrenProp
70
67
 
71
68
  if (textOverflow === 'ellipsis') {
@@ -77,10 +74,10 @@ export const Text = forwardRef(function Text(
77
74
  data-ui="Text"
78
75
  {...restProps}
79
76
  $accent={accent}
80
- $align={$align}
81
- $size={$size}
77
+ $align={useArrayProp(align)}
82
78
  $muted={muted}
83
79
  ref={ref}
80
+ $size={useArrayProp(size)}
84
81
  $weight={weight}
85
82
  >
86
83
  <span>{children}</span>
@@ -1,8 +1,7 @@
1
1
  import {ThemeFontWeightKey} from '@sanity/ui/theme'
2
- import {forwardRef, useImperativeHandle, useMemo, useRef} from 'react'
2
+ import {forwardRef, useImperativeHandle, useRef} from 'react'
3
3
  import {styled} from 'styled-components'
4
- import {useCustomValidity} from '../../hooks'
5
- import {_getArrayProp} from '../../styles'
4
+ import {useCustomValidity, useArrayProp} from '../../hooks'
6
5
  import {
7
6
  responsiveInputPaddingStyle,
8
7
  responsiveRadiusStyle,
@@ -81,11 +80,6 @@ export const TextArea = forwardRef(function TextArea(
81
80
 
82
81
  useCustomValidity(ref, customValidity)
83
82
 
84
- const $radius = useMemo(() => _getArrayProp(radius), [radius])
85
- const $fontSize = useMemo(() => _getArrayProp(fontSize), [fontSize])
86
- const $padding = useMemo(() => _getArrayProp(padding), [padding])
87
- const $space = useMemo(() => _getArrayProp(0), [])
88
-
89
83
  return (
90
84
  <Root data-ui="TextArea">
91
85
  <InputRoot>
@@ -94,17 +88,17 @@ export const TextArea = forwardRef(function TextArea(
94
88
  data-scheme={rootTheme.scheme}
95
89
  data-tone={rootTheme.tone}
96
90
  {...restProps}
97
- $fontSize={$fontSize}
98
- $padding={$padding}
99
- $space={$space}
91
+ $fontSize={useArrayProp(fontSize)}
92
+ $padding={useArrayProp(padding)}
100
93
  $scheme={rootTheme.scheme}
94
+ $space={useArrayProp(0)}
101
95
  $tone={rootTheme.tone}
102
96
  $weight={weight}
103
97
  disabled={disabled}
104
98
  ref={ref}
105
99
  />
106
100
  <Presentation
107
- $radius={$radius}
101
+ $radius={useArrayProp(radius)}
108
102
  $scheme={rootTheme.scheme}
109
103
  $tone={rootTheme.tone}
110
104
  data-border={border ? '' : undefined}
@@ -4,8 +4,7 @@ import {forwardRef, isValidElement, useCallback, useImperativeHandle, useMemo, u
4
4
  import {isValidElementType} from 'react-is'
5
5
  import {styled} from 'styled-components'
6
6
  import {EMPTY_RECORD} from '../../constants'
7
- import {useCustomValidity} from '../../hooks'
8
- import {_getArrayProp} from '../../styles'
7
+ import {useArrayProp, useCustomValidity} from '../../hooks'
9
8
  import {
10
9
  responsiveRadiusStyle,
11
10
  ResponsiveRadiusStyleProps,
@@ -178,10 +177,10 @@ export const TextInput = forwardRef(function TextInput(
178
177
 
179
178
  const rootTheme = useRootTheme()
180
179
 
181
- const fontSize = useMemo(() => _getArrayProp(fontSizeProp), [fontSizeProp])
182
- const padding = useMemo(() => _getArrayProp(paddingProp), [paddingProp])
183
- const radius = useMemo(() => _getArrayProp(radiusProp), [radiusProp])
184
- const space = useMemo(() => _getArrayProp(spaceProp), [spaceProp])
180
+ const fontSize = useArrayProp(fontSizeProp)
181
+ const padding = useArrayProp(paddingProp)
182
+ const radius = useArrayProp(radiusProp)
183
+ const space = useArrayProp(spaceProp)
185
184
 
186
185
  // Transient properties
187
186
  const $hasClearButton = Boolean(clearButton)
@@ -24,10 +24,9 @@ import {
24
24
  useImperativeHandle,
25
25
  } from 'react'
26
26
  import {styled} from 'styled-components'
27
- import {usePrefersReducedMotion} from '../../hooks'
27
+ import {useArrayProp, usePrefersReducedMotion} from '../../hooks'
28
28
  import {useDelayedState} from '../../hooks/useDelayedState'
29
29
  import {origin} from '../../middleware/origin'
30
- import {_getArrayProp} from '../../styles'
31
30
  import {useTheme_v2} from '../../theme'
32
31
  import type {Placement} from '../../types'
33
32
  import {
@@ -105,31 +104,25 @@ export const Tooltip = forwardRef(function Tooltip(
105
104
  const {
106
105
  animate: _animate = false,
107
106
  arrow: arrowProp = false,
108
- boundaryElement: _boundaryElement,
107
+ boundaryElement = boundaryElementContext?.element,
109
108
  children: childProp,
110
109
  content,
111
110
  disabled,
112
- fallbackPlacements: _fallbackPlacements,
111
+ fallbackPlacements: fallbackPlacementsProp = props.fallbackPlacements ??
112
+ DEFAULT_FALLBACK_PLACEMENTS[props.placement ?? 'bottom'],
113
113
  padding = 2,
114
114
  placement: placementProp = 'bottom',
115
115
  portal: portalProp,
116
116
  radius = 2,
117
117
  scheme,
118
118
  shadow = 2,
119
- zOffset: _zOffset,
119
+ zOffset = layer.tooltip.zOffset,
120
120
  delay,
121
121
  ...restProps
122
122
  } = props
123
- const zOffset = _zOffset ?? layer.tooltip.zOffset
124
- const fallbackPlacementsProp =
125
- _fallbackPlacements ?? DEFAULT_FALLBACK_PLACEMENTS[props.placement ?? 'bottom']
126
- const boundaryElement = _boundaryElement ?? boundaryElementContext?.element
127
123
  const prefersReducedMotion = usePrefersReducedMotion()
128
124
  const animate = prefersReducedMotion ? false : _animate
129
- const fallbackPlacements = useMemo(
130
- () => _getArrayProp(fallbackPlacementsProp),
131
- [fallbackPlacementsProp],
132
- )
125
+ const fallbackPlacements = useArrayProp(fallbackPlacementsProp)
133
126
  const ref = useRef<HTMLDivElement | null>(null)
134
127
  const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null)
135
128
  const arrowRef = useRef<HTMLDivElement | null>(null)
@@ -298,7 +291,7 @@ export const Tooltip = forwardRef(function Tooltip(
298
291
  useEffect(() => {
299
292
  if (!showTooltip) return
300
293
 
301
- const handleWindowMouseMove = (event: MouseEvent) => {
294
+ function handleWindowMouseMove(event: MouseEvent) {
302
295
  if (!referenceElement) return
303
296
 
304
297
  const isHoveringReference =
@@ -364,6 +357,10 @@ export const Tooltip = forwardRef(function Tooltip(
364
357
  )
365
358
 
366
359
  const childRef = useRef<HTMLElement | null>(null)
360
+
361
+ // Merge refs so that any ref we are overriding is called as well
362
+ useImperativeHandle((childProp as any)?.ref, () => childRef.current)
363
+
367
364
  const child = useMemo(() => {
368
365
  if (!childProp) return null
369
366
 
@@ -24,11 +24,13 @@ export interface ThemeProviderProps {
24
24
  * @public
25
25
  */
26
26
  export function ThemeProvider(props: ThemeProviderProps): React.ReactElement {
27
- const {children} = props
28
27
  const parentTheme = useContext(ThemeContext)
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
@@ -21,16 +21,15 @@ 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
 
27
26
  const ref = useRef<HTMLDivElement | null>(null)
28
27
  const [element, setElement] = useState<HTMLDivElement | null>(null)
29
28
  const elementSize = useElementSize(element)
30
29
  const width = useMemo(() => elementSize?.border.width ?? window.innerWidth, [elementSize])
31
30
 
32
- const max = findMaxBreakpoints(media, width)
33
- const min = findMinBreakpoints(media, width)
31
+ const max = useMemo(() => findMaxBreakpoints(media, width), [media, width])
32
+ const min = useMemo(() => findMinBreakpoints(media, width), [media, width])
34
33
 
35
34
  useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(forwardedRef, () => ref.current)
36
35
 
@@ -8,6 +8,9 @@ describe('getLayerContext', () => {
8
8
  version: 0.0,
9
9
  isTopLayer: true,
10
10
  level: 0,
11
+ registerChild: () => () => {
12
+ //
13
+ },
11
14
  size: 0,
12
15
  zIndex: 0,
13
16
  }
@@ -18,6 +21,7 @@ describe('getLayerContext', () => {
18
21
  version: 0.0,
19
22
  isTopLayer: true,
20
23
  level: 0,
24
+ registerChild: expect.any(Function),
21
25
  size: 0,
22
26
  zIndex: 0,
23
27
  })
@@ -24,6 +24,7 @@ describe('utils/layer', () => {
24
24
  version: 0.0,
25
25
  isTopLayer: true,
26
26
  level: 0,
27
+ registerChild: () => () => undefined,
27
28
  size: 0,
28
29
  zIndex: 0,
29
30
  }
@@ -39,6 +40,7 @@ describe('utils/layer', () => {
39
40
 
40
41
  expect(log.mock.calls[0][0].version).toBe(0.0)
41
42
  expect(log.mock.calls[0][0].isTopLayer).toBe(true)
43
+ expect(typeof log.mock.calls[0][0].registerChild).toBe('function')
42
44
  expect(log.mock.calls[0][0].size).toBe(0)
43
45
  expect(log.mock.calls[0][0].zIndex).toBe(0)
44
46
  })