@sanity/ui 0.37.12 → 0.37.14-next.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 (269) hide show
  1. package/lib/dts/src/components/autocomplete/autocomplete.d.ts +2 -2
  2. package/lib/dts/src/components/autocomplete/autocomplete.d.ts.map +1 -1
  3. package/lib/dts/src/components/autocomplete/autocomplete.styles.d.ts +1 -1
  4. package/lib/dts/src/components/autocomplete/autocomplete.styles.d.ts.map +1 -1
  5. package/lib/dts/src/components/autocomplete/constants.d.ts +0 -4
  6. package/lib/dts/src/components/autocomplete/constants.d.ts.map +1 -1
  7. package/lib/dts/src/components/breadcrumbs/breadcrumbs.d.ts.map +1 -1
  8. package/lib/dts/src/components/dialog/dialog.d.ts.map +1 -1
  9. package/lib/dts/src/components/dialog/styles.d.ts +1 -1
  10. package/lib/dts/src/components/dialog/styles.d.ts.map +1 -1
  11. package/lib/dts/src/components/hotkeys/hotkeys.d.ts.map +1 -1
  12. package/lib/dts/src/components/menu/menuButton.d.ts.map +1 -1
  13. package/lib/dts/src/components/menu/menuGroup.d.ts.map +1 -1
  14. package/lib/dts/src/components/menu/menuItem.d.ts.map +1 -1
  15. package/lib/dts/src/components/skeleton/skeleton.d.ts.map +1 -1
  16. package/lib/dts/src/constants.d.ts +10 -0
  17. package/lib/dts/src/constants.d.ts.map +1 -1
  18. package/lib/dts/src/hooks/_internal/useUnique.d.ts +2 -3
  19. package/lib/dts/src/hooks/_internal/useUnique.d.ts.map +1 -1
  20. package/lib/dts/src/hooks/index.d.ts +2 -1
  21. package/lib/dts/src/hooks/index.d.ts.map +1 -1
  22. package/lib/dts/src/hooks/useArrayProp.d.ts +7 -0
  23. package/lib/dts/src/hooks/useArrayProp.d.ts.map +1 -0
  24. package/lib/dts/src/hooks/useElementRect/useElementRect.d.ts +1 -1
  25. package/lib/dts/src/hooks/useElementRect/useElementRect.d.ts.map +1 -1
  26. package/lib/dts/src/hooks/useElementSize.d.ts +7 -0
  27. package/lib/dts/src/hooks/useElementSize.d.ts.map +1 -0
  28. package/lib/dts/src/index.d.ts +1 -0
  29. package/lib/dts/src/index.d.ts.map +1 -1
  30. package/lib/dts/src/observers/elementSizeObserver.d.ts +37 -0
  31. package/lib/dts/src/observers/elementSizeObserver.d.ts.map +1 -0
  32. package/lib/dts/src/observers/index.d.ts +3 -0
  33. package/lib/dts/src/observers/index.d.ts.map +1 -0
  34. package/lib/dts/src/observers/resizeObserver.d.ts +5 -0
  35. package/lib/dts/src/observers/resizeObserver.d.ts.map +1 -0
  36. package/lib/dts/src/primitives/_selectable/selectable.d.ts +1 -2
  37. package/lib/dts/src/primitives/_selectable/selectable.d.ts.map +1 -1
  38. package/lib/dts/src/primitives/avatar/avatar.d.ts.map +1 -1
  39. package/lib/dts/src/primitives/avatar/avatarCounter.d.ts +1 -0
  40. package/lib/dts/src/primitives/avatar/avatarCounter.d.ts.map +1 -1
  41. package/lib/dts/src/primitives/avatar/avatarStack.d.ts +1 -0
  42. package/lib/dts/src/primitives/avatar/avatarStack.d.ts.map +1 -1
  43. package/lib/dts/src/primitives/avatar/styles.d.ts.map +1 -1
  44. package/lib/dts/src/primitives/badge/badge.d.ts.map +1 -1
  45. package/lib/dts/src/primitives/box/box.d.ts.map +1 -1
  46. package/lib/dts/src/primitives/button/button.d.ts.map +1 -1
  47. package/lib/dts/src/primitives/card/card.d.ts.map +1 -1
  48. package/lib/dts/src/primitives/code/code.d.ts.map +1 -1
  49. package/lib/dts/src/primitives/container/container.d.ts.map +1 -1
  50. package/lib/dts/src/primitives/container/styles.d.ts.map +1 -1
  51. package/lib/dts/src/primitives/container/types.d.ts +1 -1
  52. package/lib/dts/src/primitives/container/types.d.ts.map +1 -1
  53. package/lib/dts/src/primitives/flex/flex.d.ts.map +1 -1
  54. package/lib/dts/src/primitives/grid/grid.d.ts.map +1 -1
  55. package/lib/dts/src/primitives/heading/heading.d.ts.map +1 -1
  56. package/lib/dts/src/primitives/inline/inline.d.ts.map +1 -1
  57. package/lib/dts/src/primitives/inline/styles.d.ts.map +1 -1
  58. package/lib/dts/src/primitives/inline/types.d.ts +1 -1
  59. package/lib/dts/src/primitives/inline/types.d.ts.map +1 -1
  60. package/lib/dts/src/primitives/kbd/kbd.d.ts.map +1 -1
  61. package/lib/dts/src/primitives/label/label.d.ts.map +1 -1
  62. package/lib/dts/src/primitives/popover/popover.d.ts +6 -5
  63. package/lib/dts/src/primitives/popover/popover.d.ts.map +1 -1
  64. package/lib/dts/src/primitives/popover/{arrow.d.ts → popoverArrow.d.ts} +1 -1
  65. package/lib/dts/src/primitives/popover/popoverArrow.d.ts.map +1 -0
  66. package/lib/dts/src/primitives/popover/popoverCard.d.ts +33 -0
  67. package/lib/dts/src/primitives/popover/popoverCard.d.ts.map +1 -0
  68. package/lib/dts/src/primitives/select/styles.d.ts +5 -1
  69. package/lib/dts/src/primitives/select/styles.d.ts.map +1 -1
  70. package/lib/dts/src/primitives/stack/stack.d.ts.map +1 -1
  71. package/lib/dts/src/primitives/stack/styles.d.ts +1 -1
  72. package/lib/dts/src/primitives/stack/styles.d.ts.map +1 -1
  73. package/lib/dts/src/primitives/text/text.d.ts.map +1 -1
  74. package/lib/dts/src/primitives/textArea/textArea.d.ts.map +1 -1
  75. package/lib/dts/src/primitives/textInput/textInput.d.ts.map +1 -1
  76. package/lib/dts/src/primitives/tooltip/tooltip.d.ts +2 -0
  77. package/lib/dts/src/primitives/tooltip/tooltip.d.ts.map +1 -1
  78. package/lib/dts/src/primitives/tooltip/tooltipArrow.d.ts.map +1 -1
  79. package/lib/dts/src/primitives/types.d.ts +1 -1
  80. package/lib/dts/src/primitives/types.d.ts.map +1 -1
  81. package/lib/dts/src/styles/border/types.d.ts +5 -5
  82. package/lib/dts/src/styles/border/types.d.ts.map +1 -1
  83. package/lib/dts/src/styles/box/types.d.ts +4 -4
  84. package/lib/dts/src/styles/box/types.d.ts.map +1 -1
  85. package/lib/dts/src/styles/flex/flexItemStyle.d.ts.map +1 -1
  86. package/lib/dts/src/styles/flex/types.d.ts +6 -6
  87. package/lib/dts/src/styles/flex/types.d.ts.map +1 -1
  88. package/lib/dts/src/styles/font/responsiveFont.d.ts +1 -1
  89. package/lib/dts/src/styles/font/responsiveFont.d.ts.map +1 -1
  90. package/lib/dts/src/styles/font/types.d.ts +3 -3
  91. package/lib/dts/src/styles/font/types.d.ts.map +1 -1
  92. package/lib/dts/src/styles/grid/types.d.ts +14 -14
  93. package/lib/dts/src/styles/grid/types.d.ts.map +1 -1
  94. package/lib/dts/src/styles/helpers.d.ts +4 -4
  95. package/lib/dts/src/styles/helpers.d.ts.map +1 -1
  96. package/lib/dts/src/styles/input/responsiveInputPaddingStyle.d.ts +12 -12
  97. package/lib/dts/src/styles/input/responsiveInputPaddingStyle.d.ts.map +1 -1
  98. package/lib/dts/src/styles/input/textInputStyle.d.ts +4 -1
  99. package/lib/dts/src/styles/input/textInputStyle.d.ts.map +1 -1
  100. package/lib/dts/src/styles/margin/types.d.ts +7 -7
  101. package/lib/dts/src/styles/margin/types.d.ts.map +1 -1
  102. package/lib/dts/src/styles/padding/types.d.ts +7 -7
  103. package/lib/dts/src/styles/padding/types.d.ts.map +1 -1
  104. package/lib/dts/src/styles/radius/types.d.ts +1 -1
  105. package/lib/dts/src/styles/radius/types.d.ts.map +1 -1
  106. package/lib/dts/src/styles/shadow/shadowStyle.d.ts.map +1 -1
  107. package/lib/dts/src/styles/shadow/types.d.ts +1 -1
  108. package/lib/dts/src/styles/shadow/types.d.ts.map +1 -1
  109. package/lib/dts/src/theme/lib/theme/fonts.d.ts +1 -3
  110. package/lib/dts/src/theme/lib/theme/fonts.d.ts.map +1 -1
  111. package/lib/dts/src/theme/studioTheme/fonts.d.ts.map +1 -1
  112. package/lib/dts/src/types/index.d.ts +2 -1
  113. package/lib/dts/src/types/index.d.ts.map +1 -1
  114. package/lib/dts/src/types/placement.d.ts +7 -0
  115. package/lib/dts/src/types/placement.d.ts.map +1 -0
  116. package/lib/dts/src/types/text.d.ts +5 -0
  117. package/lib/dts/src/types/text.d.ts.map +1 -0
  118. package/lib/dts/src/utils/elementQuery/elementQuery.d.ts.map +1 -1
  119. package/lib/dts/src/utils/index.d.ts +0 -1
  120. package/lib/dts/src/utils/index.d.ts.map +1 -1
  121. package/lib/dts/src/utils/virtualList/virtualList.d.ts.map +1 -1
  122. package/lib/sanity-ui.js +1214 -1054
  123. package/lib/sanity-ui.js.map +1 -1
  124. package/lib/{sanity-ui.modern.js → sanity-ui.modern.mjs} +1246 -1120
  125. package/lib/sanity-ui.modern.mjs.map +1 -0
  126. package/lib/sanity-ui.module.js +1106 -947
  127. package/lib/sanity-ui.module.js.map +1 -1
  128. package/package.json +11 -12
  129. package/src/__workshop__/color/overview.tsx +9 -11
  130. package/src/components/autocomplete/__workshop__/async.tsx +14 -12
  131. package/src/components/autocomplete/__workshop__/constrainedHeight.tsx +36 -0
  132. package/src/components/autocomplete/autocomplete.styles.tsx +0 -6
  133. package/src/components/autocomplete/autocomplete.tsx +14 -7
  134. package/src/components/autocomplete/constants.ts +3 -8
  135. package/src/components/breadcrumbs/breadcrumbs.tsx +3 -2
  136. package/src/components/dialog/dialog.tsx +17 -9
  137. package/src/components/dialog/styles.ts +3 -3
  138. package/src/components/hotkeys/hotkeys.tsx +3 -1
  139. package/src/components/menu/__workshop__/constrainedInBoundary.tsx +11 -14
  140. package/src/components/menu/__workshop__/groups.tsx +1 -1
  141. package/src/components/menu/menuButton.tsx +21 -13
  142. package/src/components/menu/menuGroup.tsx +3 -2
  143. package/src/components/menu/menuItem.tsx +4 -5
  144. package/src/components/skeleton/skeleton.tsx +10 -1
  145. package/src/components/skeleton/textSkeleton.tsx +7 -7
  146. package/src/constants.ts +17 -0
  147. package/src/hooks/_internal/useUnique.ts +4 -5
  148. package/src/hooks/index.ts +2 -1
  149. package/src/hooks/useArrayProp.ts +23 -0
  150. package/src/hooks/useElementRect/useElementRect.ts +4 -16
  151. package/src/hooks/useElementSize.ts +18 -0
  152. package/src/index.ts +1 -0
  153. package/src/observers/elementSizeObserver.ts +116 -0
  154. package/src/observers/index.ts +2 -0
  155. package/src/{utils → observers}/resizeObserver.ts +1 -4
  156. package/src/primitives/_selectable/selectable.tsx +5 -4
  157. package/src/primitives/avatar/avatar.tsx +7 -5
  158. package/src/primitives/avatar/avatarCounter.tsx +14 -12
  159. package/src/primitives/avatar/avatarStack.tsx +19 -13
  160. package/src/primitives/avatar/styles.ts +2 -2
  161. package/src/primitives/badge/badge.tsx +3 -2
  162. package/src/primitives/box/box.tsx +27 -26
  163. package/src/primitives/button/button.tsx +22 -10
  164. package/src/primitives/card/card.tsx +13 -11
  165. package/src/primitives/checkbox/__workshop__/example.tsx +4 -2
  166. package/src/primitives/checkbox/__workshop__/props.tsx +4 -2
  167. package/src/primitives/checkbox/__workshop__/readOnly.tsx +4 -2
  168. package/src/primitives/code/__workshop__/props.tsx +1 -1
  169. package/src/primitives/code/code.tsx +2 -1
  170. package/src/primitives/container/container.tsx +10 -1
  171. package/src/primitives/container/styles.ts +2 -2
  172. package/src/primitives/container/types.ts +1 -1
  173. package/src/primitives/flex/flex.tsx +6 -5
  174. package/src/primitives/grid/__workshop__/responsive.tsx +13 -12
  175. package/src/primitives/grid/grid.tsx +9 -8
  176. package/src/primitives/heading/__workshop__/opticalAlignment.tsx +19 -7
  177. package/src/primitives/heading/heading.tsx +3 -2
  178. package/src/primitives/inline/inline.tsx +12 -6
  179. package/src/primitives/inline/styles.ts +2 -2
  180. package/src/primitives/inline/types.ts +1 -1
  181. package/src/primitives/kbd/kbd.tsx +2 -1
  182. package/src/primitives/label/label.tsx +4 -3
  183. package/src/primitives/popover/__workshop__/{margins.tsx → MarginsStory.tsx} +1 -1
  184. package/src/primitives/popover/__workshop__/{matchReferenceWidth.tsx → MatchReferenceWidthStory.tsx} +0 -0
  185. package/src/primitives/popover/__workshop__/{plain.tsx → PlainStory.tsx} +13 -14
  186. package/src/primitives/popover/__workshop__/{recursive.tsx → RecursiveStory.tsx} +4 -1
  187. package/src/primitives/popover/__workshop__/RightAlignedStory.tsx +61 -0
  188. package/src/primitives/popover/__workshop__/TestStory.tsx +80 -0
  189. package/src/primitives/popover/__workshop__/index.ts +10 -5
  190. package/src/primitives/popover/popover.tsx +245 -193
  191. package/src/primitives/popover/{arrow.tsx → popoverArrow.tsx} +5 -5
  192. package/src/primitives/popover/popoverCard.tsx +160 -0
  193. package/src/primitives/select/select.tsx +9 -9
  194. package/src/primitives/select/styles.ts +10 -4
  195. package/src/primitives/stack/stack.tsx +2 -1
  196. package/src/primitives/stack/styles.ts +3 -3
  197. package/src/primitives/text/__workshop__/opticalAlignment.tsx +15 -5
  198. package/src/primitives/text/text.tsx +3 -2
  199. package/src/primitives/textArea/__workshop__/plain.tsx +23 -18
  200. package/src/primitives/textArea/textArea.tsx +17 -5
  201. package/src/primitives/textInput/__workshop__/clearButton.tsx +14 -8
  202. package/src/primitives/textInput/__workshop__/index.ts +2 -2
  203. package/src/primitives/textInput/__workshop__/plain.tsx +39 -32
  204. package/src/primitives/textInput/__workshop__/tones.tsx +97 -75
  205. package/src/primitives/textInput/__workshop__/typed.tsx +8 -2
  206. package/src/primitives/textInput/textInput.tsx +43 -12
  207. package/src/primitives/tooltip/__workshop__/props.tsx +7 -1
  208. package/src/primitives/tooltip/tooltip.tsx +162 -85
  209. package/src/primitives/tooltip/tooltipArrow.tsx +25 -10
  210. package/src/primitives/types.ts +1 -1
  211. package/src/styles/border/borderStyle.ts +6 -6
  212. package/src/styles/border/types.ts +5 -5
  213. package/src/styles/box/boxStyle.ts +5 -5
  214. package/src/styles/box/types.ts +4 -4
  215. package/src/styles/flex/flexItemStyle.ts +5 -4
  216. package/src/styles/flex/flexStyle.ts +6 -6
  217. package/src/styles/flex/types.ts +6 -6
  218. package/src/styles/font/responsiveFont.ts +7 -27
  219. package/src/styles/font/textAlignStyle.ts +2 -2
  220. package/src/styles/font/types.ts +4 -3
  221. package/src/styles/grid/gridItemStyle.ts +7 -7
  222. package/src/styles/grid/gridStyle.ts +9 -9
  223. package/src/styles/grid/types.ts +14 -14
  224. package/src/styles/helpers.ts +9 -9
  225. package/src/styles/input/responsiveInputPaddingStyle.ts +24 -27
  226. package/src/styles/input/textInputStyle.ts +89 -79
  227. package/src/styles/margin/marginStyle.ts +8 -8
  228. package/src/styles/margin/marginsStyle.test.ts +1 -1
  229. package/src/styles/margin/types.ts +7 -7
  230. package/src/styles/padding/paddingStyle.test.ts +1 -1
  231. package/src/styles/padding/paddingStyle.ts +8 -8
  232. package/src/styles/padding/types.ts +7 -7
  233. package/src/styles/radius/radiusStyle.ts +2 -2
  234. package/src/styles/radius/types.ts +1 -1
  235. package/src/styles/shadow/shadowStyle.ts +2 -5
  236. package/src/styles/shadow/types.ts +1 -1
  237. package/src/theme/lib/theme/fonts.ts +1 -3
  238. package/src/theme/studioTheme/fonts.ts +5 -9
  239. package/src/types/index.ts +2 -2
  240. package/src/types/placement.ts +18 -0
  241. package/src/types/text.ts +4 -0
  242. package/src/utils/elementQuery/elementQuery.tsx +5 -18
  243. package/src/utils/index.ts +0 -1
  244. package/src/utils/layer/layer.tsx +1 -1
  245. package/src/utils/layer/layerProvider.tsx +2 -2
  246. package/src/utils/virtualList/virtualList.tsx +8 -7
  247. package/lib/dts/src/hooks/useResponsiveProp.d.ts +0 -6
  248. package/lib/dts/src/hooks/useResponsiveProp.d.ts.map +0 -1
  249. package/lib/dts/src/primitives/popover/arrow.d.ts.map +0 -1
  250. package/lib/dts/src/primitives/popover/modifiers/getPopoverModifiers.d.ts +0 -4
  251. package/lib/dts/src/primitives/popover/modifiers/getPopoverModifiers.d.ts.map +0 -1
  252. package/lib/dts/src/primitives/popover/modifiers/index.d.ts +0 -2
  253. package/lib/dts/src/primitives/popover/modifiers/index.d.ts.map +0 -1
  254. package/lib/dts/src/primitives/popover/modifiers/types.d.ts +0 -18
  255. package/lib/dts/src/primitives/popover/modifiers/types.d.ts.map +0 -1
  256. package/lib/dts/src/primitives/popover/modifiers/usePopoverModifiers.d.ts +0 -4
  257. package/lib/dts/src/primitives/popover/modifiers/usePopoverModifiers.d.ts.map +0 -1
  258. package/lib/dts/src/types/common.d.ts +0 -11
  259. package/lib/dts/src/types/common.d.ts.map +0 -1
  260. package/lib/dts/src/utils/resizeObserver.d.ts +0 -6
  261. package/lib/dts/src/utils/resizeObserver.d.ts.map +0 -1
  262. package/lib/sanity-ui.modern.js.map +0 -1
  263. package/src/hooks/useResponsiveProp.ts +0 -10
  264. package/src/primitives/popover/__workshop__/rightAligned.tsx +0 -57
  265. package/src/primitives/popover/modifiers/getPopoverModifiers.ts +0 -137
  266. package/src/primitives/popover/modifiers/index.ts +0 -1
  267. package/src/primitives/popover/modifiers/types.ts +0 -18
  268. package/src/primitives/popover/modifiers/usePopoverModifiers.ts +0 -58
  269. package/src/types/common.ts +0 -12
