@sanity/ui 0.37.14-next.6 → 0.37.14

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 (46) hide show
  1. package/lib/dts/src/components/autocomplete/autocomplete.styles.d.ts +1 -1
  2. package/lib/dts/src/components/autocomplete/autocomplete.styles.d.ts.map +1 -1
  3. package/lib/dts/src/components/autocomplete/constants.d.ts.map +1 -1
  4. package/lib/dts/src/constants.d.ts +0 -10
  5. package/lib/dts/src/constants.d.ts.map +1 -1
  6. package/lib/dts/src/primitives/popover/{popoverArrow.d.ts → arrow.d.ts} +1 -1
  7. package/lib/dts/src/primitives/popover/arrow.d.ts.map +1 -0
  8. package/lib/dts/src/primitives/popover/modifiers/getPopoverModifiers.d.ts +4 -0
  9. package/lib/dts/src/primitives/popover/modifiers/getPopoverModifiers.d.ts.map +1 -0
  10. package/lib/dts/src/primitives/popover/modifiers/index.d.ts +2 -0
  11. package/lib/dts/src/primitives/popover/modifiers/index.d.ts.map +1 -0
  12. package/lib/dts/src/primitives/popover/modifiers/types.d.ts +18 -0
  13. package/lib/dts/src/primitives/popover/modifiers/types.d.ts.map +1 -0
  14. package/lib/dts/src/primitives/popover/modifiers/usePopoverModifiers.d.ts +4 -0
  15. package/lib/dts/src/primitives/popover/modifiers/usePopoverModifiers.d.ts.map +1 -0
  16. package/lib/dts/src/primitives/popover/popover.d.ts +5 -6
  17. package/lib/dts/src/primitives/popover/popover.d.ts.map +1 -1
  18. package/lib/dts/src/primitives/tooltip/tooltip.d.ts +0 -2
  19. package/lib/dts/src/primitives/tooltip/tooltip.d.ts.map +1 -1
  20. package/lib/dts/src/primitives/tooltip/tooltipArrow.d.ts.map +1 -1
  21. package/lib/sanity-ui.js +439 -488
  22. package/lib/sanity-ui.js.map +1 -1
  23. package/lib/sanity-ui.modern.mjs +555 -561
  24. package/lib/sanity-ui.modern.mjs.map +1 -1
  25. package/lib/sanity-ui.module.js +439 -489
  26. package/lib/sanity-ui.module.js.map +1 -1
  27. package/package.json +6 -5
  28. package/src/components/autocomplete/autocomplete.styles.tsx +5 -0
  29. package/src/components/autocomplete/constants.ts +3 -3
  30. package/src/constants.ts +0 -17
  31. package/src/primitives/popover/__workshop__/PlainStory.tsx +0 -1
  32. package/src/primitives/popover/__workshop__/RightAlignedStory.tsx +0 -1
  33. package/src/primitives/popover/__workshop__/TestStory.tsx +0 -1
  34. package/src/primitives/popover/{popoverArrow.tsx → arrow.tsx} +5 -5
  35. package/src/primitives/popover/modifiers/getPopoverModifiers.ts +137 -0
  36. package/src/primitives/popover/modifiers/index.ts +1 -0
  37. package/src/primitives/popover/modifiers/types.ts +18 -0
  38. package/src/primitives/popover/modifiers/usePopoverModifiers.ts +58 -0
  39. package/src/primitives/popover/popover.tsx +195 -245
  40. package/src/primitives/tooltip/__workshop__/props.tsx +1 -3
  41. package/src/primitives/tooltip/tooltip.tsx +83 -159
  42. package/src/primitives/tooltip/tooltipArrow.tsx +10 -25
  43. package/lib/dts/src/primitives/popover/popoverArrow.d.ts.map +0 -1
  44. package/lib/dts/src/primitives/popover/popoverCard.d.ts +0 -33
  45. package/lib/dts/src/primitives/popover/popoverCard.d.ts.map +0 -1
  46. package/src/primitives/popover/popoverCard.tsx +0 -160
