@graview/react 0.1.8 → 0.1.10

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 (51) hide show
  1. package/dist/connectors.d.ts.map +1 -1
  2. package/dist/connectors.js +4 -3
  3. package/dist/connectors.js.map +1 -1
  4. package/dist/context.d.ts +22 -0
  5. package/dist/context.d.ts.map +1 -1
  6. package/dist/context.js +30 -4
  7. package/dist/context.js.map +1 -1
  8. package/dist/edge-signs.d.ts +1 -1
  9. package/dist/edge-signs.d.ts.map +1 -1
  10. package/dist/edge-signs.js +2 -1
  11. package/dist/edge-signs.js.map +1 -1
  12. package/dist/go.d.ts +22 -0
  13. package/dist/go.d.ts.map +1 -0
  14. package/dist/go.js +24 -0
  15. package/dist/go.js.map +1 -0
  16. package/dist/index.d.ts +5 -1
  17. package/dist/index.d.ts.map +1 -1
  18. package/dist/index.js +3 -1
  19. package/dist/index.js.map +1 -1
  20. package/dist/plots.d.ts +3 -26
  21. package/dist/plots.d.ts.map +1 -1
  22. package/dist/plots.js +7 -62
  23. package/dist/plots.js.map +1 -1
  24. package/dist/popover.d.ts +190 -0
  25. package/dist/popover.d.ts.map +1 -0
  26. package/dist/popover.js +374 -0
  27. package/dist/popover.js.map +1 -0
  28. package/dist/provider.d.ts +5 -1
  29. package/dist/provider.d.ts.map +1 -1
  30. package/dist/provider.js +3 -1
  31. package/dist/provider.js.map +1 -1
  32. package/dist/rails.d.ts +5 -1
  33. package/dist/rails.d.ts.map +1 -1
  34. package/dist/rails.js +8 -2
  35. package/dist/rails.js.map +1 -1
  36. package/dist/resolved-view.d.ts.map +1 -1
  37. package/dist/resolved-view.js +14 -47
  38. package/dist/resolved-view.js.map +1 -1
  39. package/dist/scene-lines.d.ts +1 -1
  40. package/dist/scene-lines.d.ts.map +1 -1
  41. package/dist/scene-lines.js +3 -2
  42. package/dist/scene-lines.js.map +1 -1
  43. package/dist/scene-root.d.ts.map +1 -1
  44. package/dist/scene-root.js +10 -8
  45. package/dist/scene-root.js.map +1 -1
  46. package/dist/view-host.js +2 -2
  47. package/dist/view-host.js.map +1 -1
  48. package/dist/view-registry.d.ts.map +1 -1
  49. package/dist/view-registry.js +8 -0
  50. package/dist/view-registry.js.map +1 -1
  51. package/package.json +5 -5
