@graview/react 0.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 (147) hide show
  1. package/LICENSE +96 -0
  2. package/README.md +20 -0
  3. package/dist/activity.d.ts +113 -0
  4. package/dist/activity.d.ts.map +1 -0
  5. package/dist/activity.js +207 -0
  6. package/dist/activity.js.map +1 -0
  7. package/dist/animation.d.ts +64 -0
  8. package/dist/animation.d.ts.map +1 -0
  9. package/dist/animation.js +245 -0
  10. package/dist/animation.js.map +1 -0
  11. package/dist/captions.d.ts +43 -0
  12. package/dist/captions.d.ts.map +1 -0
  13. package/dist/captions.js +61 -0
  14. package/dist/captions.js.map +1 -0
  15. package/dist/channels.d.ts +15 -0
  16. package/dist/channels.d.ts.map +1 -0
  17. package/dist/channels.js +114 -0
  18. package/dist/channels.js.map +1 -0
  19. package/dist/connectors.d.ts +176 -0
  20. package/dist/connectors.d.ts.map +1 -0
  21. package/dist/connectors.js +837 -0
  22. package/dist/connectors.js.map +1 -0
  23. package/dist/context.d.ts +348 -0
  24. package/dist/context.d.ts.map +1 -0
  25. package/dist/context.js +568 -0
  26. package/dist/context.js.map +1 -0
  27. package/dist/drawn.d.ts +60 -0
  28. package/dist/drawn.d.ts.map +1 -0
  29. package/dist/drawn.js +58 -0
  30. package/dist/drawn.js.map +1 -0
  31. package/dist/edge-signs.d.ts +13 -0
  32. package/dist/edge-signs.d.ts.map +1 -0
  33. package/dist/edge-signs.js +76 -0
  34. package/dist/edge-signs.js.map +1 -0
  35. package/dist/hooks.d.ts +160 -0
  36. package/dist/hooks.d.ts.map +1 -0
  37. package/dist/hooks.js +457 -0
  38. package/dist/hooks.js.map +1 -0
  39. package/dist/index.d.ts +37 -0
  40. package/dist/index.d.ts.map +1 -0
  41. package/dist/index.js +22 -0
  42. package/dist/index.js.map +1 -0
  43. package/dist/keyboard.d.ts +5 -0
  44. package/dist/keyboard.d.ts.map +1 -0
  45. package/dist/keyboard.js +178 -0
  46. package/dist/keyboard.js.map +1 -0
  47. package/dist/kit.d.ts +10 -0
  48. package/dist/kit.d.ts.map +1 -0
  49. package/dist/kit.js +32 -0
  50. package/dist/kit.js.map +1 -0
  51. package/dist/local-intelligence.d.ts +31 -0
  52. package/dist/local-intelligence.d.ts.map +1 -0
  53. package/dist/local-intelligence.js +66 -0
  54. package/dist/local-intelligence.js.map +1 -0
  55. package/dist/motion.d.ts +17 -0
  56. package/dist/motion.d.ts.map +1 -0
  57. package/dist/motion.js +26 -0
  58. package/dist/motion.js.map +1 -0
  59. package/dist/occupants.d.ts +45 -0
  60. package/dist/occupants.d.ts.map +1 -0
  61. package/dist/occupants.js +57 -0
  62. package/dist/occupants.js.map +1 -0
  63. package/dist/parallel.d.ts +19 -0
  64. package/dist/parallel.d.ts.map +1 -0
  65. package/dist/parallel.js +30 -0
  66. package/dist/parallel.js.map +1 -0
  67. package/dist/picking.d.ts +30 -0
  68. package/dist/picking.d.ts.map +1 -0
  69. package/dist/picking.js +140 -0
  70. package/dist/picking.js.map +1 -0
  71. package/dist/plots.d.ts +106 -0
  72. package/dist/plots.d.ts.map +1 -0
  73. package/dist/plots.js +306 -0
  74. package/dist/plots.js.map +1 -0
  75. package/dist/pointer.d.ts +27 -0
  76. package/dist/pointer.d.ts.map +1 -0
  77. package/dist/pointer.js +39 -0
  78. package/dist/pointer.js.map +1 -0
  79. package/dist/presence.d.ts +110 -0
  80. package/dist/presence.d.ts.map +1 -0
  81. package/dist/presence.js +280 -0
  82. package/dist/presence.js.map +1 -0
  83. package/dist/rails.d.ts +11 -0
  84. package/dist/rails.d.ts.map +1 -0
  85. package/dist/rails.js +15 -0
  86. package/dist/rails.js.map +1 -0
  87. package/dist/resolved-view.d.ts +78 -0
  88. package/dist/resolved-view.d.ts.map +1 -0
  89. package/dist/resolved-view.js +365 -0
  90. package/dist/resolved-view.js.map +1 -0
  91. package/dist/robot.d.ts +114 -0
  92. package/dist/robot.d.ts.map +1 -0
  93. package/dist/robot.js +93 -0
  94. package/dist/robot.js.map +1 -0
  95. package/dist/routes.d.ts +50 -0
  96. package/dist/routes.d.ts.map +1 -0
  97. package/dist/routes.js +150 -0
  98. package/dist/routes.js.map +1 -0
  99. package/dist/scene-camera.d.ts +25 -0
  100. package/dist/scene-camera.d.ts.map +1 -0
  101. package/dist/scene-camera.js +130 -0
  102. package/dist/scene-camera.js.map +1 -0
  103. package/dist/scene-hand.d.ts +110 -0
  104. package/dist/scene-hand.d.ts.map +1 -0
  105. package/dist/scene-hand.js +317 -0
  106. package/dist/scene-hand.js.map +1 -0
  107. package/dist/scene-helpers.d.ts +46 -0
  108. package/dist/scene-helpers.d.ts.map +1 -0
  109. package/dist/scene-helpers.js +108 -0
  110. package/dist/scene-helpers.js.map +1 -0
  111. package/dist/scene-lines.d.ts +76 -0
  112. package/dist/scene-lines.d.ts.map +1 -0
  113. package/dist/scene-lines.js +578 -0
  114. package/dist/scene-lines.js.map +1 -0
  115. package/dist/scene-root.d.ts +71 -0
  116. package/dist/scene-root.d.ts.map +1 -0
  117. package/dist/scene-root.js +790 -0
  118. package/dist/scene-root.js.map +1 -0
  119. package/dist/scene.d.ts +17 -0
  120. package/dist/scene.d.ts.map +1 -0
  121. package/dist/scene.js +17 -0
  122. package/dist/scene.js.map +1 -0
  123. package/dist/seat-marks.d.ts +35 -0
  124. package/dist/seat-marks.d.ts.map +1 -0
  125. package/dist/seat-marks.js +43 -0
  126. package/dist/seat-marks.js.map +1 -0
  127. package/dist/settings.d.ts +30 -0
  128. package/dist/settings.d.ts.map +1 -0
  129. package/dist/settings.js +73 -0
  130. package/dist/settings.js.map +1 -0
  131. package/dist/view-boundary.d.ts +33 -0
  132. package/dist/view-boundary.d.ts.map +1 -0
  133. package/dist/view-boundary.js +53 -0
  134. package/dist/view-boundary.js.map +1 -0
  135. package/dist/view-host.d.ts +57 -0
  136. package/dist/view-host.d.ts.map +1 -0
  137. package/dist/view-host.js +474 -0
  138. package/dist/view-host.js.map +1 -0
  139. package/dist/view-registry.d.ts +122 -0
  140. package/dist/view-registry.d.ts.map +1 -0
  141. package/dist/view-registry.js +20 -0
  142. package/dist/view-registry.js.map +1 -0
  143. package/dist/where-drawn.d.ts +151 -0
  144. package/dist/where-drawn.d.ts.map +1 -0
  145. package/dist/where-drawn.js +231 -0
  146. package/dist/where-drawn.js.map +1 -0
  147. package/package.json +60 -0
