@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,140 @@
1
+ import { useEffect } from "react";
2
+ /**
3
+ * The one rule that makes anything a view drew into a real target.
4
+ *
5
+ * A view marks an element with `data-graview-pick="<node id>"` and that is the
6
+ * WHOLE contract: whatever surface the view is drawn on routes the gesture to
7
+ * that node. Which surface is the part that was wrong — the rule lived inside
8
+ * the scene's host, so a view lifted out into a full page kept its marks and
9
+ * lost its behaviour. Every chip on it was a button-shaped thing that did
10
+ * nothing, which is precisely the "I clicked it and nothing happened" the
11
+ * marks exist to prevent.
12
+ *
13
+ * So it lives here, and both surfaces use it.
14
+ */
15
+ /** The node a pointer or key event is really about, if any. */
16
+ export function pickedFrom(target) {
17
+ return (target?.closest?.("[data-graview-pick]")?.getAttribute("data-graview-pick") ?? null);
18
+ }
19
+ /**
20
+ * Makes every `data-graview-pick` element inside a host a real control.
21
+ *
22
+ * Having made clicking the primary way to move through the graph, leaving
23
+ * those targets unreachable by keyboard would make the primary interaction
24
+ * mouse-only.
25
+ *
26
+ * Set as attributes rather than as props because the elements belong to
27
+ * whatever view drew them; React is not managing these, so there is nothing
28
+ * to fight over.
29
+ */
30
+ export function usePickTargets(ref) {
31
+ /*
32
+ * WHEN THE CONTENT CHANGES, not after every render. This ran on every
33
+ * render of every host — every frame of a transition, for every card —
34
+ * scanning each subtree for marks that had not moved (docs/scale.md). The
35
+ * marks only change when a view draws something new, so the scan runs
36
+ * when the host mounts and when elements are added under it, at most
37
+ * once a frame.
38
+ */
39
+ useEffect(() => {
40
+ const host = ref.current;
41
+ if (!host)
42
+ return;
43
+ const mark = () => {
44
+ for (const target of host.querySelectorAll("[data-graview-pick]")) {
45
+ if (target.getAttribute("tabindex") === null)
46
+ target.setAttribute("tabindex", "0");
47
+ if (target.getAttribute("role") === null && takesButton(target)) {
48
+ target.setAttribute("role", "button");
49
+ }
50
+ }
51
+ };
52
+ mark();
53
+ if (typeof MutationObserver === "undefined")
54
+ return;
55
+ let queued = 0;
56
+ const watch = new MutationObserver(() => {
57
+ if (queued !== 0)
58
+ return;
59
+ queued = typeof requestAnimationFrame === "undefined" ? 0 : requestAnimationFrame(() => {
60
+ queued = 0;
61
+ mark();
62
+ });
63
+ if (queued === 0)
64
+ mark();
65
+ });
66
+ watch.observe(host, { childList: true, subtree: true, attributes: true, attributeFilter: ["data-graview-pick"] });
67
+ return () => {
68
+ watch.disconnect();
69
+ if (queued !== 0)
70
+ cancelAnimationFrame(queued);
71
+ };
72
+ }, [ref]);
73
+ }
74
+ /**
75
+ * Whether `role="button"` is a legal thing to say about this element.
76
+ *
77
+ * It was said about EVERY pick target, and a view is free to mark whatever
78
+ * it drew — so a list whose heading was a `<header>` got
79
+ * `<header role="button">`, which ARIA forbids and axe reports
80
+ * (`aria-allowed-role`). Three of them on the first screen of the app this
81
+ * repository shows people first, unnoticed because nothing had ever run axe
82
+ * over the scene.
83
+ *
84
+ * An allowlist rather than a list of forbidden tags: the elements that carry
85
+ * no semantics of their own are a short, closed set, and everything else —
86
+ * landmarks, headings, lists, form controls, links — either already means
87
+ * something or is somewhere a button may not be. A target that is not on it
88
+ * still gets `tabindex`, so the keyboard reaches it; what it does not get is
89
+ * a role that is a lie about the markup.
90
+ */
91
+ const GENERIC = new Set([
92
+ "div",
93
+ "span",
94
+ "p",
95
+ "figure",
96
+ "img",
97
+ "td",
98
+ "output",
99
+ "b",
100
+ "i",
101
+ "em",
102
+ "strong",
103
+ "small",
104
+ "canvas",
105
+ /*
106
+ * AND THE SHAPES, because any lens that draws a picture draws it in SVG.
107
+ *
108
+ * The allowlist was HTML only, so a map, a chart, a floor plan or a
109
+ * network diagram marked its regions with `data-graview-pick`, got the tab
110
+ * stop, and got no role at all — every target announced as nothing, which
111
+ * is a worse outcome than not being focusable, because a keyboard user now
112
+ * tabs through silent stops. ARIA permits `role="button"` on all of these,
113
+ * and `takesButton` still keeps `<header>`, headings and form controls
114
+ * safe, because the guard is an allowlist rather than a list of things to
115
+ * avoid.
116
+ *
117
+ * The role is the framework's half. The NAME is the view's: a shape has no
118
+ * text inside it, so a lens drawing in SVG sets `aria-label` on what it
119
+ * marks. `graview-lens` says so.
120
+ */
121
+ "g",
122
+ "polygon",
123
+ "circle",
124
+ "rect",
125
+ "path",
126
+ "ellipse",
127
+ "polyline",
128
+ "line",
129
+ "use",
130
+ ]);
131
+ function takesButton(element) {
132
+ /*
133
+ * `tagName` is upper-case on an HTML element and EXACTLY AS WRITTEN on an
134
+ * SVG one, so the comparison is lower-cased on both sides. `localName` is
135
+ * already lower-case for HTML and correct-case for SVG; these tags are all
136
+ * lower-case in the SVG namespace, so either answer agrees.
137
+ */
138
+ return GENERIC.has(element.localName.toLowerCase());
139
+ }
140
+ //# sourceMappingURL=picking.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"picking.js","sourceRoot":"","sources":["../src/picking.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAElC;;;;;;;;;;;;GAYG;AAEH,+DAA+D;AAC/D,MAAM,UAAU,UAAU,CAAC,MAA0B;IACnD,OAAO,CACJ,MAA6B,EAAE,OAAO,EAAE,CAAC,qBAAqB,CAAC,EAAE,YAAY,CAC5E,mBAAmB,CACpB,IAAI,IAAI,CACV,CAAC;AACJ,CAAC;AAED;;;;;;;;;;GAUG;AACH,MAAM,UAAU,cAAc,CAAC,GAAoC;IACjE;;;;;;;OAOG;IACH,SAAS,CAAC,GAAG,EAAE;QACb,MAAM,IAAI,GAAG,GAAG,CAAC,OAAO,CAAC;QACzB,IAAI,CAAC,IAAI;YAAE,OAAO;QAClB,MAAM,IAAI,GAAG,GAAG,EAAE;YAChB,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,gBAAgB,CAAU,qBAAqB,CAAC,EAAE,CAAC;gBAC3E,IAAI,MAAM,CAAC,YAAY,CAAC,UAAU,CAAC,KAAK,IAAI;oBAAE,MAAM,CAAC,YAAY,CAAC,UAAU,EAAE,GAAG,CAAC,CAAC;gBACnF,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,IAAI,IAAI,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC;oBAChE,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC;QACH,CAAC,CAAC;QACF,IAAI,EAAE,CAAC;QACP,IAAI,OAAO,gBAAgB,KAAK,WAAW;YAAE,OAAO;QACpD,IAAI,MAAM,GAAG,CAAC,CAAC;QACf,MAAM,KAAK,GAAG,IAAI,gBAAgB,CAAC,GAAG,EAAE;YACtC,IAAI,MAAM,KAAK,CAAC;gBAAE,OAAO;YACzB,MAAM,GAAG,OAAO,qBAAqB,KAAK,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,qBAAqB,CAAC,GAAG,EAAE;gBACrF,MAAM,GAAG,CAAC,CAAC;gBACX,IAAI,EAAE,CAAC;YACT,CAAC,CAAC,CAAC;YACH,IAAI,MAAM,KAAK,CAAC;gBAAE,IAAI,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;QACH,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,eAAe,EAAE,CAAC,mBAAmB,CAAC,EAAE,CAAC,CAAC;QAClH,OAAO,GAAG,EAAE;YACV,KAAK,CAAC,UAAU,EAAE,CAAC;YACnB,IAAI,MAAM,KAAK,CAAC;gBAAE,oBAAoB,CAAC,MAAM,CAAC,CAAC;QACjD,CAAC,CAAC;IACJ,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;AACZ,CAAC;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC;IACtB,KAAK;IACL,MAAM;IACN,GAAG;IACH,QAAQ;IACR,KAAK;IACL,IAAI;IACJ,QAAQ;IACR,GAAG;IACH,GAAG;IACH,IAAI;IACJ,QAAQ;IACR,OAAO;IACP,QAAQ;IACR;;;;;;;;;;;;;;;OAeG;IACH,GAAG;IACH,SAAS;IACT,QAAQ;IACR,MAAM;IACN,MAAM;IACN,SAAS;IACT,UAAU;IACV,MAAM;IACN,KAAK;CACN,CAAC,CAAC;AAEH,SAAS,WAAW,CAAC,OAAgB;IACnC;;;;;OAKG;IACH,OAAO,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC,WAAW,EAAE,CAAC,CAAC;AACtD,CAAC"}
@@ -0,0 +1,106 @@
1
+ import { type Brand } from "@graview/core";
2
+ import { type InterpolatedLayout } from "@graview/layout";
3
+ import { type ReactElement } from "react";
4
+ export interface Point {
5
+ readonly x: number;
6
+ readonly y: number;
7
+ }
8
+ export interface City {
9
+ readonly cell: number;
10
+ readonly originX: number;
11
+ readonly originY: number;
12
+ }
13
+ export interface PlotLike {
14
+ readonly col: number;
15
+ readonly row: number;
16
+ readonly side: number;
17
+ }
18
+ /** The four corners of a plot's tile on the canvas: back, right, front, left — clockwise from the top. */
19
+ export declare function tileCorners(plot: PlotLike, city: City, pan?: Point): [Point, Point, Point, Point];
20
+ export interface PlotsProps {
21
+ readonly frame: InterpolatedLayout;
22
+ readonly width: number;
23
+ readonly height: number;
24
+ /** The pan baked into the frame's cards, so a tile sits under its card. */
25
+ readonly pan: Point;
26
+ readonly brand?: Brand | undefined;
27
+ /** Which district ids are hand-placed: their kerb is dashed, as the pinned mark. */
28
+ readonly pinned?: ReadonlySet<string>;
29
+ /** The scene's own flag for a click that a drag is about to produce: a pan that ends on a tile is not a press. */
30
+ readonly swallowed?: {
31
+ readonly current: boolean;
32
+ };
33
+ onFocus?(id: string): void;
34
+ }
35
+ /**
36
+ * One SVG for every tile, under the cards and over the fields. Aria-hidden:
37
+ * the district card is the thing with a name; this is the ground it stands
38
+ * on. The fill takes the pointer so a click on the land focuses its
39
+ * district, the same as a click on the card.
40
+ *
41
+ * THE GROUND IS DRAWN AT THE ORIGIN AND MOVED AS ONE. Every piece of it is
42
+ * computed at origin zero and the pan and origin are one translate on the
43
+ * group, so a pan or a tween changes one attribute. Each plot is its own
44
+ * memoised tile whose village is kept for as long as that plot and its
45
+ * members are the same, so dragging one district redraws that district and
46
+ * the roads, not every building in the city on every frame.
47
+ */
48
+ export declare function Plots({ frame, width, height, pan, brand, pinned, swallowed, onFocus }: PlotsProps): ReactElement | null;
49
+ /** The most buildings a plot of this side holds: a sub-lattice of side+1 to a side, minus the square in the middle. */
50
+ export declare function villageCap(side: number): number;
51
+ /** A stable number in [0, 1) from an id, so a village is not a barracks and does not reshuffle on every render. */
52
+ export declare function heightOf(id: string): number;
53
+ export interface Building {
54
+ readonly id: string;
55
+ /** The foot, in lattice units from the plot's own corner. */
56
+ readonly col: number;
57
+ readonly row: number;
58
+ /** How wide a building is on the ground, in lattice units. */
59
+ readonly footprint: number;
60
+ /** How tall, as a fraction of its footprint. */
61
+ readonly height: number;
62
+ }
63
+ /**
64
+ * WHERE THE MEMBERS STAND. One building per member on the plot's own
65
+ * sub-lattice, back to front so the near ones are drawn last; the middle
66
+ * of the plot is the village square, where the nameplate and the kind's
67
+ * landmark stand, so no building is under them. Past the cap the rest are
68
+ * a number on the kerb.
69
+ */
70
+ export declare function villageOf(plot: PlotLike, memberIds: readonly string[]): {
71
+ readonly buildings: readonly Building[];
72
+ readonly rest: number;
73
+ };
74
+ /** The three faces of one building on the canvas, from its foot cell. */
75
+ export declare function buildingFaces(building: Building, city: City, pan: Point): {
76
+ readonly roof: string;
77
+ readonly left: string;
78
+ readonly right: string;
79
+ readonly top: Point;
80
+ };
81
+ /** Lattice coordinates of a canvas point: the isometric map run backwards. */
82
+ export declare function toLattice(point: Point, city: City, pan: Point): {
83
+ readonly col: number;
84
+ readonly row: number;
85
+ };
86
+ /**
87
+ * THE STREETS. Plots stand at multiples of BLOCK and never fill their
88
+ * block, so between every block there is a gutter — a row and a column
89
+ * of cells nothing stands on. A road runs along them: out of its plot to
90
+ * the gutter beside its block, along that gutter, up the gutter beside
91
+ * the other block, and in. Every leg is a lattice line (one coordinate
92
+ * held), no leg crosses a third plot, and the whole city reads as
93
+ * villages on a street grid rather than lines drawn over it.
94
+ */
95
+ export declare function streetPoints(from: PlotLike, to: PlotLike): {
96
+ readonly col: number;
97
+ readonly row: number;
98
+ }[];
99
+ /**
100
+ * A ROAD FROM KERB TO KERB: the street between two plots, with the run
101
+ * inside either plot cut away, so the road starts at one kerb and ends at
102
+ * the other rather than diving under the buildings. Sampled and bisected,
103
+ * the same way a connector is clipped against a box.
104
+ */
105
+ export declare function roadBetween(from: PlotLike, to: PlotLike, city: City, pan: Point): Point[];
106
+ //# sourceMappingURL=plots.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plots.d.ts","sourceRoot":"","sources":["../src/plots.tsx"],"names":[],"mappings":"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"}
package/dist/plots.js ADDED
@@ -0,0 +1,306 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { BLOCK, hueFor, roadsOf, toIso } from "@graview/core";
3
+ import { kindOfCard } from "@graview/layout";
4
+ import { memo, useCallback, useMemo, useRef } from "react";
5
+ import { useGraview } from "./context.js";
6
+ import { useFlagged } from "./hooks.js";
7
+ /** The four corners of a plot's tile on the canvas: back, right, front, left — clockwise from the top. */
8
+ export function tileCorners(plot, city, pan = { x: 0, y: 0 }) {
9
+ const at = (col, row) => {
10
+ const iso = toIso(col, row, city.cell);
11
+ return { x: city.originX + pan.x + iso.x, y: city.originY + pan.y + iso.y };
12
+ };
13
+ return [
14
+ at(plot.col, plot.row),
15
+ at(plot.col + plot.side, plot.row),
16
+ at(plot.col + plot.side, plot.row + plot.side),
17
+ at(plot.col, plot.row + plot.side),
18
+ ];
19
+ }
20
+ const points = (corners) => corners.map((p) => `${p.x.toFixed(1)},${p.y.toFixed(1)}`).join(" ");
21
+ /**
22
+ * One SVG for every tile, under the cards and over the fields. Aria-hidden:
23
+ * the district card is the thing with a name; this is the ground it stands
24
+ * on. The fill takes the pointer so a click on the land focuses its
25
+ * district, the same as a click on the card.
26
+ *
27
+ * THE GROUND IS DRAWN AT THE ORIGIN AND MOVED AS ONE. Every piece of it is
28
+ * computed at origin zero and the pan and origin are one translate on the
29
+ * group, so a pan or a tween changes one attribute. Each plot is its own
30
+ * memoised tile whose village is kept for as long as that plot and its
31
+ * members are the same, so dragging one district redraws that district and
32
+ * the roads, not every building in the city on every frame.
33
+ */
34
+ export function Plots({ frame, width, height, pan, brand, pinned, swallowed, onFocus }) {
35
+ const { selection, store, emphasis } = useGraview();
36
+ const flagged = useFlagged();
37
+ const city = frame.city;
38
+ const tiles = frame.nodes.filter((node) => node.plot !== undefined && Math.round(node.plane) === 2);
39
+ const cell = city?.cell ?? 0;
40
+ // The callback is read when the tile is pressed, so a new one each render redraws nothing.
41
+ const focus = useRef(onFocus);
42
+ focus.current = onFocus;
43
+ const press = useCallback((id) => {
44
+ if (!focus.current || swallowed?.current)
45
+ return false;
46
+ focus.current(id);
47
+ return true;
48
+ }, [swallowed]);
49
+ /*
50
+ * THE ROADS, one per pair of plots joined by any declared edge
51
+ * (`roadsOf`), kerb to kerb along the gutters. They depend on every
52
+ * plot, so they are routed again when any plot moves — and only then.
53
+ */
54
+ const plotsSignature = `${cell}|${tiles.map((node) => `${node.id}:${node.plot.col},${node.plot.row},${node.plot.side}`).join(";")}`;
55
+ const roads = useMemo(() => {
56
+ if (!city)
57
+ return [];
58
+ const at0 = { cell, originX: 0, originY: 0 };
59
+ const plotsByKind = new Map();
60
+ for (const node of tiles) {
61
+ const kind = kindOfCard(node.id);
62
+ if (kind !== null && node.plot)
63
+ plotsByKind.set(kind, node.plot);
64
+ }
65
+ return roadsOf(store.schema, plotsByKind).map((road) => ({
66
+ ...road,
67
+ d: roadBetween(plotsByKind.get(road.from), plotsByKind.get(road.to), at0, { x: 0, y: 0 })
68
+ .map((p, i) => `${i === 0 ? "M" : "L"} ${p.x.toFixed(1)} ${p.y.toFixed(1)}`)
69
+ .join(" "),
70
+ }));
71
+ // `plotsSignature` stands for the tiles and the cell.
72
+ }, [plotsSignature, store.schema]);
73
+ /* EACH PLOT'S GROUND, kept while that plot and its members are unchanged. */
74
+ const drawn = useRef(new Map());
75
+ const kept = new Map();
76
+ for (const node of tiles) {
77
+ const members = node.aggregate?.memberIds ?? [];
78
+ const key = `${cell}|${node.plot.col},${node.plot.row},${node.plot.side}|${members.join(",")}`;
79
+ const held = drawn.current.get(node.id);
80
+ if (held && held.key === key) {
81
+ kept.set(node.id, held);
82
+ continue;
83
+ }
84
+ const at0 = { cell, originX: 0, originY: 0 };
85
+ const none = { x: 0, y: 0 };
86
+ const { buildings, rest } = villageOf(node.plot, members);
87
+ const corners = tileCorners(node.plot, at0, none);
88
+ kept.set(node.id, {
89
+ key,
90
+ tile: points(corners),
91
+ front: corners[2],
92
+ rest,
93
+ buildings: buildings.map((building) => ({ id: building.id, ...buildingFaces(building, at0, none) })),
94
+ });
95
+ }
96
+ drawn.current = kept;
97
+ if (!city)
98
+ return null;
99
+ const style = { position: "absolute", left: 0, top: 0, pointerEvents: "none", overflow: "visible" };
100
+ const chosenKey = selection.join("\n");
101
+ const flaggedKey = flagged.join("\n");
102
+ return (_jsx("svg", { className: "graview-plots", "aria-hidden": "true", "data-graview-world": "", width: width, height: height, style: style, "data-graview-plots": tiles.length, children: _jsxs("g", { transform: `translate(${(city.originX + pan.x).toFixed(1)} ${(city.originY + pan.y).toFixed(1)})`, children: [_jsx("g", { className: "graview-roads", "data-graview-roads": roads.length, children: roads.map((road) => road.d.includes("L") ? (_jsxs("g", { className: "graview-road", "data-graview-road": road.edges.join(","), "data-graview-lit": emphasis !== null && road.edges.includes(emphasis) ? "" : undefined, children: [_jsx("path", { className: "graview-road-edge", d: road.d }), _jsx("path", { className: "graview-road-bed", d: road.d })] }, `${road.from}|${road.to}`)) : null) }), tiles.map((node) => (_jsx(PlotTile, { id: node.id, hue: Math.round(hueFor(node.kind, brand?.accents)), drawing: kept.get(node.id), pinned: pinned?.has(node.id) ?? false, chosenKey: chosenKey, flaggedKey: flaggedKey, press: press }, node.id)))] }) }));
103
+ }
104
+ const PlotTile = memo(function PlotTile({ id, hue, drawing, pinned, chosenKey, flaggedKey, press, }) {
105
+ const chosen = new Set(chosenKey.split("\n"));
106
+ const broken = new Set(flaggedKey.split("\n"));
107
+ return (_jsxs("g", { className: "graview-plot", "data-graview-plot": id, "data-graview-pinned": pinned ? "" : undefined, style: { ["--graview-hue"]: hue }, children: [_jsx("polygon", { className: "graview-plot-tile", points: drawing.tile, onClick: (event) => {
108
+ if (press(id))
109
+ event.stopPropagation();
110
+ } }), drawing.buildings.length > 0 ? (_jsxs("g", { className: "graview-village", "data-graview-village": drawing.buildings.length, "data-graview-rest": drawing.rest || undefined, children: [drawing.buildings.map((faces) => (_jsxs("g", { className: "graview-building", "data-graview-building": faces.id, "data-graview-flagged": broken.has(faces.id) ? "" : undefined, "data-graview-selected": chosen.has(faces.id) ? "" : undefined, children: [_jsx("polygon", { className: "graview-iso-left", points: faces.left }), _jsx("polygon", { className: "graview-iso-right", points: faces.right }), _jsx("polygon", { className: "graview-iso-roof", points: faces.roof })] }, faces.id))), drawing.rest > 0 ? (_jsxs("text", { className: "graview-village-rest", x: drawing.front.x, y: drawing.front.y - 4, textAnchor: "middle", children: ["+", drawing.rest] })) : null] })) : null] }));
111
+ });
112
+ /* ------------------------------------------------------------ the village */
113
+ /** The most buildings a plot of this side holds: a sub-lattice of side+1 to a side, minus the square in the middle. */
114
+ export function villageCap(side) {
115
+ const n = side + 1;
116
+ return n * n - squareCells(n).length;
117
+ }
118
+ /** The sub-cells of an n×n sub-lattice that make the village square: the middle one, or the middle four; a 2×2 has no room for one. */
119
+ function squareCells(n) {
120
+ if (n < 3)
121
+ return [];
122
+ if (n % 2 === 1) {
123
+ const mid = (n - 1) / 2;
124
+ return [[mid, mid]];
125
+ }
126
+ const a = n / 2 - 1;
127
+ const b = n / 2;
128
+ return [
129
+ [a, a],
130
+ [b, a],
131
+ [a, b],
132
+ [b, b],
133
+ ];
134
+ }
135
+ /** A stable number in [0, 1) from an id, so a village is not a barracks and does not reshuffle on every render. */
136
+ export function heightOf(id) {
137
+ let h = 2166136261;
138
+ for (let i = 0; i < id.length; i++)
139
+ h = Math.imul(h ^ id.charCodeAt(i), 16777619);
140
+ return ((h >>> 0) % 1000) / 1000;
141
+ }
142
+ /**
143
+ * WHERE THE MEMBERS STAND. One building per member on the plot's own
144
+ * sub-lattice, back to front so the near ones are drawn last; the middle
145
+ * of the plot is the village square, where the nameplate and the kind's
146
+ * landmark stand, so no building is under them. Past the cap the rest are
147
+ * a number on the kerb.
148
+ */
149
+ export function villageOf(plot, memberIds) {
150
+ const n = plot.side + 1;
151
+ const square = new Set(squareCells(n).map(([c, r]) => `${c},${r}`));
152
+ const pitch = plot.side / n;
153
+ const cells = [];
154
+ for (let r = 0; r < n; r++)
155
+ for (let c = 0; c < n; c++)
156
+ if (!square.has(`${c},${r}`))
157
+ cells.push([c, r]);
158
+ // Back to front: a smaller col+row is further from the viewer on a 2:1 lattice.
159
+ cells.sort((a, b) => a[0] + a[1] - (b[0] + b[1]) || a[0] - b[0]);
160
+ const shown = memberIds.slice(0, cells.length);
161
+ const buildings = shown.map((id, i) => {
162
+ const [c, r] = cells[i];
163
+ return {
164
+ id,
165
+ col: plot.col + (c + 0.5) * pitch,
166
+ row: plot.row + (r + 0.5) * pitch,
167
+ footprint: pitch * 0.62,
168
+ height: 0.55 + heightOf(id) * 0.7,
169
+ };
170
+ });
171
+ return { buildings, rest: Math.max(0, memberIds.length - shown.length) };
172
+ }
173
+ /** The three faces of one building on the canvas, from its foot cell. */
174
+ export function buildingFaces(building, city, pan) {
175
+ const half = building.footprint / 2;
176
+ const at = (col, row, lift = 0) => {
177
+ const iso = toIso(col, row, city.cell);
178
+ return { x: city.originX + pan.x + iso.x, y: city.originY + pan.y + iso.y - lift };
179
+ };
180
+ const rise = building.footprint * city.cell * 0.5 * building.height;
181
+ const back = at(building.col - half, building.row - half, rise);
182
+ const right = at(building.col + half, building.row - half, rise);
183
+ const front = at(building.col + half, building.row + half, rise);
184
+ const left = at(building.col - half, building.row + half, rise);
185
+ const frontFoot = at(building.col + half, building.row + half);
186
+ const leftFoot = at(building.col - half, building.row + half);
187
+ const rightFoot = at(building.col + half, building.row - half);
188
+ return {
189
+ roof: points([back, right, front, left]),
190
+ left: points([left, front, frontFoot, leftFoot]),
191
+ right: points([front, right, rightFoot, frontFoot]),
192
+ top: back,
193
+ };
194
+ }
195
+ /* --------------------------------------------------------------- the roads */
196
+ /** Lattice coordinates of a canvas point: the isometric map run backwards. */
197
+ export function toLattice(point, city, pan) {
198
+ const x = point.x - city.originX - pan.x;
199
+ const y = point.y - city.originY - pan.y;
200
+ return { col: x / city.cell + (2 * y) / city.cell, row: (2 * y) / city.cell - x / city.cell };
201
+ }
202
+ const insidePlot = (point, plot, city, pan) => {
203
+ const { col, row } = toLattice(point, city, pan);
204
+ return col >= plot.col && col <= plot.col + plot.side && row >= plot.row && row <= plot.row + plot.side;
205
+ };
206
+ const lerp = (a, b, t) => ({ x: a.x + (b.x - a.x) * t, y: a.y + (b.y - a.y) * t });
207
+ /**
208
+ * THE STREETS. Plots stand at multiples of BLOCK and never fill their
209
+ * block, so between every block there is a gutter — a row and a column
210
+ * of cells nothing stands on. A road runs along them: out of its plot to
211
+ * the gutter beside its block, along that gutter, up the gutter beside
212
+ * the other block, and in. Every leg is a lattice line (one coordinate
213
+ * held), no leg crosses a third plot, and the whole city reads as
214
+ * villages on a street grid rather than lines drawn over it.
215
+ */
216
+ export function streetPoints(from, to) {
217
+ const ca = from.col + from.side / 2;
218
+ const ra = from.row + from.side / 2;
219
+ const cb = to.col + to.side / 2;
220
+ const rb = to.row + to.side / 2;
221
+ const blockRow = (plot) => Math.floor(plot.row / BLOCK);
222
+ const blockCol = (plot) => Math.floor(plot.col / BLOCK);
223
+ const ja = blockRow(from);
224
+ const jb = blockRow(to);
225
+ const ia = blockCol(from);
226
+ const ib = blockCol(to);
227
+ // The gutter row beside `from`, on the side `to` lies; the gutter column beside `to`, on the side `from` lies.
228
+ const gr = jb > ja ? ja * BLOCK + BLOCK - 0.5 : jb < ja ? ja * BLOCK - 0.5 : ja * BLOCK + BLOCK - 0.5;
229
+ const gc = ib > ia ? ib * BLOCK - 0.5 : ib < ia ? ib * BLOCK + BLOCK - 0.5 : ib * BLOCK - 0.5;
230
+ const raw = [
231
+ { col: ca, row: ra },
232
+ { col: ca, row: gr },
233
+ { col: gc, row: gr },
234
+ { col: gc, row: rb },
235
+ { col: cb, row: rb },
236
+ ];
237
+ // Drop a leg of no length, and a middle point that lies on the line of its neighbours.
238
+ const out = [];
239
+ for (const p of raw) {
240
+ const last = out[out.length - 1];
241
+ if (last && Math.abs(last.col - p.col) < 1e-9 && Math.abs(last.row - p.row) < 1e-9)
242
+ continue;
243
+ out.push(p);
244
+ }
245
+ for (let i = out.length - 2; i > 0; i--) {
246
+ const a = out[i - 1];
247
+ const b = out[i];
248
+ const c = out[i + 1];
249
+ const sameCol = Math.abs(a.col - b.col) < 1e-9 && Math.abs(b.col - c.col) < 1e-9;
250
+ const sameRow = Math.abs(a.row - b.row) < 1e-9 && Math.abs(b.row - c.row) < 1e-9;
251
+ if (sameCol || sameRow)
252
+ out.splice(i, 1);
253
+ }
254
+ return out;
255
+ }
256
+ /**
257
+ * A ROAD FROM KERB TO KERB: the street between two plots, with the run
258
+ * inside either plot cut away, so the road starts at one kerb and ends at
259
+ * the other rather than diving under the buildings. Sampled and bisected,
260
+ * the same way a connector is clipped against a box.
261
+ */
262
+ export function roadBetween(from, to, city, pan) {
263
+ const points = streetPoints(from, to).map((p) => {
264
+ const iso = toIso(p.col, p.row, city.cell);
265
+ return { x: city.originX + pan.x + iso.x, y: city.originY + pan.y + iso.y };
266
+ });
267
+ // Walk out of `from`: the first point on the polyline outside its plot.
268
+ const out = [];
269
+ let started = false;
270
+ for (let i = 0; i < points.length - 1; i++) {
271
+ const a = points[i];
272
+ const b = points[i + 1];
273
+ if (!started) {
274
+ if (insidePlot(b, from, city, pan))
275
+ continue;
276
+ let lo = 0;
277
+ let hi = 1;
278
+ for (let k = 0; k < 12; k++) {
279
+ const mid = (lo + hi) / 2;
280
+ if (insidePlot(lerp(a, b, mid), from, city, pan))
281
+ lo = mid;
282
+ else
283
+ hi = mid;
284
+ }
285
+ out.push(lerp(a, b, hi));
286
+ started = true;
287
+ }
288
+ // Walk into `to`: the first point on the polyline inside its plot.
289
+ if (insidePlot(b, to, city, pan)) {
290
+ let lo = 0;
291
+ let hi = 1;
292
+ for (let k = 0; k < 12; k++) {
293
+ const mid = (lo + hi) / 2;
294
+ if (insidePlot(lerp(a, b, mid), to, city, pan))
295
+ hi = mid;
296
+ else
297
+ lo = mid;
298
+ }
299
+ out.push(lerp(a, b, lo));
300
+ return out;
301
+ }
302
+ out.push(b);
303
+ }
304
+ return out;
305
+ }
306
+ //# sourceMappingURL=plots.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plots.js","sourceRoot":"","sources":["../src/plots.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ /**
2
+ * THE POINTER OVER THE SCENE, for whoever asks — and NOBODY listening
3
+ * costs nothing.
4
+ *
5
+ * A quiet scene must not run a listener on every pointer move on the off
6
+ * chance something wants it. So this is a store with a subscriber count:
7
+ * the scene attaches its listener when the first subscriber arrives and
8
+ * detaches it when the last one leaves. `useScenePointer` reads it through
9
+ * `useSyncExternalStore`, which is what makes the count exact.
10
+ */
11
+ export interface ScenePoint {
12
+ /** In scene coordinates — the same space the layout places things in. */
13
+ readonly x: number;
14
+ readonly y: number;
15
+ }
16
+ export interface PointerStore {
17
+ subscribe(listener: () => void): () => void;
18
+ snapshot(): ScenePoint | null;
19
+ /** The scene calls this; nobody else does. */
20
+ set(point: ScenePoint | null): void;
21
+ /** How many are listening right now. */
22
+ readonly listeners: number;
23
+ /** Told when the count crosses zero either way — attach or detach. */
24
+ onActive(listener: (active: boolean) => void): () => void;
25
+ }
26
+ export declare function createPointerStore(): PointerStore;
27
+ //# sourceMappingURL=pointer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pointer.d.ts","sourceRoot":"","sources":["../src/pointer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,MAAM,WAAW,UAAU;IACzB,yEAAyE;IACzE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,YAAY;IAC3B,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC;IAC5C,QAAQ,IAAI,UAAU,GAAG,IAAI,CAAC;IAC9B,8CAA8C;IAC9C,GAAG,CAAC,KAAK,EAAE,UAAU,GAAG,IAAI,GAAG,IAAI,CAAC;IACpC,wCAAwC;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC;CAC3D;AAED,wBAAgB,kBAAkB,IAAI,YAAY,CAiCjD"}