@@ -0,0 +1,374 @@
1
+ import { layer } from "@graview/core";
2
+ import { useCallback, useEffect, useId, useLayoutEffect, useRef, useState } from "react";
3
+ /**
4
+ * EVERY POPOVER THE FRAMEWORK DRAWS, BY NAME — the family a harness opens
5
+ * one by one rather than a list somebody keeps by hand (FR-77). Each says
6
+ * the `data-testid` of what opens it and of its pane, how it is opened,
7
+ * where the framework draws it, and where the keyboard goes when it opens:
8
+ * into the pane, except under the Find box, which is a combobox's listbox
9
+ * and keeps the keyboard in the box (its rows are `aria-activedescendant`).
10
+ * A popover that is not in here is not in the family, and `usePopover`
11
+ * takes no name that is not.
12
+ */
13
+ export const POPOVERS = {
14
+ /** Who you are and your own settings, from the bar and the embed's strip. */
15
+ profile: { trigger: "profile-button", pane: "profile", opens: "press", focus: "into", drawn: ["shell", "embed"] },
16
+ /** What is broken, from Standing, on the bar and the strip. */
17
+ problems: { trigger: "standing", pane: "problems", opens: "press", focus: "into", drawn: ["shell", "embed"] },
18
+ /** What has happened, from the bar. */
19
+ activity: { trigger: "activity-button", pane: "activity", opens: "press", focus: "into", drawn: ["shell"] },
20
+ /** What the words find, under the Find box. */
21
+ find: { trigger: "find-box", pane: "find-strip", opens: "typing", focus: "stays", drawn: ["shell"] },
22
+ /** The districts the row could not hold, from "+N more" on the ground. */
23
+ districts: { trigger: "beyond-more", pane: "beyond-list", opens: "press", focus: "into", drawn: ["shell", "embed"] },
24
+ /** A card's acts at the pointer: right-click, the context menu. The card is what the keyboard goes back to. */
25
+ acts: { trigger: null, pane: "context-menu", opens: "context-menu", focus: "into", drawn: ["shell", "embed"] },
26
+ /** The conversation as a pill's popover, where an app puts `ChatPanel` on a bar of its own. */
27
+ chat: { trigger: "chat", pane: "chat-panel", opens: "press", focus: "into", drawn: [] },
28
+ /** The studio's own seat, from its bar. */
29
+ "studio-ask": { trigger: "studio-agent", pane: "studio-agent-panel", opens: "press", focus: "into", drawn: ["studio"] },
30
+ };
31
+ /**
32
+ * A TRANSIENT SURFACE OPENS IN THE BROWSER'S TOP LAYER (FR-76).
33
+ *
34
+ * A popover, a menu, a list of suggestions: each used to hang from its
35
+ * trigger with `position: absolute` and a `z-index` of its own choosing, in
36
+ * the one stacking context the bar, the scene and the seat's rail share —
37
+ * and on a hosted app the profile opened under the rail at 40 and could not
38
+ * be read. The browser has a layer above every stacking context for exactly
39
+ * this: an element shown with `showPopover()` is drawn over everything on
40
+ * the page, whatever `z-index`, `overflow: hidden` or `backdrop-filter` its
41
+ * ancestors carry, and it is still where it was in the DOM — so an embed's
42
+ * scoped theme still reaches it and its custom properties are inherited,
43
+ * and nothing of it lands on the host's page that was not there before.
44
+ *
45
+ * Chromium 114, Firefox 125 and Safari 17 have it, and Playwright's
46
+ * Chromium, WebKit and Firefox do; where `showPopover` is missing, the pane
47
+ * stands on the ladder's popover rung (`layer("popover")`), over every rail.
48
+ *
49
+ * In the top layer the pane's containing block is the viewport, so it is
50
+ * placed by its anchor's rectangle: under it, or over it where there is
51
+ * more room above (`placePane`), and kept to the viewport on both axes.
52
+ */
53
+ export const POPOVER_STYLE = {
54
+ position: "fixed",
55
+ inset: "auto",
56
+ margin: 0,
57
+ zIndex: layer("popover"),
58
+ boxSizing: "border-box",
59
+ };
60
+ /** The pane's distance from its anchor, and from the viewport's edges. */
61
+ const GAP = 6;
62
+ const MARGIN = 8;
63
+ const supportsTopLayer = (pane) => typeof pane.showPopover === "function";
64
+ /** Whether the pane is in the top layer now. */
65
+ export function inTopLayer(pane) {
66
+ try {
67
+ return pane.matches(":popover-open");
68
+ }
69
+ catch {
70
+ return false;
71
+ }
72
+ }
73
+ function anchorRect(anchor) {
74
+ if (typeof anchor === "function") {
75
+ const at = anchor();
76
+ return at ? { left: at.x, right: at.x, top: at.y, bottom: at.y } : null;
77
+ }
78
+ const element = anchor.current;
79
+ if (!element || !element.isConnected)
80
+ return null;
81
+ const rect = element.getBoundingClientRect();
82
+ return { left: rect.left, right: rect.right, top: rect.top, bottom: rect.bottom };
83
+ }
84
+ /**
85
+ * Puts the pane by its anchor, inside the viewport: under the anchor, or
86
+ * over it when the room above is the larger and the pane does not fit
87
+ * below; no taller than the room it was given, so what it holds scrolls
88
+ * inside it rather than running off the screen.
89
+ */
90
+ export function placePane(pane, anchor, options = {}) {
91
+ const at = anchorRect(anchor);
92
+ if (!at)
93
+ return;
94
+ const view = { width: document.documentElement.clientWidth || innerWidth, height: innerHeight };
95
+ // The height the pane was designed to stop at, kept the first time: the room is laid over it, never instead of it.
96
+ const designed = (pane.dataset["graviewDesignedHeight"] ??= pane.style.maxHeight);
97
+ pane.style.maxHeight = designed;
98
+ const natural = pane.getBoundingClientRect();
99
+ const below = view.height - at.bottom - GAP - MARGIN;
100
+ const above = at.top - GAP - MARGIN;
101
+ const down = natural.height <= below || below >= above;
102
+ const room = Math.max(96, Math.floor(down ? below : above));
103
+ const height = Math.min(natural.height, room);
104
+ // Border-box (`POPOVER_STYLE`), so the room is the pane's whole height, its frame included.
105
+ if (natural.height > room)
106
+ pane.style.maxHeight = designed ? `min(${designed}, ${room}px)` : `${room}px`;
107
+ const width = natural.width;
108
+ const wanted = options.align === "start" ? at.left : at.right - width;
109
+ // A sheet the viewport's width (a phone's) stands from its left edge; anything narrower keeps a margin.
110
+ const left = width >= view.width - 2 * MARGIN ? Math.max(0, (view.width - width) / 2) : Math.max(MARGIN, Math.min(wanted, view.width - MARGIN - width));
111
+ const top = down ? at.bottom + GAP : Math.max(MARGIN, at.top - GAP - height);
112
+ pane.style.left = `${Math.round(left)}px`;
113
+ pane.style.top = `${Math.round(top)}px`;
114
+ }
115
+ /**
116
+ * Shows the pane in the top layer while `open`, placed by its anchor and
117
+ * placed again as the page scrolls, the window changes size or the pane's
118
+ * own content does. The pane carries `popover="manual"` and
119
+ * `POPOVER_STYLE`; whoever draws it decides when it is open.
120
+ */
121
+ export function useTopLayer(pane, open, anchor, options = {}) {
122
+ const align = options.align ?? "end";
123
+ useLayoutEffect(() => {
124
+ const element = pane.current;
125
+ if (!open || !element)
126
+ return;
127
+ if (supportsTopLayer(element) && !inTopLayer(element)) {
128
+ try {
129
+ element.showPopover();
130
+ // The notices stay over it: the ladder's top rung is theirs.
131
+ raiseAgain();
132
+ }
133
+ catch {
134
+ // Not connected, or shown already: the ladder's rung still holds it over every rail.
135
+ }
136
+ }
137
+ let frame = 0;
138
+ const place = (event) => {
139
+ // The pane's own scrolling moves nothing it hangs from.
140
+ if (event?.target instanceof Node && element.contains(event.target))
141
+ return;
142
+ cancelAnimationFrame(frame);
143
+ frame = requestAnimationFrame(() => placePane(element, anchor, { align }));
144
+ };
145
+ placePane(element, anchor, { align });
146
+ addEventListener("resize", place);
147
+ addEventListener("scroll", place, true);
148
+ const watch = typeof ResizeObserver === "undefined" ? null : new ResizeObserver(() => place());
149
+ watch?.observe(element);
150
+ return () => {
151
+ cancelAnimationFrame(frame);
152
+ removeEventListener("resize", place);
153
+ removeEventListener("scroll", place, true);
154
+ watch?.disconnect();
155
+ if (element.isConnected && inTopLayer(element)) {
156
+ try {
157
+ element.hidePopover();
158
+ }
159
+ catch {
160
+ // Gone already.
161
+ }
162
+ }
163
+ };
164
+ // The anchor is read when placing, not watched: a new function each render is the same anchor.
165
+ // eslint-disable-next-line react-hooks/exhaustive-deps
166
+ }, [open, pane, align]);
167
+ }
168
+ /**
169
+ * WHAT STANDS OVER A POPOVER: the notices (FR-75), the ladder's top rung.
170
+ * The top layer is ordered by when a thing was shown, so a popover opened
171
+ * after a toast would stand over it; each element here is shown again,
172
+ * over it, the moment a popover of the family opens.
173
+ */
174
+ const raised = new Set();
175
+ /** Keeps an element in the top layer over any popover that opens after it; returns the way to stop. */
176
+ export function raiseOverPopovers(element) {
177
+ raised.add(element);
178
+ return () => raised.delete(element);
179
+ }
180
+ function raiseAgain() {
181
+ for (const element of raised) {
182
+ if (!element.isConnected || !inTopLayer(element))
183
+ continue;
184
+ try {
185
+ element.hidePopover();
186
+ element.showPopover();
187
+ }
188
+ catch {
189
+ // Not shown after all: nothing to raise.
190
+ }
191
+ }
192
+ }
193
+ /**
194
+ * THE ONE OPEN POPOVER, page-wide. Opening one closes the one before it —
195
+ * two embeds on a page included — so a profile and a problems list are
196
+ * never open over each other, each sure it is the one on top.
197
+ */
198
+ let current = null;
199
+ /** Where the keyboard can land inside a pane. */
200
+ const FOCUSABLE = 'button:not([disabled]), [href], input:not([disabled]):not([type="hidden"]), select:not([disabled]), textarea:not([disabled]), summary, [tabindex]:not([tabindex="-1"])';
201
+ /** The first thing in the pane the keyboard can stand on, or the pane itself. */
202
+ function firstStop(pane) {
203
+ for (const candidate of pane.querySelectorAll(FOCUSABLE)) {
204
+ // Not one that is hidden, or inside something hidden (a closed setting's own pane).
205
+ if (candidate.closest("[hidden]") === null && getComputedStyle(candidate).visibility !== "hidden")
206
+ return candidate;
207
+ }
208
+ return pane;
209
+ }
210
+ /**
211
+ * ONE FAMILY OF POPOVERS (FR-77).
212
+ *
213
+ * Every popover had its own way of closing: the profile closed on a press
214
+ * outside it, the districts on a pointer down, the menu at the pointer a
215
+ * frame late; one gave the keyboard back to its button and the next left
216
+ * it on `<body>`; none moved the keyboard in when it opened, so a person
217
+ * working from the keyboard opened the profile and was still on its button;
218
+ * and two could be open at once. This is the one way, and every popover in
219
+ * `POPOVERS` uses it:
220
+ *
221
+ * one at a time — opening one closes any other, page-wide;
222
+ * the keyboard goes in — to the pane's first control, or the pane;
223
+ * Escape closes it, and so does a press anywhere that is not the pane or
224
+ * its trigger (nor a dialog the pane opened); the keyboard goes back to
225
+ * the trigger when it was inside the pane or the press left it nowhere;
226
+ * it hangs from its trigger, in the top layer (`useTopLayer`), turned
227
+ * over when there is more room above and no taller than the room, so
228
+ * no row of it is ever under the viewport's edge.
229
+ */
230
+ export function usePopover(name, options = {}) {
231
+ const { at, returnTo, onOpenChange } = options;
232
+ const enabled = options.popover !== false;
233
+ const [held, setHeld] = useState(false);
234
+ const open = options.open ?? held;
235
+ const triggerRef = useRef(null);
236
+ const paneRef = useRef(null);
237
+ // Callbacks, so a button, a section or a list can each carry them.
238
+ const holdTrigger = useCallback((element) => {
239
+ triggerRef.current = element;
240
+ }, []);
241
+ const holdPane = useCallback((element) => {
242
+ paneRef.current = element;
243
+ }, []);
244
+ const id = `graview-popover-${useId().replace(/:/g, "")}`;
245
+ const latest = useRef({ onOpenChange, returnTo, controlled: options.open !== undefined });
246
+ latest.current = { onOpenChange, returnTo, controlled: options.open !== undefined };
247
+ const change = useCallback((next) => {
248
+ if (!latest.current.controlled)
249
+ setHeld(next);
250
+ latest.current.onOpenChange?.(next);
251
+ }, []);
252
+ /** Closes it; the keyboard goes back to where it came from when it was inside, or nowhere. */
253
+ const close = useCallback((giveBack) => {
254
+ const pane = paneRef.current;
255
+ const active = typeof document === "undefined" ? null : document.activeElement;
256
+ const lost = active === null || active === document.body || (pane !== null && pane.contains(active));
257
+ change(false);
258
+ if (!giveBack || !lost)
259
+ return;
260
+ const back = triggerRef.current ?? latest.current.returnTo?.() ?? null;
261
+ back?.focus({ preventScroll: true });
262
+ }, [change]);
263
+ useTopLayer(paneRef, enabled && open, at ?? triggerRef, options.align ? { align: options.align } : {});
264
+ useEffect(() => {
265
+ if (!enabled || !open)
266
+ return;
267
+ const me = { name, close: () => close(false) };
268
+ if (current && current.close !== me.close)
269
+ current.close();
270
+ current = me;
271
+ /* The keyboard goes in, unless it stays in a combobox's box. */
272
+ if (POPOVERS[name].focus === "into") {
273
+ const pane = paneRef.current;
274
+ if (pane && !pane.contains(document.activeElement))
275
+ firstStop(pane).focus({ preventScroll: true });
276
+ }
277
+ const key = (event) => {
278
+ if (event.key !== "Escape")
279
+ return;
280
+ close(true);
281
+ };
282
+ const away = (event) => {
283
+ const target = event.target;
284
+ if (!(target instanceof Node))
285
+ return;
286
+ const pane = paneRef.current;
287
+ if (pane?.contains(target) || triggerRef.current?.contains(target))
288
+ return;
289
+ /*
290
+ * A CONTROL IN HERE MAY OPEN SOMETHING BIGGER THAN HERE: the studio is
291
+ * a dialog its button in the profile opens, portalled to the body, and
292
+ * a press inside it is not a press away from the pane that opened it.
293
+ * A dialog the pane itself stands in (the studio's own seat) is not
294
+ * that: a press elsewhere in it is away.
295
+ */
296
+ const dialog = target instanceof Element ? target.closest('[role="dialog"], [role="alertdialog"]') : null;
297
+ if (dialog && !(pane && dialog.contains(pane)))
298
+ return;
299
+ close(false);
300
+ /*
301
+ * A press on something that takes the keyboard keeps it; a press on
302
+ * bare ground gives it back to the trigger. Not to a combobox's box: a
303
+ * press away from a text box is leaving it, and putting the keyboard
304
+ * back in would open its list again.
305
+ */
306
+ if (POPOVERS[name].focus !== "into")
307
+ return;
308
+ requestAnimationFrame(() => {
309
+ const active = document.activeElement;
310
+ if (active === null || active === document.body || (pane !== null && pane.contains(active))) {
311
+ (triggerRef.current ?? latest.current.returnTo?.() ?? null)?.focus({ preventScroll: true });
312
+ }
313
+ });
314
+ };
315
+ /*
316
+ * A DIALOG IT OPENED TAKES OVER. The studio is a dialog its button in
317
+ * the profile opens; in the top layer the profile stood over it and
318
+ * covered its bar. When the keyboard goes into a dialog the pane does
319
+ * not hold, the pane closes (it stays mounted where its owner keeps it
320
+ * so, and the dialog with it), and when that dialog is gone and has left
321
+ * the keyboard nowhere — its way back was a control in the closed pane —
322
+ * the keyboard goes to the trigger.
323
+ */
324
+ let handedTo = null;
325
+ let watching = null;
326
+ const takenOver = (event) => {
327
+ const target = event.target;
328
+ if (!(target instanceof Element))
329
+ return;
330
+ const pane = paneRef.current;
331
+ const dialog = target.closest('[role="dialog"], [role="alertdialog"]');
332
+ if (!dialog || (pane && (pane.contains(dialog) || dialog.contains(pane))))
333
+ return;
334
+ handedTo = dialog;
335
+ close(false);
336
+ };
337
+ document.addEventListener("keydown", key);
338
+ document.addEventListener("pointerdown", away, true);
339
+ document.addEventListener("focusin", takenOver);
340
+ return () => {
341
+ document.removeEventListener("keydown", key);
342
+ document.removeEventListener("pointerdown", away, true);
343
+ document.removeEventListener("focusin", takenOver);
344
+ const dialog = handedTo;
345
+ if (dialog && typeof MutationObserver !== "undefined") {
346
+ watching?.disconnect();
347
+ watching = new MutationObserver(() => {
348
+ if (dialog.isConnected)
349
+ return;
350
+ watching?.disconnect();
351
+ requestAnimationFrame(() => {
352
+ const active = document.activeElement;
353
+ const lost = active === null || active === document.body || (active instanceof HTMLElement && active.closest("[hidden]") !== null);
354
+ if (lost)
355
+ (triggerRef.current ?? latest.current.returnTo?.() ?? null)?.focus({ preventScroll: true });
356
+ });
357
+ });
358
+ watching.observe(document.body, { childList: true, subtree: true });
359
+ // Given up after a while: a dialog left open for good is not waited on.
360
+ setTimeout(() => watching?.disconnect(), 10 * 60_000);
361
+ }
362
+ if (current?.close === me.close)
363
+ current = null;
364
+ };
365
+ }, [enabled, open, name, close]);
366
+ return {
367
+ open,
368
+ setOpen: (next) => (next ? change(true) : close(true)),
369
+ toggle: () => (open ? close(true) : change(true)),
370
+ trigger: { ref: holdTrigger, "aria-expanded": open, "aria-controls": id, "data-graview-popover-trigger": name },
371
+ pane: { ref: holdPane, id, popover: "manual", tabIndex: -1, "data-graview-popover": name, "data-graview-overlay": "" },
372
+ };
373
+ }
374
+ //# sourceMappingURL=popover.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"popover.js","sourceRoot":"","sources":["../src/popover.ts"],"names":[],"mappings":"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"}
@@ -11,7 +11,9 @@
11
11
  * with the face that draws it. Nothing in this module's files may import
