@tamagui/popover 2.0.0-rc.8 → 2.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (49) hide show
  1. package/dist/cjs/Popover.cjs +624 -408
  2. package/dist/cjs/Popover.native.js +637 -438
  3. package/dist/cjs/Popover.native.js.map +1 -1
  4. package/dist/cjs/index.cjs +7 -5
  5. package/dist/cjs/index.native.js +7 -5
  6. package/dist/cjs/index.native.js.map +1 -1
  7. package/dist/cjs/useFloatingContext.cjs +226 -58
  8. package/dist/cjs/useFloatingContext.native.js +28 -26
  9. package/dist/cjs/useFloatingContext.native.js.map +1 -1
  10. package/dist/esm/Popover.mjs +576 -377
  11. package/dist/esm/Popover.mjs.map +1 -1
  12. package/dist/esm/Popover.native.js +591 -409
  13. package/dist/esm/Popover.native.js.map +1 -1
  14. package/dist/esm/index.js +2 -2
  15. package/dist/esm/index.js.map +1 -6
  16. package/dist/esm/useFloatingContext.mjs +200 -34
  17. package/dist/esm/useFloatingContext.mjs.map +1 -1
  18. package/dist/jsx/Popover.mjs +576 -377
  19. package/dist/jsx/Popover.mjs.map +1 -1
  20. package/dist/jsx/Popover.native.js +637 -438
  21. package/dist/jsx/Popover.native.js.map +1 -1
  22. package/dist/jsx/index.js +2 -2
  23. package/dist/jsx/index.js.map +1 -6
  24. package/dist/jsx/index.native.js +7 -5
  25. package/dist/jsx/useFloatingContext.mjs +200 -34
  26. package/dist/jsx/useFloatingContext.mjs.map +1 -1
  27. package/dist/jsx/useFloatingContext.native.js +28 -26
  28. package/dist/jsx/useFloatingContext.native.js.map +1 -1
  29. package/package.json +26 -31
  30. package/src/Popover.tsx +494 -175
  31. package/src/useFloatingContext.tsx +321 -43
  32. package/types/Popover.d.ts +126 -8
  33. package/types/Popover.d.ts.map +1 -1
  34. package/types/useFloatingContext.d.ts +14 -8
  35. package/types/useFloatingContext.d.ts.map +1 -1
  36. package/dist/cjs/Popover.js +0 -394
  37. package/dist/cjs/Popover.js.map +0 -6
  38. package/dist/cjs/index.js +0 -16
  39. package/dist/cjs/index.js.map +0 -6
  40. package/dist/cjs/useFloatingContext.js +0 -74
  41. package/dist/cjs/useFloatingContext.js.map +0 -6
  42. package/dist/esm/Popover.js +0 -415
  43. package/dist/esm/Popover.js.map +0 -6
  44. package/dist/esm/useFloatingContext.js +0 -59
  45. package/dist/esm/useFloatingContext.js.map +0 -6
  46. package/dist/jsx/Popover.js +0 -415
  47. package/dist/jsx/Popover.js.map +0 -6
  48. package/dist/jsx/useFloatingContext.js +0 -59
  49. package/dist/jsx/useFloatingContext.js.map +0 -6
@@ -1,155 +1,317 @@
1
- import "@tamagui/polyfill-dev";
2
1
  import { Adapt, AdaptParent, AdaptPortalContents, ProvideAdaptContext, useAdaptContext, useAdaptIsActive } from "@tamagui/adapt";
3
2
  import { Animate } from "@tamagui/animate";
4
3
  import { ResetPresence } from "@tamagui/animate-presence";
5
4
  import { useComposedRefs } from "@tamagui/compose-refs";
6
- import { isWeb } from "@tamagui/constants";
7
- import { createStyledContext, styled, Theme, useCreateShallowSetState, useEvent, useGet, useThemeName, View } from "@tamagui/core";
5
+ import { isWeb, useIsomorphicLayoutEffect } from "@tamagui/constants";
6
+ import { createStyledContext, useCreateShallowSetState, useEvent, useGet, View } from "@tamagui/core";
7
+ import { Dismissable, DismissableBranch } from "@tamagui/dismissable";
8
8
  import { FloatingOverrideContext } from "@tamagui/floating";
9
9
  import { FocusScope, FocusScopeController } from "@tamagui/focus-scope";
10
10
  import { composeEventHandlers, withStaticProperties } from "@tamagui/helpers";
11
11
  import { Popper, PopperAnchor, PopperArrow, PopperArrowFrame, PopperContent, PopperContentFrame, PopperProvider, usePopperContext } from "@tamagui/popper";
12
- import { needsPortalRepropagation, Portal, resolveViewZIndex } from "@tamagui/portal";
12
+ import { needsPortalRepropagation, Portal } from "@tamagui/portal";
13
13
  import { RemoveScroll } from "@tamagui/remove-scroll";
14
14
  import { ScrollView } from "@tamagui/scroll-view";
15
15
  import { SheetController } from "@tamagui/sheet/controller";
16
16
  import { YStack } from "@tamagui/stacks";
17
17
  import { useControllableState } from "@tamagui/use-controllable-state";
18
- import { StackZIndexContext } from "@tamagui/z-index-stack";
19
18
  import * as React from "react";
20
19
  import { useFloatingContext } from "./useFloatingContext.mjs";