@@ -1,30 +1,17 @@
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'
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 {useArrayProp, useForwardedRef} from '../../hooks'
23
6
  import {ThemeColorSchemeKey, useTheme} from '../../theme'
24
- import {BoxOverflow, CardTone, Placement, PopoverMargins} from '../../types'
25
- import {LayerProps, LayerProvider, Portal, useBoundaryElement} from '../../utils'
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'
26
12
  import {ResponsiveRadiusProps, ResponsiveShadowProps, ResponsiveWidthProps} from '../types'
27
- import {PopoverCard} from './popoverCard'
13
+ import {PopoverArrow} from './arrow'
14
+ import {usePopoverModifiers} from './modifiers'
28
15
 
29
16
  /**
30
17
  * @public
@@ -38,7 +25,6 @@ export interface PopoverProps
38
25
  * @beta
39
26
  */
40
27
  __unstable_margins?: PopoverMargins
41
- /** @deprecated Use `fallbackPlacements` instead. */
42
28
  allowedAutoPlacements?: Placement[]
43
29
  arrow?: boolean
44
30
  boundaryElement?: HTMLElement | null
@@ -48,7 +34,6 @@ export interface PopoverProps
48
34
  disabled?: boolean
49
35
  fallbackPlacements?: Placement[]
50
36
  open?: boolean
51
- overflow?: BoxOverflow
52
37
  padding?: number | number[]
53
38
  placement?: Placement
54
39
  portal?: boolean | string
@@ -56,243 +41,208 @@ export interface PopoverProps
56
41
  referenceElement?: HTMLElement | null
57
42
  matchReferenceWidth?: boolean
58
43
  scheme?: ThemeColorSchemeKey
59
- /** @deprecated No longer supported. */
60
44
  tether?: boolean
61
- /** @deprecated No longer supported. */
62
45
  tetherOffset?: number | ((...args: any[]) => number)
63
46
  tone?: CardTone
64
47
  }
65
48
 
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
- }
80
-
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[] = []
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);
141
55
 
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
- )
152
- }
153
-
154
- // Track sizes
155
- ret.push(
156
- size({
157
- boundaryElement,
158
- constrainSize,
159
- matchReferenceWidth: matchReferenceWidthProp,
160
- setAvailableHeight,
161
- setAvailableWidth,
162
- setReferenceWidth,
163
- })
164
- )
165
-
166
- // Define distance between reference and floating element
167
- ret.push(offset({mainAxis: arrowProp ? 4 : 0}))
56
+ & > * {
57
+ min-height: 0;
58
+ }
168
59
 
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
- )
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;
178
65
  }
66
+ `}
67
+ `
68
+ )
179
69
 
180
- // Place arrow
181
- if (arrowProp) {
182
- ret.push(arrow({element: arrowRef, padding: 4}))
183
- }
70
+ const PopoverCard = styled(Card)<
71
+ ResponsiveWidthStyleProps & {
72
+ $constrainSize?: boolean
73
+ $preventOverflow?: boolean
74
+ $width: (number | 'auto')[]
75
+ }
76
+ >(
77
+ ({$constrainSize}) => css`
78
+ flex: 1;
79
+ max-height: ${$constrainSize && '100%'};
80
+ pointer-events: all;
81
+
82
+ && {
83
+ display: flex;
84
+ }
184
85
 
185
- return ret
186
- }, [
187
- arrowProp,
188
- boundaryElement,
189
- constrainSize,
190
- fallbackPlacements,
191
- matchReferenceWidthProp,
192
- preventOverflow,
193
- ])
86
+ flex-direction: column;
194
87
 
195
- const {x, y, placement, reference, floating, middlewareData, strategy} = useFloating({
196
- middleware,
197
- placement: placementProp,
198
- whileElementsMounted: autoUpdate,
199
- })
88
+ & > * {
89
+ min-height: 0;
90
+ }
200
91
 
201
- const arrowX = middlewareData.arrow?.x
202
- const arrowY = middlewareData.arrow?.y
92
+ ${responsiveContainerWidthStyle}
93
+ `
94
+ )
203
95
 