12
12
  * the scene's, or `@graview/react`.
13
13
  */
14
- export { GraviewProvider, ROBOT_REST_MS, useFound, useGraph, useGraview, useGraviewIfAny, useNode, useRobots, useScenePointer, useTheWatchKnowsWhatIsUnseen, useViewMode, useWhereIs, ViewModeProvider } from "./context.js";
14
+ export { GraviewProvider, openingView, ROBOT_REST_MS, useFound, useGraph, useGraview, useGraviewIfAny, useNode, useRobots, useScenePointer, useTheWatchKnowsWhatIsUnseen, useViewMode, useWhereIs, ViewModeProvider } from "./context.js";
15
+ export { GoToContext, useGoTo } from "./go.js";
16
+ export type { GoTo } from "./go.js";
15
17
  export type { ActsDoor, AdministeredModule, DrawnBox, GraviewContextValue, GraviewProviderProps, PointerMenu, SceneHandle, Scheme, Seat, ViewMode } from "./context.js";
16
18
  export { anchorOf, AUDIENCE_ROW, HEARTBEAT_MS, placeOthers, PRESENCE_SETTINGS, SHARE_OVER, SHARE_WHERE, tabSession, usePresenceState } from "./presence.js";
17
19
  export type { Placed, PresenceInputs, PresenceState } from "./presence.js";
