@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
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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"}
@@ -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"}