@tamagui/popover 1.43.2 → 1.43.3
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.
- package/dist/cjs/Popover.js +81 -51
- package/dist/cjs/Popover.js.map +1 -1
- package/dist/esm/Popover.js +81 -51
- package/dist/esm/Popover.js.map +1 -1
- package/dist/jsx/Popover.js +58 -32
- package/dist/jsx/Popover.js.map +1 -1
- package/dist/jsx/Popover.mjs +58 -32
- package/dist/jsx/Popover.mjs.map +1 -1
- package/package.json +18 -18
- package/src/Popover.tsx +118 -87
- package/types/Popover.d.ts +1 -1
- package/types/Popover.d.ts.map +1 -1
package/src/Popover.tsx
CHANGED
|
@@ -47,6 +47,7 @@ import { Freeze } from 'react-freeze'
|
|
|
47
47
|
import { Platform, ScrollView, ScrollViewProps } from 'react-native'
|
|
48
48
|
|
|
49
49
|
import { useFloatingContext } from './useFloatingContext'
|
|
50
|
+
|
|
50
51
|
// adapted from radix-ui popover
|
|
51
52
|
|
|
52
53
|
export type PopoverProps = PopperProps & {
|
|
@@ -148,6 +149,18 @@ export interface PopoverContentTypeProps
|
|
|
148
149
|
export const PopoverContent = PopperContentFrame.extractable(
|
|
149
150
|
React.forwardRef<PopoverContentTypeElement, PopoverContentTypeProps>(
|
|
150
151
|
function PopoverContent(props: PopoverContentTypeProps, forwardedRef) {
|
|
152
|
+
return (
|
|
153
|
+
<PopoverContentPortal zIndex={props.zIndex}>
|
|
154
|
+
<PopoverContentInner {...props} ref={forwardedRef} />
|
|
155
|
+
</PopoverContentPortal>
|
|
156
|
+
)
|
|
157
|
+
}
|
|
158
|
+
)
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
const PopoverContentInner = React.memo(
|
|
162
|
+
React.forwardRef<PopoverContentTypeElement, PopoverContentTypeProps>(
|
|
163
|
+
(props, forwardedRef) => {
|
|
151
164
|
const {
|
|
152
165
|
allowPinchZoom,
|
|
153
166
|
trapFocus,
|
|
@@ -159,6 +172,7 @@ export const PopoverContent = PopperContentFrame.extractable(
|
|
|
159
172
|
const contentRef = React.useRef<any>(null)
|
|
160
173
|
const composedRefs = useComposedRefs(forwardedRef, contentRef)
|
|
161
174
|
const isRightClickOutsideRef = React.useRef(false)
|
|
175
|
+
const themeName = useThemeName()
|
|
162
176
|
|
|
163
177
|
// aria-hide everything except the content (better supported equivalent to setting aria-modal)
|
|
164
178
|
React.useEffect(() => {
|
|
@@ -167,49 +181,42 @@ export const PopoverContent = PopperContentFrame.extractable(
|
|
|
167
181
|
if (content) return hideOthers(content)
|
|
168
182
|
}, [context.open])
|
|
169
183
|
|
|
170
|
-
const themeName = useThemeName()
|
|
171
184
|
return (
|
|
172
|
-
<
|
|
173
|
-
<
|
|
174
|
-
<
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
)
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
{ checkDefaultPrevented: false }
|
|
208
|
-
)}
|
|
209
|
-
/>
|
|
210
|
-
</Theme>
|
|
211
|
-
</Stack>
|
|
212
|
-
</PopoverContentPortal>
|
|
185
|
+
<Stack pointerEvents={context.open ? 'auto' : 'none'}>
|
|
186
|
+
<Theme name={themeName}>
|
|
187
|
+
<PopoverContentImpl
|
|
188
|
+
{...contentImplProps}
|
|
189
|
+
disableRemoveScroll={disableRemoveScroll}
|
|
190
|
+
ref={composedRefs}
|
|
191
|
+
// we make sure we're not trapping once it's been closed
|
|
192
|
+
// (closed !== unmounted when animating out)
|
|
193
|
+
trapFocus={trapFocus ?? context.open}
|
|
194
|
+
disableOutsidePointerEvents
|
|
195
|
+
onCloseAutoFocus={composeEventHandlers(props.onCloseAutoFocus, (event) => {
|
|
196
|
+
event.preventDefault()
|
|
197
|
+
if (!isRightClickOutsideRef.current) context.triggerRef.current?.focus()
|
|
198
|
+
})}
|
|
199
|
+
onPointerDownOutside={composeEventHandlers(
|
|
200
|
+
props.onPointerDownOutside,
|
|
201
|
+
(event) => {
|
|
202
|
+
const originalEvent = event.detail.originalEvent
|
|
203
|
+
const ctrlLeftClick =
|
|
204
|
+
originalEvent.button === 0 && originalEvent.ctrlKey === true
|
|
205
|
+
const isRightClick = originalEvent.button === 2 || ctrlLeftClick
|
|
206
|
+
isRightClickOutsideRef.current = isRightClick
|
|
207
|
+
},
|
|
208
|
+
{ checkDefaultPrevented: false }
|
|
209
|
+
)}
|
|
210
|
+
// When focus is trapped, a `focusout` event may still happen.
|
|
211
|
+
// We make sure we don't trigger our `onDismiss` in such case.
|
|
212
|
+
onFocusOutside={composeEventHandlers(
|
|
213
|
+
props.onFocusOutside,
|
|
214
|
+
(event) => event.preventDefault(),
|
|
215
|
+
{ checkDefaultPrevented: false }
|
|
216
|
+
)}
|
|
217
|
+
/>
|
|
218
|
+
</Theme>
|
|
219
|
+
</Stack>
|
|
213
220
|
)
|
|
214
221
|
}
|
|
215
222
|
)
|
|
@@ -230,9 +237,22 @@ function PopoverRepropagateContext(props: {
|
|
|
230
237
|
}
|
|
231
238
|
|
|
232
239
|
function PopoverContentPortal(props: PopoverContentTypeProps) {
|
|
240
|
+
const zIndex = props.zIndex ?? 150_000
|
|
241
|
+
|
|
242
|
+
// Portal the contents and add a transparent bg overlay to handle dismiss on native
|
|
243
|
+
return (
|
|
244
|
+
<Portal zIndex={zIndex}>
|
|
245
|
+
{React.useMemo(() => {
|
|
246
|
+
return <PopoverContentPortalContents {...props} />
|
|
247
|
+
}, [props])}
|
|
248
|
+
</Portal>
|
|
249
|
+
)
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
const PopoverContentPortalContents = (props: PopoverContentTypeProps) => {
|
|
233
253
|
const themeName = useThemeName()
|
|
234
|
-
const context = usePopoverContext()
|
|
235
254
|
const popperContext = usePopperContext()
|
|
255
|
+
const context = usePopoverContext()
|
|
236
256
|
|
|
237
257
|
// on android we have to re-pass context
|
|
238
258
|
let contents = props.children
|
|
@@ -245,21 +265,16 @@ function PopoverContentPortal(props: PopoverContentTypeProps) {
|
|
|
245
265
|
)
|
|
246
266
|
}
|
|
247
267
|
|
|
248
|
-
const zIndex = props.zIndex ?? 150_000
|
|
249
|
-
|
|
250
|
-
// Portal the contents and add a transparent bg overlay to handle dismiss on native
|
|
251
268
|
return (
|
|
252
|
-
<
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
</Theme>
|
|
262
|
-
</Portal>
|
|
269
|
+
<Theme forceClassName name={themeName}>
|
|
270
|
+
{!!context.open && !context.breakpointActive && (
|
|
271
|
+
<YStack
|
|
272
|
+
fullscreen
|
|
273
|
+
onPress={composeEventHandlers(props.onPress as any, context.onOpenToggle)}
|
|
274
|
+
/>
|
|
275
|
+
)}
|
|
276
|
+
{contents}
|
|
277
|
+
</Theme>
|
|
263
278
|
)
|
|
264
279
|
}
|
|
265
280
|
|
|
@@ -309,14 +324,22 @@ const PopoverContentImpl = React.forwardRef<
|
|
|
309
324
|
...contentProps
|
|
310
325
|
} = props
|
|
311
326
|
const context = usePopoverContext()
|
|
327
|
+
const { open, keepChildrenMounted } = context
|
|
312
328
|
const popperContext = usePopperContext()
|
|
313
329
|
const [isFullyHidden, setIsFullyHidden] = React.useState(!context.open)
|
|
330
|
+
const [hasShownOnce, setHasShownOnce] = React.useState(false)
|
|
331
|
+
|
|
332
|
+
React.useEffect(() => {
|
|
333
|
+
if (!open) {
|
|
334
|
+
setHasShownOnce(true)
|
|
335
|
+
}
|
|
336
|
+
}, [open])
|
|
314
337
|
|
|
315
|
-
if (
|
|
338
|
+
if (open && isFullyHidden) {
|
|
316
339
|
setIsFullyHidden(false)
|
|
317
340
|
}
|
|
318
341
|
|
|
319
|
-
if (!
|
|
342
|
+
if (!keepChildrenMounted) {
|
|
320
343
|
if (isFullyHidden) {
|
|
321
344
|
return null
|
|
322
345
|
}
|
|
@@ -327,7 +350,7 @@ const PopoverContentImpl = React.forwardRef<
|
|
|
327
350
|
// TODO this should be disabled through context
|
|
328
351
|
const childrenWithoutScrollView = React.Children.toArray(children).map((child) => {
|
|
329
352
|
if (React.isValidElement(child)) {
|
|
330
|
-
if (child.type ===
|
|
353
|
+
if (child.type === ScrollView) {
|
|
331
354
|
return child.props.children
|
|
332
355
|
}
|
|
333
356
|
}
|
|
@@ -360,25 +383,35 @@ const PopoverContentImpl = React.forwardRef<
|
|
|
360
383
|
// onDismiss={handleDismiss}
|
|
361
384
|
// >
|
|
362
385
|
|
|
386
|
+
const contents = React.useMemo(() => {
|
|
387
|
+
return isWeb ? <div style={{ display: 'contents' }}>{children}</div> : children
|
|
388
|
+
}, [children])
|
|
389
|
+
|
|
390
|
+
const freeze = isFullyHidden && (hasShownOnce || !keepChildrenMounted)
|
|
391
|
+
|
|
363
392
|
return (
|
|
364
393
|
<Animate
|
|
365
394
|
type="presence"
|
|
366
|
-
present={Boolean(
|
|
367
|
-
keepChildrenMounted={
|
|
395
|
+
present={Boolean(open)}
|
|
396
|
+
keepChildrenMounted={keepChildrenMounted}
|
|
368
397
|
onExitComplete={() => {
|
|
369
398
|
setIsFullyHidden(true)
|
|
370
399
|
}}
|
|
371
400
|
>
|
|
372
|
-
<
|
|
401
|
+
<FreezeToLastContents
|
|
402
|
+
// freeze if fully hidden but fallback to last contents
|
|
403
|
+
// if keepChildrenMounted then mount it on the first
|
|
404
|
+
freeze={freeze}
|
|
405
|
+
>
|
|
373
406
|
<PopperContent
|
|
374
407
|
key={context.contentId}
|
|
375
|
-
data-state={getState(
|
|
408
|
+
data-state={getState(open)}
|
|
376
409
|
id={context.contentId}
|
|
377
410
|
ref={forwardedRef}
|
|
378
411
|
{...contentProps}
|
|
379
412
|
>
|
|
380
413
|
<RemoveScroll
|
|
381
|
-
enabled={disableRemoveScroll ? false :
|
|
414
|
+
enabled={disableRemoveScroll ? false : open}
|
|
382
415
|
allowPinchZoom
|
|
383
416
|
// causes lots of bugs on touch web on site
|
|
384
417
|
removeScrollBar={false}
|
|
@@ -386,25 +419,31 @@ const PopoverContentImpl = React.forwardRef<
|
|
|
386
419
|
display: 'contents',
|
|
387
420
|
}}
|
|
388
421
|
>
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
>
|
|
398
|
-
{isWeb ? <div style={{ display: 'contents' }}>{children}</div> : children}
|
|
399
|
-
</FocusScope>
|
|
400
|
-
)}
|
|
422
|
+
<FocusScope
|
|
423
|
+
loop
|
|
424
|
+
trapped={trapFocus ?? open}
|
|
425
|
+
onMountAutoFocus={onOpenAutoFocus}
|
|
426
|
+
onUnmountAutoFocus={onCloseAutoFocus}
|
|
427
|
+
>
|
|
428
|
+
{contents}
|
|
429
|
+
</FocusScope>
|
|
401
430
|
</RemoveScroll>
|
|
402
431
|
</PopperContent>
|
|
403
|
-
</
|
|
432
|
+
</FreezeToLastContents>
|
|
404
433
|
</Animate>
|
|
405
434
|
)
|
|
406
435
|
})
|
|
407
436
|
|
|
437
|
+
const FreezeToLastContents = (props: { freeze: boolean; children: any }) => {
|
|
438
|
+
const last = React.useRef()
|
|
439
|
+
|
|
440
|
+
if (!props.freeze) {
|
|
441
|
+
last.current = props.children
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
return <Freeze placeholder={last.current} {...props} />
|
|
445
|
+
}
|
|
446
|
+
|
|
408
447
|
/* -------------------------------------------------------------------------------------------------
|
|
409
448
|
* PopoverClose
|
|
410
449
|
* -----------------------------------------------------------------------------------------------*/
|
|
@@ -439,14 +478,6 @@ export const PopoverArrow = React.forwardRef<TamaguiElement, PopoverArrowProps>(
|
|
|
439
478
|
}
|
|
440
479
|
)
|
|
441
480
|
|
|
442
|
-
/* -------------------------------------------------------------------------------------------------
|
|
443
|
-
* PopoverScrollView
|
|
444
|
-
* -----------------------------------------------------------------------------------------------*/
|
|
445
|
-
|
|
446
|
-
const PopoverScrollView = React.forwardRef<ScrollView, ScrollViewProps>((props, ref) => {
|
|
447
|
-
return <ScrollView ref={ref} {...props} />
|
|
448
|
-
})
|
|
449
|
-
|
|
450
481
|
/* -------------------------------------------------------------------------------------------------
|
|
451
482
|
* Popover
|
|
452
483
|
* -----------------------------------------------------------------------------------------------*/
|
|
@@ -539,7 +570,7 @@ export const Popover = withStaticProperties(
|
|
|
539
570
|
Content: PopoverContent,
|
|
540
571
|
Close: PopoverClose,
|
|
541
572
|
Adapt,
|
|
542
|
-
ScrollView:
|
|
573
|
+
ScrollView: ScrollView,
|
|
543
574
|
Sheet: Sheet.Controlled,
|
|
544
575
|
}
|
|
545
576
|
)
|
package/types/Popover.d.ts
CHANGED
|
@@ -206,7 +206,7 @@ export declare const Popover: React.FC<PopoverProps> & {
|
|
|
206
206
|
shouldForwardSpace: boolean;
|
|
207
207
|
};
|
|
208
208
|
};
|
|
209
|
-
ScrollView:
|
|
209
|
+
ScrollView: typeof ScrollView;
|
|
210
210
|
Sheet: React.FunctionComponent<Omit<import("@tamagui/sheet").SheetProps, "open" | "onOpenChange"> & React.RefAttributes<import("react-native").View>> & {
|
|
211
211
|
Frame: React.ForwardRefExoticComponent<Omit<import("react-native").ViewProps, "display" | "children" | "onLayout" | keyof import("react-native").GestureResponderHandlers | "style"> & import("@tamagui/core").ExtendBaseStackProps & import("@tamagui/core").TamaguiComponentPropsBase & {
|
|
212
212
|
style?: import("@tamagui/core").StyleProp<React.CSSProperties | import("react-native").ViewStyle | (React.CSSProperties & import("react-native").ViewStyle)>;
|
package/types/Popover.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../src/Popover.tsx"],"names":[],"mappings":"AAAA,OAAO,uBAAuB,CAAA;AAM9B,OAAO,EAEL,UAAU,EAEV,UAAU,EACV,cAAc,EAYf,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAA;AAEvD,OAAO,EAAc,eAAe,EAAE,MAAM,sBAAsB,CAAA;AAClE,OAAO,EAIL,gBAAgB,EAGhB,kBAAkB,EAElB,WAAW,EAEZ,MAAM,iBAAiB,CAAA;AAExB,OAAO,EAAgB,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAExE,OAAO,EAAU,WAAW,EAAE,MAAM,iBAAiB,CAAA;AAErD,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,EAAY,UAAU,EAAE,eAAe,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"Popover.d.ts","sourceRoot":"","sources":["../src/Popover.tsx"],"names":[],"mappings":"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"}
|