@@ -0,0 +1,61 @@
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
+ overflow="auto"
44
+ padding={3}
45
+ portal
46
+ placement="bottom"
47
+ ref={setPopoverElement}
48
+ >
49
+ <Button
50
+ icon={EllipsisVerticalIcon}
51
+ mode="bleed"
52
+ onClick={handleToggleOpen}
53
+ ref={setButtonElement}
54
+ selected={open}
55
+ />
56
+ </Popover>
57
+ </Flex>
58
+ </Card>
59
+ </Card>
60
+ )
61
+ }
@@ -0,0 +1,80 @@
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
+ overflow="auto"
65
+ padding={3}
66
+ placement={placement}
67
+ portal
68
+ preventOverflow={preventOverflow}
69
+ radius={radius}
70
+ width={width}
71
+ >
72
+ <Button text="reference" style={{width: referenceWide ? 300 : undefined}} />
73
+ </Popover>
74
+ </BoundaryElementProvider>
75
+ </PortalProvider>
76
+ </div>
77
+ </div>
78
+ </Card>
79
+ )
80
+ }
@@ -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,17 +1,30 @@
1
- import React, {cloneElement, forwardRef, useCallback, useEffect, useMemo, useState} from 'react'
2
- import {usePopper} from 'react-popper'
3
- import styled, {css} from 'styled-components'
4
- import {EMPTY_RECORD} from '../../constants'
5
- import {useForwardedRef} from '../../hooks'
1
+ import {
2
+ Middleware,
3
+ arrow,
4
+ autoUpdate,
5
+ flip,
6
+ offset,
7
+ shift,
8
+ useFloating,
9
+ size as sizeMiddleware,
10
+ RootBoundary,
11
+ } from '@floating-ui/react-dom'
12
+ import React, {
13
+ cloneElement,
14
+ forwardRef,
15
+ memo,
16
+ useCallback,
17
+ useEffect,
18
+ useMemo,
19
+ useRef,
20
+ useState,
21
+ } from 'react'
22
+ import {useForwardedRef, useArrayProp, useElementSize} from '../../hooks'
6
23
  import {ThemeColorSchemeKey, useTheme} from '../../theme'
