@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.
- package/LICENSE +96 -0
- package/README.md +20 -0
- package/dist/activity.d.ts +113 -0
- package/dist/activity.d.ts.map +1 -0
- package/dist/activity.js +207 -0
- package/dist/activity.js.map +1 -0
- package/dist/animation.d.ts +64 -0
- package/dist/animation.d.ts.map +1 -0
- package/dist/animation.js +245 -0
- package/dist/animation.js.map +1 -0
- package/dist/captions.d.ts +43 -0
- package/dist/captions.d.ts.map +1 -0
- package/dist/captions.js +61 -0
- package/dist/captions.js.map +1 -0
- package/dist/channels.d.ts +15 -0
- package/dist/channels.d.ts.map +1 -0
- package/dist/channels.js +114 -0
- package/dist/channels.js.map +1 -0
- package/dist/connectors.d.ts +176 -0
- package/dist/connectors.d.ts.map +1 -0
- package/dist/connectors.js +837 -0
- package/dist/connectors.js.map +1 -0
- package/dist/context.d.ts +348 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +568 -0
- package/dist/context.js.map +1 -0
- package/dist/drawn.d.ts +60 -0
- package/dist/drawn.d.ts.map +1 -0
- package/dist/drawn.js +58 -0
- package/dist/drawn.js.map +1 -0
- package/dist/edge-signs.d.ts +13 -0
- package/dist/edge-signs.d.ts.map +1 -0
- package/dist/edge-signs.js +76 -0
- package/dist/edge-signs.js.map +1 -0
- package/dist/hooks.d.ts +160 -0
- package/dist/hooks.d.ts.map +1 -0
- package/dist/hooks.js +457 -0
- package/dist/hooks.js.map +1 -0
- package/dist/index.d.ts +37 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +22 -0
- package/dist/index.js.map +1 -0
- package/dist/keyboard.d.ts +5 -0
- package/dist/keyboard.d.ts.map +1 -0
- package/dist/keyboard.js +178 -0
- package/dist/keyboard.js.map +1 -0
- package/dist/kit.d.ts +10 -0
- package/dist/kit.d.ts.map +1 -0
- package/dist/kit.js +32 -0
- package/dist/kit.js.map +1 -0
- package/dist/local-intelligence.d.ts +31 -0
- package/dist/local-intelligence.d.ts.map +1 -0
- package/dist/local-intelligence.js +66 -0
- package/dist/local-intelligence.js.map +1 -0
- package/dist/motion.d.ts +17 -0
- package/dist/motion.d.ts.map +1 -0
- package/dist/motion.js +26 -0
- package/dist/motion.js.map +1 -0
- package/dist/occupants.d.ts +45 -0
- package/dist/occupants.d.ts.map +1 -0
- package/dist/occupants.js +57 -0
- package/dist/occupants.js.map +1 -0
- package/dist/parallel.d.ts +19 -0
- package/dist/parallel.d.ts.map +1 -0
- package/dist/parallel.js +30 -0
- package/dist/parallel.js.map +1 -0
- package/dist/picking.d.ts +30 -0
- package/dist/picking.d.ts.map +1 -0
- package/dist/picking.js +140 -0
- package/dist/picking.js.map +1 -0
- package/dist/plots.d.ts +106 -0
- package/dist/plots.d.ts.map +1 -0
- package/dist/plots.js +306 -0
- package/dist/plots.js.map +1 -0
- package/dist/pointer.d.ts +27 -0
- package/dist/pointer.d.ts.map +1 -0
- package/dist/pointer.js +39 -0
- package/dist/pointer.js.map +1 -0
- package/dist/presence.d.ts +110 -0
- package/dist/presence.d.ts.map +1 -0
- package/dist/presence.js +280 -0
- package/dist/presence.js.map +1 -0
- package/dist/rails.d.ts +11 -0
- package/dist/rails.d.ts.map +1 -0
- package/dist/rails.js +15 -0
- package/dist/rails.js.map +1 -0
- package/dist/resolved-view.d.ts +78 -0
- package/dist/resolved-view.d.ts.map +1 -0
- package/dist/resolved-view.js +365 -0
- package/dist/resolved-view.js.map +1 -0
- package/dist/robot.d.ts +114 -0
- package/dist/robot.d.ts.map +1 -0
- package/dist/robot.js +93 -0
- package/dist/robot.js.map +1 -0
- package/dist/routes.d.ts +50 -0
- package/dist/routes.d.ts.map +1 -0
- package/dist/routes.js +150 -0
- package/dist/routes.js.map +1 -0
- package/dist/scene-camera.d.ts +25 -0
- package/dist/scene-camera.d.ts.map +1 -0
- package/dist/scene-camera.js +130 -0
- package/dist/scene-camera.js.map +1 -0
- package/dist/scene-hand.d.ts +110 -0
- package/dist/scene-hand.d.ts.map +1 -0
- package/dist/scene-hand.js +317 -0
- package/dist/scene-hand.js.map +1 -0
- package/dist/scene-helpers.d.ts +46 -0
- package/dist/scene-helpers.d.ts.map +1 -0
- package/dist/scene-helpers.js +108 -0
- package/dist/scene-helpers.js.map +1 -0
- package/dist/scene-lines.d.ts +76 -0
- package/dist/scene-lines.d.ts.map +1 -0
- package/dist/scene-lines.js +578 -0
- package/dist/scene-lines.js.map +1 -0
- package/dist/scene-root.d.ts +71 -0
- package/dist/scene-root.d.ts.map +1 -0
- package/dist/scene-root.js +790 -0
- package/dist/scene-root.js.map +1 -0
- package/dist/scene.d.ts +17 -0
- package/dist/scene.d.ts.map +1 -0
- package/dist/scene.js +17 -0
- package/dist/scene.js.map +1 -0
- package/dist/seat-marks.d.ts +35 -0
- package/dist/seat-marks.d.ts.map +1 -0
- package/dist/seat-marks.js +43 -0
- package/dist/seat-marks.js.map +1 -0
- package/dist/settings.d.ts +30 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/settings.js +73 -0
- package/dist/settings.js.map +1 -0
- package/dist/view-boundary.d.ts +33 -0
- package/dist/view-boundary.d.ts.map +1 -0
- package/dist/view-boundary.js +53 -0
- package/dist/view-boundary.js.map +1 -0
- package/dist/view-host.d.ts +57 -0
- package/dist/view-host.d.ts.map +1 -0
- package/dist/view-host.js +474 -0
- package/dist/view-host.js.map +1 -0
- package/dist/view-registry.d.ts +122 -0
- package/dist/view-registry.d.ts.map +1 -0
- package/dist/view-registry.js +20 -0
- package/dist/view-registry.js.map +1 -0
- package/dist/where-drawn.d.ts +151 -0
- package/dist/where-drawn.d.ts.map +1 -0
- package/dist/where-drawn.js +231 -0
- package/dist/where-drawn.js.map +1 -0
- package/package.json +60 -0
package/dist/drawn.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { estimateWidth } from "@graview/layout";
|
|
2
|
+
import { useEffect, useMemo, useRef, useState } from "react";
|
|
3
|
+
export function useDrawnSize(ref, { units, target = 0, legibleAt = 260 }) {
|
|
4
|
+
const [width, setWidth] = useState(units);
|
|
5
|
+
useEffect(() => {
|
|
6
|
+
const element = ref.current;
|
|
7
|
+
if (element === null || typeof ResizeObserver === "undefined")
|
|
8
|
+
return;
|
|
9
|
+
const watch = new ResizeObserver(([entry]) => {
|
|
10
|
+
const seen = entry?.contentRect.width ?? 0;
|
|
11
|
+
if (seen > 0)
|
|
12
|
+
setWidth(seen);
|
|
13
|
+
});
|
|
14
|
+
watch.observe(element);
|
|
15
|
+
return () => watch.disconnect();
|
|
16
|
+
}, [ref]);
|
|
17
|
+
const scale = width / units;
|
|
18
|
+
return { scale, width, touchable: scale * target >= 24, legible: width >= legibleAt };
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A TEXT MEASURER THAT MEASURES, where there is something to measure with.
|
|
22
|
+
*
|
|
23
|
+
* `fitLabel` takes a `Measure` because the honest answer depends on where
|
|
24
|
+
* you are. In a browser it is a 2D canvas context: synchronous, no layout,
|
|
25
|
+
* the same engine that will draw the SVG. The alternative is
|
|
26
|
+
* `getComputedTextLength`, which means rendering wrong once and correcting
|
|
27
|
+
* in an effect every time anything moves.
|
|
28
|
+
*
|
|
29
|
+
* The face matters. Pass the CSS variable the text is actually drawn in —
|
|
30
|
+
* a display serif and a body sans measure very differently, and guessing an
|
|
31
|
+
* average advance for both is what let three names overflow a plan.
|
|
32
|
+
*/
|
|
33
|
+
export function useTextMeasure(faceVariable = "--graview-font-body", fallback = "sans-serif") {
|
|
34
|
+
const ruler = useRef(undefined);
|
|
35
|
+
const face = useMemo(() => {
|
|
36
|
+
if (typeof getComputedStyle !== "function" || typeof document === "undefined")
|
|
37
|
+
return fallback;
|
|
38
|
+
const said = getComputedStyle(document.documentElement).getPropertyValue(faceVariable).trim();
|
|
39
|
+
return said.length > 0 ? said : fallback;
|
|
40
|
+
}, [faceVariable, fallback]);
|
|
41
|
+
return useMemo(() => {
|
|
42
|
+
if (ruler.current === undefined) {
|
|
43
|
+
ruler.current =
|
|
44
|
+
typeof document === "undefined" ? null : (document.createElement("canvas").getContext("2d") ?? null);
|
|
45
|
+
}
|
|
46
|
+
const context = ruler.current;
|
|
47
|
+
if (context === null)
|
|
48
|
+
return estimateWidth;
|
|
49
|
+
return (text, fontSize) => {
|
|
50
|
+
context.font = `${fontSize}px ${face}`;
|
|
51
|
+
const measured = context.measureText(text).width;
|
|
52
|
+
/* jsdom's stub answers 0 for everything, and so does a context that
|
|
53
|
+
has lost its backing store. Either way the estimate is the answer. */
|
|
54
|
+
return measured > 0 ? measured : estimateWidth(text, fontSize);
|
|
55
|
+
};
|
|
56
|
+
}, [face]);
|
|
57
|
+
}
|
|
58
|
+
//# sourceMappingURL=drawn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"drawn.js","sourceRoot":"","sources":["../src/drawn.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { AnySchema } from "@graview/core";
|
|
2
|
+
import { type Layout } from "@graview/layout";
|
|
3
|
+
import type { ReactElement } from "react";
|
|
4
|
+
export declare function EdgeSigns({ result, schema, onGo, }: {
|
|
5
|
+
readonly result: Pick<Layout, "nodes" | "width" | "height" | "city">;
|
|
6
|
+
readonly schema: AnySchema;
|
|
7
|
+
/** Pan the ground by this much. */
|
|
8
|
+
readonly onGo: (by: {
|
|
9
|
+
readonly x: number;
|
|
10
|
+
readonly y: number;
|
|
11
|
+
}) => void;
|
|
12
|
+
}): ReactElement | null;
|
|
13
|
+
//# sourceMappingURL=edge-signs.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-signs.d.ts","sourceRoot":"","sources":["../src/edge-signs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAwB,KAAK,MAAM,EAAoB,MAAM,iBAAiB,CAAC;AACtF,OAAO,KAAK,EAAiB,YAAY,EAAE,MAAM,OAAO,CAAC;AAqBzD,wBAAgB,SAAS,CAAC,EACxB,MAAM,EACN,MAAM,EACN,IAAI,GACL,EAAE;IACD,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC,CAAC;IACrE,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,mCAAmC;IACnC,QAAQ,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE;QAAE,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,CAAA;KAAE,KAAK,IAAI,CAAC;CACzE,GAAG,YAAY,GAAG,IAAI,CAgDtB"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import { jsx as _jsx, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { districtsPastTheEdge } from "@graview/layout";
|
|
3
|
+
/**
|
|
4
|
+
* THE SIGNS AT THE EDGE OF THE GROUND. A city wider than the window keeps
|
|
5
|
+
* its shape and is reached by panning; what it did not do was say so. On a
|
|
6
|
+
* phone the conference's Topics and Staff stood wholly past the left edge,
|
|
7
|
+
* and nothing on the screen said they were there or which way to go — a
|
|
8
|
+
* pointer could not press them, because there was nothing to press.
|
|
9
|
+
*
|
|
10
|
+
* Each district past an edge gets a sign on that edge, at the height (or
|
|
11
|
+
* across the width) it lies, in its own name and pointing at it. Pressing
|
|
12
|
+
* the sign pans the ground to bring the district in; the district itself
|
|
13
|
+
* is then pressed like any other. A sign is a way to somewhere, not a
|
|
14
|
+
* second way to do what the district does.
|
|
15
|
+
*/
|
|
16
|
+
const ARROW = { left: "←", right: "→", top: "↑", bottom: "↓" };
|
|
17
|
+
/** How far apart two signs on one edge stand, at the least: one sign's height and a gap. */
|
|
18
|
+
const SPACING = 36;
|
|
19
|
+
/** Room kept clear at the canvas's ends: the zoom in one corner, the way in at the other. */
|
|
20
|
+
const MARGIN = 56;
|
|
21
|
+
export function EdgeSigns({ result, schema, onGo, }) {
|
|
22
|
+
const past = districtsPastTheEdge(result);
|
|
23
|
+
if (past.length === 0)
|
|
24
|
+
return null;
|
|
25
|
+
const signs = [];
|
|
26
|
+
for (const side of ["left", "right", "top", "bottom"]) {
|
|
27
|
+
const span = side === "left" || side === "right" ? result.height : result.width;
|
|
28
|
+
let last = -Infinity;
|
|
29
|
+
const onSide = past.filter((one) => one.side === side).sort((a, b) => a.along - b.along);
|
|
30
|
+
for (const one of onSide) {
|
|
31
|
+
const at = Math.max(MARGIN, Math.min(span - MARGIN, Math.max(one.along, last + SPACING)));
|
|
32
|
+
last = at;
|
|
33
|
+
const plural = schema.tryDefinition(one.kind)?.plural ?? one.kind;
|
|
34
|
+
const place = side === "left"
|
|
35
|
+
? { left: 6, top: at, transform: "translateY(-50%)" }
|
|
36
|
+
: side === "right"
|
|
37
|
+
? { right: 6, top: at, transform: "translateY(-50%)" }
|
|
38
|
+
: side === "top"
|
|
39
|
+
? { top: 6, left: at, transform: "translateX(-50%)" }
|
|
40
|
+
: { bottom: 6, left: at, transform: "translateX(-50%)" };
|
|
41
|
+
signs.push(_jsx("button", { type: "button", className: "graview-edge-sign", "data-graview-past-edge": one.id, "aria-label": `${plural}, past the ${side} edge — bring it into view`, title: `${plural} is past the ${side} edge`,
|
|
42
|
+
/*
|
|
43
|
+
* Not a tab stop: the keys reach the district itself, and focus
|
|
44
|
+
* brings it into the window. Seven more stops in front of every
|
|
45
|
+
* district was the price a keyboard paid for the pointer's sign.
|
|
46
|
+
*/
|
|
47
|
+
tabIndex: -1,
|
|
48
|
+
// A press on a sign is not the start of a pan.
|
|
49
|
+
onPointerDown: (event) => event.stopPropagation(), onClick: (event) => {
|
|
50
|
+
event.stopPropagation();
|
|
51
|
+
onGo(one.by);
|
|
52
|
+
}, style: { ...SIGN, ...place }, children: side === "right" || side === "bottom" ? `${plural} ${ARROW[side]}` : `${ARROW[side]} ${plural}` }, one.id));
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
return _jsx(_Fragment, { children: signs });
|
|
56
|
+
}
|
|
57
|
+
const SIGN = {
|
|
58
|
+
position: "absolute",
|
|
59
|
+
zIndex: 3,
|
|
60
|
+
minHeight: 28,
|
|
61
|
+
maxWidth: "40%",
|
|
62
|
+
padding: "3px 10px",
|
|
63
|
+
font: "inherit",
|
|
64
|
+
fontSize: "0.75rem",
|
|
65
|
+
letterSpacing: "0.04em",
|
|
66
|
+
whiteSpace: "nowrap",
|
|
67
|
+
overflow: "hidden",
|
|
68
|
+
textOverflow: "ellipsis",
|
|
69
|
+
color: "var(--graview-ink)",
|
|
70
|
+
background: "var(--graview-panel)",
|
|
71
|
+
border: "1px solid var(--graview-edge)",
|
|
72
|
+
borderRadius: 999,
|
|
73
|
+
boxShadow: "0 2px 8px rgb(0 0 0 / 0.12)",
|
|
74
|
+
cursor: "pointer",
|
|
75
|
+
};
|
|
76
|
+
//# sourceMappingURL=edge-signs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"edge-signs.js","sourceRoot":"","sources":["../src/edge-signs.tsx"],"names":[],"mappings":"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"}
|
package/dist/hooks.d.ts
ADDED
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import type { AnySchema } from "@graview/core";
|
|
2
|
+
import { type ViewState } from "@graview/layout";
|
|
3
|
+
import { type Affordance, type AffordanceSet, type DeriveOptions, type EditableField } from "@graview/tools";
|
|
4
|
+
/** The current selection, and the ways an interface changes it. */
|
|
5
|
+
export declare function useSelection(): {
|
|
6
|
+
selection: readonly string[];
|
|
7
|
+
set: (ids: readonly string[]) => void;
|
|
8
|
+
clear: () => void;
|
|
9
|
+
toggle: (id: string) => void;
|
|
10
|
+
isSelected: (id: string) => boolean;
|
|
11
|
+
};
|
|
12
|
+
/**
|
|
13
|
+
* Everything currently broken, recomputed whenever the graph changes.
|
|
14
|
+
*
|
|
15
|
+
* The invariant engine has always known this and the interface only ever
|
|
16
|
+
* showed it to someone who happened to select an implicated node. An
|
|
17
|
+
* agreement nobody can see the state of is not an agreement anyone is
|
|
18
|
+
* keeping — "is anything wrong?" is the first question a person asks of a
|
|
19
|
+
* week, and it should never require hunting for it.
|
|
20
|
+
*/
|
|
21
|
+
export declare function useViolations<S extends AnySchema>(): import("@graview/core").Violation[];
|
|
22
|
+
/** Ids implicated in some current violation, for marking them in place. */
|
|
23
|
+
export declare function useFlagged(): readonly string[];
|
|
24
|
+
/**
|
|
25
|
+
* Everything the selection reaches: the selected nodes, plus everything one
|
|
26
|
+
* edge away from them.
|
|
27
|
+
*
|
|
28
|
+
* Selecting a person and having the week sit there unchanged is the same
|
|
29
|
+
* failure as clicking an event and getting an empty plane — the graph knows
|
|
30
|
+
* which five events that person is in, and the calendar is right there
|
|
31
|
+
* drawing all eighteen of them. A view that receives this can say so in its
|
|
32
|
+
* own idiom: a calendar lights up the spans, a roster rings the chips.
|
|
33
|
+
*
|
|
34
|
+
* Empty when nothing is selected, which every view must read as "no
|
|
35
|
+
* emphasis" rather than "nothing is related".
|
|
36
|
+
*/
|
|
37
|
+
export declare function useImplicated(): readonly string[];
|
|
38
|
+
/**
|
|
39
|
+
* What the SELECTION alone reaches — `useImplicated` without the search.
|
|
40
|
+
* For the one reading that must not confuse the two: a district's "tied"
|
|
41
|
+
* count is about what you picked, not what you typed.
|
|
42
|
+
*/
|
|
43
|
+
export declare function useReached(): readonly string[];
|
|
44
|
+
/** Stands in the implicated set when a search found nothing, so every view dims. */
|
|
45
|
+
export declare const NOTHING_FOUND = "search:nothing";
|
|
46
|
+
/**
|
|
47
|
+
* What can be done with the current selection, recomputed whenever the
|
|
48
|
+
* selection or the graph changes.
|
|
49
|
+
*
|
|
50
|
+
* Derivation is cheap enough to run on every selection change — measured
|
|
51
|
+
* under a millisecond on the household example's whole graph — so there is no cache to go
|
|
52
|
+
* stale and no "refresh actions" button.
|
|
53
|
+
*/
|
|
54
|
+
export declare function useAffordances<S extends AnySchema>(options?: DeriveOptions<S> & {
|
|
55
|
+
/**
|
|
56
|
+
* Derive for THESE ids rather than the selection. The companion's rail
|
|
57
|
+
* is about a subject that may be nothing anybody clicked — the place
|
|
58
|
+
* you are looking at — and the acts under its name have to be its own.
|
|
59
|
+
*/
|
|
60
|
+
readonly about?: readonly string[];
|
|
61
|
+
}): AffordanceSet;
|
|
62
|
+
/** Runs an affordance, or shows what it would do first. */
|
|
63
|
+
export declare function useApplyAffordance<S extends AnySchema>(): {
|
|
64
|
+
preview: (affordance: Affordance, args?: Record<string, unknown>) => import("@graview/core").Preview<S>;
|
|
65
|
+
apply: (affordance: Affordance, args?: Record<string, unknown>) => import("@graview/core").ApplyResult<S>;
|
|
66
|
+
};
|
|
67
|
+
/** Navigation: every stop is a view, and every view is a URL. */
|
|
68
|
+
export declare function useNavigation(): {
|
|
69
|
+
view: ViewState;
|
|
70
|
+
url: string;
|
|
71
|
+
focus: (id: string | null) => void;
|
|
72
|
+
show: (relation: string | null) => void;
|
|
73
|
+
toggle: (aggregateId: string) => void;
|
|
74
|
+
go: (next: ViewState) => void;
|
|
75
|
+
};
|
|
76
|
+
/**
|
|
77
|
+
* Keeps the view in the URL fragment and honours the back button.
|
|
78
|
+
*
|
|
79
|
+
* The back button returning to the exact prior view is not a nicety here: it
|
|
80
|
+
* is the thing that makes a spatial interface navigable at all, because it
|
|
81
|
+
* means no arrangement is ever unreachable once you have left it.
|
|
82
|
+
*/
|
|
83
|
+
/**
|
|
84
|
+
* `useUrlSync` as a component, for shells that make syncing conditional —
|
|
85
|
+
* a hook inside `if (syncUrl)` is a Rules-of-Hooks trap the moment the
|
|
86
|
+
* flag ever changes; a conditionally RENDERED component is not.
|
|
87
|
+
*/
|
|
88
|
+
export declare function UrlSync(): null;
|
|
89
|
+
export declare function useUrlSync(): void;
|
|
90
|
+
/**
|
|
91
|
+
* Where you are in your own history.
|
|
92
|
+
*
|
|
93
|
+
* The History API says nothing about whether there is anywhere to go forward
|
|
94
|
+
* to, and an interface cannot offer a control it does not know the state of —
|
|
95
|
+
* a forward arrow that is always enabled and usually does nothing is worse
|
|
96
|
+
* than none. So the position is tracked here, from the pushes this hook makes
|
|
97
|
+
* and the pops the browser reports.
|
|
98
|
+
*
|
|
99
|
+
* Module-level because there is one history per document, and because a hook
|
|
100
|
+
* that re-created it per component would count each navigation once per
|
|
101
|
+
* mounted consumer.
|
|
102
|
+
*/
|
|
103
|
+
/**
|
|
104
|
+
* Whether one view differs from another only in what the user MOVED.
|
|
105
|
+
*
|
|
106
|
+
* Where you are is the focus, the relation, what is expanded and whether you
|
|
107
|
+
* have risen above the stack. Where you dragged things to is not a different
|
|
108
|
+
* place; it is the same place, rearranged.
|
|
109
|
+
*/
|
|
110
|
+
/**
|
|
111
|
+
* WHETHER A CHANGE IS A STOP OR JUST A NUDGE OF THE ONE YOU ARE ON.
|
|
112
|
+
*
|
|
113
|
+
* Exported so it can be read and held to: what belongs in here is the
|
|
114
|
+
* difference between the back button meaning something and meaning "one
|
|
115
|
+
* pixel ago", and the two things that went wrong went wrong silently — the
|
|
116
|
+
* address changed, no entry was pushed, and the arrows stayed grey.
|
|
117
|
+
*/
|
|
118
|
+
export declare function adjustment(before: ViewState | null, after: ViewState): boolean;
|
|
119
|
+
/**
|
|
120
|
+
* Whether there is anywhere to go, and the way to go there.
|
|
121
|
+
*
|
|
122
|
+
* Every stop in a Graview app is a URL — that was the point of view state
|
|
123
|
+
* being serialisable — so back and forward are the BROWSER's, and this only
|
|
124
|
+
* makes them visible. An interface whose navigation is the browser's should
|
|
125
|
+
* not require the person using it to know that.
|
|
126
|
+
*/
|
|
127
|
+
export declare function useBacktrack(): {
|
|
128
|
+
readonly canGoBack: boolean;
|
|
129
|
+
readonly canGoForward: boolean;
|
|
130
|
+
back: () => void;
|
|
131
|
+
forward: () => void;
|
|
132
|
+
};
|
|
133
|
+
/**
|
|
134
|
+
* "Jack in": lift one view out of the scene into a conventional full page.
|
|
135
|
+
*
|
|
136
|
+
* A FAMILIARITY affordance, not an interactivity escape hatch. Because
|
|
137
|
+
* pointer routing keeps the in-scene view fully interactive, jacking in is a
|
|
138
|
+
* comfort for a novel interface rather than a requirement to get work done —
|
|
139
|
+
* and every view has to render correctly both ways.
|
|
140
|
+
*/
|
|
141
|
+
export declare function useJackIn(): {
|
|
142
|
+
jackedIn: string | null;
|
|
143
|
+
enter: (id: string) => void;
|
|
144
|
+
exit: () => void;
|
|
145
|
+
isJackedIn: boolean;
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* The fields of a node that can be changed where they are shown, and the way
|
|
149
|
+
* to change one.
|
|
150
|
+
*
|
|
151
|
+
* `commit` runs the mutation the framework found, with the author set to a
|
|
152
|
+
* person — so an in-place edit lands in the op log, can be undone, and is
|
|
153
|
+
* judged by the invariants exactly like an edit made from the actions strip.
|
|
154
|
+
* There is no second write path.
|
|
155
|
+
*/
|
|
156
|
+
export declare function useEditableFields<S extends AnySchema>(id: string | null): {
|
|
157
|
+
readonly fields: readonly EditableField[];
|
|
158
|
+
commit: (field: EditableField, value: unknown, rest?: Record<string, unknown>) => void;
|
|
159
|
+
};
|
|
160
|
+
//# sourceMappingURL=hooks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"hooks.d.ts","sourceRoot":"","sources":["../src/hooks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAUL,KAAK,SAAS,EAIf,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAKL,KAAK,UAAU,EACf,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,aAAa,EACnB,MAAM,gBAAgB,CAAC;AAIxB,mEAAmE;AACnE,wBAAgB,YAAY;;eAKX,SAAS,MAAM,EAAE;;iBAEf,MAAM;qBAIF,MAAM;EAI5B;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,CAAC,SAAS,SAAS,yCAKhD;AA4BD,2EAA2E;AAC3E,wBAAgB,UAAU,IAAI,SAAS,MAAM,EAAE,CAM9C;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,aAAa,IAAI,SAAS,MAAM,EAAE,CAgBjD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,IAAI,SAAS,MAAM,EAAE,CA0B9C;AAED,oFAAoF;AACpF,eAAO,MAAM,aAAa,mBAAmB,CAAC;AAE9C;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,CAAC,SAAS,SAAS,EAChD,OAAO,GAAE,aAAa,CAAC,CAAC,CAAC,GAAG;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,KAAK,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,GACL,aAAa,CAwBf;AAED,2DAA2D;AAC3D,wBAAgB,kBAAkB,CAAC,CAAC,SAAS,SAAS;0BAI1B,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;wBAE5C,UAAU,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC;EASnE;AAED,iEAAiE;AACjE,wBAAgB,aAAa;;;gBAMX,MAAM,GAAG,IAAI;qBACR,MAAM,GAAG,IAAI;0BACR,MAAM;eAEjB,SAAS;EAIzB;AAED;;;;;;GAMG;AACH;;;;GAIG;AACH,wBAAgB,OAAO,IAAI,IAAI,CAG9B;AAED,wBAAgB,UAAU,IAAI,IAAI,CAwGjC;AAED;;;;;;;;;;;;GAYG;AACH;;;;;;GAMG;AACH;;;;;;;GAOG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CA8B9E;AA+CD;;;;;;;GAOG;AACH,wBAAgB,YAAY,IAAI;IAC9B,QAAQ,CAAC,SAAS,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,YAAY,EAAE,OAAO,CAAC;IAC/B,IAAI,EAAE,MAAM,IAAI,CAAC;IACjB,OAAO,EAAE,MAAM,IAAI,CAAC;CACrB,CAwBA;AAED;;;;;;;GAOG;AACH,wBAAgB,SAAS;;gBASQ,MAAM;;;EAOtC;AAED;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,SAAS,EACnD,EAAE,EAAE,MAAM,GAAG,IAAI,GAChB;IACD,QAAQ,CAAC,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;IAC1C,MAAM,EAAE,CAAC,KAAK,EAAE,aAAa,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KAAK,IAAI,CAAC;CACxF,CAkBA"}
|