@sanity/ui 0.37.21 → 0.38.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 (210) hide show
  1. package/lib/dts/src/components/breadcrumbs/breadcrumbs.d.ts.map +1 -1
  2. package/lib/dts/src/components/dialog/dialog.d.ts.map +1 -1
  3. package/lib/dts/src/components/dialog/styles.d.ts +1 -1
  4. package/lib/dts/src/components/dialog/styles.d.ts.map +1 -1
  5. package/lib/dts/src/components/hotkeys/hotkeys.d.ts.map +1 -1
  6. package/lib/dts/src/components/menu/menuGroup.d.ts.map +1 -1
  7. package/lib/dts/src/components/skeleton/skeleton.d.ts.map +1 -1
  8. package/lib/dts/src/hooks/index.d.ts +2 -1
  9. package/lib/dts/src/hooks/index.d.ts.map +1 -1
  10. package/lib/dts/src/hooks/useArrayProp.d.ts +7 -0
  11. package/lib/dts/src/hooks/useArrayProp.d.ts.map +1 -0
  12. package/lib/dts/src/hooks/useElementRect/useElementRect.d.ts +1 -1
  13. package/lib/dts/src/hooks/useElementRect/useElementRect.d.ts.map +1 -1
  14. package/lib/dts/src/hooks/useElementSize.d.ts +7 -0
  15. package/lib/dts/src/hooks/useElementSize.d.ts.map +1 -0
  16. package/lib/dts/src/index.d.ts +1 -0
  17. package/lib/dts/src/index.d.ts.map +1 -1
  18. package/lib/dts/src/observers/elementSizeObserver.d.ts +37 -0
  19. package/lib/dts/src/observers/elementSizeObserver.d.ts.map +1 -0
  20. package/lib/dts/src/observers/index.d.ts +3 -0
  21. package/lib/dts/src/observers/index.d.ts.map +1 -0
  22. package/lib/dts/src/observers/resizeObserver.d.ts +5 -0
  23. package/lib/dts/src/observers/resizeObserver.d.ts.map +1 -0
  24. package/lib/dts/src/primitives/_selectable/selectable.d.ts +1 -2
  25. package/lib/dts/src/primitives/_selectable/selectable.d.ts.map +1 -1
  26. package/lib/dts/src/primitives/avatar/avatar.d.ts.map +1 -1
  27. package/lib/dts/src/primitives/avatar/avatarCounter.d.ts.map +1 -1
  28. package/lib/dts/src/primitives/avatar/avatarStack.d.ts.map +1 -1
  29. package/lib/dts/src/primitives/avatar/styles.d.ts.map +1 -1
  30. package/lib/dts/src/primitives/badge/badge.d.ts.map +1 -1
  31. package/lib/dts/src/primitives/box/box.d.ts.map +1 -1
  32. package/lib/dts/src/primitives/button/button.d.ts.map +1 -1
  33. package/lib/dts/src/primitives/card/card.d.ts.map +1 -1
  34. package/lib/dts/src/primitives/code/code.d.ts.map +1 -1
  35. package/lib/dts/src/primitives/container/container.d.ts.map +1 -1
  36. package/lib/dts/src/primitives/container/styles.d.ts.map +1 -1
  37. package/lib/dts/src/primitives/container/types.d.ts +1 -1
  38. package/lib/dts/src/primitives/container/types.d.ts.map +1 -1
  39. package/lib/dts/src/primitives/flex/flex.d.ts.map +1 -1
  40. package/lib/dts/src/primitives/grid/grid.d.ts.map +1 -1
  41. package/lib/dts/src/primitives/heading/heading.d.ts.map +1 -1
  42. package/lib/dts/src/primitives/inline/inline.d.ts.map +1 -1
  43. package/lib/dts/src/primitives/inline/styles.d.ts.map +1 -1
  44. package/lib/dts/src/primitives/inline/types.d.ts +1 -1
  45. package/lib/dts/src/primitives/inline/types.d.ts.map +1 -1
  46. package/lib/dts/src/primitives/kbd/kbd.d.ts.map +1 -1
  47. package/lib/dts/src/primitives/label/label.d.ts.map +1 -1
  48. package/lib/dts/src/primitives/popover/popover.d.ts.map +1 -1
  49. package/lib/dts/src/primitives/select/styles.d.ts +5 -1
  50. package/lib/dts/src/primitives/select/styles.d.ts.map +1 -1
  51. package/lib/dts/src/primitives/stack/stack.d.ts.map +1 -1
  52. package/lib/dts/src/primitives/stack/styles.d.ts +1 -1
  53. package/lib/dts/src/primitives/stack/styles.d.ts.map +1 -1
  54. package/lib/dts/src/primitives/text/text.d.ts.map +1 -1
  55. package/lib/dts/src/primitives/textArea/textArea.d.ts.map +1 -1
  56. package/lib/dts/src/primitives/textInput/textInput.d.ts.map +1 -1
  57. package/lib/dts/src/primitives/tooltip/tooltip.d.ts.map +1 -1
  58. package/lib/dts/src/primitives/types.d.ts +1 -1
  59. package/lib/dts/src/primitives/types.d.ts.map +1 -1
  60. package/lib/dts/src/styles/border/types.d.ts +5 -5
  61. package/lib/dts/src/styles/border/types.d.ts.map +1 -1
  62. package/lib/dts/src/styles/box/types.d.ts +4 -4
  63. package/lib/dts/src/styles/box/types.d.ts.map +1 -1
  64. package/lib/dts/src/styles/flex/flexItemStyle.d.ts.map +1 -1
  65. package/lib/dts/src/styles/flex/types.d.ts +6 -6
  66. package/lib/dts/src/styles/flex/types.d.ts.map +1 -1
  67. package/lib/dts/src/styles/font/responsiveFont.d.ts.map +1 -1
  68. package/lib/dts/src/styles/font/types.d.ts +3 -3
  69. package/lib/dts/src/styles/font/types.d.ts.map +1 -1
  70. package/lib/dts/src/styles/grid/types.d.ts +14 -14
  71. package/lib/dts/src/styles/grid/types.d.ts.map +1 -1
  72. package/lib/dts/src/styles/helpers.d.ts +4 -4
  73. package/lib/dts/src/styles/helpers.d.ts.map +1 -1
  74. package/lib/dts/src/styles/input/responsiveInputPaddingStyle.d.ts +12 -12
  75. package/lib/dts/src/styles/input/responsiveInputPaddingStyle.d.ts.map +1 -1
  76. package/lib/dts/src/styles/input/textInputStyle.d.ts +7 -2
  77. package/lib/dts/src/styles/input/textInputStyle.d.ts.map +1 -1
  78. package/lib/dts/src/styles/margin/types.d.ts +7 -7
  79. package/lib/dts/src/styles/margin/types.d.ts.map +1 -1
  80. package/lib/dts/src/styles/padding/types.d.ts +7 -7
  81. package/lib/dts/src/styles/padding/types.d.ts.map +1 -1
  82. package/lib/dts/src/styles/radius/types.d.ts +1 -1
  83. package/lib/dts/src/styles/radius/types.d.ts.map +1 -1
  84. package/lib/dts/src/styles/shadow/shadowStyle.d.ts.map +1 -1
  85. package/lib/dts/src/styles/shadow/types.d.ts +1 -1
  86. package/lib/dts/src/styles/shadow/types.d.ts.map +1 -1
  87. package/lib/dts/src/theme/studioTheme/color.d.ts.map +1 -1
  88. package/lib/dts/src/utils/elementQuery/elementQuery.d.ts.map +1 -1
  89. package/lib/dts/src/utils/index.d.ts +0 -1
  90. package/lib/dts/src/utils/index.d.ts.map +1 -1
  91. package/lib/dts/src/utils/virtualList/virtualList.d.ts.map +1 -1
  92. package/lib/sanity-ui.js +734 -573
  93. package/lib/sanity-ui.js.map +1 -1
  94. package/lib/sanity-ui.modern.js +763 -592
  95. package/lib/sanity-ui.modern.js.map +1 -1
  96. package/lib/sanity-ui.module.js +728 -569
  97. package/lib/sanity-ui.module.js.map +1 -1
  98. package/package.json +11 -11
  99. package/src/__workshop__/color/overview.tsx +9 -11
  100. package/src/components/autocomplete/__workshop__/async.tsx +14 -12
  101. package/src/components/autocomplete/__workshop__/constrainedHeight.tsx +36 -0
  102. package/src/components/autocomplete/autocomplete.tsx +2 -2
  103. package/src/components/breadcrumbs/breadcrumbs.tsx +3 -2
  104. package/src/components/dialog/dialog.tsx +17 -9
  105. package/src/components/dialog/styles.ts +4 -4
  106. package/src/components/hotkeys/hotkeys.tsx +3 -1
  107. package/src/components/menu/__workshop__/constrainedInBoundary.tsx +11 -14
  108. package/src/components/menu/__workshop__/groups.tsx +1 -1
  109. package/src/components/menu/menuGroup.tsx +3 -2
  110. package/src/components/menu/menuItem.tsx +3 -3
  111. package/src/components/skeleton/skeleton.tsx +10 -1
  112. package/src/components/skeleton/textSkeleton.tsx +7 -7
  113. package/src/hooks/index.ts +2 -1
  114. package/src/hooks/useArrayProp.ts +23 -0
  115. package/src/hooks/useElementRect/useElementRect.ts +4 -16
  116. package/src/hooks/useElementSize.ts +18 -0
  117. package/src/index.ts +1 -0
  118. package/src/observers/elementSizeObserver.ts +116 -0
  119. package/src/observers/index.ts +2 -0
  120. package/src/{utils → observers}/resizeObserver.ts +1 -3
  121. package/src/primitives/_selectable/selectable.tsx +5 -4
  122. package/src/primitives/avatar/avatar.tsx +7 -5
  123. package/src/primitives/avatar/avatarCounter.tsx +12 -11
  124. package/src/primitives/avatar/avatarStack.tsx +15 -10
  125. package/src/primitives/avatar/styles.ts +2 -2
  126. package/src/primitives/badge/badge.tsx +3 -2
  127. package/src/primitives/box/box.tsx +26 -25
  128. package/src/primitives/button/button.tsx +22 -10
  129. package/src/primitives/card/card.tsx +8 -7
  130. package/src/primitives/checkbox/__workshop__/example.tsx +4 -2
  131. package/src/primitives/checkbox/__workshop__/props.tsx +4 -2
  132. package/src/primitives/checkbox/__workshop__/readOnly.tsx +4 -2
  133. package/src/primitives/code/__workshop__/props.tsx +1 -1
  134. package/src/primitives/code/code.tsx +2 -1
  135. package/src/primitives/container/container.tsx +10 -1
  136. package/src/primitives/container/styles.ts +2 -2
  137. package/src/primitives/container/types.ts +1 -1
  138. package/src/primitives/flex/flex.tsx +6 -5
  139. package/src/primitives/grid/__workshop__/responsive.tsx +13 -12
  140. package/src/primitives/grid/grid.tsx +9 -8
  141. package/src/primitives/heading/__workshop__/opticalAlignment.tsx +19 -7
  142. package/src/primitives/heading/heading.tsx +3 -2
  143. package/src/primitives/inline/inline.tsx +12 -6
  144. package/src/primitives/inline/styles.ts +2 -2
  145. package/src/primitives/inline/types.ts +1 -1
  146. package/src/primitives/kbd/kbd.tsx +2 -1
  147. package/src/primitives/label/label.tsx +4 -3
  148. package/src/primitives/popover/__workshop__/{margins.tsx → MarginsStory.tsx} +1 -1
  149. package/src/primitives/popover/__workshop__/{matchReferenceWidth.tsx → MatchReferenceWidthStory.tsx} +0 -0
  150. package/src/primitives/popover/__workshop__/{plain.tsx → PlainStory.tsx} +12 -14
  151. package/src/primitives/popover/__workshop__/{recursive.tsx → RecursiveStory.tsx} +4 -1
  152. package/src/primitives/popover/__workshop__/RightAlignedStory.tsx +60 -0
  153. package/src/primitives/popover/__workshop__/TestStory.tsx +79 -0
  154. package/src/primitives/popover/__workshop__/index.ts +10 -5
  155. package/src/primitives/popover/popover.tsx +29 -10
  156. package/src/primitives/select/select.tsx +9 -9
  157. package/src/primitives/select/styles.ts +10 -4
  158. package/src/primitives/stack/stack.tsx +2 -1
  159. package/src/primitives/stack/styles.ts +3 -3
  160. package/src/primitives/text/__workshop__/opticalAlignment.tsx +15 -5
  161. package/src/primitives/text/text.tsx +3 -2
  162. package/src/primitives/textArea/__workshop__/plain.tsx +23 -18
  163. package/src/primitives/textArea/textArea.tsx +21 -5
  164. package/src/primitives/textInput/__workshop__/clearButton.tsx +14 -8
  165. package/src/primitives/textInput/__workshop__/index.ts +2 -2
  166. package/src/primitives/textInput/__workshop__/plain.tsx +39 -32
  167. package/src/primitives/textInput/__workshop__/tones.tsx +234 -95
  168. package/src/primitives/textInput/__workshop__/typed.tsx +8 -2
  169. package/src/primitives/textInput/textInput.tsx +47 -12
  170. package/src/primitives/tooltip/__workshop__/props.tsx +7 -2
  171. package/src/primitives/tooltip/tooltip.tsx +19 -9
  172. package/src/primitives/types.ts +1 -1
  173. package/src/styles/border/borderStyle.ts +6 -6
  174. package/src/styles/border/types.ts +5 -5
  175. package/src/styles/box/boxStyle.ts +5 -5
  176. package/src/styles/box/types.ts +4 -4
  177. package/src/styles/flex/flexItemStyle.ts +5 -4
  178. package/src/styles/flex/flexStyle.ts +6 -6
  179. package/src/styles/flex/types.ts +6 -6
  180. package/src/styles/font/responsiveFont.ts +2 -4
  181. package/src/styles/font/textAlignStyle.ts +2 -2
  182. package/src/styles/font/types.ts +4 -3
  183. package/src/styles/grid/gridItemStyle.ts +7 -7
  184. package/src/styles/grid/gridStyle.ts +9 -9
  185. package/src/styles/grid/types.ts +14 -14
  186. package/src/styles/helpers.ts +9 -9
  187. package/src/styles/input/responsiveInputPaddingStyle.ts +24 -27
  188. package/src/styles/input/textInputStyle.ts +92 -80
  189. package/src/styles/margin/marginStyle.ts +8 -8
  190. package/src/styles/margin/marginsStyle.test.ts +1 -1
  191. package/src/styles/margin/types.ts +7 -7
  192. package/src/styles/padding/paddingStyle.test.ts +1 -1
  193. package/src/styles/padding/paddingStyle.ts +8 -8
  194. package/src/styles/padding/types.ts +7 -7
  195. package/src/styles/radius/radiusStyle.ts +2 -2
  196. package/src/styles/radius/types.ts +1 -1
  197. package/src/styles/shadow/shadowStyle.ts +2 -5
  198. package/src/styles/shadow/types.ts +1 -1
  199. package/src/theme/studioTheme/color.ts +15 -14
  200. package/src/theme/studioTheme/fonts.ts +4 -4
  201. package/src/utils/elementQuery/elementQuery.tsx +5 -18
  202. package/src/utils/index.ts +0 -1
  203. package/src/utils/layer/layerProvider.tsx +2 -2
  204. package/src/utils/virtualList/virtualList.tsx +3 -1
  205. package/lib/dts/src/hooks/useResponsiveProp.d.ts +0 -6
  206. package/lib/dts/src/hooks/useResponsiveProp.d.ts.map +0 -1
  207. package/lib/dts/src/utils/resizeObserver.d.ts +0 -6
  208. package/lib/dts/src/utils/resizeObserver.d.ts.map +0 -1
  209. package/src/hooks/useResponsiveProp.ts +0 -10
  210. package/src/primitives/popover/__workshop__/rightAligned.tsx +0 -57
