@sanity/ui 3.0.0-static.10 → 3.0.0-static.12

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 (275) hide show
  1. package/dist/_chunks-cjs/_visual-editing.js +1300 -1269
  2. package/dist/_chunks-cjs/_visual-editing.js.map +1 -1
  3. package/dist/_chunks-cjs/buildCommand.js +28 -10
  4. package/dist/_chunks-cjs/buildCommand.js.map +1 -1
  5. package/dist/_chunks-es/_visual-editing.mjs +1298 -1263
  6. package/dist/_chunks-es/_visual-editing.mjs.map +1 -1
  7. package/dist/_visual-editing.d.mts +516 -360
  8. package/dist/_visual-editing.d.ts +516 -360
  9. package/dist/cli.js +1 -1
  10. package/dist/css.d.mts +258 -75
  11. package/dist/css.d.ts +258 -75
  12. package/dist/css.js +746 -752
  13. package/dist/css.js.map +1 -1
  14. package/dist/css.mjs +748 -754
  15. package/dist/css.mjs.map +1 -1
  16. package/dist/index.d.mts +1342 -871
  17. package/dist/index.d.ts +1342 -871
  18. package/dist/index.js +433 -325
  19. package/dist/index.js.map +1 -1
  20. package/dist/index.mjs +429 -321
  21. package/dist/index.mjs.map +1 -1
  22. package/dist/sanity-palette.css +105 -1
  23. package/dist/sanity-palette.min.css +1 -0
  24. package/dist/sanity-theme.css +4571 -1
  25. package/dist/sanity-theme.min.css +1 -0
  26. package/dist/system.css +22053 -21710
  27. package/dist/system.min.css +1 -0
  28. package/dist/theme.d.mts +51 -106
  29. package/dist/theme.d.ts +51 -106
  30. package/dist/theme.js +19 -20
  31. package/dist/theme.js.map +1 -1
  32. package/dist/theme.mjs +19 -20
  33. package/dist/theme.mjs.map +1 -1
  34. package/package.json +10 -5
  35. package/src/cli/buildCommand.ts +46 -19
  36. package/src/css/_comp.ts +2 -2
  37. package/src/css/{compile/compileStyle.ts → _compileStyle.ts} +7 -7
  38. package/src/css/_resp.ts +0 -1
  39. package/src/css/{system.style.ts → _system.style.ts} +3 -2
  40. package/src/css/aspects/display/display.ts +1 -0
  41. package/src/css/aspects/display/types.ts +2 -3
  42. package/src/css/aspects/flex/types.ts +4 -12
  43. package/src/css/aspects/flexItem/types.ts +1 -3
  44. package/src/css/aspects/font/font.style.ts +7 -66
  45. package/src/css/aspects/font/types.ts +1 -3
  46. package/src/css/aspects/grid/grid.ts +1 -0
  47. package/src/css/aspects/grid/types.ts +5 -9
  48. package/src/css/aspects/gridItem/gridItem.ts +1 -1
  49. package/src/css/aspects/gridItem/types.ts +7 -18
  50. package/src/css/aspects/height/height.ts +3 -4
  51. package/src/css/aspects/inset/inset.ts +1 -0
  52. package/src/css/aspects/margin/margin.ts +1 -0
  53. package/src/css/aspects/margin/types.ts +1 -0
  54. package/src/css/aspects/maxWidth/maxWidth.ts +1 -0
  55. package/src/css/aspects/maxWidth/types.ts +1 -0
  56. package/src/css/aspects/minWidth/minWidth.ts +1 -0
  57. package/src/css/aspects/minWidth/types.ts +2 -0
  58. package/src/css/aspects/overflow/overflow.ts +1 -0
  59. package/src/css/aspects/padding/padding.ts +1 -0
  60. package/src/css/aspects/pointerEvents/pointerEvents.ts +1 -0
  61. package/src/css/aspects/position/position.ts +1 -0
  62. package/src/css/aspects/shadow/shadow.style.ts +16 -41
  63. package/src/css/aspects/shadow/shadow.ts +1 -0
  64. package/src/css/aspects/textOverflow/textOverflow.ts +1 -0
  65. package/src/css/aspects/textOverflow/types.ts +1 -0
  66. package/src/css/aspects/width/types.ts +2 -0
  67. package/src/css/aspects/width/width.ts +1 -0
  68. package/src/css/compilePalette.ts +32 -0
  69. package/src/css/compileSystem.ts +7 -0
  70. package/src/css/{compile/compileTheme.ts → compileTheme.ts} +1 -0
  71. package/src/css/compileTheme_v3.ts +434 -0
  72. package/src/css/components/breadcrumbs/breadcrumbs.ts +1 -0
  73. package/src/css/components/dialog/dialog.ts +7 -0
  74. package/src/css/components/menu/menu.ts +2 -0
  75. package/src/css/components/skeleton/skeleton.style.ts +8 -4
  76. package/src/css/components/skeleton/skeleton.ts +4 -0
  77. package/src/css/components/skeleton/types.ts +4 -0
  78. package/src/css/components/toast/toast.ts +5 -0
  79. package/src/css/components/tree/tree.ts +1 -0
  80. package/src/css/composeClassNames.ts +4 -2
  81. package/src/css/constants.ts +11 -0
  82. package/src/css/index.ts +4 -3
  83. package/src/css/primitives/_arrow/_arrow.style.ts +6 -8
  84. package/src/css/primitives/_arrow/_arrow.ts +7 -0
  85. package/src/css/primitives/_input/input.ts +2 -0
  86. package/src/css/primitives/_selectable/_selectable.style.ts +24 -25
  87. package/src/css/primitives/_selectable/selectable.ts +1 -2
  88. package/src/css/primitives/avatar/avatar.style.ts +5 -8
  89. package/src/css/primitives/avatar/avatar.ts +6 -0
  90. package/src/css/primitives/avatar/types.ts +1 -0
  91. package/src/css/primitives/box/types.ts +1 -3
  92. package/src/css/primitives/button/button.style.ts +48 -15
  93. package/src/css/primitives/button/button.ts +4 -21
  94. package/src/css/primitives/button/index.ts +1 -0
  95. package/src/css/primitives/button/types.ts +18 -0
  96. package/src/css/primitives/card/card.style.ts +4 -7
  97. package/src/css/primitives/card/card.ts +2 -2
  98. package/src/css/primitives/card/types.ts +2 -2
  99. package/src/css/primitives/checkbox/checkbox.ts +2 -0
  100. package/src/css/primitives/container/container.ts +1 -0
  101. package/src/css/primitives/container/types.ts +1 -0
  102. package/src/css/primitives/kbd/kbd.ts +1 -0
  103. package/src/css/primitives/label/types.ts +7 -2
  104. package/src/css/primitives/popover/popover.ts +2 -0
  105. package/src/css/primitives/radio/radio.ts +1 -0
  106. package/src/css/primitives/select/select.ts +2 -0
  107. package/src/css/primitives/spinner/spinner.ts +2 -0
  108. package/src/css/primitives/switch/switch.ts +5 -0
  109. package/src/css/primitives/text/types.ts +4 -0
  110. package/src/css/primitives/textArea/textArea.ts +1 -0
  111. package/src/css/primitives/textInput/textInput.ts +1 -0
  112. package/src/css/primitives/token/token.style.ts +37 -36
  113. package/src/css/primitives/tooltip/tooltip.ts +2 -0
  114. package/src/css/responsiveRules.ts +12 -19
  115. package/src/css/scopeClassName.ts +1 -0
  116. package/src/css/types.ts +115 -15
  117. package/src/css/util.ts +5 -0
  118. package/src/css/utils/srOnly/srOnly.ts +1 -0
  119. package/src/css/varNames.ts +230 -143
  120. package/src/css/vars.ts +53 -22
  121. package/src/theme/palette/constants.ts +2 -0
  122. package/src/theme/palette/types.ts +3 -0
  123. package/src/theme/types.ts +2 -6
  124. package/src/theme/v0/focusRing.ts +1 -3
  125. package/src/theme/v0/font.ts +6 -18
  126. package/src/theme/v0/layer.ts +1 -3
  127. package/src/theme/v0/shadow.ts +2 -6
  128. package/src/theme/v2/avatar.ts +1 -3
  129. package/src/theme/v2/color/_system.ts +1 -3
  130. package/src/theme/v2/color/avatar.ts +2 -6
  131. package/src/theme/v2/color/badge.ts +2 -6
  132. package/src/theme/v2/color/button.ts +3 -9
  133. package/src/theme/v2/color/color.ts +3 -9
  134. package/src/theme/v2/color/input.ts +3 -9
  135. package/src/theme/v2/color/kbd.ts +1 -3
  136. package/src/theme/v2/color/selectable.ts +2 -6
  137. package/src/theme/v2/color/state.ts +1 -3
  138. package/src/theme/v2/color/syntax.ts +1 -3
  139. package/src/theme/v2/input.ts +1 -3
  140. package/src/theme/v2/theme.ts +2 -6
  141. package/src/theme/v3/buildTheme_v3.ts +2 -1
  142. package/src/theme/v3/color/color.ts +6 -4
  143. package/src/theme/v3/color/renderColor.ts +4 -1
  144. package/src/theme/v3/{defaults.ts → defaultTokens.ts} +2 -2
  145. package/src/theme/v3/index.ts +1 -1
  146. package/src/theme/v3/resolveTokens.ts +18 -18
  147. package/src/ui/RootClassNames.tsx +44 -0
  148. package/src/ui/StyleTags.tsx +3 -1
  149. package/src/ui/_compat/helpers.ts +72 -0
  150. package/src/ui/_compat/index.ts +2 -6
  151. package/src/ui/_compat/studioTheme.ts +7 -0
  152. package/src/ui/_compat/theme/themeColorProvider.tsx +2 -6
  153. package/src/ui/_compat/theme/themeProvider.tsx +2 -6
  154. package/src/ui/_compat/theme/types.ts +1 -3
  155. package/src/ui/_compat/theme/useRootTheme.ts +1 -3
  156. package/src/ui/_compat/theme/useTheme.ts +2 -6
  157. package/src/ui/_compat/types.ts +0 -83
  158. package/src/ui/components/autocomplete/__workshop__/constrainedHeight.tsx +2 -2
  159. package/src/ui/components/autocomplete/autocomplete.tsx +86 -114
  160. package/src/ui/components/autocomplete/autocompleteOption.tsx +2 -0
  161. package/src/ui/components/autocomplete/types.ts +3 -8
  162. package/src/ui/components/breadcrumbs/breadcrumbs.tsx +27 -21
  163. package/src/ui/components/dialog/dialog.tsx +89 -291
  164. package/src/ui/components/dialog/dialogCard.tsx +183 -0
  165. package/src/ui/components/dialog/isTargetWithinScope.ts +14 -0
  166. package/src/ui/components/hotkeys/hotkeys.tsx +33 -15
  167. package/src/ui/components/menu/__workshop__/asComponent.tsx +6 -6
  168. package/src/ui/components/menu/menu.tsx +27 -33
  169. package/src/ui/components/menu/menuButton.tsx +10 -14
  170. package/src/ui/components/menu/menuDivider.tsx +25 -13
  171. package/src/ui/components/menu/menuGroup.tsx +34 -26
  172. package/src/ui/components/menu/menuItem.tsx +51 -40
  173. package/src/ui/components/skeleton/codeSkeleton.tsx +53 -0
  174. package/src/ui/components/skeleton/headingSkeleton.tsx +52 -0
  175. package/src/ui/components/skeleton/index.ts +3 -0
  176. package/src/ui/components/skeleton/labelSkeleton.tsx +51 -0
  177. package/src/ui/components/skeleton/skeleton.tsx +39 -16
  178. package/src/ui/components/skeleton/textSkeleton.tsx +31 -110
  179. package/src/ui/components/tab/tab.tsx +23 -19
  180. package/src/ui/components/tab/tabList.tsx +34 -33
  181. package/src/ui/components/tab/tabPanel.tsx +25 -19
  182. package/src/ui/components/toast/toast.tsx +21 -16
  183. package/src/ui/components/toast/toastLayer.tsx +28 -10
  184. package/src/ui/components/toast/toastProvider.tsx +2 -6
  185. package/src/ui/components/toast/types.ts +2 -6
  186. package/src/ui/components/toast/useToast.ts +1 -3
  187. package/src/ui/components/tree/tree.tsx +194 -187
  188. package/src/ui/components/tree/treeGroup.tsx +25 -5
  189. package/src/ui/components/tree/treeItem.tsx +35 -23
  190. package/src/ui/hooks/useClickOutside.ts +2 -6
  191. package/src/ui/hooks/useClickOutsideEvent.ts +3 -9
  192. package/src/ui/index.ts +1 -0
  193. package/src/ui/primitives/_selectable/selectable.tsx +33 -20
  194. package/src/ui/primitives/avatar/avatar.tsx +28 -31
  195. package/src/ui/primitives/avatar/avatarCounter.tsx +33 -25
  196. package/src/ui/primitives/avatar/avatarStack.tsx +31 -24
  197. package/src/ui/primitives/avatar/types.ts +2 -0
  198. package/src/ui/primitives/badge/__workshop__/props.tsx +1 -9
  199. package/src/ui/primitives/badge/__workshop__/tones.tsx +1 -6
  200. package/src/ui/primitives/badge/badge.tsx +33 -32
  201. package/src/ui/primitives/badge/types.ts +2 -1
  202. package/src/ui/primitives/box/box.tsx +59 -29
  203. package/src/ui/primitives/button/__workshop__/sanityUploadButton.tsx +3 -3
  204. package/src/ui/primitives/button/__workshop__/uploadButton.tsx +2 -1
  205. package/src/ui/primitives/button/button.test.tsx +1 -15
  206. package/src/ui/primitives/button/button.tsx +63 -70
  207. package/src/ui/primitives/card/__workshop__/asComponent.tsx +3 -3
  208. package/src/ui/primitives/card/card.tsx +22 -22
  209. package/src/ui/primitives/card/cardProvider.tsx +2 -0
  210. package/src/ui/primitives/checkbox/checkbox.tsx +26 -15
  211. package/src/ui/primitives/code/code.tsx +24 -22
  212. package/src/ui/primitives/container/container.tsx +26 -15
  213. package/src/ui/primitives/flex/flex.tsx +21 -19
  214. package/src/ui/primitives/grid/grid.tsx +21 -16
  215. package/src/ui/primitives/heading/heading.tsx +42 -19
  216. package/src/ui/primitives/inline/inline.tsx +26 -23
  217. package/src/ui/primitives/kbd/kbd.tsx +25 -23
  218. package/src/ui/primitives/label/label.tsx +29 -26
  219. package/src/ui/primitives/popover/popover.tsx +293 -271
  220. package/src/ui/primitives/popover/popoverCard.tsx +122 -120
  221. package/src/ui/primitives/radio/radio.tsx +30 -14
  222. package/src/ui/primitives/select/select.tsx +24 -16
  223. package/src/ui/primitives/spinner/animatedSpinnerIcon.tsx +4 -2
  224. package/src/ui/primitives/spinner/spinner.tsx +24 -12
  225. package/src/ui/primitives/stack/stack.tsx +27 -18
  226. package/src/ui/primitives/switch/switch.tsx +31 -14
  227. package/src/ui/primitives/text/text.tsx +30 -24
  228. package/src/ui/primitives/textArea/textArea.tsx +33 -18
  229. package/src/ui/primitives/textInput/textInput.tsx +28 -40
  230. package/src/ui/primitives/tooltip/constants.ts +1 -1
  231. package/src/ui/primitives/tooltip/tooltip.tsx +85 -61
  232. package/src/ui/primitives/tooltip/tooltipCard.tsx +89 -82
  233. package/src/ui/primitives/types.ts +1 -3
  234. package/src/ui/types/avatar.ts +3 -6
  235. package/src/ui/types/badge.ts +1 -3
  236. package/src/ui/types/button.ts +1 -3
  237. package/src/ui/types/card.ts +1 -3
  238. package/src/ui/types/dialog.ts +1 -3
  239. package/src/ui/types/props.ts +20 -10
  240. package/src/ui/utils/arrow/arrow.tsx +43 -25
  241. package/src/ui/utils/boundaryElement/boundaryElementProvider.tsx +2 -6
  242. package/src/ui/utils/boundaryElement/types.ts +1 -3
  243. package/src/ui/utils/boundaryElement/useBoundaryElement.ts +1 -3
  244. package/src/ui/utils/elementQuery/elementQuery.tsx +43 -19
  245. package/src/ui/utils/errorBoundary.tsx +2 -0
  246. package/src/ui/utils/index.ts +0 -1
  247. package/src/ui/utils/layer/layer.tsx +23 -93
  248. package/src/ui/utils/layer/layerCard.tsx +92 -0
  249. package/src/ui/utils/layer/layerProvider.tsx +2 -6
  250. package/src/ui/utils/layer/useLayer.ts +1 -3
  251. package/src/ui/utils/portal/portal.ts +2 -6
  252. package/src/ui/utils/portal/portalProvider.tsx +2 -6
  253. package/src/ui/utils/portal/types.ts +1 -3
  254. package/src/ui/utils/portal/usePortal.ts +1 -3
  255. package/src/ui/utils/srOnly/srOnly.tsx +25 -20
  256. package/src/ui/utils/virtualList/virtualList.tsx +69 -50
  257. package/src/css/compile/compilePalette.ts +0 -27
  258. package/src/css/compile/compileRule.ts +0 -97
  259. package/src/css/compile/compileRules.test.ts +0 -36
  260. package/src/css/compile/compileRules.ts +0 -43
  261. package/src/css/compile/compileSystem.ts +0 -10
  262. package/src/css/compile/compileTheme_v3.ts +0 -401
  263. package/src/css/compile/types.ts +0 -6
  264. package/src/css/components/breadcrumbs/rules.ts +0 -25
  265. package/src/css/components/dialog/rules.ts +0 -78
  266. package/src/css/components/skeleton/rules.ts +0 -113
  267. package/src/css/components/toast/rules.ts +0 -18
  268. package/src/css/components/tree/rules.ts +0 -168
  269. package/src/css/primitives/_selectable/_contants.ts +0 -11
  270. package/src/css/primitives/card/_constants.ts +0 -13
  271. package/src/css/primitives/popover/rules.ts +0 -5
  272. package/src/css/primitives/spinner/rules.ts +0 -21
  273. package/src/css/primitives/token/rules.ts +0 -45
  274. package/src/ui/utils/conditionalWrapper/conditionalWrapper.tsx +0 -23
  275. package/src/ui/utils/conditionalWrapper/index.ts +0 -1