@@ -36,4 +38,6 @@ export type { DrawnOptions, DrawnSize } from "./drawn.js";
36
38
  export { createMotionStore, useSceneStill } from "./motion.js";
37
39
  export type { MotionStore } from "./motion.js";
38
40
  export { landingIn, useTheKeyboardLandsSomewhere } from "./keyboard.js";
41
+ export { inTopLayer, placePane, POPOVER_STYLE, POPOVERS, raiseOverPopovers, usePopover, useTopLayer } from "./popover.js";
42
+ export type { PlaceOptions, Popover, PopoverAnchor, PopoverName, PopoverOptions } from "./popover.js";
39
43
  //# sourceMappingURL=provider.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,4BAA4B,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC7N,YAAY,EAAE,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,EAAE,mBAAmB,EAAE,oBAAoB,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AACxK,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC5J,YAAY,EAAE,MAAM,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AAC3E,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AACtF,YAAY,EAAE,UAAU,EAAE,SAAS,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAC;AAC9E,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAClD,YAAY,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAC3F,YAAY,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAClD,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAC3G,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,iBAAiB,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACvH,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AACtE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACzE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAC1F,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AACnF,OAAO,EACL,UAAU,EACV,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,UAAU,EACV,YAAY,EACZ,OAAO,EACP,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAC/D,YAAY,EAAE,GAAG,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AACtE,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAC1D,YAAY,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC/D,YAAY,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"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"}
