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