7
- import {CardTone, Placement, PopoverMargins} from '../../types'
8
- import {Layer, LayerProps, Portal, useBoundaryElement, usePortal} from '../../utils'
9
- import {Card} from '../card'
10
- import {ResponsiveWidthStyleProps} from '../container'
11
- import {responsiveContainerWidthStyle} from '../container/styles'
24
+ import {BoxOverflow, CardTone, Placement, PopoverMargins} from '../../types'
25
+ import {LayerProps, LayerProvider, Portal, useBoundaryElement} from '../../utils'
12
26
  import {ResponsiveRadiusProps, ResponsiveShadowProps, ResponsiveWidthProps} from '../types'
13
- import {PopoverArrow} from './arrow'
14
- import {usePopoverModifiers} from './modifiers'
27
+ import {PopoverCard} from './popoverCard'
15
28
 
16
29
  /**
17
30
  * @public
@@ -25,6 +38,7 @@ export interface PopoverProps
25
38
  * @beta
26
39
  */
27
40
  __unstable_margins?: PopoverMargins
41
+ /** @deprecated Use `fallbackPlacements` instead. */
28
42
  allowedAutoPlacements?: Placement[]
29
43
  arrow?: boolean
30
44
  boundaryElement?: HTMLElement | null
@@ -34,6 +48,7 @@ export interface PopoverProps
34
48
  disabled?: boolean