package/dist/provider.js CHANGED
@@ -11,7 +11,8 @@
11
11
  * with the face that draws it. Nothing in this module's files may import
12
12
  * the scene's, or `@graview/react`.
13
13
  */
14
- export { GraviewProvider, ROBOT_REST_MS, useFound, useGraph, useGraview, useGraviewIfAny, useNode, useRobots, useScenePointer, useTheWatchKnowsWhatIsUnseen, useViewMode, useWhereIs, ViewModeProvider } from "./context.js";
14
+ export { GraviewProvider, openingView, ROBOT_REST_MS, useFound, useGraph, useGraview, useGraviewIfAny, useNode, useRobots, useScenePointer, useTheWatchKnowsWhatIsUnseen, useViewMode, useWhereIs, ViewModeProvider } from "./context.js";
15
+ export { GoToContext, useGoTo } from "./go.js";
15
16
  export { anchorOf, AUDIENCE_ROW, HEARTBEAT_MS, placeOthers, PRESENCE_SETTINGS, SHARE_OVER, SHARE_WHERE, tabSession, usePresenceState } from "./presence.js";
16
17
  export { foldRobots, participantOf, standingFor, VISIT_EACH_UP_TO } from "./robot.js";
17
18
  export { createPointerStore } from "./pointer.js";