204
- const setArrow = useCallback((arrowEl: HTMLDivElement | null) => {
205
- arrowRef.current = arrowEl
206
- }, [])
96
+ /**
97
+ * @public
98
+ */
99
+ export const Popover = forwardRef(function Popover(
100
+ props: PopoverProps &
101
+ Omit<React.HTMLProps<HTMLDivElement>, 'as' | 'children' | 'content' | 'width'>,
102
+ ref: React.ForwardedRef<HTMLDivElement>
103
+ ) {
104
+ const boundaryElementContext = useBoundaryElement()
105
+ const theme = useTheme()
106
+ const {
107
+ __unstable_margins: margins,
108
+ allowedAutoPlacements,
109
+ arrow = true,
110
+ boundaryElement: boundaryElementProp = boundaryElementContext.element,
111
+ children: child,
112
+ content,
113
+ constrainSize,
114
+ disabled,
115
+ fallbackPlacements,
116
+ open = false,
117
+ padding,
118
+ placement = 'bottom',
119
+ portal: portalProp = false,
120
+ preventOverflow,
121
+ radius = 3,
122
+ referenceElement: referenceElementProp,
123
+ matchReferenceWidth,
124
+ shadow = 3,
125
+ scheme,
126
+ style = EMPTY_RECORD,
127
+ tether,
128
+ tetherOffset,
129
+ tone = 'inherit',
130
+ width: widthProp = 0,
131
+ zOffset = theme.sanity.layer?.popover.zOffset,
132
+ ...restProps
133
+ } = props
134
+ const forwardedRef = useForwardedRef(ref)
135
+ const portal = usePortal()
136
+ const [referenceElement, setReferenceElement] = useState<HTMLElement | null>(null)
137
+ const [popperElement, setPopperElement] = useState<HTMLElement | null>(null)
138
+ const [arrowElement, setArrowElement] = useState<HTMLElement | null>(null)
139
+ const popperReferenceElement = referenceElementProp || referenceElement
140
+ const width = useArrayProp(widthProp)
141
+
142
+ const modifiers = usePopoverModifiers({
143
+ allowedAutoPlacements,
144
+ arrow,
145
+ arrowElement,
146
+ boundaryElement: boundaryElementProp || portal.boundaryElement,
147
+ constrainSize,
148
+ distance: arrow ? 4 : 0,
149
+ fallbackPlacements,
150
+ margins,
151
+ matchReferenceWidth,
152
+ open,
153
+ preventOverflow,
154
+ skidding: 0,
155
+ tether,
156
+ tetherOffset,
157
+ })
207
158
 
208
- const setFloating = useCallback(
209
- (node: HTMLDivElement | null) => {
210
- forwardedRef.current = node
211
- floating(node)
212
- },
213
- [floating, forwardedRef]
214
- )
159
+ const popper = usePopper(popperReferenceElement, popperElement, {
160
+ placement,
161
+ modifiers,
162
+ })
215
163
 
216
- const setReference = useCallback(
217
- (node: HTMLElement | null) => {
218
- reference(node)
164
+ const {attributes, forceUpdate, styles} = popper
219
165
 
220
- const childRef = (childProp as any)?.ref
166
+ const setRef = useCallback(
167
+ (el: HTMLElement | null) => {
168
+ const childRef = (child as any).ref
221
169
 
222
- if (typeof childRef === 'function') {
223
- childRef(node)
224
- } else if (childRef) {
225
- childRef.current = node
226
- }
227
- },
228
- [childProp, reference]
229
- )
170
+ setReferenceElement(el)
230
171
 
231
- const child = useMemo(() => {
232
- if (!childProp || referenceElement) return null
172
+ if (typeof childRef === 'function') {
173
+ childRef(el)
174
+ } else if (childRef) {
175
+ childRef.current = el
176
+ }
177
+ },
178
+ [child]
179
+ )
233
180
 
234
- return cloneElement(childProp, {ref: setReference})
235
- }, [childProp, referenceElement, setReference])
181
+ const setRootRef = useCallback(
182
+ (el: HTMLDivElement | null) => {
183
+ setPopperElement(el)
184
+ forwardedRef.current = el
185
+ },
186
+ [forwardedRef]
187
+ )
236
188
 
237
- useEffect(() => {
238
- if (referenceElement) reference(referenceElement)
239
- }, [reference, referenceElement])
189
+ const popoverStyle = useMemo(() => ({...style, ...styles.popper}), [style, styles])
240
190
 
241
- if (disabled) {
242
- return childProp || <></>
191
+ useEffect(() => {
192
+ if (forceUpdate) {
193
+ try {
194
+ forceUpdate()
195
+ } catch (_) {
196
+ // ignore caught error
197
+ }
243
198
  }
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'
199
+ }, [content, forceUpdate, open, popperReferenceElement])
200
+
201
+ if (disabled) {
202
+ return child || <></>
203
+ }
204
+
205
+ const node = (
206
+ <Root
207
+ data-ui="Popover"
208
+ {...restProps}
209
+ $preventOverflow={preventOverflow}
210
+ ref={setRootRef}
211
+ style={popoverStyle}
212
+ zOffset={zOffset}
213
+ {...attributes.popper}
214
+ >
215
+ <PopoverCard
216
+ $constrainSize={constrainSize}
217
+ $width={width}
218
+ data-ui="PopoverCard"
219
+ padding={padding}
220
+ radius={radius}
221
+ scheme={scheme}
222
+ shadow={shadow}
223
+ tone={tone}
224
+ >
225
+ {arrow && <PopoverArrow ref={setArrowElement} style={styles.arrow} />}
226
+ {content}
227
+ </PopoverCard>
228
+ </Root>
229
+ )
230
+
231
+ return (
232
+ <>
233
+ {child && !referenceElementProp ? cloneElement(child, {ref: setRef}) : child || <></>}
234
+
235
+ {open && (
236
+ <>
237
+ {portalProp && (
238
+ <Portal __unstable_name={typeof portalProp === 'string' ? portalProp : undefined}>
239
+ {node}
240
+ </Portal>
241
+ )}
242
+
243
+ {!portalProp && node}
244
+ </>
245
+ )}
246
+ </>
247
+ )
248
+ })
@@ -1,11 +1,10 @@
1
1
  import {Box, Button, Card, Flex, Text, Tooltip} from '@sanity/ui'
2
2
  import {useSelect} from '@sanity/ui-workshop'
3
3
  import React from 'react'
4
- import {WORKSHOP_PLACEMENT_OPTIONS, WORKSHOP_SHADOW_OPTIONS} from '../../../__workshop__/constants'
4
+ import {WORKSHOP_PLACEMENT_OPTIONS} from '../../../__workshop__/constants'
5
5
 
6
6
  export default function PropsStory() {
7
7
  const placement = useSelect('Placement', WORKSHOP_PLACEMENT_OPTIONS, 'top')
8
- const shadow = useSelect('Shadow', WORKSHOP_SHADOW_OPTIONS, 2)
9
8
 
10
9
  return (
11
10
  <Card height="fill">
@@ -18,7 +17,6 @@ export default function PropsStory() {
18
17
  }
19
18
  placement={placement}
20
19
  portal
21
- shadow={shadow}
22
20
  >
23
21
  <Button mode="bleed" text="Hover me" />
24
22
  </Tooltip>