@funstack/ui 0.1.0-alpha.7 → 0.1.0-alpha.8
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/internal/anchor-position.mjs +24 -1
- package/dist/internal/anchor-position.mjs.map +1 -1
- package/dist/internal/use-popover-popup.mjs +22 -4
- package/dist/internal/use-popover-popup.mjs.map +1 -1
- package/dist/menu/index.d.mts +5 -1
- package/dist/menu/index.d.mts.map +1 -1
- package/dist/menu/index.mjs +5 -1
- package/dist/menu/index.mjs.map +1 -1
- package/dist/menu/menu-context-trigger.d.mts +46 -0
- package/dist/menu/menu-context-trigger.d.mts.map +1 -0
- package/dist/menu/menu-context-trigger.mjs +226 -0
- package/dist/menu/menu-context-trigger.mjs.map +1 -0
- package/dist/menu/menu-context.mjs +34 -1
- package/dist/menu/menu-context.mjs.map +1 -1
- package/dist/menu/menu-dom.mjs +37 -1
- package/dist/menu/menu-dom.mjs.map +1 -1
- package/dist/menu/menu-popup.d.mts +18 -4
- package/dist/menu/menu-popup.d.mts.map +1 -1
- package/dist/menu/menu-popup.mjs +116 -17
- package/dist/menu/menu-popup.mjs.map +1 -1
- package/dist/menu/menu-root.d.mts +5 -0
- package/dist/menu/menu-root.d.mts.map +1 -1
- package/dist/menu/menu-root.mjs +48 -6
- package/dist/menu/menu-root.mjs.map +1 -1
- package/package.json +1 -1
package/dist/menu/menu-root.mjs
CHANGED
|
@@ -3,8 +3,8 @@ import { useDevWarning } from "../internal/use-dev-warning.mjs";
|
|
|
3
3
|
import { resolveStateValue } from "../internal/render-element.mjs";
|
|
4
4
|
import { useDelayedPair } from "../internal/use-delayed-pair.mjs";
|
|
5
5
|
import { usePopoverRoot } from "../internal/use-popover-root.mjs";
|
|
6
|
-
import { MenuContext, MenuListContext } from "./menu-context.mjs";
|
|
7
|
-
import { use, useCallback, useMemo, useRef } from "react";
|
|
6
|
+
import { ANCHOR_PLACEMENT, MenuContext, MenuListContext, MenuRegionContext } from "./menu-context.mjs";
|
|
7
|
+
import { use, useCallback, useMemo, useRef, useState } from "react";
|
|
8
8
|
import { jsx } from "react/jsx-runtime";
|
|
9
9
|
//#region src/menu/menu-root.tsx
|
|
10
10
|
/**
|
|
@@ -27,10 +27,14 @@ function MenuRoot({ open, defaultOpen, openChangeAction, loop = true, delay, clo
|
|
|
27
27
|
const parentMenu = list !== null ? list.menu : null;
|
|
28
28
|
const submenu = parentMenu !== null;
|
|
29
29
|
useDevWarning(!submenu && (delay !== void 0 || closeDelay !== void 0), "Menu.Root: `delay` and `closeDelay` only apply to a submenu (a Menu.Root inside a Menu.Popup); a top-level menu does not open on hover.");
|
|
30
|
-
|
|
30
|
+
const inRegion = use(MenuRegionContext);
|
|
31
|
+
useDevWarning(parent !== null && !submenu && !inRegion, "Menu.Root: rendered inside another Menu.Root but outside its Menu.Popup. A submenu's Root goes inside the parent's Menu.Popup.");
|
|
31
32
|
const timers = useDelayedPair();
|
|
32
33
|
const nextCause = useRef(null);
|
|
33
34
|
const openCause = useRef(null);
|
|
35
|
+
const [placement, setPlacement] = useState(ANCHOR_PLACEMENT);
|
|
36
|
+
const placementGeneration = useRef(0);
|
|
37
|
+
const pointDispatch = useRef(false);
|
|
34
38
|
const popover = usePopoverRoot({
|
|
35
39
|
component: "menu",
|
|
36
40
|
part: "Menu.Root",
|
|
@@ -42,8 +46,39 @@ function MenuRoot({ open, defaultOpen, openChangeAction, loop = true, delay, clo
|
|
|
42
46
|
timers.cancel();
|
|
43
47
|
if (next) openCause.current = nextCause.current ?? DEFAULT_FOCUS;
|
|
44
48
|
nextCause.current = null;
|
|
49
|
+
if (next && !pointDispatch.current) setPlacement(ANCHOR_PLACEMENT);
|
|
45
50
|
}
|
|
46
51
|
});
|
|
52
|
+
const { intended, requestOpen } = popover;
|
|
53
|
+
const openAt = useCallback((point, options) => {
|
|
54
|
+
const generation = ++placementGeneration.current;
|
|
55
|
+
setPlacement({
|
|
56
|
+
kind: "point",
|
|
57
|
+
x: point.x,
|
|
58
|
+
y: point.y,
|
|
59
|
+
generation,
|
|
60
|
+
source: options.source,
|
|
61
|
+
pointerId: options.pointerId
|
|
62
|
+
});
|
|
63
|
+
const focus = {
|
|
64
|
+
cause: "first",
|
|
65
|
+
pointer: options.pointer
|
|
66
|
+
};
|
|
67
|
+
if (intended()) {
|
|
68
|
+
openCause.current = focus;
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
nextCause.current = focus;
|
|
72
|
+
pointDispatch.current = true;
|
|
73
|
+
try {
|
|
74
|
+
requestOpen(options.event, "activate");
|
|
75
|
+
} finally {
|
|
76
|
+
pointDispatch.current = false;
|
|
77
|
+
}
|
|
78
|
+
}, [intended, requestOpen]);
|
|
79
|
+
const resetPlacement = useCallback((generation) => {
|
|
80
|
+
setPlacement((current) => current.kind === "point" && current.generation === generation ? ANCHOR_PLACEMENT : current);
|
|
81
|
+
}, []);
|
|
47
82
|
const setOpenCause = useCallback((cause, pointer = false) => {
|
|
48
83
|
nextCause.current = {
|
|
49
84
|
cause,
|
|
@@ -71,7 +106,10 @@ function MenuRoot({ open, defaultOpen, openChangeAction, loop = true, delay, clo
|
|
|
71
106
|
triggerId: `${popover.ids.popup}-trigger`,
|
|
72
107
|
setOpenCause,
|
|
73
108
|
takeOpenCause,
|
|
74
|
-
timers
|
|
109
|
+
timers,
|
|
110
|
+
placement,
|
|
111
|
+
openAt,
|
|
112
|
+
resetPlacement
|
|
75
113
|
};
|
|
76
114
|
return self;
|
|
77
115
|
}, [
|
|
@@ -83,12 +121,16 @@ function MenuRoot({ open, defaultOpen, openChangeAction, loop = true, delay, clo
|
|
|
83
121
|
resolvedCloseDelay,
|
|
84
122
|
setOpenCause,
|
|
85
123
|
takeOpenCause,
|
|
86
|
-
timers
|
|
124
|
+
timers,
|
|
125
|
+
placement,
|
|
126
|
+
openAt,
|
|
127
|
+
resetPlacement
|
|
87
128
|
]);
|
|
88
129
|
const state = {
|
|
89
130
|
open: popover.optimistic,
|
|
90
131
|
pending: popover.pending,
|
|
91
|
-
submenu
|
|
132
|
+
submenu,
|
|
133
|
+
context: popover.optimistic && placement.kind === "point"
|
|
92
134
|
};
|
|
93
135
|
return /* @__PURE__ */ jsx(MenuContext, {
|
|
94
136
|
value,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu-root.mjs","names":[],"sources":["../../src/menu/menu-root.tsx"],"sourcesContent":["\"use client\";\nimport { use, useCallback, useMemo, useRef } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { ActionDetails, ChangeAction, ChangeReason, StateValue } from \"../internal/types.js\";\nimport { useDelayedPair } from \"../internal/use-delayed-pair.js\";\nimport { useDevWarning } from \"../internal/use-dev-warning.js\";\nimport { usePopoverRoot } from \"../internal/use-popover-root.js\";\nimport { resolveStateValue } from \"../internal/use-render.js\";\nimport { MenuContext, MenuListContext } from \"./menu-context.js\";\nimport type { MenuContextValue, MenuOpenFocus } from \"./menu-context.js\";\n\n/** Details passed as the second argument of `Menu.Root`'s `openChangeAction`. */\nexport interface MenuOpenChangeDetails extends ActionDetails {\n /**\n * `\"activate\"`: the user acted on a part: the Trigger or SubmenuTrigger (click, Enter / Space,\n * arrow keys), an item's activation (the close after its action), ArrowLeft in a submenu, or a\n * foreign invoker.\n * `\"dismiss\"`: Escape, a click outside, Tab or focus leaving the menu, the pointer leaving a\n * hover-opened submenu, the parent menu closing (a submenu when the whole stack closes), script.\n * `\"platform\"`: the menu was found open on mount (opened before hydration); `event` is\n * `undefined`.\n */\n readonly reason: ChangeReason;\n}\n\nexport interface MenuRootState {\n /** Optimistic open state. Content rendered from it must not suspend. */\n readonly open: boolean;\n /** An open or close of this Root is in flight (its `openChangeAction`). */\n readonly pending: boolean;\n /** This Root is a submenu (rendered inside a `Menu.Popup`). */\n readonly submenu: boolean;\n}\n\nexport interface MenuRootProps {\n /** Controlled open state. `undefined` means uncontrolled. */\n open?: boolean;\n /** Initial open state when uncontrolled. Opens after hydration. */\n defaultOpen?: boolean;\n /**\n * Awaited for `true` (the menu opens when it resolves and the items have rendered) and for the\n * closes the user asks a part for (Trigger toggle, an item's activation, ArrowLeft in a\n * submenu); a notification for dismissals (Escape, a click outside, Tab, the parent menu\n * closing). May be a Server Function. A `setState` placed after your own `await` needs\n * `startTransition` (React limitation).\n */\n openChangeAction?: ChangeAction<boolean, MenuOpenChangeDetails>;\n /** Arrow keys wrap from the last item to the first and back. Default `true`. */\n loop?: boolean;\n /** Submenu only: milliseconds from hovering the SubmenuTrigger to the open. Default 100. */\n delay?: number;\n /**\n * Submenu only: milliseconds from the pointer leaving the SubmenuTrigger and the submenu to the\n * close. Default 150.\n */\n closeDelay?: number;\n children?: StateValue<ReactNode, MenuRootState>;\n}\n\n/**\n * Owns the ids, the open state and the context of one menu level. Renders no DOM. A `Menu.Root`\n * rendered inside a `Menu.Popup` is a **submenu**: its Trigger is a `Menu.SubmenuTrigger` (an\n * item of the parent menu) and its Popup opens beside that item.\n *\n * A menu is always in library mode (design/components/menu.md 2.1): opening and the closes a\n * part asks for are transitions (pending Trigger, items render from committed state,\n * `showPopover()` / `hidePopover()` once the change has committed); dismissals are the\n * browser's and `openChangeAction(false)` is a notification.\n */\nconst DEFAULT_FOCUS: MenuOpenFocus = { cause: \"first\", pointer: false };\n\nexport function MenuRoot({\n open,\n defaultOpen,\n openChangeAction,\n loop = true,\n delay,\n closeDelay,\n children,\n}: MenuRootProps) {\n const parent = use(MenuContext);\n const list = use(MenuListContext);\n // A Root inside a Popup's content is a submenu (design 1); the enclosing menu is the Popup's.\n const parentMenu = list !== null ? list.menu : null;\n const submenu = parentMenu !== null;\n\n useDevWarning(\n !submenu && (delay !== undefined || closeDelay !== undefined),\n \"Menu.Root: `delay` and `closeDelay` only apply to a submenu (a Menu.Root inside a \" +\n \"Menu.Popup); a top-level menu does not open on hover.\",\n );\n useDevWarning(\n parent !== null && !submenu,\n \"Menu.Root: rendered inside another Menu.Root but outside its Menu.Popup. A submenu's Root \" +\n \"goes inside the parent's Menu.Popup.\",\n );\n\n const timers = useDelayedPair();\n // The cause recorded by the part about to dispatch an open, and the cause of the open being\n // shown (design 14, \"Open cause\").\n const nextCause = useRef<MenuOpenFocus | null>(null);\n const openCause = useRef<MenuOpenFocus | null>(null);\n\n const popover = usePopoverRoot<MenuOpenChangeDetails>({\n component: \"menu\",\n part: \"Menu.Root\",\n mode: \"library\",\n open,\n defaultOpen,\n openChangeAction,\n onDispatch: (next) => {\n // Any dispatch cancels hover intent (walkthrough 9).\n timers.cancel();\n if (next) openCause.current = nextCause.current ?? DEFAULT_FOCUS;\n nextCause.current = null;\n },\n });\n\n const setOpenCause = useCallback((cause: MenuOpenFocus[\"cause\"], pointer = false) => {\n nextCause.current = { cause, pointer };\n }, []);\n const takeOpenCause = useCallback(() => {\n const cause = openCause.current ?? DEFAULT_FOCUS;\n openCause.current = null;\n return cause;\n }, []);\n\n const resolvedDelay = delay ?? 100;\n const resolvedCloseDelay = closeDelay ?? 150;\n // `popover` is memoised by `usePopoverRoot` (#48) and the other members are stable, so this\n // changes only with the open state, pending and the props listed below.\n const value = useMemo<MenuContextValue>(() => {\n const self: MenuContextValue = {\n popover,\n submenu,\n // The top-level menu: this one, or the parent's root (design 2.2).\n get root() {\n return parentMenu?.root ?? self;\n },\n parent: parentMenu,\n loop,\n delay: resolvedDelay,\n closeDelay: resolvedCloseDelay,\n triggerId: `${popover.ids.popup}-trigger`,\n setOpenCause,\n takeOpenCause,\n timers,\n };\n return self;\n }, [\n popover,\n submenu,\n parentMenu,\n loop,\n resolvedDelay,\n resolvedCloseDelay,\n setOpenCause,\n takeOpenCause,\n timers,\n ]);\n\n const state: MenuRootState = {\n open: popover.optimistic,\n pending: popover.pending,\n submenu,\n };\n\n return <MenuContext value={value}>{resolveStateValue(children, state)}</MenuContext>;\n}\n\nMenuRoot.displayName = \"MenuRoot\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAqEA,MAAM,gBAA+B;CAAE,OAAO;CAAS,SAAS;AAAM;AAEtE,SAAgB,SAAS,EACvB,MACA,aACA,kBACA,OAAO,MACP,OACA,YACA,YACgB;CAChB,MAAM,SAAS,IAAI,WAAW;CAC9B,MAAM,OAAO,IAAI,eAAe;CAEhC,MAAM,aAAa,SAAS,OAAO,KAAK,OAAO;CAC/C,MAAM,UAAU,eAAe;CAE/B,cACE,CAAC,YAAY,UAAU,KAAA,KAAa,eAAe,KAAA,IACnD,yIAEF;CACA,cACE,WAAW,QAAQ,CAAC,SACpB,gIAEF;CAEA,MAAM,SAAS,eAAe;CAG9B,MAAM,YAAY,OAA6B,IAAI;CACnD,MAAM,YAAY,OAA6B,IAAI;CAEnD,MAAM,UAAU,eAAsC;EACpD,WAAW;EACX,MAAM;EACN,MAAM;EACN;EACA;EACA;EACA,aAAa,SAAS;GAEpB,OAAO,OAAO;GACd,IAAI,MAAM,UAAU,UAAU,UAAU,WAAW;GACnD,UAAU,UAAU;EACtB;CACF,CAAC;CAED,MAAM,eAAe,aAAa,OAA+B,UAAU,UAAU;EACnF,UAAU,UAAU;GAAE;GAAO;EAAQ;CACvC,GAAG,CAAC,CAAC;CACL,MAAM,gBAAgB,kBAAkB;EACtC,MAAM,QAAQ,UAAU,WAAW;EACnC,UAAU,UAAU;EACpB,OAAO;CACT,GAAG,CAAC,CAAC;CAEL,MAAM,gBAAgB,SAAS;CAC/B,MAAM,qBAAqB,cAAc;CAGzC,MAAM,QAAQ,cAAgC;EAC5C,MAAM,OAAyB;GAC7B;GACA;GAEA,IAAI,OAAO;IACT,OAAO,YAAY,QAAQ;GAC7B;GACA,QAAQ;GACR;GACA,OAAO;GACP,YAAY;GACZ,WAAW,GAAG,QAAQ,IAAI,MAAM;GAChC;GACA;GACA;EACF;EACA,OAAO;CACT,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,QAAuB;EAC3B,MAAM,QAAQ;EACd,SAAS,QAAQ;EACjB;CACF;CAEA,OAAO,oBAAC,aAAD;EAAoB;EAAQ,UAAA,kBAAkB,UAAU,KAAK;CAAe,CAAA;AACrF;AAEA,SAAS,cAAc"}
|
|
1
|
+
{"version":3,"file":"menu-root.mjs","names":[],"sources":["../../src/menu/menu-root.tsx"],"sourcesContent":["\"use client\";\nimport { use, useCallback, useMemo, useRef, useState } from \"react\";\nimport type { ReactNode } from \"react\";\nimport type { ActionDetails, ChangeAction, ChangeReason, StateValue } from \"../internal/types.js\";\nimport { useDelayedPair } from \"../internal/use-delayed-pair.js\";\nimport { useDevWarning } from \"../internal/use-dev-warning.js\";\nimport { usePopoverRoot } from \"../internal/use-popover-root.js\";\nimport { resolveStateValue } from \"../internal/use-render.js\";\nimport {\n ANCHOR_PLACEMENT,\n MenuContext,\n MenuListContext,\n MenuRegionContext,\n} from \"./menu-context.js\";\nimport type {\n MenuContextValue,\n MenuOpenAtOptions,\n MenuOpenFocus,\n MenuPlacement,\n} from \"./menu-context.js\";\n\n/** Details passed as the second argument of `Menu.Root`'s `openChangeAction`. */\nexport interface MenuOpenChangeDetails extends ActionDetails {\n /**\n * `\"activate\"`: the user acted on a part: the Trigger or SubmenuTrigger (click, Enter / Space,\n * arrow keys), an item's activation (the close after its action), ArrowLeft in a submenu, or a\n * foreign invoker.\n * `\"dismiss\"`: Escape, a click outside, Tab or focus leaving the menu, the pointer leaving a\n * hover-opened submenu, the parent menu closing (a submenu when the whole stack closes), script.\n * `\"platform\"`: the menu was found open on mount (opened before hydration); `event` is\n * `undefined`.\n */\n readonly reason: ChangeReason;\n}\n\nexport interface MenuRootState {\n /** Optimistic open state. Content rendered from it must not suspend. */\n readonly open: boolean;\n /** An open or close of this Root is in flight (its `openChangeAction`). */\n readonly pending: boolean;\n /** This Root is a submenu (rendered inside a `Menu.Popup`). */\n readonly submenu: boolean;\n /**\n * The current open (optimistic) came from a `Menu.ContextTrigger`: the menu is placed at the\n * pointer rather than against the Trigger.\n */\n readonly context: boolean;\n}\n\nexport interface MenuRootProps {\n /** Controlled open state. `undefined` means uncontrolled. */\n open?: boolean;\n /** Initial open state when uncontrolled. Opens after hydration. */\n defaultOpen?: boolean;\n /**\n * Awaited for `true` (the menu opens when it resolves and the items have rendered) and for the\n * closes the user asks a part for (Trigger toggle, an item's activation, ArrowLeft in a\n * submenu); a notification for dismissals (Escape, a click outside, Tab, the parent menu\n * closing). May be a Server Function. A `setState` placed after your own `await` needs\n * `startTransition` (React limitation).\n */\n openChangeAction?: ChangeAction<boolean, MenuOpenChangeDetails>;\n /** Arrow keys wrap from the last item to the first and back. Default `true`. */\n loop?: boolean;\n /** Submenu only: milliseconds from hovering the SubmenuTrigger to the open. Default 100. */\n delay?: number;\n /**\n * Submenu only: milliseconds from the pointer leaving the SubmenuTrigger and the submenu to the\n * close. Default 150.\n */\n closeDelay?: number;\n children?: StateValue<ReactNode, MenuRootState>;\n}\n\n/**\n * Owns the ids, the open state and the context of one menu level. Renders no DOM. A `Menu.Root`\n * rendered inside a `Menu.Popup` is a **submenu**: its Trigger is a `Menu.SubmenuTrigger` (an\n * item of the parent menu) and its Popup opens beside that item.\n *\n * A menu is always in library mode (design/components/menu.md 2.1): opening and the closes a\n * part asks for are transitions (pending Trigger, items render from committed state,\n * `showPopover()` / `hidePopover()` once the change has committed); dismissals are the\n * browser's and `openChangeAction(false)` is a notification.\n */\nconst DEFAULT_FOCUS: MenuOpenFocus = { cause: \"first\", pointer: false };\n\nexport function MenuRoot({\n open,\n defaultOpen,\n openChangeAction,\n loop = true,\n delay,\n closeDelay,\n children,\n}: MenuRootProps) {\n const parent = use(MenuContext);\n const list = use(MenuListContext);\n // A Root inside a Popup's content is a submenu (design 1); the enclosing menu is the Popup's.\n const parentMenu = list !== null ? list.menu : null;\n const submenu = parentMenu !== null;\n\n useDevWarning(\n !submenu && (delay !== undefined || closeDelay !== undefined),\n \"Menu.Root: `delay` and `closeDelay` only apply to a submenu (a Menu.Root inside a \" +\n \"Menu.Popup); a top-level menu does not open on hover.\",\n );\n const inRegion = use(MenuRegionContext);\n useDevWarning(\n parent !== null && !submenu && !inRegion,\n \"Menu.Root: rendered inside another Menu.Root but outside its Menu.Popup. A submenu's Root \" +\n \"goes inside the parent's Menu.Popup.\",\n );\n\n const timers = useDelayedPair();\n // The cause recorded by the part about to dispatch an open, and the cause of the open being\n // shown (design 14, \"Open cause\").\n const nextCause = useRef<MenuOpenFocus | null>(null);\n const openCause = useRef<MenuOpenFocus | null>(null);\n\n // Placement of the current open (context-menu.md 3.1). Written urgently, not in a transition:\n // while closed it renders nothing visible, and a move of an open menu (4.3) answers the\n // right-click at once, where a transition would be entangled with any pending async action\n // (an item's, the open's) and the menu would stay at the old point until it settled.\n const [placement, setPlacement] = useState<MenuPlacement>(ANCHOR_PLACEMENT);\n const placementGeneration = useRef(0);\n // Set by `openAt` around its `requestOpen`: the dispatch is a point open.\n const pointDispatch = useRef(false);\n\n const popover = usePopoverRoot<MenuOpenChangeDetails>({\n component: \"menu\",\n part: \"Menu.Root\",\n mode: \"library\",\n open,\n defaultOpen,\n openChangeAction,\n onDispatch: (next) => {\n // Any dispatch cancels hover intent (walkthrough 9).\n timers.cancel();\n if (next) openCause.current = nextCause.current ?? DEFAULT_FOCUS;\n nextCause.current = null;\n // Every other open (Trigger, foreign invoker, mount reconciliation) is anchored.\n if (next && !pointDispatch.current) setPlacement(ANCHOR_PLACEMENT);\n },\n });\n\n const { intended, requestOpen } = popover;\n const openAt = useCallback(\n (point: { readonly x: number; readonly y: number }, options: MenuOpenAtOptions) => {\n const generation = ++placementGeneration.current;\n setPlacement({\n kind: \"point\",\n x: point.x,\n y: point.y,\n generation,\n source: options.source,\n pointerId: options.pointerId,\n });\n const focus: MenuOpenFocus = { cause: \"first\", pointer: options.pointer };\n if (intended()) {\n // A move, or a right-click while the open is still pending: no dispatch. The re-show\n // (or the open being shown) focuses the first item by this event's modality.\n openCause.current = focus;\n return;\n }\n nextCause.current = focus;\n pointDispatch.current = true;\n try {\n requestOpen(options.event, \"activate\");\n } finally {\n pointDispatch.current = false;\n }\n },\n [intended, requestOpen],\n );\n const resetPlacement = useCallback((generation: number) => {\n setPlacement((current) =>\n current.kind === \"point\" && current.generation === generation ? ANCHOR_PLACEMENT : current,\n );\n }, []);\n\n const setOpenCause = useCallback((cause: MenuOpenFocus[\"cause\"], pointer = false) => {\n nextCause.current = { cause, pointer };\n }, []);\n const takeOpenCause = useCallback(() => {\n const cause = openCause.current ?? DEFAULT_FOCUS;\n openCause.current = null;\n return cause;\n }, []);\n\n const resolvedDelay = delay ?? 100;\n const resolvedCloseDelay = closeDelay ?? 150;\n // `popover` is memoised by `usePopoverRoot` (#48) and the other members are stable, so this\n // changes only with the open state, pending and the props listed below.\n const value = useMemo<MenuContextValue>(() => {\n const self: MenuContextValue = {\n popover,\n submenu,\n // The top-level menu: this one, or the parent's root (design 2.2).\n get root() {\n return parentMenu?.root ?? self;\n },\n parent: parentMenu,\n loop,\n delay: resolvedDelay,\n closeDelay: resolvedCloseDelay,\n triggerId: `${popover.ids.popup}-trigger`,\n setOpenCause,\n takeOpenCause,\n timers,\n placement,\n openAt,\n resetPlacement,\n };\n return self;\n }, [\n popover,\n submenu,\n parentMenu,\n loop,\n resolvedDelay,\n resolvedCloseDelay,\n setOpenCause,\n takeOpenCause,\n timers,\n placement,\n openAt,\n resetPlacement,\n ]);\n\n const state: MenuRootState = {\n open: popover.optimistic,\n pending: popover.pending,\n submenu,\n context: popover.optimistic && placement.kind === \"point\",\n };\n\n return <MenuContext value={value}>{resolveStateValue(children, state)}</MenuContext>;\n}\n\nMenuRoot.displayName = \"MenuRoot\";\n"],"mappings":";;;;;;;;;;;;;;;;;;;AAoFA,MAAM,gBAA+B;CAAE,OAAO;CAAS,SAAS;AAAM;AAEtE,SAAgB,SAAS,EACvB,MACA,aACA,kBACA,OAAO,MACP,OACA,YACA,YACgB;CAChB,MAAM,SAAS,IAAI,WAAW;CAC9B,MAAM,OAAO,IAAI,eAAe;CAEhC,MAAM,aAAa,SAAS,OAAO,KAAK,OAAO;CAC/C,MAAM,UAAU,eAAe;CAE/B,cACE,CAAC,YAAY,UAAU,KAAA,KAAa,eAAe,KAAA,IACnD,yIAEF;CACA,MAAM,WAAW,IAAI,iBAAiB;CACtC,cACE,WAAW,QAAQ,CAAC,WAAW,CAAC,UAChC,gIAEF;CAEA,MAAM,SAAS,eAAe;CAG9B,MAAM,YAAY,OAA6B,IAAI;CACnD,MAAM,YAAY,OAA6B,IAAI;CAMnD,MAAM,CAAC,WAAW,gBAAgB,SAAwB,gBAAgB;CAC1E,MAAM,sBAAsB,OAAO,CAAC;CAEpC,MAAM,gBAAgB,OAAO,KAAK;CAElC,MAAM,UAAU,eAAsC;EACpD,WAAW;EACX,MAAM;EACN,MAAM;EACN;EACA;EACA;EACA,aAAa,SAAS;GAEpB,OAAO,OAAO;GACd,IAAI,MAAM,UAAU,UAAU,UAAU,WAAW;GACnD,UAAU,UAAU;GAEpB,IAAI,QAAQ,CAAC,cAAc,SAAS,aAAa,gBAAgB;EACnE;CACF,CAAC;CAED,MAAM,EAAE,UAAU,gBAAgB;CAClC,MAAM,SAAS,aACZ,OAAmD,YAA+B;EACjF,MAAM,aAAa,EAAE,oBAAoB;EACzC,aAAa;GACX,MAAM;GACN,GAAG,MAAM;GACT,GAAG,MAAM;GACT;GACA,QAAQ,QAAQ;GAChB,WAAW,QAAQ;EACrB,CAAC;EACD,MAAM,QAAuB;GAAE,OAAO;GAAS,SAAS,QAAQ;EAAQ;EACxE,IAAI,SAAS,GAAG;GAGd,UAAU,UAAU;GACpB;EACF;EACA,UAAU,UAAU;EACpB,cAAc,UAAU;EACxB,IAAI;GACF,YAAY,QAAQ,OAAO,UAAU;EACvC,UAAU;GACR,cAAc,UAAU;EAC1B;CACF,GACA,CAAC,UAAU,WAAW,CACxB;CACA,MAAM,iBAAiB,aAAa,eAAuB;EACzD,cAAc,YACZ,QAAQ,SAAS,WAAW,QAAQ,eAAe,aAAa,mBAAmB,OACrF;CACF,GAAG,CAAC,CAAC;CAEL,MAAM,eAAe,aAAa,OAA+B,UAAU,UAAU;EACnF,UAAU,UAAU;GAAE;GAAO;EAAQ;CACvC,GAAG,CAAC,CAAC;CACL,MAAM,gBAAgB,kBAAkB;EACtC,MAAM,QAAQ,UAAU,WAAW;EACnC,UAAU,UAAU;EACpB,OAAO;CACT,GAAG,CAAC,CAAC;CAEL,MAAM,gBAAgB,SAAS;CAC/B,MAAM,qBAAqB,cAAc;CAGzC,MAAM,QAAQ,cAAgC;EAC5C,MAAM,OAAyB;GAC7B;GACA;GAEA,IAAI,OAAO;IACT,OAAO,YAAY,QAAQ;GAC7B;GACA,QAAQ;GACR;GACA,OAAO;GACP,YAAY;GACZ,WAAW,GAAG,QAAQ,IAAI,MAAM;GAChC;GACA;GACA;GACA;GACA;GACA;EACF;EACA,OAAO;CACT,GAAG;EACD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,QAAuB;EAC3B,MAAM,QAAQ;EACd,SAAS,QAAQ;EACjB;EACA,SAAS,QAAQ,cAAc,UAAU,SAAS;CACpD;CAEA,OAAO,oBAAC,aAAD;EAAoB;EAAQ,UAAA,kBAAkB,UAAU,KAAK;CAAe,CAAA;AACrF;AAEA,SAAS,cAAc"}
|