@@ -25,4 +26,5 @@ export { kitConnector, useKit } from "./kit.js";
25
26
  export { useDrawnSize, useTextMeasure } from "./drawn.js";
26
27
  export { createMotionStore, useSceneStill } from "./motion.js";
27
28
  export { landingIn, useTheKeyboardLandsSomewhere } from "./keyboard.js";
29
+ export { inTopLayer, placePane, POPOVER_STYLE, POPOVERS, raiseOverPopovers, usePopover, useTopLayer } from "./popover.js";
28
30
  //# sourceMappingURL=provider.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,eAAe,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,4BAA4B,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAE7N,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE5J,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAE3F,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE3G,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE1F,OAAO,EACL,UAAU,EACV,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,UAAU,EACV,YAAY,EACZ,OAAO,EACP,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,SAAS,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC"}
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,EAAE,eAAe,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,eAAe,EAAE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,4BAA4B,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAC1O,OAAO,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAG/C,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,YAAY,EAAE,WAAW,EAAE,iBAAiB,EAAE,UAAU,EAAE,WAAW,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAE5J,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEtF,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AAElD,OAAO,EAAE,aAAa,EAAE,aAAa,EAAE,WAAW,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAE3F,OAAO,EAAE,WAAW,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE3G,OAAO,EAAE,kBAAkB,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEtE,OAAO,EAAE,gBAAgB,EAAE,YAAY,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE1F,OAAO,EACL,UAAU,EACV,aAAa,EACb,YAAY,EACZ,iBAAiB,EACjB,UAAU,EACV,aAAa,EACb,SAAS,EACT,aAAa,EACb,UAAU,EACV,YAAY,EACZ,OAAO,EACP,UAAU,EACV,aAAa,GACd,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D,OAAO,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAE1D,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAE/D,OAAO,EAAE,SAAS,EAAE,4BAA4B,EAAE,MAAM,eAAe,CAAC;AACxE,OAAO,EAAE,UAAU,EAAE,SAAS,EAAE,aAAa,EAAE,QAAQ,EAAE,iBAAiB,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC"}
package/dist/rails.d.ts CHANGED
@@ -3,8 +3,12 @@
3
3
  * A full-size scene reserves 264 and 128; a narrow one, where the panes
4
4
  * are sheets rather than rails, keeps only the corner the altitude control
5
5
  * stands in.
6
+ *
7
+ * `left`, where the seat has said how much of the left edge it takes (FR-78):
8
+ * put away to a tab, laid over the picture, or hidden, it takes nothing of
9
+ * the picture's own box, and the city has the room.
6
10
  */
