@danxbot/ui 10.0.1 → 11.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/dist/index.js +34015 -31794
- package/dist/index.js.map +1 -1
- package/dist/types/components/EditGutter.d.ts +20 -0
- package/dist/types/components/InlineEdit.d.ts +23 -15
- package/dist/types/components/InlineMarkdownEdit.d.ts +37 -0
- package/dist/types/components/MarkdownEditor.d.ts +7 -1
- package/dist/types/components/code-editor/recipe.d.ts +3 -3
- package/dist/types/components/edit/outcome.d.ts +30 -0
- package/dist/types/components/node-canvas/NodeCanvas.d.ts +35 -27
- package/dist/types/components/node-canvas/index.d.ts +2 -2
- package/dist/types/components/node-canvas/layout.d.ts +22 -10
- package/dist/types/components/node-canvas/types.d.ts +145 -51
- package/dist/types/index.d.ts +4 -2
- package/package.json +2 -1
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
/** The controlled activation pair every pencil-activated field takes. */
|
|
3
|
+
export interface EditActivation {
|
|
4
|
+
editing: boolean;
|
|
5
|
+
onEditingChange: (editing: boolean) => void;
|
|
6
|
+
}
|
|
7
|
+
export interface EditGutterProps {
|
|
8
|
+
/**
|
|
9
|
+
* The pencil's accessible name — say WHAT it edits ("Edit title"), because
|
|
10
|
+
* a screen reader lists it among every other pencil on the page.
|
|
11
|
+
*/
|
|
12
|
+
label: string;
|
|
13
|
+
/**
|
|
14
|
+
* Render the field, spreading the activation onto it:
|
|
15
|
+
* `{(edit) => <InlineEdit {...edit} … />}`.
|
|
16
|
+
*/
|
|
17
|
+
children: (activation: EditActivation) => ReactNode;
|
|
18
|
+
className?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function EditGutter({ label, children, className }: EditGutterProps): import("react").JSX.Element;
|
|
@@ -1,14 +1,7 @@
|
|
|
1
1
|
import { type Ref } from "react";
|
|
2
2
|
import { useRender } from "@base-ui/react/use-render";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* Unchanged from 5.2.1 — see `InlineEditOutcome`.
|
|
6
|
-
*/
|
|
7
|
-
export interface InlineEditRefusal {
|
|
8
|
-
refusal: string;
|
|
9
|
-
}
|
|
10
|
-
/** What `onCommit` may report. Returning nothing accepts the value. */
|
|
11
|
-
export type InlineEditOutcome = void | InlineEditRefusal;
|
|
3
|
+
import { type InlineEditCommit } from "./edit/outcome";
|
|
4
|
+
export type { InlineEditCommit, InlineEditOutcome, InlineEditRefusal } from "./edit/outcome";
|
|
12
5
|
export interface InlineEditProps {
|
|
13
6
|
/**
|
|
14
7
|
* The committed value. Controlled — this component never holds the truth,
|
|
@@ -30,7 +23,7 @@ export interface InlineEditProps {
|
|
|
30
23
|
* it settles. Resolve/return `{ refusal }` to reject the value with a
|
|
31
24
|
* reason; throw or reject to report that the save itself failed.
|
|
32
25
|
*/
|
|
33
|
-
onCommit:
|
|
26
|
+
onCommit: InlineEditCommit;
|
|
34
27
|
/**
|
|
35
28
|
* The refusals that are knowable WITHOUT a request. Return the reason, or
|
|
36
29
|
* `null` to accept. Runs after the unchanged check and before `onCommit`.
|
|
@@ -115,10 +108,25 @@ export interface InlineEditProps {
|
|
|
115
108
|
/** The rejected error, handed on so it can be logged or reported. */
|
|
116
109
|
onError?: (error: unknown) => void;
|
|
117
110
|
/**
|
|
118
|
-
*
|
|
119
|
-
*
|
|
120
|
-
*
|
|
121
|
-
*
|
|
111
|
+
* CONTROLLED ACTIVATION (DX-3372). Pass it and the control never opens
|
|
112
|
+
* ITSELF — no click, Enter or F2 — because something else (the pencil of an
|
|
113
|
+
* `EditGutter`, a menu item, a shortcut) is the way in. Setting it `true`
|
|
114
|
+
* opens the field, focused, caret at the end; the control asks to close
|
|
115
|
+
* through `onEditingChange(false)` once a commit lands or Escape cancels.
|
|
116
|
+
* Setting it `false` yourself while it is open abandons the draft exactly as
|
|
117
|
+
* Escape would — nothing is written. At rest the element leaves the tab
|
|
118
|
+
* order and drops its hover affordance, so the trigger is the one stop.
|
|
119
|
+
*
|
|
120
|
+
* Omit it for the self-opening control (click, Enter or F2).
|
|
121
|
+
*/
|
|
122
|
+
editing?: boolean;
|
|
123
|
+
/**
|
|
124
|
+
* Fires exactly when the control itself starts or ends editing — never while
|
|
125
|
+
* a read-only control merely declines to open, and never for a change the
|
|
126
|
+
* caller made through `editing`. Use it to suspend any re-render-from-server
|
|
127
|
+
* logic of your own for as long as someone is actually looking at the
|
|
128
|
+
* field; see the module comment. With `editing` controlled, this is how the
|
|
129
|
+
* control hands the closed state back.
|
|
122
130
|
*/
|
|
123
131
|
onEditingChange?: (editing: boolean) => void;
|
|
124
132
|
/** Render as a different element — see `Button`'s own `render` for the shape. */
|
|
@@ -135,4 +143,4 @@ export interface InlineEditProps {
|
|
|
135
143
|
messageClassName?: string;
|
|
136
144
|
ref?: Ref<HTMLElement>;
|
|
137
145
|
}
|
|
138
|
-
export declare function InlineEdit({ value, onCommit, validate, liveValidate, label, placeholder, size, multiline, autosaveMs, readOnly, failureMessage, onError, onEditingChange, render, className, messageClassName, inputMode, ref, }: InlineEditProps): import("react").JSX.Element;
|
|
146
|
+
export declare function InlineEdit({ value, onCommit, validate, liveValidate, label, placeholder, size, multiline, autosaveMs, readOnly, failureMessage, onError, editing: editingProp, onEditingChange, render, className, messageClassName, inputMode, ref, }: InlineEditProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { ImageUploader } from "../lib/markdown/image-pipeline";
|
|
3
|
+
import { type InlineEditCommit } from "./edit/outcome";
|
|
4
|
+
export interface InlineMarkdownEditProps {
|
|
5
|
+
/** The committed markdown. Controlled — the field only ever holds a draft. */
|
|
6
|
+
value: string;
|
|
7
|
+
/**
|
|
8
|
+
* Commit a new value — the same contract as `InlineEdit.onCommit`: called
|
|
9
|
+
* only when the draft differs from `value`, with `base` = the value editing
|
|
10
|
+
* began from; return/resolve `{ refusal }` to refuse with a reason, throw or
|
|
11
|
+
* reject to report a failed save.
|
|
12
|
+
*/
|
|
13
|
+
onCommit: InlineEditCommit;
|
|
14
|
+
/** Whether the editor is open. REQUIRED — see the module comment. */
|
|
15
|
+
editing: boolean;
|
|
16
|
+
/** The field asks to close through this, once a commit lands or Escape cancels. */
|
|
17
|
+
onEditingChange: (editing: boolean) => void;
|
|
18
|
+
/** The accessible name of the field and of its editor. */
|
|
19
|
+
label: string;
|
|
20
|
+
/** Shown at rest and in the editor when the value is empty. @default "Empty" */
|
|
21
|
+
placeholder?: string;
|
|
22
|
+
/** Collapse the rendered view to this many lines behind a `ReadMore`. */
|
|
23
|
+
collapsedLines?: number;
|
|
24
|
+
/** Extra toolbar content for the editor, after its built-in groups. */
|
|
25
|
+
toolbar?: ReactNode;
|
|
26
|
+
/** Stores a pasted/dropped/picked image — see `MarkdownEditorProps.uploadImage`. */
|
|
27
|
+
uploadImage?: ImageUploader;
|
|
28
|
+
/**
|
|
29
|
+
* What is shown when the commit REJECTS (never a `{ refusal }`, which
|
|
30
|
+
* renders its own text).
|
|
31
|
+
*/
|
|
32
|
+
failureMessage?: string;
|
|
33
|
+
/** The rejected error, handed on so it can be logged or reported. */
|
|
34
|
+
onError?: (error: unknown) => void;
|
|
35
|
+
className?: string;
|
|
36
|
+
}
|
|
37
|
+
export declare function InlineMarkdownEdit({ value, onCommit, editing, onEditingChange, label, placeholder, collapsedLines, toolbar, uploadImage, failureMessage, onError, className, }: InlineMarkdownEditProps): import("react").JSX.Element;
|
|
@@ -10,7 +10,13 @@ import { type ImageUploadState, type ImageUploader } from "../lib/markdown/image
|
|
|
10
10
|
* contenteditable host, never a proxy element.
|
|
11
11
|
*/
|
|
12
12
|
export interface MarkdownEditorHandle {
|
|
13
|
-
|
|
13
|
+
/**
|
|
14
|
+
* Focus the surface. `caret` places the caret at the document's `"start"` or
|
|
15
|
+
* `"end"` (snapped to a real caret stop); omit it to leave the caret wherever
|
|
16
|
+
* the browser puts it. DX-3372: `InlineMarkdownEdit` opens with the caret at
|
|
17
|
+
* the end, the same place `InlineEdit` puts it.
|
|
18
|
+
*/
|
|
19
|
+
focus: (caret?: "start" | "end") => void;
|
|
14
20
|
}
|
|
15
21
|
export interface MarkdownEditorProps {
|
|
16
22
|
/** The markdown. Controlled when `onChange` is given. */
|
|
@@ -9,11 +9,11 @@ export declare const code: import("tailwind-variants").TVReturnType<{
|
|
|
9
9
|
footer?: import("tailwind-variants").ClassValue;
|
|
10
10
|
hint?: import("tailwind-variants").ClassValue;
|
|
11
11
|
root?: import("tailwind-variants").ClassValue;
|
|
12
|
-
control?: import("tailwind-variants").ClassValue;
|
|
13
12
|
rendered?: import("tailwind-variants").ClassValue;
|
|
14
13
|
layers?: import("tailwind-variants").ClassValue;
|
|
15
14
|
gutter?: import("tailwind-variants").ClassValue;
|
|
16
15
|
fade?: import("tailwind-variants").ClassValue;
|
|
16
|
+
control?: import("tailwind-variants").ClassValue;
|
|
17
17
|
scroller?: import("tailwind-variants").ClassValue;
|
|
18
18
|
expand?: import("tailwind-variants").ClassValue;
|
|
19
19
|
};
|
|
@@ -29,11 +29,11 @@ export declare const code: import("tailwind-variants").TVReturnType<{
|
|
|
29
29
|
footer?: import("tailwind-variants").ClassValue;
|
|
30
30
|
hint?: import("tailwind-variants").ClassValue;
|
|
31
31
|
root?: import("tailwind-variants").ClassValue;
|
|
32
|
-
control?: import("tailwind-variants").ClassValue;
|
|
33
32
|
rendered?: import("tailwind-variants").ClassValue;
|
|
34
33
|
layers?: import("tailwind-variants").ClassValue;
|
|
35
34
|
gutter?: import("tailwind-variants").ClassValue;
|
|
36
35
|
fade?: import("tailwind-variants").ClassValue;
|
|
36
|
+
control?: import("tailwind-variants").ClassValue;
|
|
37
37
|
scroller?: import("tailwind-variants").ClassValue;
|
|
38
38
|
expand?: import("tailwind-variants").ClassValue;
|
|
39
39
|
};
|
|
@@ -65,11 +65,11 @@ export declare const code: import("tailwind-variants").TVReturnType<{
|
|
|
65
65
|
footer?: import("tailwind-variants").ClassValue;
|
|
66
66
|
hint?: import("tailwind-variants").ClassValue;
|
|
67
67
|
root?: import("tailwind-variants").ClassValue;
|
|
68
|
-
control?: import("tailwind-variants").ClassValue;
|
|
69
68
|
rendered?: import("tailwind-variants").ClassValue;
|
|
70
69
|
layers?: import("tailwind-variants").ClassValue;
|
|
71
70
|
gutter?: import("tailwind-variants").ClassValue;
|
|
72
71
|
fade?: import("tailwind-variants").ClassValue;
|
|
72
|
+
control?: import("tailwind-variants").ClassValue;
|
|
73
73
|
scroller?: import("tailwind-variants").ClassValue;
|
|
74
74
|
expand?: import("tailwind-variants").ClassValue;
|
|
75
75
|
};
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The caller's refusal of a value, with the reason that will be shown.
|
|
3
|
+
*/
|
|
4
|
+
export interface InlineEditRefusal {
|
|
5
|
+
refusal: string;
|
|
6
|
+
}
|
|
7
|
+
/** What `onCommit` may report. Returning nothing accepts the value. */
|
|
8
|
+
export type InlineEditOutcome = void | InlineEditRefusal;
|
|
9
|
+
/** Every in-place editor's `onCommit`: the new value and the value editing began from. */
|
|
10
|
+
export type InlineEditCommit = (value: string, base: string) => InlineEditOutcome | Promise<InlineEditOutcome>;
|
|
11
|
+
export declare function isRefusal(outcome: InlineEditOutcome): outcome is InlineEditRefusal;
|
|
12
|
+
export declare function isPromise(outcome: InlineEditOutcome | Promise<InlineEditOutcome>): outcome is Promise<InlineEditOutcome>;
|
|
13
|
+
export declare const DEFAULT_FAILURE = "Could not save. Your text is still here \u2014 press Enter to try again.";
|
|
14
|
+
/**
|
|
15
|
+
* A refusal nobody can read leaves the field open with nothing beside it — the
|
|
16
|
+
* exact silent failure the outcome contract exists to rule out — so an empty
|
|
17
|
+
* reason is a programming error, thrown rather than rendered.
|
|
18
|
+
*/
|
|
19
|
+
export declare function assertReadableRefusal(component: string, reason: string, source: "validate" | "onCommit"): void;
|
|
20
|
+
/**
|
|
21
|
+
* THE MESSAGE IS AN OVERLAY, for the reason `InlineEdit` measured: in normal
|
|
22
|
+
* flow a refusal grows the control's own wrapper, which inside a fixed-height
|
|
23
|
+
* row shoves everything beside it. Absolutely positioned, it cannot contribute
|
|
24
|
+
* height. The parent must be `relative`.
|
|
25
|
+
*/
|
|
26
|
+
export declare function OutcomeMessage({ id, children, className, }: {
|
|
27
|
+
id?: string;
|
|
28
|
+
children: string;
|
|
29
|
+
className?: string;
|
|
30
|
+
}): import("react").JSX.Element;
|
|
@@ -1,48 +1,56 @@
|
|
|
1
|
-
import type { CanvasNode, CanvasOrientation, NodeRenderer } from "./types";
|
|
1
|
+
import type { CanvasGraph, CanvasGroup, CanvasNode, CanvasOrientation, CanvasPlacedEdge, NodeRenderer } from "./types";
|
|
2
2
|
export interface NodeCanvasProps<Extra = unknown> {
|
|
3
|
-
/** The whole
|
|
4
|
-
|
|
3
|
+
/** The whole graph — every node and edge, however many scopes it spans. Never mutated. */
|
|
4
|
+
graph: CanvasGraph<Extra>;
|
|
5
|
+
/** Named clusters nodes can belong to via `CanvasNode.groupId`. Flat — see `CanvasGroup`. */
|
|
6
|
+
groups?: readonly CanvasGroup[];
|
|
5
7
|
/**
|
|
6
|
-
* What this canvas IS — "
|
|
8
|
+
* What this canvas IS — "Import graph for the docs map", "Service dependency graph".
|
|
7
9
|
*
|
|
8
|
-
* Required for the same reason `StatusChecklist.label` and
|
|
9
|
-
*
|
|
10
|
-
*
|
|
10
|
+
* Required for the same reason `StatusChecklist.label` and `KanbanBoard.label`
|
|
11
|
+
* are: it is the accessible name of the whole structure, and somebody landing
|
|
12
|
+
* on it by keyboard or in the list view has nothing else to tell them what
|
|
11
13
|
* they are inside.
|
|
12
14
|
*/
|
|
13
15
|
label: string;
|
|
14
16
|
/**
|
|
15
17
|
* The node body. Receives the consumer's own node type and a context of
|
|
16
|
-
* purely structural facts
|
|
18
|
+
* purely structural facts — see `NodeRenderContext`.
|
|
17
19
|
*
|
|
18
|
-
* A RENDER PROP RATHER THAN CHILDREN-AS-A-FUNCTION,
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
20
|
+
* A RENDER PROP RATHER THAN CHILDREN-AS-A-FUNCTION, for the same reason
|
|
21
|
+
* `ProvenanceDisclosure` takes `actions` and `Chat` takes a `components` map:
|
|
22
|
+
* a canvas draws MANY nodes and `children` reads as one. Optional: the
|
|
23
|
+
* default draws the label, and a member count when this box stands in for a
|
|
24
|
+
* group or a condensed cycle.
|
|
25
|
+
*
|
|
26
|
+
* Called with a SYNTHETIC node for a collapsed group or cycle — `{id, label}`
|
|
27
|
+
* only, `Extra`'s own fields absent — since no single real node's `Extra`
|
|
28
|
+
* would be honest to hand back for a box standing in for several.
|
|
26
29
|
*/
|
|
27
30
|
renderNode?: NodeRenderer<Extra>;
|
|
31
|
+
/**
|
|
32
|
+
* The hover summary's content. Defaults to the node's `label`. Return
|
|
33
|
+
* `null`/`undefined` to suppress the tooltip for a particular node.
|
|
34
|
+
*/
|
|
35
|
+
renderSummary?: (node: CanvasNode<Extra>) => React.ReactNode;
|
|
36
|
+
/** A class name for one drawn edge, keyed on its (possibly aggregated) `kind`. */
|
|
37
|
+
edgeClassName?: (edge: CanvasPlacedEdge) => string | undefined;
|
|
28
38
|
/** Which way the chart grows. See `CanvasOrientation`. */
|
|
29
39
|
orientation?: CanvasOrientation;
|
|
30
|
-
/** Levels below the current root to draw. `1` is the root and its children. */
|
|
31
|
-
depth?: number;
|
|
32
40
|
/** Along-axis extent of a node that does not declare its own, in px. */
|
|
33
41
|
nodeWidth?: number;
|
|
34
42
|
/** Cross-axis extent of a node that does not declare its own, in px. */
|
|
35
43
|
nodeHeight?: number;
|
|
36
44
|
/** Height of the scrolling viewport. Any CSS length. */
|
|
37
45
|
height?: string;
|
|
38
|
-
/**
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
+
/** Which group is currently drilled into. `null` is the top level. Controlled. */
|
|
47
|
+
expandedGroupId?: string | null;
|
|
48
|
+
/** Initial drilled-into group for uncontrolled use. Default `null` (top level). */
|
|
49
|
+
defaultExpandedGroupId?: string | null;
|
|
50
|
+
/** Fired whenever the drilled-into group changes, from either a click or the keyboard. */
|
|
51
|
+
onExpandedGroupIdChange?: (groupId: string | null) => void;
|
|
52
|
+
/** Fired when an ORDINARY node (not a group, not a cycle) is clicked. Navigation is the consumer's. */
|
|
53
|
+
onNodeClick?: (node: CanvasNode<Extra>) => void;
|
|
46
54
|
/** Fired when a node drag commits. The offset is from its laid-out position. */
|
|
47
55
|
onNodeDragEnd?: (event: {
|
|
48
56
|
id: string;
|
|
@@ -55,4 +63,4 @@ export interface NodeCanvasProps<Extra = unknown> {
|
|
|
55
63
|
disabled?: boolean;
|
|
56
64
|
className?: string;
|
|
57
65
|
}
|
|
58
|
-
export declare function NodeCanvas<Extra = unknown>({
|
|
66
|
+
export declare function NodeCanvas<Extra = unknown>({ graph, groups, label, renderNode, renderSummary, edgeClassName, orientation, nodeWidth, nodeHeight, height, expandedGroupId, defaultExpandedGroupId, onExpandedGroupIdChange, onNodeClick, onNodeDragEnd, disabled, className, }: NodeCanvasProps<Extra>): import("react").JSX.Element;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { NodeCanvas, type NodeCanvasProps } from "./NodeCanvas";
|
|
2
|
-
export { LAYOUT_DEFAULTS,
|
|
3
|
-
export type { CanvasEdge, CanvasLayout, CanvasNode, CanvasOrientation, LayoutOptions, NodeRenderContext, NodeRenderer, PlacedNode, } from "./types";
|
|
2
|
+
export { LAYOUT_DEFAULTS, edgePath, layoutGraph, neighbourhood } from "./layout";
|
|
3
|
+
export type { CanvasCycleScope, CanvasEdge, CanvasGraph, CanvasGroup, CanvasLayout, CanvasNode, CanvasOrientation, CanvasPlacedEdge, CanvasScope, LayoutOptions, NodeRenderContext, NodeRenderer, PlacedNode, } from "./types";
|
|
@@ -1,17 +1,29 @@
|
|
|
1
|
-
import type { CanvasLayout,
|
|
1
|
+
import type { CanvasGraph, CanvasGroup, CanvasLayout, CanvasPlacedEdge, CanvasScope, LayoutOptions } from "./types";
|
|
2
2
|
export declare const LAYOUT_DEFAULTS: Required<LayoutOptions>;
|
|
3
3
|
/**
|
|
4
|
-
* Lay a
|
|
4
|
+
* Lay out one scope of a graph.
|
|
5
5
|
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
6
|
+
* `scope` is `null` for the top level, a `CanvasGroup.id` to draw that
|
|
7
|
+
* group's own members, or a `CanvasCycleScope` to draw a condensed cycle's
|
|
8
|
+
* own members (see that type's doc for why it is not just "another group
|
|
9
|
+
* id" — it skips this function's own condensing pre-pass on purpose).
|
|
10
|
+
* Coordinates are plane-local and start at 0 on both axes: the caller
|
|
11
|
+
* decides where the plane sits and how much padding surrounds it.
|
|
8
12
|
*/
|
|
9
|
-
export declare function
|
|
13
|
+
export declare function layoutGraph<Extra>(graph: CanvasGraph<Extra>, groups: readonly CanvasGroup[], scope: CanvasScope, options?: LayoutOptions): CanvasLayout<Extra>;
|
|
14
|
+
/** The SVG `d` attribute for one drawn edge. See `smoothPath` above. */
|
|
15
|
+
export declare function edgePath(edge: CanvasPlacedEdge): string;
|
|
10
16
|
/**
|
|
11
|
-
*
|
|
17
|
+
* Every real node id reachable from `id` within `hops` steps, along either
|
|
18
|
+
* edge direction — the "1–2-hop neighbourhood" `NodeRenderContext.focusDistance`
|
|
19
|
+
* reports. Undirected on purpose: a node's neighbourhood, for the purpose of
|
|
20
|
+
* "what should stay legible while I'm reading this one", is what points at it
|
|
21
|
+
* as much as what it points at.
|
|
12
22
|
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* renders nothing is how a broken `rootId` looks like a styling bug.
|
|
23
|
+
* Keyed by the drawn (possibly condensed) ids, not raw graph node ids — the
|
|
24
|
+
* canvas calls this with whatever `CanvasPlacedEdge` already uses.
|
|
16
25
|
*/
|
|
17
|
-
export declare function
|
|
26
|
+
export declare function neighbourhood(id: string, edges: readonly {
|
|
27
|
+
from: string;
|
|
28
|
+
to: string;
|
|
29
|
+
}[], hops: number): Map<string, number>;
|
|
@@ -1,76 +1,165 @@
|
|
|
1
1
|
import type { ReactNode } from "react";
|
|
2
2
|
/**
|
|
3
|
-
* One node of the
|
|
3
|
+
* One node of the graph.
|
|
4
4
|
*
|
|
5
|
-
* `Extra` carries the consumer's own fields
|
|
6
|
-
*
|
|
5
|
+
* `Extra` carries the consumer's own fields, so `renderNode` receives their
|
|
6
|
+
* type rather than ours plus a cast:
|
|
7
7
|
*
|
|
8
8
|
* ```ts
|
|
9
|
-
* type
|
|
10
|
-
* const
|
|
11
|
-
*
|
|
9
|
+
* type Service = { owner: string; deployed: boolean };
|
|
10
|
+
* const nodes: CanvasNode<Service>[] = [
|
|
11
|
+
* { id: "api", label: "API", owner: "ada", deployed: true },
|
|
12
|
+
* ];
|
|
13
|
+
* <NodeCanvas graph={{ nodes, edges }} renderNode={(node) => <span>{node.owner}</span>} />
|
|
12
14
|
* ```
|
|
13
|
-
*
|
|
14
|
-
* Written as an intersection rather than an interface with a type parameter
|
|
15
|
-
* because the recursion has to carry `Extra` into `children` — an interface
|
|
16
|
-
* cannot refer to its own instantiation that way without a self-referencing
|
|
17
|
-
* constraint that every consumer then has to spell out.
|
|
18
15
|
*/
|
|
19
16
|
export type CanvasNode<Extra = unknown> = Extra & {
|
|
20
17
|
/** Stable across renders. Node positions, focus and drag offsets are keyed on it. */
|
|
21
18
|
id: string;
|
|
22
19
|
/**
|
|
23
|
-
* The accessible name, the
|
|
20
|
+
* The accessible name, the list-view row text, and the default body.
|
|
24
21
|
*
|
|
25
22
|
* A plain string, not a `ReactNode`, and that is deliberate: it is read
|
|
26
|
-
* aloud and printed into a
|
|
23
|
+
* aloud and printed into a row, and neither of those can do anything with
|
|
27
24
|
* an element tree. Rich content belongs in `renderNode`.
|
|
28
25
|
*/
|
|
29
26
|
label: string;
|
|
30
|
-
|
|
27
|
+
/**
|
|
28
|
+
* Which `CanvasGroup` this node belongs to, if any. A node with no group
|
|
29
|
+
* sits at the top level next to every declared group's own aggregate node.
|
|
30
|
+
* Groups are flat — a group cannot itself belong to another group — which
|
|
31
|
+
* matches every real case this shipped with (a domain, a package, a team):
|
|
32
|
+
* one level of clustering is what "collapse the noisy part" needs, and nested
|
|
33
|
+
* clustering is a UI nobody asked for yet. Add it if a real consumer needs it.
|
|
34
|
+
*/
|
|
35
|
+
groupId?: string;
|
|
31
36
|
/** Along-axis extent for this node only, when it differs from the canvas default. */
|
|
32
37
|
width?: number;
|
|
33
38
|
/** Cross-axis extent for this node only, when it differs from the canvas default. */
|
|
34
39
|
height?: number;
|
|
35
40
|
};
|
|
41
|
+
/**
|
|
42
|
+
* A directed connection between two node ids.
|
|
43
|
+
*
|
|
44
|
+
* `kind` is a free-form string the library assigns NO meaning to — same rule
|
|
45
|
+
* as `label`'s absence of a `type` field. A consumer distinguishing "imports"
|
|
46
|
+
* from "calls" reads `kind` back out in `edgeClassName` or in its own styling;
|
|
47
|
+
* the library never brands one kind as more important than another.
|
|
48
|
+
*/
|
|
49
|
+
export interface CanvasEdge {
|
|
50
|
+
from: string;
|
|
51
|
+
to: string;
|
|
52
|
+
kind?: string;
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* A named cluster of nodes, collapsed to one box by default.
|
|
56
|
+
*
|
|
57
|
+
* COLLAPSED IS THE DEFAULT because a real graph worth drawing (the spike's
|
|
58
|
+
* 402-node/2,099-edge import graph) is unreadable — and, for a graph with
|
|
59
|
+
* enough cross-cluster cycles, catastrophically slow to lay out — at full
|
|
60
|
+
* detail. A group's aggregate node stands in for every member until a
|
|
61
|
+
* consumer drills into it; see `NodeCanvasProps.expandedGroupId`.
|
|
62
|
+
*/
|
|
63
|
+
export interface CanvasGroup {
|
|
64
|
+
id: string;
|
|
65
|
+
label: string;
|
|
66
|
+
/** Along-axis extent of this group's collapsed box, when it differs from the default. */
|
|
67
|
+
width?: number;
|
|
68
|
+
/** Cross-axis extent of this group's collapsed box, when it differs from the default. */
|
|
69
|
+
height?: number;
|
|
70
|
+
}
|
|
71
|
+
/** The whole graph. Never mutated by the canvas. */
|
|
72
|
+
export interface CanvasGraph<Extra = unknown> {
|
|
73
|
+
nodes: readonly CanvasNode<Extra>[];
|
|
74
|
+
edges: readonly CanvasEdge[];
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* The scope drilled into when a consumer clicks a CONDENSED CYCLE rather than
|
|
78
|
+
* a declared group — captured directly from the `PlacedNode.memberIds` the
|
|
79
|
+
* click landed on, since a cycle has no stable, externally-nameable id of its
|
|
80
|
+
* own the way a `CanvasGroup` does.
|
|
81
|
+
*
|
|
82
|
+
* `layoutGraph` treats this shape as an instruction to skip its own
|
|
83
|
+
* cycle-condensing pre-pass for this call: every member of a genuine strongly
|
|
84
|
+
* connected component is, by definition, reachable from every other member
|
|
85
|
+
* using ONLY edges between members of that same component (that is what
|
|
86
|
+
* "strongly connected" means) — so re-running Tarjan on exactly this member
|
|
87
|
+
* set would immediately re-discover the identical single component and
|
|
88
|
+
* collapse it right back to one box, drilling in would show nothing new, and
|
|
89
|
+
* a naive implementation of "drill into a cycle" is a no-op wearing a
|
|
90
|
+
* breadcrumb. Skipping condensation here hands the (now small, already
|
|
91
|
+
* isolated) subgraph to dagre's OWN cycle-breaking pass directly — the exact
|
|
92
|
+
* cost/quality tradeoff this card's condensing pre-pass exists to avoid at
|
|
93
|
+
* the FULL graph's scale is perfectly acceptable once bounded to one cycle's
|
|
94
|
+
* membership.
|
|
95
|
+
*/
|
|
96
|
+
export interface CanvasCycleScope {
|
|
97
|
+
cycleMemberIds: readonly string[];
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* What `layoutGraph`'s third argument names: the top level (`null`), a
|
|
101
|
+
* declared group's own members (its `CanvasGroup.id`), or a condensed
|
|
102
|
+
* cycle's own members (`CanvasCycleScope`). See `CanvasCycleScope` for why
|
|
103
|
+
* the last case is not just "another group id".
|
|
104
|
+
*/
|
|
105
|
+
export type CanvasScope = string | null | CanvasCycleScope;
|
|
36
106
|
/**
|
|
37
107
|
* Which way the chart grows.
|
|
38
108
|
*
|
|
39
|
-
* `vertical`
|
|
40
|
-
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
109
|
+
* `vertical` ranks top to bottom — the shape most people picture. `horizontal`
|
|
110
|
+
* ranks left to right, which is what a graph with long labels and few ranks
|
|
111
|
+
* actually wants: label text runs along the rank axis in one and across it in
|
|
112
|
+
* the other, so a horizontal chart of the same graph is narrower and reads
|
|
113
|
+
* without truncation.
|
|
44
114
|
*/
|
|
45
115
|
export type CanvasOrientation = "vertical" | "horizontal";
|
|
46
|
-
/**
|
|
116
|
+
/**
|
|
117
|
+
* A node with its box resolved, in plane coordinates. `x`/`y` are its
|
|
118
|
+
* TOP-LEFT. This is what the layout actually drew — which is not always one
|
|
119
|
+
* real node: a collapsed group or a condensed cycle draws as ONE placed node
|
|
120
|
+
* standing in for several.
|
|
121
|
+
*/
|
|
47
122
|
export interface PlacedNode<Extra = unknown> {
|
|
48
123
|
id: string;
|
|
49
|
-
node
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
124
|
+
/** Null for a placed node standing in for a group or a condensed cycle. */
|
|
125
|
+
node: CanvasNode<Extra> | null;
|
|
126
|
+
/** Set when this placed node IS a collapsed group's aggregate box. */
|
|
127
|
+
group: CanvasGroup | null;
|
|
128
|
+
/**
|
|
129
|
+
* Set when this placed node is a condensed strongly-connected cluster —
|
|
130
|
+
* nodes that mutually reach each other with no acyclic rank to give them.
|
|
131
|
+
* Collapsing a cycle is not a user-facing "group" (nobody named it), but it
|
|
132
|
+
* renders and drills in exactly like one: see the module doc in `layout.ts`.
|
|
133
|
+
*/
|
|
134
|
+
cycle: boolean;
|
|
135
|
+
/**
|
|
136
|
+
* How many real graph nodes this placed node stands for. `1` for an
|
|
137
|
+
* ordinary node; more than one for a collapsed group or a condensed cycle.
|
|
138
|
+
*/
|
|
139
|
+
memberCount: number;
|
|
140
|
+
/** Ids of the real nodes this placed node stands for. `[id]` for an ordinary node. */
|
|
141
|
+
memberIds: readonly string[];
|
|
54
142
|
x: number;
|
|
55
143
|
y: number;
|
|
56
144
|
width: number;
|
|
57
145
|
height: number;
|
|
58
|
-
/** How many children it has, whether or not this view is showing them. */
|
|
59
|
-
childCount: number;
|
|
60
|
-
/**
|
|
61
|
-
* It has children and this view is not drawing them — the node sits on the
|
|
62
|
-
* bottom row of the visible depth. The affordance to descend belongs here.
|
|
63
|
-
*/
|
|
64
|
-
hasHiddenChildren: boolean;
|
|
65
146
|
}
|
|
66
|
-
/**
|
|
67
|
-
export interface
|
|
147
|
+
/** One drawn connection. Both ends are always present in the returned `nodes`. */
|
|
148
|
+
export interface CanvasPlacedEdge {
|
|
68
149
|
from: string;
|
|
69
150
|
to: string;
|
|
151
|
+
kind?: string;
|
|
152
|
+
/** How many raw edges this drawn edge aggregates. `1` for an ordinary edge. */
|
|
153
|
+
weight: number;
|
|
154
|
+
/** The route dagre computed, in plane coordinates, at least two points. */
|
|
155
|
+
points: readonly {
|
|
156
|
+
x: number;
|
|
157
|
+
y: number;
|
|
158
|
+
}[];
|
|
70
159
|
}
|
|
71
160
|
export interface CanvasLayout<Extra = unknown> {
|
|
72
161
|
nodes: PlacedNode<Extra>[];
|
|
73
|
-
edges:
|
|
162
|
+
edges: CanvasPlacedEdge[];
|
|
74
163
|
/** Extent of the laid-out nodes. The plane is this plus padding on each side. */
|
|
75
164
|
width: number;
|
|
76
165
|
height: number;
|
|
@@ -80,34 +169,39 @@ export interface LayoutOptions {
|
|
|
80
169
|
nodeWidth?: number;
|
|
81
170
|
/** Cross-axis extent of a node that does not declare its own. */
|
|
82
171
|
nodeHeight?: number;
|
|
83
|
-
/** Clear space between two adjacent nodes on the same
|
|
172
|
+
/** Clear space between two adjacent nodes on the same rank. */
|
|
84
173
|
siblingGap?: number;
|
|
85
|
-
/** Clear space between one
|
|
174
|
+
/** Clear space between one rank and the next. */
|
|
86
175
|
levelGap?: number;
|
|
87
176
|
orientation?: CanvasOrientation;
|
|
88
|
-
/**
|
|
89
|
-
* How many levels BELOW the root to draw. `1` shows the root and its
|
|
90
|
-
* children; `0` shows the root alone.
|
|
91
|
-
*/
|
|
92
|
-
depth?: number;
|
|
93
177
|
}
|
|
94
178
|
/**
|
|
95
179
|
* What `renderNode` is told about the node it is drawing.
|
|
96
180
|
*
|
|
97
|
-
* Every field is structural — a fact about the node's place in the
|
|
98
|
-
* the current interaction. None of them is a fact about what the node is.
|
|
181
|
+
* Every field is structural — a fact about the node's place in the graph or
|
|
182
|
+
* in the current interaction. None of them is a fact about what the node is.
|
|
99
183
|
*/
|
|
100
184
|
export interface NodeRenderContext {
|
|
101
|
-
/**
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
185
|
+
/**
|
|
186
|
+
* This placed node stands in for a whole group or a condensed cycle rather
|
|
187
|
+
* than one real node. `renderNode` still receives a `CanvasNode`-shaped
|
|
188
|
+
* value for it (see `NodeCanvas`'s synthetic node), but `memberCount` is
|
|
189
|
+
* what says there is more inside.
|
|
190
|
+
*/
|
|
191
|
+
isGroup: boolean;
|
|
192
|
+
/** How many real nodes this placed node represents. `1` for an ordinary node. */
|
|
193
|
+
memberCount: number;
|
|
108
194
|
/** This node carries the canvas's single tab stop. */
|
|
109
195
|
isFocused: boolean;
|
|
110
196
|
/** A pointer is carrying this node right now. */
|
|
111
197
|
isDragging: boolean;
|
|
198
|
+
/**
|
|
199
|
+
* Hops from the focused node, along either edge direction: `0` is the
|
|
200
|
+
* focused node itself, `1`/`2` its one- and two-hop neighbours. `null` when
|
|
201
|
+
* nothing is focused, or this node is further away than the canvas tracks.
|
|
202
|
+
* Lets `renderNode` dim everything outside the neighbourhood a keyboard or
|
|
203
|
+
* screen-reader user is currently reading.
|
|
204
|
+
*/
|
|
205
|
+
focusDistance: number | null;
|
|
112
206
|
}
|
|
113
207
|
export type NodeRenderer<Extra = unknown> = (node: CanvasNode<Extra>, context: NodeRenderContext) => ReactNode;
|
package/dist/types/index.d.ts
CHANGED
|
@@ -21,7 +21,9 @@ export { Skeleton, SkeletonText, LoadingOverlay, type SkeletonProps, type Skelet
|
|
|
21
21
|
export { ErrorBoundary, type ErrorBoundaryProps } from "./components/ErrorBoundary";
|
|
22
22
|
export { Field, FieldSet, type FieldProps, type FieldSetProps } from "./components/Field";
|
|
23
23
|
export { Input, Textarea, type InputProps, type TextareaProps } from "./components/Input";
|
|
24
|
-
export { InlineEdit, type InlineEditProps, type InlineEditRefusal, type InlineEditOutcome, } from "./components/InlineEdit";
|
|
24
|
+
export { InlineEdit, type InlineEditProps, type InlineEditRefusal, type InlineEditOutcome, type InlineEditCommit, } from "./components/InlineEdit";
|
|
25
|
+
export { EditGutter, type EditGutterProps, type EditActivation } from "./components/EditGutter";
|
|
26
|
+
export { InlineMarkdownEdit, type InlineMarkdownEditProps } from "./components/InlineMarkdownEdit";
|
|
25
27
|
export { SecretField, type SecretFieldProps, type SecretValue } from "./components/SecretField";
|
|
26
28
|
export { SettingRow, SettingGroup, type SettingRowProps, type SettingGroupProps, type SettingRowControlRenderProps, } from "./components/SettingRow";
|
|
27
29
|
export { DescriptionList, DescriptionListItem, type DescriptionListProps, type DescriptionListItemProps, type DescriptionListEntry, } from "./components/DescriptionList";
|
|
@@ -124,7 +126,7 @@ export { UseCaseCard, RoadmapItemCard, RoadmapSwimlaneBoard, UseCaseLedgerPage,
|
|
|
124
126
|
export { ProvenanceDisclosure, ProvenanceDetail, ProvenanceBadge, ConfidenceReadout, ConfidenceMeter, ConfidenceBar, provenanceStateLabel, confidenceBand, confidenceScore, scoredConfidence, ratedConfidence, type ProvenanceRecord, type ProvenanceState, type ProvenanceSource, type ProvenanceCheck, type ProvenanceCall, type ProvenanceSignoff, type ConfidenceBand, type ConfidenceScore, type ProvenanceConfidence, type ConfidenceReadoutProps, type ConfidenceBarProps, type ConfidenceBarSize, type ProvenanceDisclosureProps, type ProvenanceDetailProps, type ProvenanceDetailTitleAs, type ProvenanceTriggerBadge, type ProvenanceBadgeProps, type ProvenanceBadgeAppearance, type ConfidenceMeterProps, } from "./components/provenance";
|
|
125
127
|
export { confidenceLevel, CONFIDENCE_LEVEL_LABELS, type ConfidenceLevel } from "./lib/confidence";
|
|
126
128
|
export { createSimStore, resetSimStores, useSimSettings, setSimSettings, getNetworkSpeed, getDataSource, simulateLatency, SimNetworkError, type SimStore, type SimStoreOptions, type SimSettings, type NetworkSpeed, type DataSource, type SimNamespace, } from "./lib/sim";
|
|
127
|
-
export { NodeCanvas, LAYOUT_DEFAULTS,
|
|
129
|
+
export { NodeCanvas, LAYOUT_DEFAULTS, edgePath, layoutGraph, neighbourhood, type NodeCanvasProps, type CanvasCycleScope, type CanvasEdge, type CanvasGraph, type CanvasGroup, type CanvasLayout, type CanvasNode, type CanvasOrientation, type CanvasPlacedEdge, type CanvasScope, type LayoutOptions, type NodeRenderContext, type NodeRenderer, type PlacedNode, } from "./components/node-canvas";
|
|
128
130
|
export { defineRecordType, resetRecordTypes, useRecord, useRecords, useStaleness, write, writeAll, peekRecord, readState, readStaleness, subscribeToKey, subscribeToStaleness, retainKeys, sweepRecords, setRecordStoreTenant, getRecordStoreTenant, flushRecordNotifications, resetRecordStore, recordStoreStats, UNKNOWN_STATE, normalizeTypeName, normalizeTimestamp, recordKey, isRecordRef, type RecordRef, type ReadOptions, type RecordPayload, type RecordState, type RecordTypeOptions, type RecordTypeToken, type StalenessEntry, type WriteAllResult, type WriteOptions, type WriteResult, type WriteSource, type WriteVerdict, } from "./lib/records";
|
|
129
131
|
export { RealtimeProvider, useRealtime, useRealtimeEpoch, useRealtimeHealth, useRealtimeRegistry, SubscriptionRegistry, normalizeScope, scopeKey, subscriptionKey, readRealtimeEpoch, subscribeToRealtimeEpoch, subscribeToRealtimeEvents, resetRealtimeSignals, type RealtimeChannel, type RealtimeConnectionState, type RealtimeDiagnostic, type RealtimeEvent, type RealtimeHealth, type RealtimeProviderProps, type RealtimeScope, type RealtimeScopeInput, type RealtimeStatus, type RealtimeTransport, type RegistryOptions, type SubscriptionHealth, type SubscriptionLease, type SubscriptionRequest, } from "./lib/realtime";
|
|
130
132
|
export { useRecordRead, useRecordListRead, useRecordStoreSweep, applyMutationResult, optimisticWrite, beginOptimisticWrite, resetOptimisticWrites, type OptimisticHandle, type OptimisticWriteOptions, type OptimisticWriteSpec, type SlotDescriptor, acquireSlot, appendCreated, emptySlotSnapshot, readSlot, resetSlots, slotKeys, subscribeToSlot, writeSlot, RefetchRunner, registerActiveRead, resetActiveReads, type ActiveRead, type ListFetch, type ListFetchResult, type ListReadOptions, type ListReadResult, type ReadError, type RecordFetch, type RecordReadOptions, type RecordReadResult, type RunnerOptions, type SlotSnapshot, } from "./lib/reads";
|