@@ -3,22 +3,19 @@ import {
3
3
  autoUpdate,
4
4
  flip,
5
5
  hide,
6
- Middleware,
6
+ type Middleware,
7
7
  offset,
8
- RootBoundary,
8
+ type RootBoundary,
9
9
  shift,
10
10
  useFloating,
11
11
  } from '@floating-ui/react-dom'
12
12
  import {AnimatePresence} from 'framer-motion'
13
13
  import {
14
14
  cloneElement,
15
- ForwardedRef,
16
- forwardRef,
17
- memo,
18
- MutableRefObject,
19
- ReactElement,
20
- ReactNode,
21
- RefCallback,
15
+ type ForwardedRef,
16
+ type ReactElement,
17
+ type ReactNode,
18
+ type Ref,
22
19
  useCallback,
23
20
  useEffect,
24
21
  useImperativeHandle,
@@ -29,9 +26,9 @@ import {
29
26
  import {Z_OFFSETS} from '../../constants'
30
27
  import {useArrayProp, usePrefersReducedMotion} from '../../hooks'
31
28
  import {origin} from '../../middleware/origin'
32
- import {Placement, PopoverMargins, Props} from '../../types'
33
- import {LayerProps, LayerProvider, Portal, useBoundaryElement, useLayer} from '../../utils'
34
- import {CardProps} from '../card'
29
+ import type {ComponentType, Placement, PopoverMargins, Props} from '../../types'
30
+ import {type LayerOwnProps, LayerProvider, Portal, useBoundaryElement, useLayer} from '../../utils'
31
+ import {CardProvider, useCard} from '../card'
35
32
  import {
36
33
  DEFAULT_FALLBACK_PLACEMENTS,
37
34
  DEFAULT_POPOVER_DISTANCE,
@@ -40,10 +37,13 @@ import {
40
37
  } from './constants'
41
38
  import {size} from './floating-ui/size'
42
39
  import {PopoverCard} from './popoverCard'
43
- import {PopoverUpdateCallback} from './types'
40
+ import type {PopoverUpdateCallback} from './types'
44
41
 
45
42
  /** @public */
46
- export interface PopoverProps extends CardProps, LayerProps {
43
+ export const DEFAULT_POPOVER_ELEMENT = 'div'
44
+
45
+ /** @public */
46
+ export type PopoverOwnProps = LayerOwnProps & {
47
47
  /** @beta */
48
48
  __unstable_margins?: PopoverMargins
49
49
  /**
@@ -101,15 +101,32 @@ export interface PopoverProps extends CardProps, LayerProps {
101
101
  */
102
102
  referenceElement?: HTMLElement | null
103
103
  /** @beta */
104
- updateRef?:
105
- | MutableRefObject<PopoverUpdateCallback | undefined>
106
- | RefCallback<PopoverUpdateCallback | undefined>
104
+ updateRef?: Ref<PopoverUpdateCallback | undefined>
107
105
  }
108
106
 
109
- const ViewportOverlay = () => {
107
+ /** @public */
108
+ export type PopoverElementType = 'div' | ComponentType
109
+
110
+ /** @public */
111
+ export type PopoverProps<E extends PopoverElementType = PopoverElementType> = Props<
112
+ PopoverOwnProps,
113
+ E
114
+ >
115
+
116
+ function ViewportOverlay() {
110
117
  const {zIndex} = useLayer()
111
118
 
112
- return <div style={{height: '100vh', inset: 0, position: 'fixed', width: '100vw', zIndex}} />
119
+ return (
120
+ <div
121
+ style={{
122
+ position: 'fixed',
123
+ inset: 0,
124
+ width: '100vw',
125
+ height: '100vh',
126
+ zIndex,
127
+ }}
128
+ />
129
+ )
113
130
  }
114
131
 
115
132
  /**
@@ -117,281 +134,286 @@ const ViewportOverlay = () => {
117
134
  *
118
135
  * @public
119
136
  */
120
- export const Popover = memo(
121
- forwardRef(function Popover(
122
- props: Props<PopoverProps, 'div'>,
123
- forwardedRef: ForwardedRef<HTMLDivElement>,
124
- ): ReactElement {
125
- const boundaryElementContext = useBoundaryElement()
126
-
127
- const {
128
- __unstable_margins: margins = DEFAULT_POPOVER_MARGINS,
129
- animate: _animate = false,
130
- arrow: arrowProp = false,
131
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
132
- boundaryElement = boundaryElementContext.element,
133
- children: childProp,
134
- constrainSize = false,
135
- content,
136
- disabled,
137
- fallbackPlacements = props.fallbackPlacements ??
138
- DEFAULT_FALLBACK_PLACEMENTS[props.placement ?? 'bottom'],
139
- matchReferenceWidth,
140
- floatingBoundary = props.boundaryElement ?? boundaryElementContext.element,
141
- modal,
142
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
143
- onActivate,
144
- open,
145
- overflow = 'hidden',
146
- padding,
147
- placement: placementProp = 'bottom',
148
- portal,
149
- preventOverflow = true,
150
- radius = 3,
151
- referenceBoundary = props.boundaryElement ?? boundaryElementContext.element,
152
- referenceElement,
153
- scheme,
154
- shadow = 3,
155
- tone = 'inherit',
156
- width: widthProp = 'auto',
157
- // zOffset: zOffsetProp = layer.popover.zOffset,
158
- zOffset: zOffsetProp = Z_OFFSETS.popover,
159
- updateRef,
160
- ...restProps
161
- } = props
162
- const prefersReducedMotion = usePrefersReducedMotion()
163
- const animate = prefersReducedMotion ? false : _animate
164
- const zOffset = useArrayProp(zOffsetProp)
165
- const ref = useRef<HTMLDivElement | null>(null)
166
- const arrowRef = useRef<HTMLDivElement | null>(null)
167
- const rootBoundary: RootBoundary = 'viewport'
168
-
169
- useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(
170
- forwardedRef,
171
- () => ref.current,
172
- )
173
-
174
- // Keep track of reference element width (see `size` middleware below)
175
- const referenceWidthRef = useRef<number>(undefined)
176
-
177
- const middleware = useMemo(() => {
178
- const ret: Middleware[] = []
179
-
180
- // Flip the floating element when leaving the boundary box
181
- if (constrainSize || preventOverflow) {
182
- ret.push(
183
- flip({
184
- boundary: floatingBoundary || undefined,
185
- fallbackPlacements,
186
- padding: DEFAULT_POPOVER_PADDING,
187
- rootBoundary,
188
- }),
189
- )
190
- }
191
-
192
- // Define distance between reference and floating element
193
- ret.push(offset({mainAxis: DEFAULT_POPOVER_DISTANCE}))
194
-
195
- // Track sizes
196
- if (constrainSize || matchReferenceWidth) {
197
- ret.push(
198
- size({
199
- apply({availableWidth, availableHeight, elements, referenceWidth}) {
200
- // not fresh, so use refs
201
-
202
- referenceWidthRef.current = referenceWidth
203
-
204
- if (matchReferenceWidth) {
205
- elements.floating.style.width = `${referenceWidth}px`
206
- }
207
-
208
- if (constrainSize) {
209
- elements.floating.style.maxWidth = `${availableWidth}px`
210
- elements.floating.style.maxHeight = `${availableHeight}px`
211
- }
212
- },
213
- boundaryElement: floatingBoundary || undefined,
214
- constrainSize,
215
- margins,
216
- matchReferenceWidth,
217
- padding: DEFAULT_POPOVER_PADDING,
218
- }),
219
- )
220
- }
137
+ export function Popover<E extends PopoverElementType = typeof DEFAULT_POPOVER_ELEMENT>(
138
+ props: PopoverProps<E>,
139
+ ) {
140
+ const boundaryElementContext = useBoundaryElement()
141
+
142
+ const {
143
+ __unstable_margins: margins = DEFAULT_POPOVER_MARGINS,
144
+ animate: _animate = false,
145
+ arrow: arrowProp = false,
146
+ as: as = DEFAULT_POPOVER_ELEMENT,
147
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
148
+ boundaryElement = boundaryElementContext.element,
149
+ children: childProp,
150
+ constrainSize = false,
151
+ content,
152
+ disabled,
153
+ fallbackPlacements = props.fallbackPlacements ??
154
+ DEFAULT_FALLBACK_PLACEMENTS[props.placement ?? 'bottom'],
155
+ matchReferenceWidth,
156
+ floatingBoundary = props.boundaryElement ?? boundaryElementContext.element,
157
+ modal,
158
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
159
+ onActivate,
160
+ open,
161
+ overflow = 'hidden',
162
+ padding,
163
+ placement: placementProp = 'bottom',
164
+ portal,
165
+ preventOverflow = true,
166
+ radius = 3,
167
+ ref: forwardedRef,
168
+ referenceBoundary = props.boundaryElement ?? boundaryElementContext.element,
169
+ referenceElement,
170
+ scheme,
171
+ shadow = 3,
172
+ tone = 'inherit',
173
+ width: widthProp = 'auto',
174
+ zOffset: zOffsetProp = Z_OFFSETS.popover,
175
+ updateRef,
176
+ ...rest
177
+ } = props as PopoverProps<typeof DEFAULT_POPOVER_ELEMENT>
178
+
179
+ const card = useCard()
180
+
181
+ const prefersReducedMotion = usePrefersReducedMotion()
182
+ const animate = prefersReducedMotion ? false : _animate
183
+ const zOffset = useArrayProp(zOffsetProp)
184
+ const ref = useRef<HTMLDivElement | null>(null)
185
+ const arrowRef = useRef<HTMLDivElement | null>(null)
186
+ const rootBoundary: RootBoundary = 'viewport'
187
+
188
+ useImperativeHandle<HTMLDivElement | null, HTMLDivElement | null>(forwardedRef, () => ref.current)
189
+
190
+ // Keep track of reference element width (see `size` middleware below)
191
+ const referenceWidthRef = useRef<number>(undefined)
192
+
193
+ const middleware = useMemo(() => {
194
+ const ret: Middleware[] = []
195
+
196
+ // Flip the floating element when leaving the boundary box
197
+ if (constrainSize || preventOverflow) {
198
+ ret.push(
199
+ flip({
200
+ boundary: floatingBoundary || undefined,
201
+ fallbackPlacements,
202
+ padding: DEFAULT_POPOVER_PADDING,
203
+ rootBoundary,
204
+ }),
205
+ )
206
+ }
221
207
 
222
- // Shift the popover so its sits within the boundary element
223
- if (preventOverflow) {
224
- ret.push(
225
- shift({
226
- boundary: floatingBoundary || undefined,
227
- rootBoundary,
228
- padding: DEFAULT_POPOVER_PADDING,
229
- }),
230
- )
231
- }
208
+ // Define distance between reference and floating element
209
+ ret.push(offset({mainAxis: DEFAULT_POPOVER_DISTANCE}))
232
210
 
233
- // Place arrow
234
- if (arrowProp) {
235
- ret.push(
236
- arrow({
237
- element: arrowRef,
238
- padding: DEFAULT_POPOVER_PADDING,
239
- }),
240
- )
241
- }
211
+ // Track sizes
212
+ if (constrainSize || matchReferenceWidth) {
213
+ ret.push(
214
+ size({
215
+ apply({availableWidth, availableHeight, elements, referenceWidth}) {
216
+ // not fresh, so use refs
217
+
218
+ referenceWidthRef.current = referenceWidth
219
+
220
+ if (matchReferenceWidth) {
221
+ elements.floating.style.width = `${referenceWidth}px`
222
+ }
223
+
224
+ if (constrainSize) {
225
+ elements.floating.style.maxWidth = `${availableWidth}px`
226
+ elements.floating.style.maxHeight = `${availableHeight}px`
227
+ }
228
+ },
229
+ boundaryElement: floatingBoundary || undefined,
230
+ constrainSize,
231
+ margins,
232
+ matchReferenceWidth,
233
+ padding: DEFAULT_POPOVER_PADDING,
234
+ }),
235
+ )
236
+ }
242
237
 
243
- // Determine the origin to scale from.
244
- // Must be placed after `@sanity/ui/size` and `shift` middleware.
245
- if (animate) {
246
- ret.push(origin)
247
- }
238
+ // Shift the popover so its sits within the boundary element
239
+ if (preventOverflow) {
240
+ ret.push(
241
+ shift({
242
+ boundary: floatingBoundary || undefined,
243
+ rootBoundary,
244
+ padding: DEFAULT_POPOVER_PADDING,
245
+ }),
246
+ )
247
+ }
248
248
 
249
+ // Place arrow
250
+ if (arrowProp) {
249
251
  ret.push(
250
- hide({
251
- boundary: referenceBoundary || undefined,
252
+ arrow({
253
+ element: arrowRef,
252
254
  padding: DEFAULT_POPOVER_PADDING,
253
- strategy: 'referenceHidden',
254
255
  }),
255
256
  )
257
+ }
256
258
 
257
- return ret
258
- }, [
259
- animate,
260
- arrowProp,
261
- constrainSize,
262
- fallbackPlacements,
263
- floatingBoundary,
264
- margins,
265
- matchReferenceWidth,
266
- preventOverflow,
267
- referenceBoundary,
268
- ])
269
-
270
- const {x, y, middlewareData, placement, refs, strategy, update} = useFloating({
271
- middleware,
272
- placement: placementProp,
273
- whileElementsMounted: autoUpdate,
274
- elements: referenceElement
275
- ? {
276
- reference: referenceElement,
277
- }
278
- : undefined,
279
- })
280
-
281
- const referenceHidden = middlewareData.hide?.referenceHidden
282
-
283
- const arrowX = middlewareData.arrow?.x
284
- const arrowY = middlewareData.arrow?.y
285
-
286
- const originX = middlewareData['@sanity/ui/origin']?.originX
287
- const originY = middlewareData['@sanity/ui/origin']?.originY
288
-
289
- const setArrow = useCallback((arrowEl: HTMLDivElement | null) => {
290
- arrowRef.current = arrowEl
291
- }, [])
292
-
293
- const setFloating = useCallback(
294
- (node: HTMLDivElement | null) => {
295
- ref.current = node
296
- refs.setFloating(node)
297
- },
298
- [refs],
259
+ // Determine the origin to scale from.
260
+ // Must be placed after `@sanity/ui/size` and `shift` middleware.
261
+ if (animate) {
262
+ ret.push(origin)
263
+ }
264
+
265
+ ret.push(
266
+ hide({
267
+ boundary: referenceBoundary || undefined,
268
+ padding: DEFAULT_POPOVER_PADDING,
269
+ strategy: 'referenceHidden',
270
+ }),
299
271
  )
300
272
 
301
- const setReference = useCallback(
302
- (node: HTMLElement | null) => {
303
- refs.setReference(node)
273
+ return ret
274
+ }, [
275
+ animate,
276
+ arrowProp,
277
+ constrainSize,
278
+ fallbackPlacements,
279
+ floatingBoundary,
280
+ margins,
281
+ matchReferenceWidth,
282
+ preventOverflow,
283
+ referenceBoundary,
284
+ ])
285
+
286
+ const {x, y, middlewareData, placement, refs, strategy, update} = useFloating({
287
+ middleware,
288
+ placement: placementProp,
289
+ whileElementsMounted: autoUpdate,
290
+ elements: referenceElement
291
+ ? {
292
+ reference: referenceElement,
293
+ }
294
+ : undefined,
295
+ })
304
296
 
305
- const childRef = getElementRef(childProp as any)
297
+ const referenceHidden = middlewareData.hide?.referenceHidden
306
298
 
307
- if (typeof childRef === 'function') {
308
- childRef(node)
309
- } else if (childRef) {
310
- childRef.current = node
311
- }
312
- },
313
- [childProp, refs],
314
- )
299
+ const arrowX = middlewareData.arrow?.x
300
+ const arrowY = middlewareData.arrow?.y
315
301
 
316
- const child = useMemo(() => {
317
- // If a reference element is defined, we don't need to clone the child
318
- if (referenceElement) return childProp
302
+ const originX = middlewareData['@sanity/ui/origin']?.originX
303
+ const originY = middlewareData['@sanity/ui/origin']?.originY
319
304
 
320
- if (!childProp) return null
305
+ const setArrow = useCallback((arrowEl: HTMLDivElement | null) => {
306
+ arrowRef.current = arrowEl
307
+ }, [])
321
308
 
322
- return cloneElement(childProp, {ref: setReference})
323
- }, [childProp, referenceElement, setReference])
309
+ const setFloating = useCallback(
310
+ (node: HTMLDivElement | null) => {
311
+ ref.current = node
312
+ refs.setFloating(node)
313
+ },
314
+ [refs],
315
+ )
324
316
 
325
- useEffect(() => {
326
- if (updateRef) {
327
- if (typeof updateRef === 'function') {
328
- updateRef(update)
329
- } else if (updateRef) {
330
- updateRef.current = update
331
- }
317
+ const setReference = useCallback(
318
+ (node: HTMLElement | null) => {
319
+ refs.setReference(node)
320
+
321
+ const childRef = getElementRef(childProp as any)
322
+
323
+ if (typeof childRef === 'function') {
324
+ childRef(node)
325
+ } else if (childRef) {
326
+ childRef.current = node
332
327
  }
333
- }, [update, updateRef])
328
+ },
329
+ [childProp, refs],
330
+ )
331
+
332
+ const child = useMemo(() => {
333
+ // If a reference element is defined, we don't need to clone the child
334
+ if (referenceElement) return childProp
334
335
 
335
- if (disabled) {
336
- return childProp || <></>
336
+ if (!childProp) return null
337
+
338
+ return cloneElement(childProp, {ref: setReference})
339
+ }, [childProp, referenceElement, setReference])
340
+
341
+ useEffect(() => {
342
+ if (updateRef) {
343
+ if (typeof updateRef === 'function') {
344
+ updateRef(update)
345
+ } else if (updateRef) {
346
+ updateRef.current = update
347
+ }
337
348
  }
349
+ }, [update, updateRef])
338
350
 
339
- const popover = (
340
- <LayerProvider zOffset={zOffset}>
341
- {/* Optional transparent blocking overlay at the top-most z-index layer. Must be positioned before the below popover card. */}
342
- {modal && <ViewportOverlay />}
343
-
344
- <PopoverCard
345
- {...restProps}
346
- __unstable_margins={margins}
347
- animate={animate}
348
- arrow={arrowProp}
349
- arrowRef={setArrow}
350
- arrowX={arrowX}
351
- arrowY={arrowY}
352
- hidden={referenceHidden}
353
- maxWidth={widthProp}
354
- overflow={overflow}
355
- padding={padding}
356
- placement={placement}
357
- radius={radius}
358
- ref={setFloating}
359
- // referenceWidth={matchReferenceWidth ? referenceWidthRef.current : width}
360
- scheme={scheme}
361
- shadow={shadow}
362
- originX={originX}
363
- originY={originY}
364
- strategy={strategy}
365
- tone={tone}
366
- x={x}
367
- y={y}
368
- >
369
- {content}
370
- </PopoverCard>
371
- </LayerProvider>
372
- )
351
+ if (disabled) {
352
+ return childProp || <></>
353
+ }
373
354
 
374
- const children =
375
- open &&
376
- (portal ? (
377
- <Portal __unstable_name={typeof portal === 'string' ? portal : undefined}>{popover}</Portal>
378
- ) : (
379
- popover
380
- ))
381
-
382
- return (
383
- <>
384
- {/* the popover */}
385
- {animate ? <AnimatePresence>{children}</AnimatePresence> : children}
386
-
387
- {/* the referred element */}
388
- {child}
389
- </>
390
- )
391
- }),
392
- )
355
+ const popover = (
356
+ <LayerProvider zOffset={zOffset}>
357
+ {/* Optional transparent blocking overlay at the top-most z-index layer. Must be positioned
358
+ before the below popover card. */}
359
+ {modal && <ViewportOverlay />}
360
+
361
+ <PopoverCard
362
+ {...rest}
363
+ __unstable_margins={margins}
364
+ animate={animate}
365
+ arrow={arrowProp}
366
+ arrowRef={setArrow}
367
+ arrowX={arrowX}
368
+ arrowY={arrowY}
369
+ as={as}
370
+ hidden={referenceHidden}
371
+ maxWidth={widthProp}
372
+ overflow={overflow}
373
+ padding={padding}
374
+ placement={placement}
375
+ radius={radius}
376
+ ref={setFloating}
377
+ scheme={scheme}
378
+ shadow={shadow}
379
+ originX={originX}
380
+ originY={originY}
381
+ strategy={strategy}
382
+ x={x}
383
+ y={y}
384
+ >
385
+ {content}
386
+ </PopoverCard>
387
+ </LayerProvider>
388
+ )
389
+
390
+ const children =
391
+ open &&
392
+ (portal ? (
393
+ <Portal __unstable_name={typeof portal === 'string' ? portal : undefined}>
394
+ <CardProvider
395
+ tone={tone === 'inherit' ? (card?.tone ?? 'default') : tone}
396
+ scheme={scheme ?? 'light'}
397
+ >
398
+ {popover}
399
+ </CardProvider>
400
+ </Portal>
401
+ ) : (
402
+ popover
403
+ ))
404
+
405
+ return (
406
+ <>
407
+ {/* the popover */}
408
+ {animate ? <AnimatePresence>{children}</AnimatePresence> : children}
409
+
410
+ {/* the referred element */}
411
+ {child}
412
+ </>
413
+ )
414
+ }
393
415
 
394
- Popover.displayName = 'Memo(ForwardRef(Popover))'
416
+ Popover.displayName = 'Popover'
395
417
 
396
418
  // Before React 19 accessing `element.props.ref` will throw a warning and suggest using `element.ref`
397
419
  // After React 19 accessing `element.ref` does the opposite.