35
49
  fallbackPlacements?: Placement[]
36
50
  open?: boolean
51
+ overflow?: BoxOverflow
37
52
  padding?: number | number[]
38
53
  placement?: Placement
39
54
  portal?: boolean | string
@@ -41,206 +56,243 @@ export interface PopoverProps
41
56
  referenceElement?: HTMLElement | null
42
57
  matchReferenceWidth?: boolean
43
58
  scheme?: ThemeColorSchemeKey
59
+ /** @deprecated No longer supported. */
44
60
  tether?: boolean
61
+ /** @deprecated No longer supported. */
45
62
  tetherOffset?: number | ((...args: any[]) => number)
46
63
  tone?: CardTone
47
64
  }
48
65
 
49
- const Root = styled(Layer)<{$preventOverflow?: boolean}>(
50
- ({$preventOverflow}) => css`
51
- pointer-events: none;
52
- display: flex;
53
- flex-direction: column;
54
- max-width: calc(100% - 16px);
66
+ function size(scope: {
67
+ boundaryElement: HTMLElement | null
68
+ constrainSize: boolean
69
+ matchReferenceWidth: boolean | undefined
70
+ setAvailableWidth: (v: number) => void
71
+ setAvailableHeight: (v: number) => void
72
+ setReferenceWidth: (v: number) => void
73
+ }) {
74
+ return sizeMiddleware({
75
+ apply(args) {
76
+ if (scope.constrainSize) {
77
+ scope.setAvailableWidth(args.availableWidth)
78
+ scope.setAvailableHeight(args.availableHeight)
79
+ }
55
80
 
56
- & > * {
57
- min-height: 0;
58
- }
81
+ if (scope.matchReferenceWidth) {
82
+ scope.setReferenceWidth(args.rects.reference.width)
83
+ }
84
+ },
85
+ boundary: scope.boundaryElement || undefined,
86
+ })
87
+ }
88
+
89
+ export const Popover = memo(
90
+ forwardRef(function Popover(
91
+ props: PopoverProps &
92
+ Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'children' | 'content' | 'width'>,
93
+ ref: React.ForwardedRef<HTMLDivElement>
94
+ ): React.ReactElement {
95
+ const theme = useTheme()
96
+ const boundaryElementContext = useBoundaryElement()
97
+
98
+ const {
99
+ __unstable_margins: margins,
100
+ allowedAutoPlacements,
101
+ arrow: arrowProp = true,
102
+ boundaryElement = boundaryElementContext.element,
103
+ children: childProp,
104
+ constrainSize = false,
105
+ content,
106
+ disabled,
107
+ fallbackPlacements,
108
+ matchReferenceWidth: matchReferenceWidthProp,
109
+ open,
110
+ overflow = props.constrainSize ? 'auto' : undefined,
111
+ padding: paddingProp,
112
+ placement: placementProp = 'bottom',
113
+ portal,
114
+ preventOverflow = true,
115
+ radius: radiusProp = 3,
116
+ referenceElement,
117
+ scheme,
118
+ shadow: shadowProp = 3,
119
+ tether,
120
+ tetherOffset,
121
+ tone = 'inherit',
122
+ width: widthProp = undefined,
123
+ zOffset: zOffsetProp = theme.sanity.layer?.popover.zOffset,
124
+ ...restProps
125
+ } = props
126
+ const boundarySize = useElementSize(boundaryElement)?.border
127
+ const padding = useArrayProp(paddingProp)
128
+ const radius = useArrayProp(radiusProp)
129
+ const shadow = useArrayProp(shadowProp)
130
+ const width = useArrayProp(widthProp)
131
+ const zOffset = useArrayProp(zOffsetProp)
132
+ const [availableWidth, setAvailableWidth] = useState<number | undefined>(undefined)
133
+ const [availableHeight, setAvailableHeight] = useState<number | undefined>(undefined)
134
+ const [referenceWidth, setReferenceWidth] = useState<number | undefined>(undefined)
135
+ const forwardedRef = useForwardedRef(ref)
136
+ const arrowRef = useRef<HTMLDivElement | null>(null)
137
+ const rootBoundary: RootBoundary = 'viewport'
138
+
139
+ const middleware = useMemo(() => {
140
+ const ret: Middleware[] = []
59
141
 
60
- /* Hide the popover when the reference element is out of bounds */
61
- ${$preventOverflow &&
62
- css`
63
- &[data-popper-reference-hidden='true'] {
64
- display: none;
142
+ // Flip the floating element when leaving the boundary box
143
+ if (constrainSize || preventOverflow) {
144
+ ret.push(
145
+ flip({
146
+ boundary: boundaryElement || undefined,
147
+ fallbackPlacements,
148
+ padding: 8,
149
+ rootBoundary,
150
+ })
151
+ )
65
152
  }
66
- `}
67
- `
68
- )
69
153
 
70
- const PopoverCard = styled(Card)<
71
- ResponsiveWidthStyleProps & {
72
- $constrainSize?: boolean
73
- $preventOverflow?: boolean
74
- }
75
- >(
76
- ({$constrainSize}) => css`
77
- flex: 1;
78
- max-height: ${$constrainSize && '100%'};
79
- pointer-events: all;
80
-
81
- && {
82
- display: flex;
83
- }
154
+ // Track sizes
155
+ ret.push(
156
+ size({
157
+ boundaryElement,
158
+ constrainSize,
159
+ matchReferenceWidth: matchReferenceWidthProp,
160
+ setAvailableHeight,
161
+ setAvailableWidth,
162
+ setReferenceWidth,
163
+ })
164
+ )
84
165
 
85
- flex-direction: column;
166
+ // Define distance between reference and floating element
167
+ ret.push(offset({mainAxis: arrowProp ? 4 : 0}))
86
168
 
87
- & > * {
88
- min-height: 0;
89
- }
169
+ // Shift the popover so its sits with the boundary eleement
170
+ if (preventOverflow) {
171
+ ret.push(
172
+ shift({
173
+ boundary: boundaryElement || undefined,
174
+ rootBoundary,
175
+ padding: 8,
176
+ })
177
+ )
178
+ }
90
179
 
91
- ${responsiveContainerWidthStyle}
92
- `
93
- )
180
+ // Place arrow
181
+ if (arrowProp) {
182
+ ret.push(arrow({element: arrowRef, padding: 4}))
183
+ }
94
184
 
95
- /**
96
- * @public
97
- */
98
- export const Popover = forwardRef(function Popover(
99
- props: PopoverProps &
100
- Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'children' | 'content' | 'width'>,
101
- ref: React.ForwardedRef<HTMLDivElement>
102
- ) {
103
- const boundaryElementContext = useBoundaryElement()
104
- const theme = useTheme()
105
- const {
106
- __unstable_margins: margins,
107
- allowedAutoPlacements,
108
- arrow = true,
109
- boundaryElement: boundaryElementProp = boundaryElementContext.element,
110
- children: child,
111
- content,
112
- constrainSize,
113
- disabled,
114
- fallbackPlacements,
115
- open = false,
116
- padding,
117
- placement = 'bottom',
118
- portal: portalProp = false,
119
- preventOverflow,
120
- radius = 3,
121
- referenceElement: referenceElementProp,
122
- matchReferenceWidth,
123
- shadow = 3,
124
- scheme,
125
- style = EMPTY_RECORD,
126
- tether,
127
- tetherOffset,
128
- tone = 'inherit',
129
- width = 0,
130
- zOffset = theme.sanity.layer?.popover.zOffset,
131
- ...restProps
132
- } = props
133
- const forwardedRef = useForwardedRef(ref)
134
- const portal = usePortal()
135
- const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null)
136
- const [popperElement, setPopperElement] = useState<HTMLElement | null>(null)
137
- const [arrowElement, setArrowElement] = useState<HTMLElement | null>(null)
138
- const popperReferenceElement = referenceElementProp || referenceElement
139
-
140
- const modifiers = usePopoverModifiers({
141
- allowedAutoPlacements,
142
- arrow,
143
- arrowElement,
144
- boundaryElement: boundaryElementProp || portal.boundaryElement,
145
- constrainSize,
146
- distance: arrow ? 4 : 0,
147
- fallbackPlacements,
148
- margins,
149
- matchReferenceWidth,
150
- open,
151
- preventOverflow,
152
- skidding: 0,
153
- tether,
154
- tetherOffset,
155
- })
185
+ return ret
186
+ }, [
187
+ arrowProp,
188
+ boundaryElement,
189
+ constrainSize,
190
+ fallbackPlacements,
191
+ matchReferenceWidthProp,
192
+ preventOverflow,
193
+ ])
156
194
 