@@ -0,0 +1,474 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { labelOf } from "@graview/core";
3
+ import { mixStyles, styleFor, transformFor, hueFor } from "@graview/render";
4
+ import { useEffect, useRef, useLayoutEffect, useState, } from "react";
5
+ import { useGraview } from "./context.js";
6
+ import { pickedFrom, usePickTargets } from "./picking.js";
7
+ import { WHO } from "./where-drawn.js";
8
+ import { cssTransform, planeShadow } from "./scene-helpers.js";
9
+ /**
10
+ * One view's box. Absolutely positioned so the canvas can place it, and sized
11
+ * so the capture texture matches the DOM exactly.
12
+ */
13
+ export function SceneViewHost({ node, useDom, touched, frontY, centreY, screen, onDrawnHeight, crowded, activity, scheme, canvasWidth, canvasHeight, selected, onSelect, onPick, onTravel, onMenu, selection, onJackIn, onDragStart, onDragMove, onDragEnd, swallowClick, children, }) {
14
+ // The tag's dot must agree with every other dot in a branded app.
15
+ const { brand: hostBrand, store: hostStore, actsDoor } = useGraview();
16
+ /*
17
+ * The name a screen reader reads for this box: the group's plural, or the
18
+ * node's own label — never the id, which is an address.
19
+ */
20
+ const hostName = node.beyond
21
+ ? /* Not a thing in the graph: the row saying what it could not hold. */
22
+ `${node.beyond.length} more district${node.beyond.length === 1 ? "" : "s"}`
23
+ : node.aggregate?.opens?.in === "place"
24
+ ? /* A band's group is heard with its count: "Single, 80 albums". */
25
+ `${node.aggregate.label}, ${node.aggregate.memberIds.length} ${node.aggregate.memberIds.length === 1 ? node.aggregate.kind.replace(/-/g, " ") : (hostStore.schema.tryDefinition(node.aggregate.kind)?.plural ?? `${node.aggregate.kind}s`).toLowerCase()}`
26
+ : node.aggregate
27
+ ? node.aggregate.label
28
+ : (() => {
29
+ const graphNode = hostStore.graph.getNode(node.id);
30
+ if (!graphNode)
31
+ return node.id;
32
+ return labelOf(hostStore.schema.tryDefinition(node.kind), graphNode);
33
+ })();
34
+ /*
35
+ * The tag hugs the PANEL, not the band slot. A host flex-centres a
36
+ * panel shorter than its slot, so a fixed top offset hung the tag in
37
+ * open ground above the card it names — measured against the drawn
38
+ * child instead, the same lesson every measured surface here learned.
39
+ */
40
+ const [tagAt, setTagAt] = useState(null);
41
+ const tagged = Math.round(node.plane) === 0 && !node.aggregate;
42
+ /*
43
+ * Measured when the panel's SIZE changes, not on every render — from the
44
+ * observer, when the layout is already clean, so the reads are free.
45
+ *
46
+ * It ran after every render and read two bounding boxes, and a host
47
+ * renders every frame of a transition — so every frame forced the browser
48
+ * to lay the whole scene out before it could paint it (docs/scale.md, a
49
+ * third of the frame landing on a hub). An observer reports once when it
50
+ * starts watching, after layout and before paint, so the tag is placed
51
+ * in its first frame without forcing one.
52
+ */
53
+ useLayoutEffect(() => {
54
+ if (!tagged)
55
+ return;
56
+ const host = ref.current;
57
+ if (!host)
58
+ return;
59
+ const place = () => {
60
+ /*
61
+ * The PANEL, never the tag itself.
62
+ *
63
+ * `firstElementChild` was the drawn panel right up until the view had
64
+ * nothing to draw — a focus on a node an act had just removed — and
65
+ * then the tag was the only child, so this measured the tag against
66
+ * its own host and moved it by the offset below, every render, until
67
+ * React gave up with "Maximum update depth exceeded" and blanked the
68
+ * page. A measurement that can read its own output has to say which
69
+ * child it means.
70
+ */
71
+ const child = [...host.children].find(
72
+ // An empty data attribute reads as "", so presence is the question.
73
+ (element) => element.dataset["graviewKindtag"] === undefined);
74
+ if (!child)
75
+ return;
76
+ /*
77
+ * Drawn boxes, in the host's own units. Offsets would ignore the
78
+ * natural box's centring and shrink (the stamp at altitude) and land
79
+ * the tag mid-card; a box difference includes them, and dividing by
80
+ * the host's drawn scale takes the plane's scale back out.
81
+ */
82
+ const hostBox = host.getBoundingClientRect();
83
+ const childBox = child.getBoundingClientRect();
84
+ const scale = host.offsetWidth > 0 ? hostBox.width / host.offsetWidth : 1;
85
+ const next = {
86
+ top: Math.round((childBox.top - hostBox.top) / scale) - 9,
87
+ right: Math.round((hostBox.right - childBox.right) / scale) + 14,
88
+ };
89
+ setTagAt((current) => current && current.top === next.top && current.right === next.right ? current : next);
90
+ };
91
+ if (typeof ResizeObserver === "undefined") {
92
+ place();
93
+ return;
94
+ }
95
+ const watch = new ResizeObserver(place);
96
+ watch.observe(host);
97
+ for (const element of host.children)
98
+ watch.observe(element);
99
+ return () => watch.disconnect();
100
+ }, [tagged, node.id]);
101
+ /*
102
+ * A node's depth is its plane, pulled forward by however near it sits
103
+ * within that plane.
104
+ *
105
+ * Mid-transition a plane is already fractional so the treatment is mixed
106
+ * rather than snapping, and `depth` uses the same machinery: a card at the
107
+ * near end of the arc is treated as 1.6 planes back rather than 2, which is
108
+ * what makes the arc curve away instead of lying flat.
109
+ */
110
+ const at = node.plane - (1 - (node.depth ?? 1)) * 0.55;
111
+ const lower = Math.max(0, Math.min(2, Math.floor(at)));
112
+ const upper = Math.max(0, Math.min(2, Math.ceil(at)));
113
+ const style = lower === upper
114
+ ? styleFor(lower, scheme)
115
+ : mixStyles(styleFor(lower, scheme), styleFor(upper, scheme), at - lower);
116
+ const transform = transformFor(style, node.x, node.y, canvasWidth, canvasHeight);
117
+ /*
118
+ * The blur is the NEAREST plane's, not a mix. It is under half a pixel,
119
+ * nobody can see it tween, and a filter whose radius changes is a filter
120
+ * repainted — every host, every frame of every transition
121
+ * (docs/scale.md). Snapped, it changes once, halfway.
122
+ */
123
+ const blur = styleFor(Math.max(0, Math.min(2, Math.round(at))), scheme).blur;
124
+ const ref = useRef(null);
125
+ usePickTargets(ref);
126
+ /*
127
+ * A view drawn smaller than it was designed for is SCALED, not re-solved.
128
+ *
129
+ * When the layout gives a node a natural size, the view lays itself out at
130
+ * that size and the whole result is transformed down into the slot. That is
131
+ * the same picture, smaller — which is what a captured texture would do on
132
+ * the GPU path anyway, and what keeps the shrunk interface an interface:
133
+ * every pick target inside it is still a real target, because nothing here
134
+ * is an image.
135
+ *
136
+ * Rendering into the slot instead is what broke it: a coverage matrix asked
137
+ * to lay itself out in a third of its width piled its rotated column
138
+ * headers into a corner and clipped its rows.
139
+ */
140
+ const natural = node.natural;
141
+ const shrink = natural
142
+ ? Math.min(node.width / natural.width, node.height / natural.height)
143
+ : 1;
144
+ /*
145
+ * A BILLBOARD REPORTS ITS PICTURE'S HEIGHT.
146
+ *
147
+ * The lens lays itself out in the natural box, as tall as the window, and
148
+ * a lens is built to fill what it is given: a header, then a scroll
149
+ * region that takes the rest. So neither the box nor the lens's own
150
+ * height says how tall the PICTURE is. What does: the extent of what is
151
+ * in flow, plus what every scroll region inside needs beyond what it has
152
+ * (negative when it has room to spare). From the whole box that comes to
153
+ * header-plus-rows; cut to that, the scroll region holds exactly its
154
+ * rows and the measure is its own fixed point. Watched for size and for
155
+ * content, because rows come and go without anything resizing; withdrawn
156
+ * when this box stops being the screen.
157
+ */
158
+ const naturalRef = useRef(null);
159
+ useEffect(() => {
160
+ if (!screen || !onDrawnHeight)
161
+ return;
162
+ const box = naturalRef.current;
163
+ if (!box || typeof ResizeObserver === "undefined")
164
+ return;
165
+ const measure = () => {
166
+ let extent = 0;
167
+ let wanted = 0;
168
+ for (const child of box.children) {
169
+ if (!(child instanceof HTMLElement) || child.classList.contains("graview-screen-fullscreen"))
170
+ continue;
171
+ extent = Math.max(extent, child.offsetTop + child.offsetHeight);
172
+ for (const el of [child, ...child.querySelectorAll("*")]) {
173
+ const overflow = getComputedStyle(el).overflowY;
174
+ if (overflow === "auto" || overflow === "scroll")
175
+ wanted += el.scrollHeight - el.clientHeight;
176
+ }
177
+ }
178
+ onDrawnHeight(extent + wanted);
179
+ };
180
+ let queued = 0;
181
+ const later = () => {
182
+ if (queued)
183
+ return;
184
+ queued = requestAnimationFrame(() => {
185
+ queued = 0;
186
+ measure();
187
+ });
188
+ };
189
+ measure();
190
+ const sizes = new ResizeObserver(later);
191
+ sizes.observe(box);
192
+ for (const child of box.children)
193
+ sizes.observe(child);
194
+ const content = new MutationObserver(later);
195
+ content.observe(box, { childList: true, subtree: true, characterData: true, attributes: true });
196
+ return () => {
197
+ if (queued)
198
+ cancelAnimationFrame(queued);
199
+ sizes.disconnect();
200
+ content.disconnect();
201
+ onDrawnHeight(undefined);
202
+ };
203
+ }, [screen, onDrawnHeight, node.id]);
204
+ const domOnly = useDom
205
+ ? {
206
+ transform: cssTransform(transform),
207
+ transformOrigin: "0 0",
208
+ filter: blur > 0 ? `blur(${blur}px)` : undefined,
209
+ // Recession dims toward the ground; entering and leaving nodes carry
210
+ // their own fade on top of it.
211
+ opacity: (1 - style.falloff * 0.55) * (node.opacity ?? 1),
212
+ /*
213
+ * Depth is handed DOWN as the elevation token, not painted on the
214
+ * host.
215
+ *
216
+ * A host box-shadow outlines the box the layout allotted, which is
217
+ * only the same shape as the view when the view fills it. Once a
218
+ * detail panel sized to its own content, every focused node picked
219
+ * up a large ghost rectangle behind it. Setting the token means the
220
+ * panel casts the plane's shadow from its own edges — and any view
221
+ * built on `Panel` gets it without knowing planes exist.
222
+ */
223
+ ["--graview-lift-low"]: planeShadow(style.shadow, scheme),
224
+ ...(frontY !== undefined ? { ["--graview-front-y"]: `${frontY.toFixed(1)}px` } : {}),
225
+ ...(centreY !== undefined ? { ["--graview-centre-y"]: `${centreY.toFixed(1)}px` } : {}),
226
+ }
227
+ : // The GPU path does NOT fade the host: the shader owns opacity there,
228
+ // and applying it in both places made an entering view fade as
229
+ // opacity² — visibly faster and dimmer than the DOM path, so the two
230
+ // renderers disagreed about the same transition. It also meant a view
231
+ // captured mid-fade baked its own transparency into the texture.
232
+ {};
233
+ return (_jsxs("div", { ref: ref, "data-graview-view": node.id, "data-graview-plane": Math.round(node.plane), "data-graview-selected": selected || undefined, "data-graview-touched": touched || undefined, "data-graview-plot": frontY !== undefined ? "" : undefined, "data-graview-screen": screen ? "" : undefined, "data-graview-nested": node.nestedUnder ?? undefined, "data-graview-crowded": crowded || undefined, "data-graview-pinned": node.pinned || undefined, "data-graview-activity": activity ? activity.manner : undefined, "data-graview-wrote": activity?.wrote || undefined, "data-graview-read": activity && !activity.wrote ? true : undefined, "data-graview-broke": activity?.broke || undefined,
234
+ /*
235
+ * "Open X" only where clicking raises X. On plane 0 the group IS what
236
+ * you are looking at, so the tooltip promised something clicking does
237
+ * not do — and it shadowed the more specific titles a view puts on its
238
+ * own contents.
239
+ */
240
+ /*
241
+ * While something is happening here, the tooltip says WHAT — the
242
+ * intent the op recorded, in the app's own words. Watching should not
243
+ * require opening the activity list to find out what the light meant.
244
+ */
245
+ title: activity
246
+ ? `${WHO[activity.manner]} ${activity.wrote ? "changed this" : "read this"}: ${activity.intent}`
247
+ : node.aggregate && Math.round(node.plane) !== 0
248
+ ? `Open ${node.aggregate.label}`
249
+ : undefined, role: "group", "aria-label": hostName, "aria-keyshortcuts": actsDoor && !node.beyond ? actsDoor.key : undefined, tabIndex: 0, onPointerDown: onDragStart, onPointerMove: onDragMove, onPointerUp: onDragEnd, onPointerCancel: onDragEnd, onClick: (event) => {
250
+ // A drag that ends on a card must not also select it.
251
+ if (swallowClick.current)
252
+ return;
253
+ /*
254
+ * A CONTROL INSIDE A VIEW HAS ITS OWN MEANING, and selecting the
255
+ * card it sits on is not it.
256
+ *
257
+ * The keyboard path below has said so since it was written; the
258
+ * pointer path had not, because until a view drew a real control
259
+ * nothing noticed. The calendar draws several — previous, next,
260
+ * today, the range, "+3 more" — and pressing any of them also
261
+ * selected every task in the district the calendar was drawing, so
262
+ * changing the month lit up the whole month.
263
+ */
264
+ const inControl = event.target?.closest("input, textarea, select, button, a[href], [contenteditable='true']");
265
+ if (inControl && !inControl.hasAttribute("data-graview-pick"))
266
+ return;
267
+ const additive = event.metaKey || event.shiftKey;
268
+ /*
269
+ * A view may nominate its own inner targets.
270
+ *
271
+ * Any element carrying `data-graview-pick="<node id>"` is a real
272
+ * thing in the graph, and clicking it means that thing — not the
273
+ * view that happens to be drawing it. One rule, in one place, and
274
+ * every view gets it: a span in the calendar, a row in a roster, a
275
+ * chip in a summary.
276
+ *
277
+ * Without this, clicking an event in the week could only ever mean
278
+ * "the week", which is why clicking an event appeared to do nothing.
279
+ */
280
+ const picked = pickedFrom(event.target);
281
+ if (picked && picked !== node.id) {
282
+ event.stopPropagation();
283
+ onPick(picked, additive);
284
+ return;
285
+ }
286
+ onSelect(additive);
287
+ }, onKeyDown: (event) => {
288
+ /*
289
+ * ITS ACTS, ONE KEY AWAY. The keyboard's right-click: what the key
290
+ * lands on is chosen, as a right-click chooses it, and the seat
291
+ * opens on its acts with the keyboard in them. Only on the card
292
+ * itself — a letter typed into a field inside it is a letter.
293
+ */
294
+ if (actsDoor &&
295
+ !node.beyond &&
296
+ event.key.toLowerCase() === actsDoor.key.toLowerCase() &&
297
+ !event.metaKey &&
298
+ !event.ctrlKey &&
299
+ !event.altKey &&
300
+ !event.target?.closest("input, textarea, select, [contenteditable='true']")) {
301
+ event.preventDefault();
302
+ event.stopPropagation();
303
+ const on = pickedFrom(event.target) ?? node.id;
304
+ if (!selection.includes(on))
305
+ onPick(on, false);
306
+ // Back to what the keyboard stood on — the card, or the mark inside it it had reached.
307
+ actsDoor.open(event.target instanceof HTMLElement ? event.target : event.currentTarget);
308
+ return;
309
+ }
310
+ if (event.key !== "Enter" && event.key !== " ")
311
+ return;
312
+ /*
313
+ * NEVER STEAL A KEY FROM A CONTROL THAT HAS ITS OWN MEANING FOR IT.
314
+ *
315
+ * A card is a target, and so are the pick marks a view draws inside
316
+ * it — but a real control is not. Preventing the default before
317
+ * asking swallowed Enter inside the title's own editor, so renaming
318
+ * a record in place stopped committing: the field stayed open and
319
+ * nothing was written. `pnpm remember` is what noticed.
320
+ */
321
+ const inControl = event.target?.closest("input, textarea, select, button, [contenteditable='true']");
322
+ if (inControl)
323
+ return;
324
+ const picked = pickedFrom(event.target);
325
+ event.preventDefault();
326
+ event.stopPropagation();
327
+ /*
328
+ * THE CARD ITSELF ANSWERS THE KEYBOARD.
329
+ *
330
+ * It was a tab stop that did nothing: the handler returned unless the
331
+ * key had landed on an inner pick target, on the grounds that the
332
+ * host "has its own meaning" — which was true, and reachable only
333
+ * with a pointer. On a blank app that is the whole of it. The one
334
+ * district is the only thing on screen, selecting it is what opens
335
+ * the strip, and the strip is where the first act lives, so a
336
+ * keyboard alone could not add the first record to a new product.
337
+ *
338
+ * Enter on the host does what a click on it does; Enter again on a
339
+ * card already selected alone does what the second click does — the
340
+ * same two-step the inner targets have.
341
+ */
342
+ if (!picked || picked === node.id) {
343
+ const already = selection.length === 1 && selection[0] === node.id;
344
+ if (already && !event.metaKey && !event.shiftKey)
345
+ onJackIn();
346
+ else
347
+ onSelect(event.metaKey || event.shiftKey);
348
+ return;
349
+ }
350
+ /*
351
+ * Enter selects; Enter again on something already selected alone
352
+ * travels. The keyboard needs the same two-step the pointer has, and
353
+ * a modifier would have been a worse answer than repeating yourself.
354
+ */
355
+ const already = selection.length === 1 && selection[0] === picked;
356
+ if (already && !event.metaKey && !event.shiftKey)
357
+ onTravel(picked);
358
+ else
359
+ onPick(picked, event.metaKey || event.shiftKey);
360
+ }, onContextMenu: (event) => {
361
+ const picked = pickedFrom(event.target);
362
+ event.preventDefault();
363
+ event.stopPropagation();
364
+ /*
365
+ * Right-click SELECTS, always — through onPick, never onSelect,
366
+ * because onSelect's kind-card branch toggles the raised relation
367
+ * and returns without selecting, which opened a menu about nothing
368
+ * (and quietly raised People on the way).
369
+ */
370
+ const on = picked && picked !== node.id ? picked : node.id;
371
+ onPick(on, false);
372
+ /*
373
+ * The menu is about THIS, and says so. Without the name the
374
+ * derivation could only rank by the selection, and a rule that
375
+ * implicates several nodes in one violation put somebody else's
376
+ * repair at the top of the menu you opened on yours.
377
+ */
378
+ onMenu({ x: event.clientX, y: event.clientY, on });
379
+ }, onDoubleClick: (event) => {
380
+ const picked = pickedFrom(event.target);
381
+ if (picked && picked !== node.id) {
382
+ event.stopPropagation();
383
+ onTravel(picked);
384
+ return;
385
+ }
386
+ onJackIn();
387
+ }, style: {
388
+ position: "absolute",
389
+ /*
390
+ * On the capture path the host is OUT of hit-testing entirely.
391
+ *
392
+ * This is the fix for the defect that kept the GPU path off by
393
+ * default. It was recorded as "a click crashes the renderer process",
394
+ * and that was a symptom rather than the cause: bisected in Chromium
395
+ * 154, a plain HOVER over a captured view brings the process down just
396
+ * as reliably, while selecting the same node from the keyboard does
397
+ * not. What is fatal is the browser's own hit-test descending into a
398
+ * `layoutsubtree` canvas child.
399
+ *
400
+ * Nothing is lost by removing it. `updateElementGeometry` does not
401
+ * redirect hit-testing in this build, so a DOM hit-test on a captured
402
+ * view was already returning the wrong answer — it reported the box
403
+ * where the element was LAID OUT rather than where it was DRAWN, which
404
+ * is why `PointerRouter` exists at all. The compositor already runs one
405
+ * on the canvas; this stops the platform racing it into a crash.
406
+ *
407
+ * Keyboard reach and the accessibility tree are untouched:
408
+ * `pointer-events` says nothing about focus, and the views stay real,
409
+ * focusable DOM.
410
+ *
411
+ * On the DOM path the theme narrows the host's hit area to its drawn
412
+ * content (`[data-graview-stage="dom"] [data-graview-view]`): the
413
+ * box is the layout's, the target is the view's.
414
+ */
415
+ ...(useDom ? {} : { pointerEvents: "none" }),
416
+ // Each host sits at its own layout position, on BOTH paths.
417
+ //
418
+ // Under `layoutsubtree` every child is laid out at the canvas origin,
419
+ // so hosts pinned to 0,0 pile up on each other and only some of them
420
+ // end up with usable paint records — five views captured completely
421
+ // blank because of it. Giving each its own box keeps them distinct
422
+ // for the capture. The GPU still draws each wherever its plane
423
+ // transform says; this only decides what gets rasterised.
424
+ // Nearer planes paint over further ones — and an OPENED district
425
+ // comes to the front outright: its roster grows over whatever is
426
+ // beside it, and a chip half-hidden behind the live view is a chip
427
+ // nobody can press.
428
+ zIndex: node.opened ? 11 : 10 - Math.round(node.plane),
429
+ left: useDom ? 0 : Math.round(node.x),
430
+ top: useDom ? 0 : Math.round(node.y),
431
+ // Whole pixels, matching what the renderer allocates a texture for.
432
+ // A host of height 399.4 rasterises into 400 rows; a texture sized
433
+ // from the rounded 399 rejects the copy, and the view keeps whatever
434
+ // was in the texture before — silently.
435
+ width: Math.round(node.width),
436
+ height: Math.round(node.height),
437
+ boxSizing: "border-box",
438
+ // A view that sizes to its content is centred in the box the layout
439
+ // gave it, rather than pinned to the top with the remainder left as
440
+ // dead white space.
441
+ display: "flex",
442
+ flexDirection: "column",
443
+ justifyContent: "center",
444
+ ...domOnly,
445
+ }, children: [natural ? (
446
+ /*
447
+ * Centred on the slot and scaled about its own middle, so the
448
+ * proportions the view chose survive a slot that does not share them.
449
+ * `position: absolute` keeps the natural box out of the host's flow —
450
+ * it must not be able to push the host's own geometry around, since
451
+ * the capture allocates a texture from that.
452
+ */
453
+ _jsx("div", { ref: naturalRef, "data-graview-natural": `${Math.round(natural.width)}x${Math.round(natural.height)}`, style: {
454
+ position: "absolute",
455
+ left: "50%",
456
+ top: "50%",
457
+ width: natural.width,
458
+ height: natural.height,
459
+ transform: `translate(-50%, -50%) scale(${shrink})`,
460
+ transformOrigin: "50% 50%",
461
+ display: "flex",
462
+ flexDirection: "column",
463
+ }, children: children })) : (children), Math.round(node.plane) === 0 && !node.aggregate ? (_jsxs("span", { "data-graview-kindtag": "", className: "graview-kind-tag", "aria-hidden": "true", style: {
464
+ ...(tagAt ?? {}),
465
+ ["--graview-hue"]: Math.round(hueFor(node.kind, hostBrand?.accents)),
466
+ }, children: [_jsx("span", { style: {
467
+ width: 6,
468
+ height: 6,
469
+ borderRadius: 999,
470
+ flex: "0 0 auto",
471
+ background: `hsl(${Math.round(hueFor(node.kind, hostBrand?.accents))} 55% var(--graview-tint-lightness) / 0.9)`,
472
+ } }), node.kind] })) : null] }));
473
+ }
474
+ //# sourceMappingURL=view-host.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-host.js","sourceRoot":"","sources":["../src/view-host.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,122 @@
1
+ import { type AnySchema, type Cardinality, type Fidelity, type KindOfSchema, type NodeOfKind, type NodeOfSchema, type ViewCell, type ViewMeta, type ViewRegistry } from "@graview/core";
2
+ import type { ComponentType } from "react";
3
+ import type { ViewMode } from "./context.js";
4
+ /**
5
+ * What a view receives. Deliberately small: a node (or a group of them), how
6
+ * it is being drawn, and whether it is selected.
7
+ *
8
+ * Everything else a view needs it gets from ordinary hooks, because views are
9
+ * ordinary React components. That is the entire reason the capture approach
10
+ * is worth its cost — authors write normal components, not a scene DSL.
11
+ */
12
+ export interface ViewProps<S extends AnySchema, K extends KindOfSchema<S> = KindOfSchema<S>> {
13
+ /** The node, for a `one` view. */
14
+ readonly node?: NodeOfKind<S, K>;
15
+ /** The members, for a `many` view standing in for a kind. */
16
+ readonly nodes?: readonly NodeOfSchema<S>[];
17
+ /** Plural label for an aggregate, from the kind's declaration. */
18
+ readonly label?: string;
19
+ /**
20
+ * THE MOST THIS PICTURE SHOULD DRAW (docs/scale.md). Set where the room is
21
+ * small — a drive-in's thumbnail hands a lens its 24 most relevant members
22
+ * and says so. A lens that reads the store for more than `nodes` (a
23
+ * coverage's columns) holds itself to it; any lens handed fewer than
24
+ * `total` says how many more there are. Absent: the picture is the
25
+ * person's, and draws what it draws.
26
+ */
27
+ readonly budget?: number;
28
+ /** How many members there are in all, when `nodes` is fewer. */
29
+ readonly total?: number;
30
+ readonly fidelity: Fidelity;
31
+ readonly cardinality: Cardinality;
32
+ /**
33
+ * Captured into the scene, or lifted out as a full page. A view MUST render
34
+ * correctly either way; jacking in is a familiarity affordance, not an
35
+ * escape hatch from a scene that does not work.
36
+ */
37
+ readonly mode: ViewMode;
38
+ readonly selected: boolean;
39
+ /**
40
+ * Ids the current selection reaches — itself plus everything one edge
41
+ * away. Absent or empty means nothing is selected, which a view must read
42
+ * as "no emphasis" rather than "nothing is related".
43
+ */
44
+ readonly implicated?: readonly string[];
45
+ /**
46
+ * Ids implicated in a current invariant violation, so a view can mark them
47
+ * where they actually are. A problem you can only find through a list is a
48
+ * problem you have to go looking for.
49
+ */
50
+ readonly flagged?: readonly string[];
51
+ /** This group's members are currently raised onto the relation plane. */
52
+ readonly raised?: boolean;
53
+ /** This group is the kind currently in focus. */
54
+ readonly focused?: boolean;
55
+ /** The aggregate is opened in place, showing its members (the ring). */
56
+ readonly opened?: boolean;
57
+ /** The rows of members an opened district has room for (the layout's `openedRows`). */
58
+ readonly openedRows?: number;
59
+ /**
60
+ * The district's address in the city, when it is drawn at altitude: its
61
+ * corner in lattice cells and how many cells it takes on a side today —
62
+ * which is how many buildings a row holds when it is opened.
63
+ */
64
+ readonly plot?: {
65
+ readonly col: number;
66
+ readonly row: number;
67
+ readonly side: number;
68
+ };
69
+ /** Members behind the horizon: retired, counted, one step away. */
70
+ readonly retired?: number;
71
+ /**
72
+ * How near this kind is to the one in focus: `primary` is one declared edge
73
+ * away, `secondary` is further. Absent when nothing is focused, and when
74
+ * the focus touches nothing — a strip where every card is secondary says
75
+ * no more than one where none is.
76
+ *
77
+ * A view is expected to read it as EMPHASIS, not as a filter: a secondary
78
+ * card is still the same card, quieter.
79
+ */
80
+ readonly rank?: "primary" | "secondary";
81
+ /** Drawn tucked behind another kind's card, because it is reachable only through it. */
82
+ readonly nestedUnder?: string;
83
+ /**
84
+ * The app registered a view of its own for this kind, rather than leaving
85
+ * it on the framework's generic one — so there is a picture to go into.
86
+ *
87
+ * Derived rather than declared: `registerDefaultViews` marks what it
88
+ * registers, and an app's own registration replaces it. True the moment
89
+ * someone writes a lens, false the moment they remove it.
90
+ */
91
+ readonly hasOwnView?: boolean;
92
+ }
93
+ export type ViewComponent<S extends AnySchema, K extends KindOfSchema<S> = KindOfSchema<S>> = ComponentType<ViewProps<S, K>>;
94
+ export interface ReactViewRegistry<S extends AnySchema> extends ViewRegistry<S, ViewComponent<S>> {
95
+ /**
96
+ * Registering a view for a kind the schema never declared is a TYPECHECK
97
+ * failure — `K` is constrained to the schema's kinds, so the mistake
98
+ * surfaces at build time rather than at render.
99
+ *
100
+ * A view written over the whole schema — every lens is, and it is what
101
+ * `graview-lens` tells an app to write — registers on any one kind
102
+ * without a cast. React's `FunctionComponent<P>` is covariant in `P`
103
+ * (its `propTypes`), so a `ViewComponent<S>` was not assignable to
104
+ * `ViewComponent<S, "plot">` and every lens in the framework's own apps
105
+ * carried `as ViewComponent<S>` to get past it; a project following the
106
+ * skill verbatim did not typecheck.
107
+ */
108
+ register<K extends KindOfSchema<S>>(kind: K, cell: ViewCell, view: ViewComponent<S, K> | ViewComponent<S>, meta?: ViewMeta): ReactViewRegistry<S>;
109
+ }
110
+ export declare function createViews<S extends AnySchema>(schema: S): ReactViewRegistry<S>;
111
+ export type { Cardinality, Fidelity, ViewCell };
112
+ /**
113
+ * The mark a framework-supplied view carries, so a scene can tell a group
114
+ * shown by the framework's own list from one an app gave a picture of its
115
+ * own. From altitude the first is its district; the second keeps its card.
116
+ */
117
+ export declare const DEFAULT_VIEW: unique symbol;
118
+ /** Marks a view as the framework's own. Returns the same component. */
119
+ export declare function markDefaultView<V extends object>(view: V): V;
120
+ /** Whether a view is the framework's own rather than the app's. */
121
+ export declare function isDefaultView(view: unknown): boolean;
122
+ //# sourceMappingURL=view-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-registry.d.ts","sourceRoot":"","sources":["../src/view-registry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import { createViewRegistry, } from "@graview/core";
2
+ export function createViews(schema) {
3
+ return createViewRegistry(schema);
4
+ }
5
+ /**
6
+ * The mark a framework-supplied view carries, so a scene can tell a group
7
+ * shown by the framework's own list from one an app gave a picture of its
8
+ * own. From altitude the first is its district; the second keeps its card.
9
+ */
10
+ export const DEFAULT_VIEW = Symbol.for("graview.default-view");
11
+ /** Marks a view as the framework's own. Returns the same component. */
12
+ export function markDefaultView(view) {
13
+ Object.defineProperty(view, DEFAULT_VIEW, { value: true, enumerable: false });
14
+ return view;
15
+ }
16
+ /** Whether a view is the framework's own rather than the app's. */
17
+ export function isDefaultView(view) {
18
+ return typeof view === "function" && view[DEFAULT_VIEW] === true;
19
+ }
20
+ //# sourceMappingURL=view-registry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"view-registry.js","sourceRoot":"","sources":["../src/view-registry.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,kBAAkB,GAUnB,MAAM,eAAe,CAAC;AAsHvB,MAAM,UAAU,WAAW,CAAsB,MAAS;IACxD,OAAO,kBAAkB,CAAsB,MAAM,CAAyB,CAAC;AACjF,CAAC;AAID;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAkB,MAAM,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;AAE9E,uEAAuE;AACvE,MAAM,UAAU,eAAe,CAAmB,IAAO;IACvD,MAAM,CAAC,cAAc,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,CAAC;IAC9E,OAAO,IAAI,CAAC;AACd,CAAC;AAED,mEAAmE;AACnE,MAAM,UAAU,aAAa,CAAC,IAAa;IACzC,OAAO,OAAO,IAAI,KAAK,UAAU,IAAK,IAAqC,CAAC,YAAY,CAAC,KAAK,IAAI,CAAC;AACrG,CAAC"}