7
- export declare function railInset(width: number): {
11
+ export declare function railInset(width: number, left?: number | null): {
8
12
  left: number;
9
13
  right: number;
10
14
  };
@@ -1 +1 @@
1
- {"version":3,"file":"rails.d.ts","sourceRoot":"","sources":["../src/rails.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAMxE"}
1
+ {"version":3,"file":"rails.d.ts","sourceRoot":"","sources":["../src/rails.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,IAAI,GAAE,MAAM,GAAG,IAAW,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAOpG"}
package/dist/rails.js CHANGED
@@ -3,10 +3,16 @@
3
3
  * A full-size scene reserves 264 and 128; a narrow one, where the panes
4
4
  * are sheets rather than rails, keeps only the corner the altitude control
5
5
  * stands in.
6
+ *
7
+ * `left`, where the seat has said how much of the left edge it takes (FR-78):
8
+ * put away to a tab, laid over the picture, or hidden, it takes nothing of
9
+ * the picture's own box, and the city has the room.
6
10
  */
7
- export function railInset(width) {
11
+ export function railInset(width, left = null) {
8
12
  if (width < 640)
9
- return { left: 8, right: 56 };
13
+ return { left: left ?? 8, right: 56 };
14
+ if (left !== null)
15
+ return { left, right: Math.round(Math.min(128, width * 0.107)) };
10
16
  return {
11
17
  left: Math.round(Math.min(264, width * 0.22)),
12
18
  right: Math.round(Math.min(128, width * 0.107)),
package/dist/rails.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"rails.js","sourceRoot":"","sources":["../src/rails.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa;IACrC,IAAI,KAAK,GAAG,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC/C,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;QAC7C,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC;KAChD,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"rails.js","sourceRoot":"","sources":["../src/rails.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,UAAU,SAAS,CAAC,KAAa,EAAE,OAAsB,IAAI;IACjE,IAAI,KAAK,GAAG,GAAG;QAAE,OAAO,EAAE,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IACvD,IAAI,IAAI,KAAK,IAAI;QAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC,EAAE,CAAC;IACpF,OAAO;QACL,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC;QAC7C,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC;KAChD,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"resolved-view.d.ts","sourceRoot":"","sources":["../src/resolved-view.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAqB,MAAM,eAAe,CAAC;AAG1F,OAAO,EAA8C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAGnF,OAAO,EAAoD,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAG/F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,+BA4IjE;AAyCD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,EAKnB,OAAO,YAAY,CAAC;AAEzB;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAAE,EAChD,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,QAAQ,GACT,EAAE,iBAAiB,+BAoInB;AAED;;;;GAIG;AACH,eAAO,MAAM,KAAK;wBAC+B,MAAM;oBAAkB,OAAO;mBAAiB,MAAM,SAAS;EAI/G,CAAC;AA0BF;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ;mBAAqD,SAAS;EA+CjF,CAAC"}
1
+ {"version":3,"file":"resolved-view.d.ts","sourceRoot":"","sources":["../src/resolved-view.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAW,KAAK,SAAS,EAAE,KAAK,QAAQ,EAAqB,MAAM,eAAe,CAAC;AAG1F,OAAO,EAAyB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE9D,OAAO,EAAoD,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAI/F,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,SAAS,CAAC;IACzB,QAAQ,CAAC,IAAI,EAAE,QAAQ,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B,yEAAyE;IACzE,QAAQ,CAAC,QAAQ,CAAC,EAAE,QAAQ,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE;IAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAA;CAAE,+BAmGjE;AAyCD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,EAKnB,OAAO,YAAY,CAAC;AAEzB;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,CAAC,SAAS,SAAS,EAAE,EAChD,IAAI,EACJ,IAAI,EACJ,QAAQ,EACR,QAAQ,GACT,EAAE,iBAAiB,+BAoInB;AAED;;;;GAIG;AACH,eAAO,MAAM,KAAK;wBAC+B,MAAM;oBAAkB,OAAO;mBAAiB,MAAM,SAAS;EAI/G,CAAC;AA0BF;;;;;;;GAOG;AACH,eAAO,MAAM,QAAQ;mBAAqD,SAAS;EA+CjF,CAAC"}
@@ -2,10 +2,10 @@ import { jsxs as _jsxs, jsx as _jsx, Fragment as _Fragment } from "react/jsx-run
2
2
  import { counted } from "@graview/core";
3
3
  import { aggregateId, isAggregateId, kindCardId, kindOfCard, withFocus } from "@graview/layout/view";
4
4
  import { PLANE_STYLES } from "@graview/render";
5
- import { memo, useEffect, useMemo, useRef, useState } from "react";
6
- import { createPortal } from "react-dom";
5
+ import { memo, useMemo, useRef } from "react";
7
6
  import { useFlagged, useImplicated, useNavigation } from "./hooks.js";
8
7
  import { useFound, useGraph, useGraview, ViewModeProvider } from "./context.js";
8
+ import { POPOVER_STYLE, usePopover } from "./popover.js";
9
9
  import { ViewBoundary } from "./view-boundary.js";
10
10
  /**
11
11
  * THE DISTRICTS THE ROW COULD NOT HOLD, NAMED — BEHIND ONE PRESS.
@@ -29,52 +29,21 @@ import { ViewBoundary } from "./view-boundary.js";
29
29
  export function BeyondCard({ kinds }) {
30
30
  const { store } = useGraview();
31
31
  const { view, go } = useNavigation();
32
- const [open, setOpen] = useState(false);
33
32
  const card = useRef(null);
34
33
  /*
35
34
  * THE PANEL LEAVES THE PLANE. Drawn inside the card it sat on plane two,
36
35
  * and the focused card on plane zero painted over it — a menu nobody
37
- * could press. It is portalled onto the scene's ground, above every
38
- * plane, and placed by the card's own screen rectangle at the moment it
39
- * opens; a press anywhere else closes it before the scene can move.
36
+ * could press. It stands in the browser's top layer (FR-76), over every
37
+ * plane, every rail and the seat, hung from the "+N more" button and
38
+ * kept to the viewport. It is one of the family (FR-77): Escape or a
39
+ * press anywhere else closes it and gives the keyboard back to "+N more",
40
+ * opening it closes any other popover, and the keyboard goes in.
40
41
  */
41
- const [anchor, setAnchor] = useState(null);
42
- const place = () => {
43
- const box = card.current;
44
- const into = box?.closest(".graview-ground");
45
- if (!box || !into)
46
- return null;
47
- const mine = box.getBoundingClientRect();
48
- const ground = into.getBoundingClientRect();
49
- return { into, left: mine.left - ground.left, bottom: ground.bottom - mine.top + 6 };
50
- };
42
+ const popover = usePopover("districts", { align: "start" });
43
+ const open = popover.open;
51
44
  const plural = (kind) => store.schema.tryDefinition(kind)?.plural ?? `${kind}s`;
52
45
  const count = (kind) => store.graph.allNodes().filter((node) => node.kind === kind).length;
53
46
  const here = (kind) => !view.overview && view.focusId === aggregateId(kind);
54
- /* Escape, or a press anywhere else, closes it; the button keeps focus. */
55
- useEffect(() => {
56
- if (!open)
57
- return;
58
- const away = (event) => {
59
- const target = event.target;
60
- if (target?.closest(".graview-beyond-list, .graview-beyond"))
61
- return;
62
- setOpen(false);
63
- setAnchor(null);
64
- };
65
- const key = (event) => {
66
- if (event.key === "Escape") {
67
- setOpen(false);
68
- card.current?.querySelector(".graview-beyond-more")?.focus();
69
- }
70
- };
71
- document.addEventListener("pointerdown", away, true);
72
- document.addEventListener("keydown", key);
73
- return () => {
74
- document.removeEventListener("pointerdown", away, true);
75
- document.removeEventListener("keydown", key);
76
- };
77
- }, [open]);
78
47
  const going = kinds.filter((kind) => !here(kind));
79
48
  /*
80
49
  * CHOSEN, THE KEYBOARD GOES WITH IT. Choosing a district closes the menu
@@ -86,7 +55,7 @@ export function BeyondCard({ kinds }) {
86
55
  * this button while it is not.
87
56
  */
88
57
  const choose = (kind) => {
89
- setOpen(false);
58
+ popover.setOpen(false);
90
59
  const button = card.current?.querySelector(".graview-beyond-more") ?? null;
91
60
  if (!here(kind))
92
61
  go(withFocus(view, aggregateId(kind)));
@@ -102,15 +71,13 @@ export function BeyondCard({ kinds }) {
102
71
  };
103
72
  requestAnimationFrame(land);
104
73
  };
105
- return (_jsxs("div", { ref: card, className: "graview-beyond", "data-graview-beyond": kinds.length, "data-graview-beyond-open": open ? "" : undefined, children: [_jsxs("button", { type: "button", className: "graview-beyond-more", "data-testid": "beyond-more", "aria-expanded": open, "aria-haspopup": "menu", title: `${going.length} more district${going.length === 1 ? "" : "s"} — press to see them`, onPointerDown: (event) => event.stopPropagation(), onClick: (event) => {
74
+ return (_jsxs("div", { ref: card, className: "graview-beyond", "data-graview-beyond": kinds.length, "data-graview-beyond-open": open ? "" : undefined, children: [_jsxs("button", { type: "button", className: "graview-beyond-more", "data-testid": "beyond-more", ...popover.trigger, "aria-haspopup": "menu", title: `${going.length} more district${going.length === 1 ? "" : "s"} — press to see them`, onPointerDown: (event) => event.stopPropagation(), onClick: (event) => {
106
75
  event.stopPropagation();
107
- const next = !open;
108
- setAnchor(next ? place() : null);
109
- setOpen(next);
110
- }, children: [_jsxs("span", { className: "graview-beyond-count", children: ["+", going.length] }), _jsx("span", { className: "graview-beyond-word", children: "more" }), _jsx("span", { className: "graview-beyond-chevron", "aria-hidden": "true", children: open ? "▾" : "▴" })] }), open && anchor ? createPortal(_jsx("ul", { className: "graview-beyond-list", role: "menu", "aria-label": "The other districts", "data-testid": "beyond-list", "data-graview-overlay": "", style: { left: anchor.left, bottom: anchor.bottom }, onPointerDown: (event) => event.stopPropagation(), children: kinds.map((kind) => (_jsx("li", { role: "none", children: _jsxs("button", { type: "button", role: "menuitem", "data-graview-pick": kindCardId(kind), "aria-current": here(kind) ? "location" : undefined, title: here(kind) ? `${plural(kind)} — where you are` : `Go to ${plural(kind)}`, onPointerDown: (event) => event.stopPropagation(), onClick: (event) => {
76
+ popover.toggle();
77
+ }, children: [_jsxs("span", { className: "graview-beyond-count", children: ["+", going.length] }), _jsx("span", { className: "graview-beyond-word", children: "more" }), _jsx("span", { className: "graview-beyond-chevron", "aria-hidden": "true", children: open ? "▾" : "▴" })] }), open ? (_jsx("ul", { ...popover.pane, className: "graview-beyond-list", role: "menu", "aria-label": "The other districts", "data-testid": "beyond-list", style: POPOVER_STYLE, onPointerDown: (event) => event.stopPropagation(), children: kinds.map((kind) => (_jsx("li", { role: "none", children: _jsxs("button", { type: "button", role: "menuitem", "data-graview-pick": kindCardId(kind), "aria-current": here(kind) ? "location" : undefined, title: here(kind) ? `${plural(kind)} — where you are` : `Go to ${plural(kind)}`, onPointerDown: (event) => event.stopPropagation(), onClick: (event) => {
111
78
  event.stopPropagation();
112
79
  choose(kind);
113
- }, children: [_jsx("span", { className: "graview-beyond-name", children: plural(kind) }), _jsx("span", { className: "graview-beyond-tally", children: here(kind) ? "here" : count(kind) })] }) }, kind))) }), anchor.into) : open ? (_jsx("ul", { className: "graview-beyond-list", role: "menu", "aria-label": "The other districts", "data-testid": "beyond-list", children: kinds.map((kind) => (_jsx("li", { role: "none", children: _jsx("button", { type: "button", role: "menuitem", "data-graview-pick": kindCardId(kind), onClick: () => choose(kind), children: plural(kind) }) }, kind))) })) : null] }));
80
+ }, children: [_jsx("span", { className: "graview-beyond-name", children: plural(kind) }), _jsx("span", { className: "graview-beyond-tally", children: here(kind) ? "here" : count(kind) })] }) }, kind))) })) : null] }));
114
81
  }
115
82
  /**
116
83
  * WHETHER TWO FRAMES ASK FOR THE SAME PICTURE.