157
- const popper = usePopper(popperReferenceElement, popperElement, {
158
- placement,
159
- modifiers,
160
- })
195
+ const {x, y, placement, reference, floating, middlewareData, strategy} = useFloating({
196
+ middleware,
197
+ placement: placementProp,
198
+ whileElementsMounted: autoUpdate,
199
+ })
161
200
 
162
- const {attributes, forceUpdate, styles} = popper
201
+ const arrowX = middlewareData.arrow?.x
202
+ const arrowY = middlewareData.arrow?.y
163
203
 
164
- const setRef = useCallback(
165
- (el: HTMLElement | null) => {
166
- const childRef = (child as any).ref
204
+ const setArrow = useCallback((arrowEl: HTMLDivElement | null) => {
205
+ arrowRef.current = arrowEl
206
+ }, [])
167
207
 
168
- setReferenceElement(el)
208
+ const setFloating = useCallback(
209
+ (node: HTMLDivElement | null) => {
210
+ forwardedRef.current = node
211
+ floating(node)
212
+ },
213
+ [floating, forwardedRef]
214
+ )
169
215
 
170
- if (typeof childRef === 'function') {
171
- childRef(el)
172
- } else if (childRef) {
173
- childRef.current = el
174
- }
175
- },
176
- [child]
177
- )
216
+ const setReference = useCallback(
217
+ (node: HTMLElement | null) => {
218
+ reference(node)
178
219
 
179
- const setRootRef = useCallback(
180
- (el: HTMLDivElement | null) => {
181
- setPopperElement(el)
182
- forwardedRef.current = el
183
- },
184
- [forwardedRef]
185
- )
220
+ const childRef = (childProp as any)?.ref
186
221
 
187
- const popoverStyle = useMemo(() => ({...style, ...styles.popper}), [style, styles])
222
+ if (typeof childRef === 'function') {
223
+ childRef(node)
224
+ } else if (childRef) {
225
+ childRef.current = node
226
+ }
227
+ },
228
+ [childProp, reference]
229
+ )
188
230
 