21
20
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
22
- const needsRepropagation = needsPortalRepropagation(),
23
- PopoverContext = createStyledContext(
24
- // since we always provide this we can avoid setting here
25
- {}, "Popover__"),
26
- usePopoverContext = PopoverContext.useStyledContext,
27
- PopoverAnchor = React.forwardRef(function (props, forwardedRef) {
28
- const {
29
- scope,
30
- ...rest
31
- } = props,
32
- context = usePopoverContext(scope),
33
- {
34
- onCustomAnchorAdd,
35
- onCustomAnchorRemove
36
- } = context || {};
37
- return React.useEffect(() => (onCustomAnchorAdd(), () => onCustomAnchorRemove()), [onCustomAnchorAdd, onCustomAnchorRemove]), /* @__PURE__ */jsx(PopperAnchor, {
38
- scope,
39
- ...rest,
40
- ref: forwardedRef
41
- });
42
- }),
43
- PopoverTrigger = React.forwardRef(function (props, forwardedRef) {
44
- const {
45
- scope,
46
- ...rest
47
- } = props,
48
- context = usePopoverContext(scope),
49
- anchorTo = context.anchorTo,
50
- composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);
51
- if (!props.children) return null;
52
- const trigger = /* @__PURE__ */jsx(View, {
53
- "aria-expanded": context.open,
54
- "data-state": getState(context.open),
55
- ...rest,
56
- ref: composedTriggerRef,
57
- onPress: composeEventHandlers(props.onPress, context.onOpenToggle)
58
- }),
59
- virtualRef = React.useMemo(() => anchorTo ? {
60
- current: {
61
- getBoundingClientRect: () => isWeb ? DOMRect.fromRect(anchorTo) : anchorTo,
62
- ...(!isWeb && {
63
- measure: c => c(anchorTo?.x, anchorTo?.y, anchorTo?.width, anchorTo?.height),
64
- measureInWindow: c => c(anchorTo?.x, anchorTo?.y, anchorTo?.width, anchorTo?.height)
65
- })
66
- }
67
- } : null, [context.anchorTo, anchorTo?.x, anchorTo?.y, anchorTo?.height, anchorTo?.width]);
68
- return context.hasCustomAnchor ? trigger : /* @__PURE__ */jsx(PopperAnchor, {
69
- ...(virtualRef && {
70
- virtualRef
71
- }),
21
+ const needsRepropagation = needsPortalRepropagation();
22
+ const openPopovers = /* @__PURE__ */new Set();
23
+ const hasOpenPopovers = () => {
24
+ return openPopovers.size > 0;
25
+ };
26
+ const closeOpenPopovers = () => {
27
+ if (openPopovers.size === 0) return false;
28
+ openPopovers.forEach(setOpen => setOpen(false));
29
+ return true;
30
+ };
31
+ const closeLastOpenedPopover = () => {
32
+ if (openPopovers.size === 0) return false;
33
+ const last = Array.from(openPopovers).pop();
34
+ if (last) {
35
+ last(false);
36
+ return true;
37
+ }
38
+ return false;
39
+ };
40
+ const PopoverContext = createStyledContext(
41
+ // since we always provide this we can avoid setting here
42
+ {}, "Popover__");
43
+ const PopoverZIndexContext = React.createContext(void 0);
44
+ const PopoverTriggerContext = createStyledContext({}, "PopoverTrigger__");
45
+ const usePopoverContext = PopoverContext.useStyledContext;
46
+ const usePopoverTriggerContext = PopoverTriggerContext.useStyledContext;
47
+ function usePopoverOpen(scope) {
48
+ return usePopoverContext(scope).open;
49
+ }
50
+ function usePopoverTriggerSetup(open) {
51
+ const triggerStateSettersRef = React.useRef(/* @__PURE__ */new Map());
52
+ const activeTriggerIdRef = React.useRef(null);
53
+ const setActiveTrigger = useEvent(id => {
54
+ const prevId = activeTriggerIdRef.current;
55
+ if (prevId === id) return;
56
+ if (prevId) triggerStateSettersRef.current.get(prevId)?.(false);
57
+ activeTriggerIdRef.current = id;
58
+ if (id && open) triggerStateSettersRef.current.get(id)?.(true);
59
+ });
60
+ const registerTrigger = useEvent((id, setOpenState) => {
61
+ triggerStateSettersRef.current.set(id, setOpenState);
62
+ setOpenState(activeTriggerIdRef.current === id && open);
63
+ });
64
+ const unregisterTrigger = useEvent(id => {
65
+ triggerStateSettersRef.current.delete(id);
66
+ if (activeTriggerIdRef.current === id) activeTriggerIdRef.current = null;
67
+ });
68
+ React.useEffect(() => {
69
+ if (!open) {
70
+ setActiveTrigger(null);
71
+ return;
72
+ }
73
+ const activeId = activeTriggerIdRef.current;
74
+ if (activeId) triggerStateSettersRef.current.get(activeId)?.(true);
75
+ }, [open, setActiveTrigger]);
76
+ return {
77
+ setActiveTrigger,
78
+ registerTrigger,
79
+ unregisterTrigger
80
+ };
81
+ }
82
+ const PopoverContextProvider = React.memo(({
83
+ scope,
84
+ children,
85
+ open,
86
+ onOpenChange,
87
+ onOpenToggle,
88
+ triggerRef,
89
+ id = "",
90
+ contentId,
91
+ hasCustomAnchor = false,
92
+ onCustomAnchorAdd = voidFn,
93
+ onCustomAnchorRemove = voidFn,
94
+ anchorTo,
95
+ adaptScope,
96
+ breakpointActive,
97
+ keepChildrenMounted,
98
+ disableDismissable,
99
+ hoverable
100
+ }) => {
101
+ const [branches] = React.useState(() => /* @__PURE__ */new Set());
102
+ const {
103
+ setActiveTrigger,
104
+ registerTrigger,
105
+ unregisterTrigger
106
+ } = usePopoverTriggerSetup(open);
107
+ return /* @__PURE__ */jsx(PopoverContext.Provider, {
108
+ scope,
109
+ popoverScope: scope,
110
+ adaptScope,
111
+ id,
112
+ contentId,
113
+ triggerRef,
114
+ open,
115
+ onOpenChange,
116
+ onOpenToggle,
117
+ hasCustomAnchor,
118
+ onCustomAnchorAdd,
119
+ onCustomAnchorRemove,
120
+ anchorTo,
121
+ branches,
122
+ breakpointActive,
123
+ keepChildrenMounted,
124
+ disableDismissable,
125
+ hoverable,
126
+ children: /* @__PURE__ */jsx(PopoverTriggerContext.Provider, {
72
127
  scope,
73
- asChild: !0,
74
- children: trigger
75
- });
76
- }),
77
- PopoverContentFrame = styled(PopperContentFrame, {
78
- name: "Popover"
79
- }),
80
- PopoverContent = PopoverContentFrame.styleable(function (props, forwardedRef) {
81
- const {
82
- trapFocus,
83
- enableRemoveScroll = !1,
84
- zIndex,
85
- scope,
86
- ...contentImplProps
87
- } = props,
88
- context = usePopoverContext(scope),
89
- contentRef = React.useRef(null),
90
- composedRefs = useComposedRefs(forwardedRef, contentRef),
91
- isRightClickOutsideRef = React.useRef(!1),
92
- [isFullyHidden, setIsFullyHidden] = React.useState(!context.open);
93
- return React.useEffect(() => {
94
- context.open && isFullyHidden && setIsFullyHidden(!1);
95
- }, [context.open, isFullyHidden]), !context.keepChildrenMounted && isFullyHidden && !context.open ? null : /* @__PURE__ */jsx(PopoverPortal, {
128
+ triggerRef,
129
+ hasCustomAnchor,
130
+ anchorTo,
131
+ branches,
132
+ onOpenToggle,
133
+ setActiveTrigger,
134
+ registerTrigger,
135
+ unregisterTrigger,
136
+ children
137
+ })
138
+ });
139
+ });
140
+ const voidFn = () => {};
141
+ const PopoverAnchor = React.memo(React.forwardRef(function PopoverAnchor2(props, forwardedRef) {
142
+ const {
143
+ scope,
144
+ ...rest
145
+ } = props;
146
+ const {
147
+ onCustomAnchorAdd,
148
+ onCustomAnchorRemove
149
+ } = usePopoverContext(scope) || {};
150
+ React.useEffect(() => {
151
+ onCustomAnchorAdd();
152
+ return () => onCustomAnchorRemove();
153
+ }, [onCustomAnchorAdd, onCustomAnchorRemove]);
154
+ return /* @__PURE__ */jsx(PopperAnchor, {
155
+ scope,
156
+ ...rest,
157
+ ref: forwardedRef
158
+ });
159
+ }));
160
+ const PopoverTrigger = React.memo(React.forwardRef(function PopoverTrigger2(props, forwardedRef) {
161
+ const {
162
+ scope,
163
+ disablePressTrigger,
164
+ ...rest
165
+ } = props;
166
+ const triggerContext = usePopoverTriggerContext(scope);
167
+ const triggerId = React.useId();
168
+ const [open, setOpen] = React.useState(false);
169
+ const anchorTo = triggerContext.anchorTo;
170
+ const triggerElRef = React.useRef(null);
171
+ const composedTriggerRef = useComposedRefs(forwardedRef, triggerElRef);
172
+ const {
173
+ registerTrigger,
174
+ unregisterTrigger
175
+ } = triggerContext;
176
+ React.useEffect(() => {
177
+ registerTrigger(triggerId, setOpen);
178
+ return () => {
179
+ unregisterTrigger(triggerId);
180
+ };
181
+ }, [registerTrigger, unregisterTrigger, triggerId]);
182
+ if (!rest.children) return null;
183
+ const activateSelf = () => {
184
+ triggerContext.setActiveTrigger(triggerId);
185
+ const el = triggerElRef.current;
186
+ if (el) triggerContext.triggerRef.current = el;
187
+ };
188
+ const trigger = /* @__PURE__ */jsx(View, {
189
+ "aria-expanded": open,
190
+ "data-state": getState(open),
191
+ ...rest,
192
+ ref: composedTriggerRef,
193
+ onPress: composeEventHandlers(rest.onPress, () => {
194
+ if (disablePressTrigger) return;
195
+ triggerContext.setActiveTrigger(open ? null : triggerId);
196
+ triggerContext.onOpenToggle();
197
+ }),
198
+ onMouseEnter: composeEventHandlers(rest.onMouseEnter, activateSelf),
199
+ onPressIn: composeEventHandlers(rest.onPressIn, activateSelf),
200
+ onFocus: composeEventHandlers(rest.onFocus, activateSelf)
201
+ });
202
+ const virtualRef = React.useMemo(() => {
203
+ if (!anchorTo) return null;
204
+ return {
205
+ current: {
206
+ getBoundingClientRect: () => isWeb ? DOMRect.fromRect(anchorTo) : anchorTo,
207
+ ...(!isWeb && {
208
+ measure: c => c(anchorTo?.x, anchorTo?.y, anchorTo?.width, anchorTo?.height),
209
+ measureInWindow: c => c(anchorTo?.x, anchorTo?.y, anchorTo?.width, anchorTo?.height)
210
+ })
211
+ }
212
+ };
213
+ }, [triggerContext.anchorTo, anchorTo?.x, anchorTo?.y, anchorTo?.height, anchorTo?.width]);
214
+ const wrappedTrigger = isWeb ? /* @__PURE__ */jsx(DismissableBranch, {
215
+ branches: triggerContext.branches,
216
+ children: trigger
217
+ }) : trigger;
218
+ return triggerContext.hasCustomAnchor ? wrappedTrigger : /* @__PURE__ */jsx(PopperAnchor, {
219
+ ...(virtualRef && {
220
+ virtualRef
221
+ }),
222
+ scope,
223
+ asChild: true,
224
+ children: wrappedTrigger
225
+ });
226
+ }));
227
+ const PopoverContent = PopperContentFrame.styleable(function PopoverContent2(props, forwardedRef) {
228
+ const {
229
+ trapFocus,
230
+ enableRemoveScroll = false,
231
+ zIndex: zIndexProp,
232
+ scope,
233
+ ...contentImplProps
234
+ } = props;
235
+ const context = usePopoverContext(scope);
236
+ const zIndexFromContext = React.useContext(PopoverZIndexContext);
237
+ const zIndex = zIndexProp ?? zIndexFromContext;
238
+ const open = usePopoverOpen(scope);
239
+ const composedRefs = useComposedRefs(forwardedRef, React.useRef(null));
240
+ const isRightClickOutsideRef = React.useRef(false);
241
+ const [isFullyHidden, setIsFullyHidden] = React.useState(!open);
242
+ useIsomorphicLayoutEffect(() => {
243
+ if (open && isFullyHidden) setIsFullyHidden(false);
244
+ }, [open, isFullyHidden]);
245
+ if (!context.keepChildrenMounted) {
246
+ if (isFullyHidden && !open) return null;
247
+ }
248
+ return /* @__PURE__ */jsx(PopoverPortal, {
249
+ passThrough: context.breakpointActive,
250
+ context,
251
+ open,
252
+ zIndex,
253
+ children: /* @__PURE__ */jsx(View, {
96
254
  passThrough: context.breakpointActive,
97
- context,
98
- zIndex,
99
- children: /* @__PURE__ */jsx(View, {
100
- passThrough: context.breakpointActive,
101
- pointerEvents: context.open ? contentImplProps.pointerEvents ?? "auto" : "none",
102
- children: /* @__PURE__ */jsx(PopoverContentImpl, {
103
- ...contentImplProps,
104
- context,
105
- enableRemoveScroll,
106
- ref: composedRefs,
107
- setIsFullyHidden,
108
- scope,
109
- trapFocus: trapFocus ?? context.open,
110
- disableOutsidePointerEvents: !0,
111
- onCloseAutoFocus: props.onCloseAutoFocus === !1 ? void 0 : composeEventHandlers(props.onCloseAutoFocus, event => {
112
- event.defaultPrevented || (event.preventDefault(), isRightClickOutsideRef.current || context.triggerRef.current?.focus());
113
- }),
114
- onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, event => {
115
- const originalEvent = event.detail.originalEvent,
116
- ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === !0,
117
- isRightClick = originalEvent.button === 2 || ctrlLeftClick;
118
- isRightClickOutsideRef.current = isRightClick;
119
- }, {
120
- checkDefaultPrevented: !1
121
- }),
122
- onFocusOutside: composeEventHandlers(props.onFocusOutside, event => event.preventDefault(), {
123
- checkDefaultPrevented: !1
124
- })
255
+ pointerEvents: open ? contentImplProps.pointerEvents ?? "auto" : "none",
256
+ children: /* @__PURE__ */jsx(PopoverContentImpl, {
257
+ ...contentImplProps,
258
+ context,
259
+ open,
260
+ enableRemoveScroll,
261
+ ref: composedRefs,
262
+ setIsFullyHidden,
263
+ scope,
264
+ trapFocus: trapFocus ?? open,
265
+ disableOutsidePointerEvents: true,
266
+ onCloseAutoFocus: props.onCloseAutoFocus === false ? void 0 : composeEventHandlers(props.onCloseAutoFocus, event => {
267
+ if (event.defaultPrevented) return;
268
+ event.preventDefault();
269
+ if (!isRightClickOutsideRef.current) context.triggerRef.current?.focus();
270
+ }),
271
+ onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, event => {
272
+ const originalEvent = event.detail.originalEvent;
273
+ const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;
274
+ isRightClickOutsideRef.current = originalEvent.button === 2 || ctrlLeftClick;
275
+ }, {
276
+ checkDefaultPrevented: false
277
+ }),
278
+ onFocusOutside: composeEventHandlers(props.onFocusOutside, event => event.preventDefault(), {
279
+ checkDefaultPrevented: false
125
280
  })
126
281
  })
127
- });
128
- }),
129
- useParentContexts = scope => {
130
- const context = usePopoverContext(scope),
131
- popperContext = usePopperContext(scope),
132
- adaptContext = useAdaptContext(context.adaptScope);
133
- return {
134
- popperContext,
135
- adaptContext,
136
- context
137
- };
282
+ })
283
+ });
284
+ });
285
+ const useParentContexts = scope => {
286
+ const context = usePopoverContext(scope);
287
+ const triggerContext = usePopoverTriggerContext(scope);
288
+ return {
289
+ popperContext: usePopperContext(scope),
290
+ adaptContext: useAdaptContext(context.adaptScope),
291
+ context,
292
+ triggerContext
138
293
  };
294
+ };
139
295
  function RepropagateParentContexts({
140
296
  adaptContext,
141
297
  children,
142
298
  context,
299
+ triggerContext,
143
300
  popperContext
144
301
  }) {
145
302
  return /* @__PURE__ */jsx(PopperProvider, {
146
303
  scope: context.popoverScope,
147
304
  ...popperContext,
148
305
  children: /* @__PURE__ */jsx(PopoverContext.Provider, {
306
+ scope: context.popoverScope,
149
307
  ...context,
150
- children: /* @__PURE__ */jsx(ProvideAdaptContext, {
151
- ...adaptContext,
152
- children
308
+ children: /* @__PURE__ */jsx(PopoverTriggerContext.Provider, {
309
+ scope: context.popoverScope,
310
+ ...triggerContext,
311
+ children: /* @__PURE__ */jsx(ProvideAdaptContext, {
312
+ ...adaptContext,
313
+ children
314
+ })
153
315
  })
154
316
  })
155
317
  });
@@ -158,6 +320,8 @@ const PortalAdaptSafe = ({
158
320
  children,
159
321
  context
160
322
  }) => {
323
+ "use no memo";
324
+
161
325
  if (needsRepropagation) {
162
326
  const parentContexts = useParentContexts(context.popoverScope);
163
327
  return /* @__PURE__ */jsx(AdaptPortalContents, {
@@ -175,287 +339,322 @@ const PortalAdaptSafe = ({
175
339
  };
176
340
  function PopoverPortal({
177
341
  context,
342
+ open,
178
343
  zIndex,
179
344
  passThrough,
180
345
  children,
181
346
  onPress
182
347
  }) {
183
- const themeName = useThemeName();
348
+ "use no memo";
349
+
184
350
  let content = children;
185
- if (needsRepropagation) {
186
- const parentContexts = useParentContexts(context.popoverScope);
187
- content = /* @__PURE__ */jsx(RepropagateParentContexts, {
188
- ...parentContexts,
189
- children: content
190
- });
191
- }
192
- return /* @__PURE__ */jsx(Portal, {
351
+ if (needsRepropagation) content = /* @__PURE__ */jsx(RepropagateParentContexts, {
352
+ ...useParentContexts(context.popoverScope),
353
+ children: content
354
+ });
355
+ return /* @__PURE__ */jsxs(Portal, {
193
356
  passThrough,
194
- stackZIndex: !0,
357
+ stackZIndex: true,
195
358
  zIndex,
196
- children: /* @__PURE__ */jsxs(Theme, {
197
- passThrough,
198
- contain: !0,
199
- forceClassName: !0,
200
- name: themeName,
201
- children: [!!context.open && !context.breakpointActive && /* @__PURE__ */jsx(YStack, {
202
- fullscreen: !0,
203
- onPress: composeEventHandlers(onPress, context.onOpenToggle)
204
- }), /* @__PURE__ */jsx(StackZIndexContext, {
205
- zIndex: resolveViewZIndex(zIndex),
206
- children: content
207
- })]
208
- })
359
+ children: [!!open && !context.breakpointActive && !context.hoverable && /* @__PURE__ */jsx(YStack, {
360
+ fullscreen: true,
361
+ onPress: composeEventHandlers(onPress, context.onOpenToggle)
362
+ }), content]
209
363
  });
210
364
  }
211
- const PopoverContentImpl = React.forwardRef(function (props, forwardedRef) {
212
- const {
213
- trapFocus,
214
- scope,
215
- onOpenAutoFocus,
216
- onCloseAutoFocus,
217
- disableOutsidePointerEvents,
218
- disableFocusScope,
219
- onEscapeKeyDown,
220
- onPointerDownOutside,
221
- onFocusOutside,
222
- onInteractOutside,
223
- children,
224
- enableRemoveScroll,
225
- freezeContentsWhenHidden,
226
- setIsFullyHidden,
227
- lazyMount,
228
- context,
229
- ...contentProps
230
- } = props,
231
- {
232
- open,
233
- keepChildrenMounted
234
- } = context,
235
- handleExitComplete = React.useCallback(() => {
236
- setIsFullyHidden?.(!0);
237
- }, [setIsFullyHidden]);
238
- let contents = /* @__PURE__ */jsx(ResetPresence, {
239
- disable: context.breakpointActive,
240
- children
241
- });
242
- return context.breakpointActive || (contents = /* @__PURE__ */jsx(RemoveScroll, {
243
- enabled: context.breakpointActive ? !1 : enableRemoveScroll ? open : !1,
244
- children: /* @__PURE__ */jsx(FocusScope, {
245
- loop: trapFocus !== !1,
246
- enabled: context.breakpointActive || disableFocusScope ? !1 : open,
247
- trapped: context.breakpointActive ? !1 : trapFocus,
248
- onMountAutoFocus: onOpenAutoFocus,
249
- onUnmountAutoFocus: onCloseAutoFocus === !1 ? void 0 : onCloseAutoFocus,
250
- children: /* @__PURE__ */jsx("div", {
251
- style: dspContentsStyle,
252
- children: contents
253
- })
365
+ const PopoverContentImpl = React.forwardRef(function PopoverContentImpl2(props, forwardedRef) {
366
+ const {
367
+ trapFocus,
368
+ scope,
369
+ onOpenAutoFocus,
370
+ onCloseAutoFocus,
371
+ disableOutsidePointerEvents,
372
+ disableFocusScope,
373
+ onEscapeKeyDown,
374
+ onPointerDownOutside,
375
+ onFocusOutside,
376
+ onInteractOutside,
377
+ children,
378
+ enableRemoveScroll,
379
+ freezeContentsWhenHidden,
380
+ setIsFullyHidden,
381
+ lazyMount,
382
+ forceUnmount,
383
+ context,
384
+ open,
385
+ alwaysDisable,
386
+ ...contentProps
387
+ } = props;
388
+ const {
389
+ keepChildrenMounted,
390
+ disableDismissable
391
+ } = context;
392
+ const handleExitComplete = React.useCallback(() => {
393
+ setIsFullyHidden?.(true);
394
+ }, [setIsFullyHidden]);
395
+ let contents = /* @__PURE__ */jsx(ResetPresence, {
396
+ disable: context.breakpointActive,
397
+ children
398
+ });
399
+ const handleDismiss = React.useCallback(() => {
400
+ context.onOpenChange(false, "press");
401
+ }, [context]);
402
+ if (!context.breakpointActive) {
403
+ if (!alwaysDisable || !alwaysDisable.focus) contents = /* @__PURE__ */jsx(FocusScope, {
404
+ loop: trapFocus !== false,
405
+ enabled: context.breakpointActive ? false : disableFocusScope ? false : open,
406
+ trapped: context.breakpointActive ? false : trapFocus,
407
+ onMountAutoFocus: onOpenAutoFocus,
408
+ onUnmountAutoFocus: onCloseAutoFocus === false ? void 0 : onCloseAutoFocus,
409
+ children: /* @__PURE__ */jsx("div", {
410
+ style: dspContentsStyle,
411
+ children: contents
254
412
  })
255
- })), /* @__PURE__ */jsx(Animate, {
256
- type: "presence",
257
- present: !!open,
258
- keepChildrenMounted: !!keepChildrenMounted,
259
- onExitComplete: handleExitComplete,
260
- lazyMount,
261
- passThrough: context.breakpointActive,
262
- children: /* @__PURE__ */jsx(PopperContent, {
263
- scope,
264
- "data-state": getState(open),
265
- id: context.contentId,
266
- ref: forwardedRef,
267
- passThrough: context.breakpointActive,
268
- ...contentProps,
269
- children: /* @__PURE__ */jsx(PortalAdaptSafe, {
270
- context,
271
- children: contents
272
- })
273
- }, context.contentId)
274
413
  });
275
- }),
276
- dspContentsStyle = {
277
- display: "contents"
278
- },
279
- PopoverClose = React.forwardRef(function (props, forwardedRef) {
280
- const {
281
- scope,
282
- ...rest
283
- } = props,
284
- context = usePopoverContext(scope);
285
- return /* @__PURE__ */jsx(YStack, {
286
- ...rest,
287
- ref: forwardedRef,
288
- componentName: "PopoverClose",
289
- onPress: composeEventHandlers(props.onPress, () => context?.onOpenChange?.(!1, "press"))
414
+ if (!alwaysDisable || !alwaysDisable["remove-scroll"]) contents = /* @__PURE__ */jsx(RemoveScroll, {
415
+ enabled: context.breakpointActive ? false : enableRemoveScroll ? open : false,
416
+ children: contents
290
417
  });
291
- }),
292
- PopoverArrow = PopperArrowFrame.styleable(function (props, forwardedRef) {
293
- const {
294
- scope,
295
- ...rest
296
- } = props,
297
- context = usePopoverContext(scope);
298
- return useAdaptIsActive(context.adaptScope) ? null : /* @__PURE__ */jsx(PopperArrow, {
299
- scope,
300
- componentName: "PopoverArrow",
301
- ...rest,
302
- ref: forwardedRef
418
+ if (!alwaysDisable || !alwaysDisable.dismiss) contents = /* @__PURE__ */jsx(Dismissable, {
419
+ branches: context.branches,
420
+ forceUnmount: disableDismissable || (forceUnmount ?? !open),
421
+ onEscapeKeyDown,
422
+ onPointerDownOutside,
423
+ onFocusOutside,
424
+ onInteractOutside,
425
+ onDismiss: handleDismiss,
426
+ children: contents
303
427
  });
304
- }),
305
- PopoverScrollView = React.forwardRef(({
428
+ }
429
+ return /* @__PURE__ */jsx(Animate, {
430
+ type: "presence",
431
+ present: Boolean(open),
432
+ keepChildrenMounted: Boolean(keepChildrenMounted),
433
+ onExitComplete: handleExitComplete,
434
+ lazyMount,
435
+ passThrough: context.breakpointActive,
436
+ children: /* @__PURE__ */jsx(PopperContent, {
437
+ scope,
438
+ "data-state": getState(open),
439
+ id: context.contentId,
440
+ ref: forwardedRef,
441
+ passThrough: context.breakpointActive,
442
+ ...(!contentProps.unstyled && {
443
+ size: "$true",
444
+ backgroundColor: "$background",
445
+ alignItems: "center"
446
+ }),
447
+ ...contentProps,
448
+ children: /* @__PURE__ */jsx(PortalAdaptSafe, {
449
+ context,
450
+ children: contents
451
+ })
452
+ }, context.contentId)
453
+ });
454
+ });
455
+ const dspContentsStyle = {
456
+ display: "contents"
457
+ };
458
+ const PopoverClose = React.forwardRef(function PopoverClose2(props, forwardedRef) {
459
+ const {
306
460
  scope,
461
+ ...rest
462
+ } = props;
463
+ const context = usePopoverContext(scope);
464
+ return /* @__PURE__ */jsx(YStack, {
465
+ ...rest,
466
+ ref: forwardedRef,
467
+ componentName: "PopoverClose",
468
+ onPress: composeEventHandlers(props.onPress, () => context?.onOpenChange?.(false, "press"))
469
+ });
470
+ });
471
+ const PopoverArrow = PopperArrowFrame.styleable(function PopoverArrow2(props, forwardedRef) {
472
+ const {
473
+ scope,
474
+ ...rest
475
+ } = props;
476
+ if (useAdaptIsActive(usePopoverContext(scope).adaptScope)) return null;
477
+ return /* @__PURE__ */jsx(PopperArrow, {
478
+ scope,
479
+ componentName: "PopoverArrow",
480
+ ...rest,
481
+ ref: forwardedRef
482
+ });
483
+ });
484
+ const PopoverScrollView = React.forwardRef(({
485
+ scope,
486
+ ...props
487
+ }, ref) => {
488
+ const context = usePopoverContext(scope);
489
+ return /* @__PURE__ */jsx(ScrollView, {
490
+ ref,
491
+ pointerEvents: context.breakpointActive ? "none" : void 0,
492
+ scrollEnabled: !context.breakpointActive,
493
+ passThrough: context.breakpointActive,
307
494
  ...props
308
- }, ref) => {
309
- const context = usePopoverContext(scope);
310
- return /* @__PURE__ */jsx(ScrollView, {
495
+ });
496
+ });
497
+ const DEFAULT_SCOPE = "";
498
+ const Popover = withStaticProperties(React.forwardRef(function Popover2({
499
+ scope = DEFAULT_SCOPE,
500
+ ...props
501
+ }, ref) {
502
+ const id = React.useId();
503
+ const adaptScope = `PopoverAdapt${scope}`;
504
+ return /* @__PURE__ */jsx(AdaptParent, {
505
+ scope: adaptScope,
506
+ portal: true,
507
+ children: /* @__PURE__ */jsx(PopoverInner, {
508
+ adaptScope,
311
509
  ref,
312
- pointerEvents: context.breakpointActive ? "none" : void 0,
313
- scrollEnabled: !context.breakpointActive,
314
- passThrough: context.breakpointActive,
510
+ id,
511
+ scope,
315
512
  ...props
316
- });
317
- }),
318
- DEFAULT_SCOPE = "",
319
- Popover = withStaticProperties(React.forwardRef(function ({
513
+ })
514
+ });
515
+ }), {
516
+ Anchor: PopoverAnchor,
517
+ Arrow: PopoverArrow,
518
+ Trigger: PopoverTrigger,
519
+ Content: PopoverContent,
520
+ Close: PopoverClose,
521
+ Adapt,
522
+ ScrollView: PopoverScrollView,
523
+ FocusScope: FocusScopeController
524
+ });
525
+ const PopoverInner = React.forwardRef(function PopoverInner2(props, forwardedRef) {
526
+ const {
527
+ children,
528
+ open: openProp,
529
+ defaultOpen,
530
+ onOpenChange,
320
531
  scope = DEFAULT_SCOPE,
321
- ...props
322
- }, ref) {
323
- const id = React.useId(),
324
- adaptScope = `PopoverAdapt${scope}`;
325
- return /* @__PURE__ */jsx(AdaptParent, {
326
- scope: adaptScope,
327
- portal: !0,
328
- children: /* @__PURE__ */jsx(PopoverInner, {
329
- adaptScope,
330
- ref,
331
- id,
332
- scope,
333
- ...props
334
- })
335
- });
336
- }), {
337
- Anchor: PopoverAnchor,
338
- Arrow: PopoverArrow,
339
- Trigger: PopoverTrigger,
340
- Content: PopoverContent,
341
- Close: PopoverClose,
342
- Adapt,
343
- ScrollView: PopoverScrollView,
344
- FocusScope: FocusScopeController
345
- }),
346
- PopoverInner = React.forwardRef(function (props, forwardedRef) {
347
- const {
348
- children,
349
- open: openProp,
350
- defaultOpen,
351
- onOpenChange,
352
- scope = DEFAULT_SCOPE,
353
- keepChildrenMounted: keepChildrenMountedProp,
354
- hoverable,
355
- disableFocus,
356
- id,
357
- adaptScope,
358
- ...restProps
359
- } = props,
360
- triggerRef = React.useRef(null),
361
- [hasCustomAnchor, setHasCustomAnchor] = React.useState(!1),
362
- viaRef = React.useRef(void 0),
363
- [keepChildrenMounted] = useControllableState({
364
- prop: keepChildrenMountedProp,
365
- defaultProp: !1,
366
- transition: keepChildrenMountedProp === "lazy"
367
- }),
368
- [open, setOpen] = useControllableState({
369
- prop: openProp,
370
- defaultProp: defaultOpen || !1,
371
- onChange: val => {
372
- onOpenChange?.(val, viaRef.current);
373
- }
374
- }),
375
- handleOpenChange = useEvent((val, via) => {
376
- viaRef.current = via, setOpen(val);
377
- }),
378
- isAdapted = useAdaptIsActive(adaptScope),
379
- floatingContext = useFloatingContext({
380
- open,
381
- setOpen: handleOpenChange,
382
- disable: isAdapted,
383
- hoverable,
384
- disableFocus
385
- }),
386
- [anchorTo, setAnchorToRaw] = React.useState(),
387
- setAnchorTo = useCreateShallowSetState(setAnchorToRaw);
388
- React.useImperativeHandle(forwardedRef, () => ({
389
- anchorTo: setAnchorTo,
390
- toggle: () => setOpen(prev => !prev),
391
- open: () => setOpen(!0),
392
- close: () => setOpen(!1),
393
- setOpen
394
- }));
395
- const popoverContext = {
396
- popoverScope: scope,
397
- adaptScope,
398
- id,
399
- contentId: React.useId(),
400
- triggerRef,
401
- open,
402
- breakpointActive: isAdapted,
403
- onOpenChange: handleOpenChange,
404
- onOpenToggle: useEvent(() => {
405
- open && isAdapted || setOpen(!open);
406
- }),
407
- hasCustomAnchor,
408
- anchorTo,
409
- onCustomAnchorAdd: React.useCallback(() => setHasCustomAnchor(!0), []),
410
- onCustomAnchorRemove: React.useCallback(() => setHasCustomAnchor(!1), []),
411
- keepChildrenMounted
412
- },
413
- memoizedChildren = React.useMemo(() => /* @__PURE__ */jsx(PopoverContext.Provider, {
414
- scope,
415
- ...popoverContext,
416
- children: /* @__PURE__ */jsx(PopoverSheetController, {
417
- context: popoverContext,
418
- onOpenChange: setOpen,
419
- children
420
- })
421
- }), [scope, setOpen, children, ...Object.values(popoverContext)]),
422
- contents = /* @__PURE__ */jsx(Popper, {
532
+ keepChildrenMounted: keepChildrenMountedProp,
533
+ hoverable,
534
+ disableFocus,
535
+ disableDismissable,
536
+ zIndex,
537
+ id,
538
+ adaptScope,
539
+ ...restProps
540
+ } = props;
541
+ const triggerRef = React.useRef(null);
542
+ const [hasCustomAnchor, setHasCustomAnchor] = React.useState(false);
543
+ const viaRef = React.useRef(void 0);
544
+ const [keepChildrenMounted] = useControllableState({
545
+ prop: keepChildrenMountedProp,
546
+ defaultProp: false,
547
+ transition: keepChildrenMountedProp === "lazy"
548
+ });
549
+ const [open, setOpen] = useControllableState({
550
+ prop: openProp,
551
+ defaultProp: defaultOpen || false,
552
+ onChange: val => {
553
+ onOpenChange?.(val, viaRef.current);
554
+ }
555
+ });
556
+ React.useEffect(() => {
557
+ if (!open) return;
558
+ openPopovers.add(setOpen);
559
+ return () => {
560
+ openPopovers.delete(setOpen);
561
+ };
562
+ }, [open, setOpen]);
563
+ const handleOpenChange = useEvent((val, via) => {
564
+ viaRef.current = via;
565
+ setOpen(val);
566
+ });
567
+ const isAdapted = useAdaptIsActive(adaptScope);
568
+ const floatingContext = useFloatingContext({
569
+ open,
570
+ setOpen: handleOpenChange,
571
+ disable: isAdapted,
572
+ hoverable,
573
+ disableFocus
574
+ });
575
+ const [anchorTo, setAnchorToRaw] = React.useState();
576
+ const setAnchorTo = useCreateShallowSetState(setAnchorToRaw);
577
+ React.useImperativeHandle(forwardedRef, () => ({
578
+ anchorTo: setAnchorTo,
579
+ toggle: () => setOpen(prev => !prev),
580
+ open: () => setOpen(true),
581
+ close: () => setOpen(false),
582
+ setOpen
583
+ }));
584
+ const contentId = React.useId();
585
+ const onOpenToggle = useEvent(() => {
586
+ if (open && isAdapted) return;
587
+ setOpen(!open);
588
+ });
589
+ const onCustomAnchorAdd = React.useCallback(() => setHasCustomAnchor(true), []);
590
+ const onCustomAnchorRemove = React.useCallback(() => setHasCustomAnchor(false), []);
591
+ const contents = /* @__PURE__ */jsx(Popper, {
592
+ open,
593
+ passThrough: isAdapted,
594
+ scope,
595
+ stayInFrame: true,
596
+ ...restProps,
597
+ children: /* @__PURE__ */jsx(PopoverContextProvider, {
598
+ scope,
599
+ open,
600
+ onOpenChange: handleOpenChange,
601
+ onOpenToggle,
602
+ triggerRef,
603
+ id,
604
+ contentId,
605
+ hasCustomAnchor,
606
+ onCustomAnchorAdd,
607
+ onCustomAnchorRemove,
608
+ anchorTo,
609
+ adaptScope,
610
+ breakpointActive: isAdapted,
611
+ keepChildrenMounted,
612
+ disableDismissable,
613
+ hoverable,
614
+ children: /* @__PURE__ */jsx(PopoverSheetController, {
615
+ onOpenChange: setOpen,
423
616
  open,
424
- passThrough: isAdapted,
425
617
  scope,
426
- stayInFrame: !0,
427
- ...restProps,
428
- children: memoizedChildren
429
- });
430
- return /* @__PURE__ */jsx(Fragment, {
431
- children: isWeb ? /* @__PURE__ */jsx(FloatingOverrideContext.Provider, {
432
- value: floatingContext,
433
- children: contents
434
- }) : contents
435
- });
618
+ children
619
+ })
620
+ })
621
+ });
622
+ let result = /* @__PURE__ */jsx(Fragment, {
623
+ children: isWeb ? /* @__PURE__ */jsx(FloatingOverrideContext.Provider, {
624
+ value: floatingContext,
625
+ children: contents
626
+ }) : contents
627
+ });
628
+ if (zIndex !== void 0) return /* @__PURE__ */jsx(PopoverZIndexContext.Provider, {
629
+ value: zIndex,
630
+ children: result
436
631
  });
632
+ return result;
633
+ });
437
634
  function getState(open) {
438
635
  return open ? "open" : "closed";
439
636
  }
440
637
  const PopoverSheetController = ({
441
- context,
442
- ...props
443
- }) => {
444
- const showSheet = useShowPopoverSheet(context),
445
- breakpointActive = context.breakpointActive,
446
- getShowSheet = useGet(showSheet);
447
- return /* @__PURE__ */jsx(SheetController, {
448
- onOpenChange: val => {
449
- getShowSheet() && props.onOpenChange?.(val);
450
- },
451
- open: context.open,
452
- hidden: !breakpointActive,
453
- children: props.children
454
- });
455
- },
456
- useShowPopoverSheet = context => {
457
- const isAdapted = useAdaptIsActive(context.adaptScope);
458
- return context.open === !1 ? !1 : isAdapted;
459
- };
460
- export { Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverContent, PopoverContext, PopoverTrigger, usePopoverContext };
638
+ open,
639
+ scope,
640
+ ...props
641
+ }) => {
642
+ const context = usePopoverContext(scope);
643
+ const showSheet = useShowPopoverSheet(context, open);
644
+ const breakpointActive = context?.breakpointActive;
645
+ const getShowSheet = useGet(showSheet);
646
+ return /* @__PURE__ */jsx(SheetController, {
647
+ onOpenChange: val => {
648
+ if (getShowSheet()) props.onOpenChange?.(val);
649
+ },
650
+ open,
651
+ hidden: !breakpointActive,
652
+ children: props.children
653
+ });
654
+ };
655
+ const useShowPopoverSheet = (context, open) => {
656
+ const isAdapted = useAdaptIsActive(context.adaptScope);
657
+ return open === false ? false : isAdapted;
658
+ };
659
+ export { Popover, PopoverAnchor, PopoverArrow, PopoverClose, PopoverContent, PopoverContext, PopoverContextProvider, PopoverTrigger, PopoverTriggerContext, PopoverZIndexContext, closeLastOpenedPopover, closeOpenPopovers, hasOpenPopovers, usePopoverContext, usePopoverOpen, usePopoverTriggerContext, usePopoverTriggerSetup };
461
660
  //# sourceMappingURL=Popover.mjs.map