@@ -10,41 +10,42 @@ export default function ResponsiveStory() {
10
10
  columns={[1, 2, 3, 4, 5, 6, 7]}
11
11
  gap={[0, 1, 2, 3, 4, 5, 6]}
12
12
  rows={[1, 2, 3, 4, 5, 6, 7]}
13
+ style={{textAlign: 'center'}}
13
14
  >
14
- <Card tone="transparent">
15
+ <Card padding={[1, 2, 3]} tone="transparent">
15
16
  <Code>1</Code>
16
17
  </Card>
17
- <Card tone="transparent">
18
+ <Card padding={[1, 2, 3]} tone="transparent">
18
19
  <Code>2</Code>
19
20
  </Card>
20
- <Card tone="transparent">
21
+ <Card padding={[1, 2, 3]} tone="transparent">
21
22
  <Code>3</Code>
22
23
  </Card>
23
- <Card tone="transparent">
24
+ <Card padding={[1, 2, 3]} tone="transparent">
24
25
  <Code>4</Code>
25
26
  </Card>
26
- <Card tone="transparent">
27
+ <Card padding={[1, 2, 3]} tone="transparent">
27
28
  <Code>5</Code>
28
29
  </Card>
29
- <Card tone="transparent">
30
+ <Card padding={[1, 2, 3]} tone="transparent">
30
31
  <Code>6</Code>
31
32
  </Card>
32
- <Card tone="transparent">
33
+ <Card padding={[1, 2, 3]} tone="transparent">
33
34
  <Code>7</Code>
34
35
  </Card>
35
- <Card tone="transparent">
36
+ <Card padding={[1, 2, 3]} tone="transparent">
36
37
  <Code>8</Code>
37
38
  </Card>
38
- <Card tone="transparent">
39
+ <Card padding={[1, 2, 3]} tone="transparent">
39
40
  <Code>9</Code>
40
41
  </Card>
41
- <Card tone="transparent">
42
+ <Card padding={[1, 2, 3]} tone="transparent">
42
43
  <Code>10</Code>
43
44
  </Card>
44
- <Card tone="transparent">
45
+ <Card padding={[1, 2, 3]} tone="transparent">
45
46
  <Code>11</Code>
46
47
  </Card>
47
- <Card tone="transparent">
48
+ <Card padding={[1, 2, 3]} tone="transparent">
48
49
  <Code>12</Code>
49
50
  </Card>
50
51
  </Grid>
@@ -1,5 +1,6 @@
1
1
  import React, {forwardRef} from 'react'
2
2
  import styled from 'styled-components'
3
+ import {useArrayProp} from '../../hooks'
3
4
  import {responsiveGridStyle, ResponsiveGridStyleProps} from '../../styles/internal'
4
5
  import {Box, BoxProps} from '../box'
5
6
  import {ResponsiveGridProps} from '../types'
@@ -26,14 +27,14 @@ export const Grid = forwardRef(function Grid(
26
27
  data-as={typeof as === 'string' ? as : undefined}
27
28
  data-ui="Grid"
28
29
  {...restProps}
29
- $autoRows={autoRows}
30
- $autoCols={autoCols}
31
- $autoFlow={autoFlow}
32
- $columns={columns}
33
- $gap={gap}
34
- $gapX={gapX}
35
- $gapY={gapY}
36
- $rows={rows}
30
+ $autoRows={useArrayProp(autoRows)}
31
+ $autoCols={useArrayProp(autoCols)}
32
+ $autoFlow={useArrayProp(autoFlow)}
33
+ $columns={useArrayProp(columns)}
34
+ $gap={useArrayProp(gap)}
35
+ $gapX={useArrayProp(gapX)}
36
+ $gapY={useArrayProp(gapY)}
37
+ $rows={useArrayProp(rows)}
37
38
  forwardedAs={as}
38
39
  ref={ref}
39
40
  >
@@ -8,43 +8,55 @@ export default function OpticalAlignment() {
8
8
  <Stack space={1}>
9
9
  <Flex>
10
10
  <Card padding={0} scheme="dark">
11
- <Heading size={5}>Hamburgefonstiv M</Heading>
11
+ <Heading accent size={5}>
12
+ Hamburgefonstiv M
13
+ </Heading>
12
14
  </Card>
13
15
  </Flex>
14
16
 
15
17
  <Flex>
16
18
  <Card padding={0} scheme="dark">
17
- <Heading size={4}>Hamburgefonstiv M</Heading>
19
+ <Heading accent size={4}>
20
+ Hamburgefonstiv M
21
+ </Heading>
18
22
  </Card>
19
23
  </Flex>
20
24
 
21
25
  <Flex>
22
26
  <Card padding={0} scheme="dark">
23
- <Heading size={3}>Hamburgefonstiv M</Heading>
27
+ <Heading accent size={3}>
28
+ Hamburgefonstiv M
29
+ </Heading>
24
30
  </Card>
25
31
  </Flex>
26
32
 
27
33
  <Flex>
28
34
  <Card padding={0} scheme="dark">
29
- <Heading size={2}>Hamburgefonstiv M</Heading>
35
+ <Heading accent size={2}>
36
+ Hamburgefonstiv M
37
+ </Heading>
30
38
  </Card>
31
39
  </Flex>
32
40
 
33
41
  <Flex>
34
42
  <Card padding={0} scheme="dark">
35
- <Heading size={1}>Hamburgefonstiv M</Heading>
43
+ <Heading accent size={1}>
44
+ Hamburgefonstiv M
45
+ </Heading>
36
46
  </Card>
37
47
  </Flex>
38
48
 
39
49
  <Flex>
40
50
  <Card padding={0} scheme="dark">
41
- <Heading size={0}>Hamburgefonstiv M</Heading>
51
+ <Heading accent size={0}>
52
+ Hamburgefonstiv M
53
+ </Heading>
42
54
  </Card>
43
55
  </Flex>
44
56
 
45
57
  <Flex>
46
58
  <Card padding={2} scheme="dark">
47
- <Heading>
59
+ <Heading accent>
48
60
  <AddCircleIcon />
49
61
  </Heading>
50
62
  </Card>
@@ -1,5 +1,6 @@
1
1
  import React, {forwardRef} from 'react'
2
2
  import styled from 'styled-components'
3
+ import {useArrayProp} from '../../hooks'
3
4
  import {
4
5
  ResponsiveFontStyleProps,
5
6
  responsiveHeadingFont,
@@ -69,9 +70,9 @@ export const Heading = forwardRef(function Heading(
69
70
  data-ui="Heading"
70
71
  {...restProps}
71
72
  $accent={accent}
72
- $align={align}
73
+ $align={useArrayProp(align)}
73
74
  $muted={muted}
74
- $size={size}
75
+ $size={useArrayProp(size)}
75
76
  $weight={weight}
76
77
  ref={ref}
77
78
  >
@@ -1,5 +1,6 @@
1
- import React, {forwardRef} from 'react'
1
+ import React, {forwardRef, useMemo} from 'react'
2
2
  import styled from 'styled-components'
3
+ import {useArrayProp} from '../../hooks'
3
4
  import {Box, BoxProps} from '../box'
4
5
  import {childrenToElementArray} from '../helpers'
5
6
  import {inlineBaseStyle, inlineSpaceStyle} from './styles'
@@ -22,13 +23,18 @@ export const Inline = forwardRef(function Inline(
22
23
  ref
23
24
  ) {
24
25
  const {as, children: childrenProp, space, ...restProps} = props
25
- const children = childrenToElementArray(childrenProp).filter(Boolean)
26
+
27
+ const children = useMemo(
28
+ () =>
29
+ childrenToElementArray(childrenProp)
30
+ .filter(Boolean)
31
+ .map((child, idx) => <div key={idx}>{child}</div>),
32
+ [childrenProp]
33
+ )
26
34
 
27
35
  return (
28
- <Root data-ui="Inline" {...restProps} $space={space} forwardedAs={as} ref={ref}>
29
- {children.map((child, idx) => (
30
- <div key={idx}>{child}</div>
31
- ))}
36
+ <Root data-ui="Inline" {...restProps} $space={useArrayProp(space)} forwardedAs={as} ref={ref}>
37
+ {children}
32
38
  </Root>
33
39
  )
34
40
  })
@@ -1,5 +1,5 @@
1
1
  import {CSSObject} from 'styled-components'
2
- import {getResponsiveProp, rem, responsive, ThemeProps} from '../../styles'
2
+ import {rem, _responsive, ThemeProps} from '../../styles'
3
3
  import {ResponsiveInlineSpaceStyleProps} from './types'
4
4
 
5
5
  export function inlineBaseStyle(): CSSObject {
@@ -20,7 +20,7 @@ export function inlineBaseStyle(): CSSObject {
20
20
  export function inlineSpaceStyle(props: ResponsiveInlineSpaceStyleProps & ThemeProps): CSSObject[] {
21
21
  const {theme} = props
22
22
 
23
- return responsive(theme.sanity.media, getResponsiveProp(props.$space), (spaceIndex) => {
23
+ return _responsive(theme.sanity.media, props.$space, (spaceIndex) => {
24
24
  const space = rem(theme.sanity.space[spaceIndex])
25
25
 
26
26
  return {
@@ -2,5 +2,5 @@
2
2
  * @internal
3
3
  */
4
4
  export interface ResponsiveInlineSpaceStyleProps {
5
- $space?: number | number[]
5
+ $space: number[]
6
6
  }
@@ -1,5 +1,6 @@
1
1
  import React, {forwardRef} from 'react'
2
2
  import styled, {css} from 'styled-components'
3
+ import {useArrayProp} from '../../hooks'
3
4
  import {responsiveRadiusStyle, ResponsiveRadiusStyleProps} from '../../styles/internal'
4
5
  import {Box} from '../box'
5
6
  import {Code} from '../code'
@@ -38,7 +39,7 @@ export const KBD = forwardRef(function KBD(
38
39
  const {children, fontSize = 1, padding = 1, radius = 2, ...restProps} = props
39
40
 
40
41
  return (
41
- <Root data-ui="KBD" {...restProps} $radius={radius} ref={ref}>
42
+ <Root data-ui="KBD" {...restProps} $radius={useArrayProp(radius)} ref={ref}>
42
43
  <Box as="span" padding={padding}>
43
44
  <Code as="span" muted size={fontSize}>
44
45
  {children}
@@ -1,5 +1,6 @@
1
1
  import React, {forwardRef} from 'react'
2
2
  import styled from 'styled-components'
3
+ import {useArrayProp} from '../../hooks'
3
4
  import {responsiveLabelFont, responsiveTextAlignStyle} from '../../styles/internal'
4
5
  import {ThemeFontWeightKey} from '../../theme'
5
6
  import {TextAlign} from '../../types'
@@ -25,7 +26,7 @@ export interface LabelProps {
25
26
 
26
27
  const Root = styled.div<{
27
28
  $accent?: boolean
28
- $align?: TextAlign | TextAlign[]
29
+ $align: TextAlign[]
29
30
  $muted: boolean
30
31
  $size: number[]
31
32
  }>(responsiveLabelFont, responsiveTextAlignStyle, labelBaseStyle)
@@ -68,9 +69,9 @@ export const Label = forwardRef(function Label(
68
69
  data-ui="Label"
69
70
  {...restProps}
70
71
  $accent={accent}
71
- $align={align}
72
+ $align={useArrayProp(align)}
72
73
  $muted={muted}
73
- $size={size}
74
+ $size={useArrayProp(size)}
74
75
  $weight={weight}
75
76
  ref={ref}
76
77
  >
@@ -5,7 +5,7 @@ export default function MarginsStory() {
5
5
  return (
6
6
  <Flex align="center" height="fill" justify="center" padding={[4, 5, 6]} sizing="border">
7
7
  <Popover
8
- __unstable_margins={[-5, -5, -5, -5]}
8
+ __unstable_margins={[-8, 8, -8, 8]}
9
9
  arrow={false}
10
10
  content={
11
11
  <Box padding={2}>
@@ -1,5 +1,5 @@
1
1
  import {Button, Card, Popover, PortalProvider, Text} from '@sanity/ui'
2
- import {useBoolean, useSelect, useText} from '@sanity/ui-workshop'
2
+ import {useBoolean, useSelect} from '@sanity/ui-workshop'
3
3
  import React, {useState} from 'react'
4
4
  import {
5
5
  WORKSHOP_CONTAINER_WIDTH_OPTIONS,
@@ -9,18 +9,17 @@ import {
9
9
  } from '../../../__workshop__/constants'
10
10
 
11
11
  export default function PlainStory() {
12
- const arrow = useBoolean('Arrow', true, 'Props')
13
- const boundaryElementFlag = useBoolean('Boundary element', true, 'Props')
14
- const content = useText('Content', 'Hello, world', 'Props')
15
- const constrainSize = useBoolean('Constrain size', true, 'Props')
16
- const matchReferenceWidth = useBoolean('Match reference width', false, 'Props')
17
- const open = useBoolean('Open', true, 'Props')
18
- const padding = useSelect('Padding', WORKSHOP_SPACE_OPTIONS, 3, 'Props')
19
- const placement = useSelect('Placement', WORKSHOP_PLACEMENT_OPTIONS, 'bottom', 'Props')
20
- const portal = useBoolean('Portal', true, 'Props')
21
- const preventOverflow = useBoolean('Prevent overflow', true, 'Props')
22
- const radius = useSelect('Radius', WORKSHOP_RADIUS_OPTIONS, 2, 'Props')
23
- const width = useSelect('Width', WORKSHOP_CONTAINER_WIDTH_OPTIONS, 'auto', 'Props')
12
+ const arrow = useBoolean('Arrow', true)
13
+ const boundaryElementFlag = useBoolean('Boundary element', true)
14
+ const constrainSize = useBoolean('Constrain size', true)
15
+ const matchReferenceWidth = useBoolean('Match reference width', false)
16
+ const open = useBoolean('Open', true)
17
+ const padding = useSelect('Padding', WORKSHOP_SPACE_OPTIONS, 3)
18
+ const placement = useSelect('Placement', WORKSHOP_PLACEMENT_OPTIONS, 'bottom')
19
+ const portal = useBoolean('Portal', true)
20
+ const preventOverflow = useBoolean('Prevent overflow', true)
21
+ const radius = useSelect('Radius', WORKSHOP_RADIUS_OPTIONS, 2)
22
+ const width = useSelect('Width', WORKSHOP_CONTAINER_WIDTH_OPTIONS, 'auto')
24
23
  const [portalElement, setPortalElement] = useState<HTMLDivElement | null>(null)
25
24
  const [boundaryElement, setBoundaryElement] = useState<HTMLDivElement | null>(null)
26
25
 
@@ -46,7 +45,6 @@ export default function PlainStory() {
46
45
  __unstable_margins={[1, 1, 1, 1]}
47
46
  arrow={arrow}
48
47
  boundaryElement={boundaryElementFlag ? boundaryElement : undefined}
49
- content={<Text>{content}</Text>}
50
48
  constrainSize={constrainSize}
51
49
  fallbackPlacements={['top', 'bottom']}
52
50
  matchReferenceWidth={matchReferenceWidth}
@@ -39,7 +39,9 @@ function RecursiveExample({onClose}: {onClose?: () => void}) {
39
39
  }, [open])
40
40
 
41
41
  useEffect(() => {
42
- buttonRef.current?.focus()
42
+ setTimeout(() => {
43
+ buttonRef.current?.focus()
44
+ }, 0)
43
45
  }, [])
44
46
 
45
47
  const handleOpen = useCallback(() => setOpen(true), [])
@@ -58,6 +60,7 @@ function RecursiveExample({onClose}: {onClose?: () => void}) {
58
60
  fallbackPlacements={fallbackPlacements}
59
61
  content={<RecursiveExample onClose={handleClose} />}
60
62
  open={open}
63
+ padding={1}
61
64
  placement={fallbackPlacements[3]}
62
65
  portal
63
66
  tone={tones[seed]}
@@ -0,0 +1,60 @@
1
+ import {EllipsisVerticalIcon} from '@sanity/icons'
2
+ import {Button, Card, Flex, Popover, Text, useClickOutside} from '@sanity/ui'
3
+ import {useBoolean} from '@sanity/ui-workshop'
4
+ import React, {useCallback, useState} from 'react'
5
+
6
+ export default function RightAlignedStory() {
7
+ const constrainSize = useBoolean('Constrain size', false)
8
+
9
+ const [open, setOpen] = useState(false)
10
+ const [boundaryElement, setBoundaryElement] = useState<HTMLDivElement | null>(null)
11
+ const [buttonElement, setButtonElement] = useState<HTMLButtonElement | null>(null)
12
+ const [popoverElement, setPopoverElement] = useState<HTMLDivElement | null>(null)
13
+
14
+ const content = (
15
+ <Text>
16
+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Quisque at nisl at sem tempor
17
+ hendrerit scelerisque ut libero. Maecenas iaculis efficitur lorem, ac faucibus mi imperdiet
18
+ quis. Cras a consectetur erat. Fusce imperdiet, dolor et pellentesque iaculis, ex quam luctus
19
+ felis, non ultrices enim sem vitae quam. Duis lorem velit, lacinia at rhoncus a, tempus vel
20
+ neque. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia curae;
21
+ Sed id mauris quam. Nam finibus sapien non lacinia ultricies. Integer fermentum tortor at
22
+ pellentesque faucibus. In venenatis commodo placerat. Curabitur commodo tortor libero, vel
23
+ pellentesque elit luctus sodales. Donec mattis tristique nunc ac lacinia. Vestibulum non
24
+ pulvinar turpis, posuere consequat arcu. Fusce ut urna blandit, finibus nisi a, molestie elit.
25
+ Nulla sed eleifend mi.
26
+ </Text>
27
+ )
28
+
29
+ const handleToggleOpen = useCallback(() => setOpen((v) => !v), [])
30
+ const handleClose = useCallback(() => setOpen(false), [])
31
+
32
+ useClickOutside(handleClose, [buttonElement, popoverElement])
33
+
34
+ return (
35
+ <Card height="fill" padding={[4, 5, 6]} sizing="border" tone="transparent">
36
+ <Card height="fill" padding={2} ref={setBoundaryElement} shadow={1}>
37
+ <Flex justify="flex-end" padding={0}>
38
+ <Popover
39
+ boundaryElement={boundaryElement}
40
+ constrainSize={constrainSize}
41
+ content={content}
42
+ open={open}
43
+ padding={3}
44
+ portal
45
+ placement="bottom"
46
+ ref={setPopoverElement}
47
+ >
48
+ <Button
49
+ icon={EllipsisVerticalIcon}
50
+ mode="bleed"
51
+ onClick={handleToggleOpen}
52
+ ref={setButtonElement}
53
+ selected={open}
54
+ />
55
+ </Popover>
56
+ </Flex>
57
+ </Card>
58
+ </Card>
59
+ )
60
+ }
@@ -0,0 +1,79 @@
1
+ import {useBoolean, useSelect, useText} from '@sanity/ui-workshop'
2
+ import React, {ReactElement, useState} from 'react'
3
+ import {
4
+ WORKSHOP_CONTAINER_WIDTH_OPTIONS,
5
+ WORKSHOP_PLACEMENT_OPTIONS,
6
+ WORKSHOP_RADIUS_OPTIONS,
7
+ } from '../../../__workshop__/constants'
8
+ import {BoundaryElementProvider, PortalProvider} from '../../../utils'
9
+ import {Button} from '../../button'
10
+ import {Card} from '../../card'
11
+ import {Text} from '../../text'
12
+ import {Popover} from '../popover'
13
+
14
+ export default function TestStory(): ReactElement {
15
+ const [portalElement, setPortalElement] = useState<HTMLDivElement | null>(null)
16
+ const [boundaryElement, setBoundaryElement] = useState<HTMLDivElement | null>(null)
17
+ const arrow = useBoolean('Arrow', true)
18
+ const matchReferenceWidth = useBoolean('Match reference width', false)
19
+ const open = useBoolean('Open', true)
20
+ const placement = useSelect('Placement', WORKSHOP_PLACEMENT_OPTIONS, 'bottom')
21
+ const preventOverflow = useBoolean('Prevent overflow', true)
22
+ const radius = useSelect('Radius', WORKSHOP_RADIUS_OPTIONS, 2)
23
+ const referenceWide = useBoolean('Reference wide?', false)
24
+ const width = useSelect('Width', WORKSHOP_CONTAINER_WIDTH_OPTIONS, 'auto')
25
+
26
+ const text = useText('Text', 'Test')
27
+
28
+ return (
29
+ <Card
30
+ ref={setBoundaryElement}
31
+ shadow={2}
32
+ style={{
33
+ position: 'absolute',
34
+ top: 50,
35
+ right: 50,
36
+ bottom: 50,
37
+ left: 50,
38
+ }}
39
+ >
40
+ <div
41
+ data-portal=""
42
+ ref={setPortalElement}
43
+ style={{
44
+ position: 'absolute',
45
+ top: 0,
46
+ right: 0,
47
+ bottom: 0,
48
+ left: 0,
49
+ overflow: 'hidden',
50
+ pointerEvents: 'none',
51
+ }}
52
+ />
53
+
54
+ <div style={{width: '100%', height: '100%', overflow: 'auto'}}>
55
+ <div style={{padding: '150vh'}}>
56
+ <PortalProvider element={portalElement}>
57
+ <BoundaryElementProvider element={boundaryElement}>
58
+ <Popover
59
+ arrow={arrow}
60
+ content={<Text size={1}>{text}</Text>}
61
+ fallbackPlacements={['left', 'bottom', 'right', 'top']}
62
+ matchReferenceWidth={matchReferenceWidth}
63
+ open={open}
64
+ padding={3}
65
+ placement={placement}
66
+ portal
67
+ preventOverflow={preventOverflow}
68
+ radius={radius}
69
+ width={width}
70
+ >
71
+ <Button text="reference" style={{width: referenceWide ? 300 : undefined}} />
72
+ </Popover>
73
+ </BoundaryElementProvider>
74
+ </PortalProvider>
75
+ </div>
76
+ </div>
77
+ </Card>
78
+ )
79
+ }
@@ -2,29 +2,34 @@ import {defineScope} from '@sanity/ui-workshop'
2
2
  import {lazy} from 'react'
3
3
 
4
4
  export default defineScope('primitives/popover', 'Popover', [
5
+ {
6
+ name: 'test',
7
+ title: 'Test',
8
+ component: lazy(() => import('./TestStory')),
9
+ },
5
10
  {
6
11
  name: 'plain',
7
12
  title: 'Plain',
8
- component: lazy(() => import('./plain')),
13
+ component: lazy(() => import('./PlainStory')),
9
14
  },
10
15
  {
11
16
  name: 'recursive',
12
17
  title: 'Recursive',
13
- component: lazy(() => import('./recursive')),
18
+ component: lazy(() => import('./RecursiveStory')),
14
19
  },
15
20
  {
16
21
  name: 'match-ref-width',
17
22
  title: 'Match reference width',
18
- component: lazy(() => import('./matchReferenceWidth')),
23
+ component: lazy(() => import('./MatchReferenceWidthStory')),
19
24
  },
20
25
  {
21
26
  name: 'margins',
22
27
  title: 'Margins',
23
- component: lazy(() => import('./margins')),
28
+ component: lazy(() => import('./MarginsStory')),
24
29
  },
25
30
  {
26
31
  name: 'right-aligned',
27
32
  title: 'Right-aligned',
28
- component: lazy(() => import('./rightAligned')),
33
+ component: lazy(() => import('./RightAlignedStory')),
29
34
  },
30
35
  ])
@@ -1,8 +1,16 @@
1
- import React, {cloneElement, forwardRef, useCallback, useEffect, useMemo, useState} from 'react'
1
+ import React, {
2
+ cloneElement,
3
+ forwardRef,
4
+ useCallback,
5
+ useEffect,
6
+ useMemo,
7
+ useRef,
8
+ useState,
9
+ } from 'react'
2
10
  import {usePopper} from 'react-popper'
3
11
  import styled, {css} from 'styled-components'
4
12
  import {EMPTY_RECORD} from '../../constants'
5
- import {useForwardedRef} from '../../hooks'
13
+ import {useArrayProp, useForwardedRef} from '../../hooks'
6
14
  import {ThemeColorSchemeKey, useTheme} from '../../theme'
7
15
  import {CardTone, Placement, PopoverMargins} from '../../types'
8
16
  import {Layer, LayerProps, Portal, useBoundaryElement, usePortal} from '../../utils'
@@ -71,6 +79,7 @@ const PopoverCard = styled(Card)<
71
79
  ResponsiveWidthStyleProps & {
72
80
  $constrainSize?: boolean
73
81
  $preventOverflow?: boolean
82
+ $width: (number | 'auto')[]
74
83
  }
75
84
  >(
76
85
  ({$constrainSize}) => css`
@@ -126,7 +135,7 @@ export const Popover = forwardRef(function Popover(
126
135
  tether,
127
136
  tetherOffset,
128
137
  tone = 'inherit',
129
- width = 0,
138
+ width: widthProp = 0,
130
139
  zOffset = theme.sanity.layer?.popover.zOffset,
131
140
  ...restProps
132
141
  } = props
@@ -136,6 +145,7 @@ export const Popover = forwardRef(function Popover(
136
145
  const [popperElement, setPopperElement] = useState<HTMLElement | null>(null)
137
146
  const [arrowElement, setArrowElement] = useState<HTMLElement | null>(null)
138
147
  const popperReferenceElement = referenceElementProp || referenceElement
148
+ const width = useArrayProp(matchReferenceWidth ? 'auto' : widthProp)
139
149
 
140
150
  const modifiers = usePopoverModifiers({
141
151
  allowedAutoPlacements,
@@ -186,14 +196,23 @@ export const Popover = forwardRef(function Popover(
186
196
 
187
197
  const popoverStyle = useMemo(() => ({...style, ...styles.popper}), [style, styles])
188
198
 
199
+ const updateTimeoutRef = useRef<NodeJS.Timeout | null>(null)
200
+
189
201
  useEffect(() => {
190
- if (forceUpdate) {
191
- try {
192
- forceUpdate()
193
- } catch (_) {
194
- // ignore caught error
195
- }
202
+ if (updateTimeoutRef.current) {
203
+ clearTimeout(updateTimeoutRef.current)
204
+ updateTimeoutRef.current = null
196
205
  }
206
+
207
+ updateTimeoutRef.current = setTimeout(() => {
208
+ if (forceUpdate) {
209
+ try {
210
+ forceUpdate()
211
+ } catch (_) {
212
+ // ignore caught error
213
+ }
214
+ }
215
+ }, 0)
197
216
  }, [content, forceUpdate, open, popperReferenceElement])
198
217
 
199
218
  if (disabled) {
@@ -212,13 +231,13 @@ export const Popover = forwardRef(function Popover(
212
231
  >
213
232
  <PopoverCard
214
233
  $constrainSize={constrainSize}
234
+ $width={width}
215
235
  data-ui="PopoverCard"
216
236
  padding={padding}
217
237
  radius={radius}
218
238
  scheme={scheme}
219
239
  shadow={shadow}
220
240
  tone={tone}
221
- width={width as any}
222
241
  >
223
242
  {arrow && <PopoverArrow ref={setArrowElement} style={styles.arrow} />}
224
243
  {content}
@@ -1,7 +1,7 @@
1
1
  import {SelectIcon} from '@sanity/icons'
2
2
  import React, {forwardRef} from 'react'
3
3
  import styled from 'styled-components'
4
- import {useForwardedRef, useCustomValidity} from '../../hooks'
4
+ import {useForwardedRef, useCustomValidity, useArrayProp} from '../../hooks'
5
5
  import {Box} from '../box'
6
6
  import {Text} from '../text'
7
7
  import {selectStyle} from './styles'
@@ -20,10 +20,10 @@ export interface SelectProps {
20
20
  const Root = styled.div(selectStyle.root)
21
21
 
22
22
  const Input = styled.select<{
23
- $fontSize?: number | number[]
24
- $padding?: number | number[]
25
- $radius?: number | number[]
26
- $space?: number | number[]
23
+ $fontSize: number[]
24
+ $padding: number[]
25
+ $radius: number[]
26
+ $space: number[]
27
27
  }>(selectStyle.input)
28
28
 
29
29
  const IconBox = styled(Box)(selectStyle.iconBox)
@@ -57,10 +57,10 @@ export const Select = forwardRef(function Select(
57
57
  data-read-only={!disabled && readOnly ? '' : undefined}
58
58
  data-ui="Select"
59
59
  {...restProps}
60
- $fontSize={fontSize}
61
- $padding={padding}
62
- $radius={radius}
63
- $space={space}
60
+ $fontSize={useArrayProp(fontSize)}
61
+ $padding={useArrayProp(padding)}
62
+ $radius={useArrayProp(radius)}
63
+ $space={useArrayProp(space)}
64
64
  disabled={disabled || readOnly}
65
65
  ref={ref}
66
66
  >