189
- useEffect(() => {
190
- if (forceUpdate) {
191
- try {
192
- forceUpdate()
193
- } catch (_) {
194
- // ignore caught error
195
- }
231
+ const child = useMemo(() => {
232
+ if (!childProp || referenceElement) return null
233
+
234
+ return cloneElement(childProp, {ref: setReference})
235
+ }, [childProp, referenceElement, setReference])
236
+
237
+ useEffect(() => {
238
+ if (referenceElement) reference(referenceElement)
239
+ }, [reference, referenceElement])
240
+
241
+ if (disabled) {
242
+ return childProp || <></>
196
243
  }
197
- }, [content, forceUpdate, open, popperReferenceElement])
198
-
199
- if (disabled) {
200
- return child || <></>
201
- }
202
-
203
- const node = (
204
- <Root
205
- data-ui="Popover"
206
- {...restProps}
207
- $preventOverflow={preventOverflow}
208
- ref={setRootRef}
209
- style={popoverStyle}
210
- zOffset={zOffset}
211
- {...attributes.popper}
212
- >
213
- <PopoverCard
214
- $constrainSize={constrainSize}
215
- data-ui="PopoverCard"
216
- padding={padding}
217
- radius={radius}
218
- scheme={scheme}
219
- shadow={shadow}
220
- tone={tone}
221
- width={width as any}
222
- >
223
- {arrow && <PopoverArrow ref={setArrowElement} style={styles.arrow} />}
224
- {content}
225
- </PopoverCard>
226
- </Root>
227
- )
228
-
229
- return (
230
- <>
231
- {child && !referenceElementProp ? cloneElement(child, {ref: setRef}) : child || <></>}
232
-
233
- {open && (
234
- <>
235
- {portalProp && (
236
- <Portal __unstable_name={typeof portalProp === 'string' ? portalProp : undefined}>
237
- {node}
238
- </Portal>
239
- )}
240
-
241
- {!portalProp && node}
242
- </>
243
- )}
244
- </>
245
- )
246
- })
244
+
245
+ const popover = (
246
+ <LayerProvider zOffset={zOffset}>
247
+ <PopoverCard
248
+ {...restProps}
249
+ __unstable_margins={margins}
250
+ arrow={arrowProp}
251
+ arrowRef={setArrow}
252
+ arrowX={arrowX}
253
+ arrowY={arrowY}
254
+ availableWidth={constrainSize ? availableWidth : undefined}
255
+ availableHeight={constrainSize ? availableHeight : undefined}
256
+ boundaryWidth={boundarySize?.width}
257
+ overflow={overflow}
258
+ padding={padding}
259
+ placement={placement}
260
+ radius={radius}
261
+ ref={setFloating}
262
+ referenceWidth={matchReferenceWidthProp ? referenceWidth : undefined}
263
+ scheme={scheme}
264
+ shadow={shadow}
265
+ strategy={strategy}
266
+ tone={tone}
267
+ x={x}
268
+ y={y}
269
+ width={width}
270
+ >
271
+ {content}
272
+ </PopoverCard>
273
+ </LayerProvider>
274
+ )
275
+
276
+ return (
277
+ <>
278
+ {/* the popover */}
279
+ {open && (
280
+ <>
281
+ {portal ? (
282
+ <Portal __unstable_name={typeof portal === 'string' ? portal : undefined}>
283
+ {popover}
284
+ </Portal>
285
+ ) : (
286
+ popover
287
+ )}
288
+ </>
289
+ )}
290
+
291
+ {/* the referred element */}
292
+ {child}
293
+ </>
294
+ )
295
+ })
296
+ )
297
+
298
+ Popover.displayName = 'Popover'