@prnt/dagr-explorer 0.1.3
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/CHANGELOG.md +93 -0
- package/LICENSE +21 -0
- package/README.md +441 -0
- package/dist/base.d.ts +63 -0
- package/dist/base.d.ts.map +1 -0
- package/dist/base.js +20 -0
- package/dist/base.js.map +1 -0
- package/dist/camera.d.ts +61 -0
- package/dist/camera.d.ts.map +1 -0
- package/dist/camera.js +142 -0
- package/dist/camera.js.map +1 -0
- package/dist/context.d.ts +110 -0
- package/dist/context.d.ts.map +1 -0
- package/dist/context.js +71 -0
- package/dist/context.js.map +1 -0
- package/dist/dagr-explorer.d.ts +41 -0
- package/dist/dagr-explorer.d.ts.map +1 -0
- package/dist/dagr-explorer.js +13 -0
- package/dist/dagr-explorer.js.map +1 -0
- package/dist/errors.d.ts +55 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +57 -0
- package/dist/errors.js.map +1 -0
- package/dist/explorer-details.d.ts +44 -0
- package/dist/explorer-details.d.ts.map +1 -0
- package/dist/explorer-details.js +76 -0
- package/dist/explorer-details.js.map +1 -0
- package/dist/explorer-search.d.ts +31 -0
- package/dist/explorer-search.d.ts.map +1 -0
- package/dist/explorer-search.js +86 -0
- package/dist/explorer-search.js.map +1 -0
- package/dist/explorer-toolbar.d.ts +17 -0
- package/dist/explorer-toolbar.d.ts.map +1 -0
- package/dist/explorer-toolbar.js +44 -0
- package/dist/explorer-toolbar.js.map +1 -0
- package/dist/explorer-trace-toggle.d.ts +16 -0
- package/dist/explorer-trace-toggle.d.ts.map +1 -0
- package/dist/explorer-trace-toggle.js +8 -0
- package/dist/explorer-trace-toggle.js.map +1 -0
- package/dist/explorer-viewport.d.ts +69 -0
- package/dist/explorer-viewport.d.ts.map +1 -0
- package/dist/explorer-viewport.js +69 -0
- package/dist/explorer-viewport.js.map +1 -0
- package/dist/explorer-views.d.ts +24 -0
- package/dist/explorer-views.d.ts.map +1 -0
- package/dist/explorer-views.js +16 -0
- package/dist/explorer-views.js.map +1 -0
- package/dist/index.d.ts +48 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +33 -0
- package/dist/index.js.map +1 -0
- package/dist/isomorphic-layout-effect.d.ts +7 -0
- package/dist/isomorphic-layout-effect.d.ts.map +1 -0
- package/dist/isomorphic-layout-effect.js +7 -0
- package/dist/isomorphic-layout-effect.js.map +1 -0
- package/dist/labels.d.ts +67 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +50 -0
- package/dist/labels.js.map +1 -0
- package/dist/layout.d.ts +82 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +244 -0
- package/dist/layout.js.map +1 -0
- package/dist/navigation.d.ts +20 -0
- package/dist/navigation.d.ts.map +1 -0
- package/dist/navigation.js +44 -0
- package/dist/navigation.js.map +1 -0
- package/dist/root.d.ts +89 -0
- package/dist/root.d.ts.map +1 -0
- package/dist/root.js +401 -0
- package/dist/root.js.map +1 -0
- package/dist/search.d.ts +19 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +31 -0
- package/dist/search.js.map +1 -0
- package/dist/size.d.ts +12 -0
- package/dist/size.d.ts.map +1 -0
- package/dist/size.js +20 -0
- package/dist/size.js.map +1 -0
- package/dist/svg-base.d.ts +33 -0
- package/dist/svg-base.d.ts.map +1 -0
- package/dist/svg-base.js +89 -0
- package/dist/svg-base.js.map +1 -0
- package/dist/types.d.ts +61 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/use-explorer-camera.d.ts +56 -0
- package/dist/use-explorer-camera.d.ts.map +1 -0
- package/dist/use-explorer-camera.js +641 -0
- package/dist/use-explorer-camera.js.map +1 -0
- package/dist/use-explorer.d.ts +23 -0
- package/dist/use-explorer.d.ts.map +1 -0
- package/dist/use-explorer.js +26 -0
- package/dist/use-explorer.js.map +1 -0
- package/dist/validate.d.ts +20 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +99 -0
- package/dist/validate.js.map +1 -0
- package/dist/viewport-surface.d.ts +90 -0
- package/dist/viewport-surface.d.ts.map +1 -0
- package/dist/viewport-surface.js +485 -0
- package/dist/viewport-surface.js.map +1 -0
- package/dist/visible-set.d.ts +65 -0
- package/dist/visible-set.d.ts.map +1 -0
- package/dist/visible-set.js +168 -0
- package/dist/visible-set.js.map +1 -0
- package/package.json +62 -0
- package/src/base.ts +67 -0
- package/src/camera.ts +206 -0
- package/src/context.ts +168 -0
- package/src/dagr-explorer.tsx +85 -0
- package/src/errors.ts +85 -0
- package/src/explorer-details.tsx +156 -0
- package/src/explorer-search.tsx +140 -0
- package/src/explorer-toolbar.tsx +77 -0
- package/src/explorer-trace-toggle.tsx +34 -0
- package/src/explorer-viewport.tsx +181 -0
- package/src/explorer-views.tsx +61 -0
- package/src/index.ts +76 -0
- package/src/isomorphic-layout-effect.ts +7 -0
- package/src/labels.ts +109 -0
- package/src/layout.ts +298 -0
- package/src/navigation.ts +51 -0
- package/src/root.tsx +544 -0
- package/src/search.ts +36 -0
- package/src/size.ts +23 -0
- package/src/svg-base.tsx +173 -0
- package/src/types.ts +69 -0
- package/src/use-explorer-camera.ts +675 -0
- package/src/use-explorer.ts +32 -0
- package/src/validate.ts +173 -0
- package/src/viewport-surface.tsx +650 -0
- package/src/visible-set.ts +225 -0
- package/styles.css +253 -0
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which node an arrow key moves focus to, as one pure function.
|
|
3
|
+
*
|
|
4
|
+
* Candidates are the nodes whose center lies strictly in the arrow's
|
|
5
|
+
* half-plane from the focused node's center. The score is the distance along
|
|
6
|
+
* the arrow's axis plus twice the distance across it, lowest wins, and a tie
|
|
7
|
+
* goes to the lower id. Weighing the cross axis keeps a press on a row or a
|
|
8
|
+
* column rather than letting it drift onto a nearer diagonal.
|
|
9
|
+
*
|
|
10
|
+
* It scans every node in the layout, mounted or not: an unmounted node is a
|
|
11
|
+
* mark with no element, and focus has to be able to reach it. Linear, like
|
|
12
|
+
* the visible set's scan, and for the same reason.
|
|
13
|
+
*
|
|
14
|
+
* Internal to the package.
|
|
15
|
+
*/
|
|
16
|
+
export function nearestInDirection(index, fromId, direction) {
|
|
17
|
+
const from = index.nodeIds.indexOf(fromId);
|
|
18
|
+
const origin = index.nodeBoxes[from];
|
|
19
|
+
if (from < 0 || origin === undefined)
|
|
20
|
+
return null;
|
|
21
|
+
const fromX = origin.x + origin.width / 2;
|
|
22
|
+
const fromY = origin.y + origin.height / 2;
|
|
23
|
+
const horizontal = direction === 'left' || direction === 'right';
|
|
24
|
+
const sign = direction === 'right' || direction === 'down' ? 1 : -1;
|
|
25
|
+
let best = null;
|
|
26
|
+
let bestScore = Infinity;
|
|
27
|
+
index.nodeBoxes.forEach((box, i) => {
|
|
28
|
+
if (i === from)
|
|
29
|
+
return;
|
|
30
|
+
const dx = box.x + box.width / 2 - fromX;
|
|
31
|
+
const dy = box.y + box.height / 2 - fromY;
|
|
32
|
+
const along = (horizontal ? dx : dy) * sign;
|
|
33
|
+
if (!(along > 0))
|
|
34
|
+
return;
|
|
35
|
+
const score = along + 2 * Math.abs(horizontal ? dy : dx);
|
|
36
|
+
const id = index.nodeIds[i];
|
|
37
|
+
if (score < bestScore || (score === bestScore && best !== null && id < best)) {
|
|
38
|
+
best = id;
|
|
39
|
+
bestScore = score;
|
|
40
|
+
}
|
|
41
|
+
});
|
|
42
|
+
return best;
|
|
43
|
+
}
|
|
44
|
+
//# sourceMappingURL=navigation.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"navigation.js","sourceRoot":"","sources":["../src/navigation.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAOH,MAAM,UAAU,kBAAkB,CAChC,KAAkB,EAClB,MAAc,EACd,SAA4B;IAE5B,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;IACrC,IAAI,IAAI,GAAG,CAAC,IAAI,MAAM,KAAK,SAAS;QAAE,OAAO,IAAI,CAAC;IAClD,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,GAAG,CAAC,CAAC;IAC1C,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC;IAC3C,MAAM,UAAU,GAAG,SAAS,KAAK,MAAM,IAAI,SAAS,KAAK,OAAO,CAAC;IACjE,MAAM,IAAI,GAAG,SAAS,KAAK,OAAO,IAAI,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEpE,IAAI,IAAI,GAAkB,IAAI,CAAC;IAC/B,IAAI,SAAS,GAAG,QAAQ,CAAC;IACzB,KAAK,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,GAAG,EAAE,CAAC,EAAE,EAAE;QACjC,IAAI,CAAC,KAAK,IAAI;YAAE,OAAO;QACvB,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,KAAK,GAAG,CAAC,GAAG,KAAK,CAAC;QACzC,MAAM,EAAE,GAAG,GAAG,CAAC,CAAC,GAAG,GAAG,CAAC,MAAM,GAAG,CAAC,GAAG,KAAK,CAAC;QAC1C,MAAM,KAAK,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC;QAC5C,IAAI,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;YAAE,OAAO;QACzB,MAAM,KAAK,GAAG,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;QACzD,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAW,CAAC;QACtC,IAAI,KAAK,GAAG,SAAS,IAAI,CAAC,KAAK,KAAK,SAAS,IAAI,IAAI,KAAK,IAAI,IAAI,EAAE,GAAG,IAAI,CAAC,EAAE,CAAC;YAC7E,IAAI,GAAG,EAAE,CAAC;YACV,SAAS,GAAG,KAAK,CAAC;QACpB,CAAC;IACH,CAAC,CAAC,CAAC;IACH,OAAO,IAAI,CAAC;AACd,CAAC"}
|
package/dist/root.d.ts
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `ExplorerRoot`: the data, its validation and layout, and the state every
|
|
3
|
+
* part reads.
|
|
4
|
+
*
|
|
5
|
+
* **Controllable, and never past the owner.** `viewId` and `selectedId` are
|
|
6
|
+
* controllable because they are what a host syncs to a URL. Under a
|
|
7
|
+
* controlled value, every change that starts inside the explorer (a click, a
|
|
8
|
+
* search pick, an `ExplorerApi` call, a view switch reselecting, the selected
|
|
9
|
+
* node leaving the data, the active view being removed) calls the callback
|
|
10
|
+
* and changes nothing on screen until the prop does. A controlled value the
|
|
11
|
+
* data lacks renders as its fallback, with no corrective callback: a
|
|
12
|
+
* callback fired to fix the owner's own prop is how update loops start.
|
|
13
|
+
*
|
|
14
|
+
* **Changes the explorer makes on its own are found after commit,** in a
|
|
15
|
+
* layout effect, not in render: they call the owner's callbacks, which must
|
|
16
|
+
* not run during render. A layout effect re-renders before paint, so the
|
|
17
|
+
* stale frame is never seen.
|
|
18
|
+
*
|
|
19
|
+
* **Closing the drawer restores focus here,** whichever way it closed: to
|
|
20
|
+
* the element that opened it, else to the search field, else to the root
|
|
21
|
+
* element itself, never to the page. Only when focus was lost with the
|
|
22
|
+
* drawer (it was inside it, or on a node that left the data), so a host
|
|
23
|
+
* control that closes the drawer keeps its focus. `Escape` anywhere in the
|
|
24
|
+
* root closes the drawer, except where a part has its own precedence (the
|
|
25
|
+
* search field, the drawer) or a host control handled the key. On a node or
|
|
26
|
+
* the graph's surface it closes the drawer and nothing else, so focus stays
|
|
27
|
+
* where it is and a second `Escape` leaves the graph. It is taken in the
|
|
28
|
+
* capture phase for that, before the camera's own `Escape` would blur the
|
|
29
|
+
* graph and drop focus to the page.
|
|
30
|
+
*
|
|
31
|
+
* **Validation and layout run in render,** so a data error reaches an error
|
|
32
|
+
* boundary. Every view is validated; only the active one is laid out, and
|
|
33
|
+
* its layout is memoized by shape, so data re-created on every render keeps
|
|
34
|
+
* its layout and its camera.
|
|
35
|
+
*/
|
|
36
|
+
import type { CSSProperties, ReactElement, ReactNode, Ref } from 'react';
|
|
37
|
+
import type { ExplorerApi } from './context.js';
|
|
38
|
+
import type { ExplorerLabels } from './labels.js';
|
|
39
|
+
import type { ExplorerEdge, ExplorerGroup, ExplorerLayoutOptions, ExplorerNode, ExplorerView } from './types.js';
|
|
40
|
+
interface ExplorerRootCommonProps<N extends ExplorerNode, E extends ExplorerEdge> {
|
|
41
|
+
/** Required. The accessible name the parts derive theirs from. */
|
|
42
|
+
readonly label: string;
|
|
43
|
+
/** Controlled active view. An id no view has renders the first view. */
|
|
44
|
+
readonly viewId?: string | undefined;
|
|
45
|
+
/** The view to start on, read once at mount. Default: the first. */
|
|
46
|
+
readonly defaultViewId?: string | undefined;
|
|
47
|
+
readonly onViewChange?: ((viewId: string) => void) | undefined;
|
|
48
|
+
/** Controlled selection. `null` is controlled and empty. An unknown id renders as none. */
|
|
49
|
+
readonly selectedId?: string | null | undefined;
|
|
50
|
+
/** The node to start with, read once at mount. */
|
|
51
|
+
readonly defaultSelectedId?: string | null | undefined;
|
|
52
|
+
readonly onSelectedChange?: ((id: string | null) => void) | undefined;
|
|
53
|
+
/** The node to select when a view becomes active. Without it, a switch clears the selection. */
|
|
54
|
+
readonly selectOnViewChange?: ((view: ExplorerView<N, E>) => string | null) | undefined;
|
|
55
|
+
/** What search reads from a node. Default: the id and the label. */
|
|
56
|
+
readonly searchText?: ((node: N) => string) | undefined;
|
|
57
|
+
/** Throw `GROUP_ENCLOSES_NON_MEMBER` when a group outline would enclose a non-member. */
|
|
58
|
+
readonly strictGroups?: boolean | undefined;
|
|
59
|
+
readonly labels?: Partial<ExplorerLabels> | undefined;
|
|
60
|
+
readonly apiRef?: Ref<ExplorerApi> | undefined;
|
|
61
|
+
readonly className?: string | undefined;
|
|
62
|
+
readonly style?: CSSProperties | undefined;
|
|
63
|
+
readonly children?: ReactNode;
|
|
64
|
+
}
|
|
65
|
+
interface ExplorerRootViews<N extends ExplorerNode, E extends ExplorerEdge> {
|
|
66
|
+
readonly views: readonly ExplorerView<N, E>[];
|
|
67
|
+
readonly nodes?: never;
|
|
68
|
+
readonly edges?: never;
|
|
69
|
+
readonly groups?: never;
|
|
70
|
+
readonly layout?: never;
|
|
71
|
+
}
|
|
72
|
+
interface ExplorerRootGraph<N extends ExplorerNode, E extends ExplorerEdge> {
|
|
73
|
+
readonly views?: never;
|
|
74
|
+
readonly nodes: readonly N[];
|
|
75
|
+
readonly edges: readonly E[];
|
|
76
|
+
readonly groups?: readonly ExplorerGroup[] | undefined;
|
|
77
|
+
readonly layout?: ExplorerLayoutOptions<N> | undefined;
|
|
78
|
+
}
|
|
79
|
+
/**
|
|
80
|
+
* The root's props. The data is exactly one of two shapes, `views` or the
|
|
81
|
+
* single-graph shorthand (`nodes`, `edges`, `groups`, `layout`), and each
|
|
82
|
+
* types the other's props as `never`, so passing both is a compile error and
|
|
83
|
+
* not a silent precedence rule. The shorthand is one view whose id is
|
|
84
|
+
* `'default'` and whose label is `label`.
|
|
85
|
+
*/
|
|
86
|
+
export type ExplorerRootProps<N extends ExplorerNode = ExplorerNode, E extends ExplorerEdge = ExplorerEdge> = ExplorerRootCommonProps<N, E> & (ExplorerRootViews<N, E> | ExplorerRootGraph<N, E>);
|
|
87
|
+
export declare function ExplorerRoot<N extends ExplorerNode = ExplorerNode, E extends ExplorerEdge = ExplorerEdge>(props: ExplorerRootProps<N, E>): ReactElement;
|
|
88
|
+
export {};
|
|
89
|
+
//# sourceMappingURL=root.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.d.ts","sourceRoot":"","sources":["../src/root.tsx"],"names":[],"mappings":"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"}
|
package/dist/root.js
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* `ExplorerRoot`: the data, its validation and layout, and the state every
|
|
4
|
+
* part reads.
|
|
5
|
+
*
|
|
6
|
+
* **Controllable, and never past the owner.** `viewId` and `selectedId` are
|
|
7
|
+
* controllable because they are what a host syncs to a URL. Under a
|
|
8
|
+
* controlled value, every change that starts inside the explorer (a click, a
|
|
9
|
+
* search pick, an `ExplorerApi` call, a view switch reselecting, the selected
|
|
10
|
+
* node leaving the data, the active view being removed) calls the callback
|
|
11
|
+
* and changes nothing on screen until the prop does. A controlled value the
|
|
12
|
+
* data lacks renders as its fallback, with no corrective callback: a
|
|
13
|
+
* callback fired to fix the owner's own prop is how update loops start.
|
|
14
|
+
*
|
|
15
|
+
* **Changes the explorer makes on its own are found after commit,** in a
|
|
16
|
+
* layout effect, not in render: they call the owner's callbacks, which must
|
|
17
|
+
* not run during render. A layout effect re-renders before paint, so the
|
|
18
|
+
* stale frame is never seen.
|
|
19
|
+
*
|
|
20
|
+
* **Closing the drawer restores focus here,** whichever way it closed: to
|
|
21
|
+
* the element that opened it, else to the search field, else to the root
|
|
22
|
+
* element itself, never to the page. Only when focus was lost with the
|
|
23
|
+
* drawer (it was inside it, or on a node that left the data), so a host
|
|
24
|
+
* control that closes the drawer keeps its focus. `Escape` anywhere in the
|
|
25
|
+
* root closes the drawer, except where a part has its own precedence (the
|
|
26
|
+
* search field, the drawer) or a host control handled the key. On a node or
|
|
27
|
+
* the graph's surface it closes the drawer and nothing else, so focus stays
|
|
28
|
+
* where it is and a second `Escape` leaves the graph. It is taken in the
|
|
29
|
+
* capture phase for that, before the camera's own `Escape` would blur the
|
|
30
|
+
* graph and drop focus to the page.
|
|
31
|
+
*
|
|
32
|
+
* **Validation and layout run in render,** so a data error reaches an error
|
|
33
|
+
* boundary. Every view is validated; only the active one is laid out, and
|
|
34
|
+
* its layout is memoized by shape, so data re-created on every render keeps
|
|
35
|
+
* its layout and its camera.
|
|
36
|
+
*/
|
|
37
|
+
import { useEffect, useImperativeHandle, useMemo, useReducer, useRef, useState, } from 'react';
|
|
38
|
+
import { ExplorerApiContext, ExplorerContext, createCameraHub } from './context.js';
|
|
39
|
+
import { ExplorerContextError } from './errors.js';
|
|
40
|
+
import { useIsomorphicLayoutEffect } from './isomorphic-layout-effect.js';
|
|
41
|
+
import { resolveLabels, sameLabels } from './labels.js';
|
|
42
|
+
import { layoutKey, layoutView } from './layout.js';
|
|
43
|
+
import { defaultSearchText, searchNodes } from './search.js';
|
|
44
|
+
import { validateViews } from './validate.js';
|
|
45
|
+
/** The id of the one view the `nodes` and `edges` shorthand makes. */
|
|
46
|
+
const DEFAULT_VIEW_ID = 'default';
|
|
47
|
+
const NOTHING = new Set();
|
|
48
|
+
/** Hidden from sight and not from a screen reader. */
|
|
49
|
+
const VISUALLY_HIDDEN = {
|
|
50
|
+
position: 'absolute',
|
|
51
|
+
width: 1,
|
|
52
|
+
height: 1,
|
|
53
|
+
margin: -1,
|
|
54
|
+
padding: 0,
|
|
55
|
+
overflow: 'hidden',
|
|
56
|
+
clip: 'rect(0 0 0 0)',
|
|
57
|
+
whiteSpace: 'nowrap',
|
|
58
|
+
border: 0,
|
|
59
|
+
};
|
|
60
|
+
/**
|
|
61
|
+
* `value`, or the one this hook returned last render if `same` says they are
|
|
62
|
+
* equal, so a value re-created with the same contents keeps its identity.
|
|
63
|
+
*/
|
|
64
|
+
function useSame(value, same) {
|
|
65
|
+
const kept = useRef(value);
|
|
66
|
+
if (!same(kept.current, value))
|
|
67
|
+
kept.current = value;
|
|
68
|
+
return kept.current;
|
|
69
|
+
}
|
|
70
|
+
const sameItems = (a, b) => a === b || (a.length === b.length && a.every((item, i) => item === b[i]));
|
|
71
|
+
const sameSet = (a, b) => a === b || (a.size === b.size && [...a].every((id) => b.has(id)));
|
|
72
|
+
export function ExplorerRoot(props) {
|
|
73
|
+
const { label, viewId, defaultViewId, onViewChange, selectedId: selectedProp, defaultSelectedId, onSelectedChange, selectOnViewChange, searchText = defaultSearchText, strictGroups = false, labels: labelOverrides, apiRef, className, style, children, } = props;
|
|
74
|
+
const { views: viewsProp, nodes, edges, groups, layout: layoutOptions } = props;
|
|
75
|
+
const views = useMemo(() => {
|
|
76
|
+
if (viewsProp !== undefined)
|
|
77
|
+
return viewsProp;
|
|
78
|
+
if (nodes === undefined)
|
|
79
|
+
return [];
|
|
80
|
+
return [{ id: DEFAULT_VIEW_ID, label, nodes, edges: edges ?? [], groups, layout: layoutOptions }];
|
|
81
|
+
}, [viewsProp, nodes, edges, groups, layoutOptions, label]);
|
|
82
|
+
// Every view, not only the active one, so a broken view fails on the page
|
|
83
|
+
// that ships it and not on the day somebody switches to it.
|
|
84
|
+
useMemo(() => validateViews(views), [views]);
|
|
85
|
+
// Kept by value, so an inline `labels={{ search: 'Find' }}` re-created on
|
|
86
|
+
// every parent render changes nothing downstream while it says the same.
|
|
87
|
+
const labels = useSame(resolveLabels(labelOverrides), sameLabels);
|
|
88
|
+
// View.
|
|
89
|
+
const [viewState, setViewState] = useState(() => defaultViewId ?? null);
|
|
90
|
+
const viewControlled = viewId !== undefined;
|
|
91
|
+
const requestedView = viewControlled ? viewId : viewState;
|
|
92
|
+
const activeView = views.find((view) => view.id === requestedView) ?? views[0] ?? null;
|
|
93
|
+
const activeId = activeView?.id ?? null;
|
|
94
|
+
// Layout, by shape. The key is a string, so the memo holds across data
|
|
95
|
+
// re-created with the same shape and a label or color change. The key
|
|
96
|
+
// itself is linear in the view and calls the host's `nodeSize`, so it is
|
|
97
|
+
// computed once per view object, not on every render.
|
|
98
|
+
const key = useMemo(() => (activeView === null ? null : layoutKey(activeView)), [activeView]);
|
|
99
|
+
const layout = useMemo(() => (activeView === null ? null : layoutView(activeView, { strictGroups })),
|
|
100
|
+
// Keyed by shape, on purpose: `activeView` is read for the key's sake.
|
|
101
|
+
[key, strictGroups]);
|
|
102
|
+
const nodeById = useMemo(() => new Map((activeView?.nodes ?? []).map((node) => [node.id, node])), [activeView]);
|
|
103
|
+
// Selection.
|
|
104
|
+
const [selectedState, setSelectedState] = useState(() => defaultSelectedId ?? null);
|
|
105
|
+
const selectionControlled = selectedProp !== undefined;
|
|
106
|
+
const rawSelected = selectionControlled ? selectedProp : selectedState;
|
|
107
|
+
const selectedNode = rawSelected === null ? null : (nodeById.get(rawSelected) ?? null);
|
|
108
|
+
const selectedId = selectedNode === null ? null : selectedNode.id;
|
|
109
|
+
// Query, trace, drawer.
|
|
110
|
+
const [query, setQueryState] = useState('');
|
|
111
|
+
const [trace, setTraceState] = useState(false);
|
|
112
|
+
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
113
|
+
// A node `inspect` asked for under a controlled selection: the drawer opens
|
|
114
|
+
// when the owner's prop arrives at it, and not before.
|
|
115
|
+
const [pendingOpen, setPendingOpen] = useState(null);
|
|
116
|
+
const [lastRaw, setLastRaw] = useState(rawSelected);
|
|
117
|
+
if (lastRaw !== rawSelected) {
|
|
118
|
+
setLastRaw(rawSelected);
|
|
119
|
+
if (pendingOpen !== null) {
|
|
120
|
+
setPendingOpen(null);
|
|
121
|
+
if (pendingOpen === rawSelected)
|
|
122
|
+
setDrawerOpen(true);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
// No selection, no drawer, and none that reopens on the next selection.
|
|
126
|
+
if (selectedId === null && drawerOpen)
|
|
127
|
+
setDrawerOpen(false);
|
|
128
|
+
const detailsOpen = drawerOpen && selectedId !== null;
|
|
129
|
+
// Kept while the same nodes match, so a keystroke that changes nothing
|
|
130
|
+
// found re-renders no list and re-dims nothing.
|
|
131
|
+
const matches = useSame(useMemo(() => (activeView === null ? [] : searchNodes(activeView.nodes, query, searchText)), [activeView, query, searchText]), sameItems);
|
|
132
|
+
const hasQuery = query.trim() !== '';
|
|
133
|
+
// Kept by value too: the graph renders again only when the dimming does.
|
|
134
|
+
const dimmedNow = useMemo(() => {
|
|
135
|
+
if (activeView === null || (!hasQuery && !(trace && selectedId !== null)))
|
|
136
|
+
return NOTHING;
|
|
137
|
+
const out = new Set();
|
|
138
|
+
if (hasQuery) {
|
|
139
|
+
const hit = new Set(matches.map((node) => node.id));
|
|
140
|
+
for (const node of activeView.nodes)
|
|
141
|
+
if (!hit.has(node.id))
|
|
142
|
+
out.add(node.id);
|
|
143
|
+
}
|
|
144
|
+
if (trace && selectedId !== null) {
|
|
145
|
+
const keep = new Set([selectedId]);
|
|
146
|
+
for (const edge of activeView.edges) {
|
|
147
|
+
if (edge.source === selectedId)
|
|
148
|
+
keep.add(edge.target);
|
|
149
|
+
if (edge.target === selectedId)
|
|
150
|
+
keep.add(edge.source);
|
|
151
|
+
}
|
|
152
|
+
for (const node of activeView.nodes)
|
|
153
|
+
if (!keep.has(node.id))
|
|
154
|
+
out.add(node.id);
|
|
155
|
+
}
|
|
156
|
+
return out.size === 0 ? NOTHING : out;
|
|
157
|
+
}, [activeView, hasQuery, matches, trace, selectedId]);
|
|
158
|
+
const dimmed = useSame(dimmedNow, sameSet);
|
|
159
|
+
const snapshot = {
|
|
160
|
+
views,
|
|
161
|
+
activeId,
|
|
162
|
+
layout,
|
|
163
|
+
nodeById,
|
|
164
|
+
rawSelected,
|
|
165
|
+
committedSelected: rawSelected,
|
|
166
|
+
selectionControlled,
|
|
167
|
+
viewControlled,
|
|
168
|
+
detailsOpen,
|
|
169
|
+
onSelectedChange,
|
|
170
|
+
onViewChange,
|
|
171
|
+
};
|
|
172
|
+
const latest = useRef(snapshot);
|
|
173
|
+
// A render after a call under control, so the commit puts the owner's
|
|
174
|
+
// value back in `latest` even when the owner does not move.
|
|
175
|
+
const [, recommit] = useReducer((n) => n + 1, 0);
|
|
176
|
+
useIsomorphicLayoutEffect(() => {
|
|
177
|
+
latest.current = snapshot;
|
|
178
|
+
});
|
|
179
|
+
const [internals] = useState(() => {
|
|
180
|
+
let viewports = 0;
|
|
181
|
+
return {
|
|
182
|
+
registerViewport() {
|
|
183
|
+
if (viewports > 0) {
|
|
184
|
+
throw new ExplorerContextError('SECOND_VIEWPORT', 'An ExplorerRoot has a second ExplorerViewport. Render exactly one per root');
|
|
185
|
+
}
|
|
186
|
+
viewports += 1;
|
|
187
|
+
return () => {
|
|
188
|
+
viewports -= 1;
|
|
189
|
+
};
|
|
190
|
+
},
|
|
191
|
+
controlsRef: { current: null },
|
|
192
|
+
camera: createCameraHub(),
|
|
193
|
+
searchInputRef: { current: null },
|
|
194
|
+
};
|
|
195
|
+
});
|
|
196
|
+
const openerRef = useRef(null);
|
|
197
|
+
const rootRef = useRef(null);
|
|
198
|
+
// Set by Escape inside the graph, whose close restores nothing.
|
|
199
|
+
const skipRestore = useRef(false);
|
|
200
|
+
const [{ api, changeSelection }] = useState(() => {
|
|
201
|
+
const changeSelection = (next) => {
|
|
202
|
+
const s = latest.current;
|
|
203
|
+
if (next === s.rawSelected)
|
|
204
|
+
return;
|
|
205
|
+
latest.current = { ...s, rawSelected: next };
|
|
206
|
+
if (s.selectionControlled)
|
|
207
|
+
recommit();
|
|
208
|
+
else
|
|
209
|
+
setSelectedState(next);
|
|
210
|
+
s.onSelectedChange?.(next);
|
|
211
|
+
};
|
|
212
|
+
const box = (id) => latest.current.layout?.boxes.get(id);
|
|
213
|
+
const methods = {
|
|
214
|
+
fit() {
|
|
215
|
+
internals.controlsRef.current?.fit();
|
|
216
|
+
},
|
|
217
|
+
zoomBy(factor) {
|
|
218
|
+
internals.controlsRef.current?.zoomBy(factor);
|
|
219
|
+
},
|
|
220
|
+
focusNode(id) {
|
|
221
|
+
const found = box(id);
|
|
222
|
+
if (found !== undefined)
|
|
223
|
+
internals.controlsRef.current?.focusBox(found);
|
|
224
|
+
},
|
|
225
|
+
reveal(id) {
|
|
226
|
+
const found = box(id);
|
|
227
|
+
if (found !== undefined)
|
|
228
|
+
internals.controlsRef.current?.revealBox(found);
|
|
229
|
+
},
|
|
230
|
+
select(id) {
|
|
231
|
+
if (id !== null && !latest.current.nodeById.has(id))
|
|
232
|
+
return;
|
|
233
|
+
setPendingOpen(null);
|
|
234
|
+
changeSelection(id);
|
|
235
|
+
},
|
|
236
|
+
inspect(id, trigger) {
|
|
237
|
+
const s = latest.current;
|
|
238
|
+
if (!s.nodeById.has(id))
|
|
239
|
+
return;
|
|
240
|
+
if (trigger !== undefined)
|
|
241
|
+
openerRef.current = trigger;
|
|
242
|
+
else if (!s.detailsOpen) {
|
|
243
|
+
const active = document.activeElement;
|
|
244
|
+
openerRef.current = active instanceof HTMLElement && active !== document.body ? active : null;
|
|
245
|
+
}
|
|
246
|
+
if (!s.selectionControlled || s.committedSelected === id) {
|
|
247
|
+
setPendingOpen(null);
|
|
248
|
+
setDrawerOpen(true);
|
|
249
|
+
latest.current = { ...s, detailsOpen: true };
|
|
250
|
+
}
|
|
251
|
+
else {
|
|
252
|
+
setPendingOpen(id);
|
|
253
|
+
}
|
|
254
|
+
changeSelection(id);
|
|
255
|
+
},
|
|
256
|
+
closeDetails() {
|
|
257
|
+
setPendingOpen(null);
|
|
258
|
+
setDrawerOpen(false);
|
|
259
|
+
latest.current = { ...latest.current, detailsOpen: false };
|
|
260
|
+
},
|
|
261
|
+
selectView(id) {
|
|
262
|
+
const s = latest.current;
|
|
263
|
+
if (id === s.activeId || !s.views.some((view) => view.id === id))
|
|
264
|
+
return;
|
|
265
|
+
latest.current = { ...s, activeId: id };
|
|
266
|
+
if (s.viewControlled)
|
|
267
|
+
recommit();
|
|
268
|
+
else
|
|
269
|
+
setViewState(id);
|
|
270
|
+
s.onViewChange?.(id);
|
|
271
|
+
},
|
|
272
|
+
setQuery(next) {
|
|
273
|
+
setQueryState(next);
|
|
274
|
+
},
|
|
275
|
+
setTrace(on) {
|
|
276
|
+
setTraceState(on);
|
|
277
|
+
},
|
|
278
|
+
};
|
|
279
|
+
return { api: methods, changeSelection };
|
|
280
|
+
});
|
|
281
|
+
useImperativeHandle(apiRef, () => api, [api]);
|
|
282
|
+
// The changes the explorer makes on its own, found after commit. See the
|
|
283
|
+
// file comment for why here and not in render.
|
|
284
|
+
const seenView = useRef(activeId);
|
|
285
|
+
const present = useRef(null);
|
|
286
|
+
useIsomorphicLayoutEffect(() => {
|
|
287
|
+
// A removed view, or an unknown default, is forgotten, so it is not
|
|
288
|
+
// reselected if it appears later.
|
|
289
|
+
if (!viewControlled && activeId !== null && viewState !== activeId)
|
|
290
|
+
setViewState(activeId);
|
|
291
|
+
// Data arriving after mount, or after every view was gone, is not a
|
|
292
|
+
// switch: there was nothing to switch from. Recorded, and nothing reset,
|
|
293
|
+
// so a deep-linked selection survives data that starts empty.
|
|
294
|
+
if (seenView.current === null && activeId !== null)
|
|
295
|
+
seenView.current = activeId;
|
|
296
|
+
if (seenView.current !== activeId) {
|
|
297
|
+
const previous = seenView.current;
|
|
298
|
+
seenView.current = activeId;
|
|
299
|
+
present.current = null;
|
|
300
|
+
setQueryState('');
|
|
301
|
+
setTraceState(false);
|
|
302
|
+
setDrawerOpen(false);
|
|
303
|
+
setPendingOpen(null);
|
|
304
|
+
// The camera resets because the viewport remounts per view.
|
|
305
|
+
changeSelection(activeView !== null && selectOnViewChange !== undefined ? selectOnViewChange(activeView) : null);
|
|
306
|
+
const removed = previous !== null && !views.some((view) => view.id === previous);
|
|
307
|
+
if (removed && activeId !== null)
|
|
308
|
+
onViewChange?.(activeId);
|
|
309
|
+
return;
|
|
310
|
+
}
|
|
311
|
+
// The selected node leaving the data is a transition: reported once,
|
|
312
|
+
// when an id that resolved last commit no longer does. An unknown id the
|
|
313
|
+
// owner passes never resolved, so it is never reported.
|
|
314
|
+
if (selectedId !== null) {
|
|
315
|
+
present.current = { view: activeId, id: selectedId };
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const was = present.current;
|
|
319
|
+
present.current = null;
|
|
320
|
+
if (was !== null && was.view === activeId && rawSelected === was.id)
|
|
321
|
+
changeSelection(null);
|
|
322
|
+
});
|
|
323
|
+
const wasOpen = useRef(detailsOpen);
|
|
324
|
+
useEffect(() => {
|
|
325
|
+
const was = wasOpen.current;
|
|
326
|
+
wasOpen.current = detailsOpen;
|
|
327
|
+
if (detailsOpen || !was)
|
|
328
|
+
return;
|
|
329
|
+
const skip = skipRestore.current;
|
|
330
|
+
skipRestore.current = false;
|
|
331
|
+
if (skip)
|
|
332
|
+
return;
|
|
333
|
+
const active = document.activeElement;
|
|
334
|
+
if (active !== null && active !== document.body)
|
|
335
|
+
return;
|
|
336
|
+
const opener = openerRef.current;
|
|
337
|
+
// Never the page: the root takes focus when nothing better is left.
|
|
338
|
+
const target = opener !== null && opener.isConnected ? opener : (internals.searchInputRef.current ?? rootRef.current);
|
|
339
|
+
target?.focus();
|
|
340
|
+
}, [detailsOpen, internals]);
|
|
341
|
+
// The capture phase, so it runs before the camera's listener on the
|
|
342
|
+
// viewport, which blurs the graph on an Escape nobody has handled. Only a
|
|
343
|
+
// node's own button or the surface: content a host renders inside a node
|
|
344
|
+
// gets the key first, as everywhere else.
|
|
345
|
+
const onKeyDownCapture = (event) => {
|
|
346
|
+
const target = event.target;
|
|
347
|
+
if (event.key !== 'Escape' || !detailsOpen || !(target instanceof HTMLElement))
|
|
348
|
+
return;
|
|
349
|
+
const viewport = target.closest('[data-dagr-explorer="viewport"]');
|
|
350
|
+
if (viewport === null || viewport.closest('[data-dagr-explorer="root"]') !== rootRef.current)
|
|
351
|
+
return;
|
|
352
|
+
if (target !== viewport && target.getAttribute('data-dagr-explorer') !== 'node')
|
|
353
|
+
return;
|
|
354
|
+
event.preventDefault();
|
|
355
|
+
api.closeDetails();
|
|
356
|
+
};
|
|
357
|
+
const onKeyDown = (event) => {
|
|
358
|
+
const target = event.target;
|
|
359
|
+
if (event.key !== 'Escape' || !detailsOpen || !(target instanceof Element))
|
|
360
|
+
return;
|
|
361
|
+
// A root nested in this one handles its own.
|
|
362
|
+
if (target.closest('[data-dagr-explorer="root"]') !== rootRef.current)
|
|
363
|
+
return;
|
|
364
|
+
if (target.closest('[data-dagr-explorer="viewport"]') !== null) {
|
|
365
|
+
// Closed already in the capture phase, or handled by content in a node.
|
|
366
|
+
if (event.defaultPrevented)
|
|
367
|
+
return;
|
|
368
|
+
// The camera has already released graph focus by now: its listener is
|
|
369
|
+
// on the viewport, below this one.
|
|
370
|
+
skipRestore.current = true;
|
|
371
|
+
api.closeDetails();
|
|
372
|
+
return;
|
|
373
|
+
}
|
|
374
|
+
// The search field and the drawer keep their own precedence, and so
|
|
375
|
+
// does a host control that handled the key.
|
|
376
|
+
if (event.defaultPrevented || target === internals.searchInputRef.current)
|
|
377
|
+
return;
|
|
378
|
+
api.closeDetails();
|
|
379
|
+
};
|
|
380
|
+
const state = useMemo(() => ({
|
|
381
|
+
...api,
|
|
382
|
+
label,
|
|
383
|
+
labels,
|
|
384
|
+
views,
|
|
385
|
+
activeView,
|
|
386
|
+
layout,
|
|
387
|
+
selectedId,
|
|
388
|
+
selectedNode,
|
|
389
|
+
query,
|
|
390
|
+
matches,
|
|
391
|
+
trace,
|
|
392
|
+
detailsOpen,
|
|
393
|
+
dimmed,
|
|
394
|
+
camera: internals.camera,
|
|
395
|
+
}), [api, label, labels, views, activeView, layout, selectedId, selectedNode, query, matches, trace, detailsOpen, dimmed, internals]);
|
|
396
|
+
const value = useMemo(() => ({ state, internals }), [state, internals]);
|
|
397
|
+
return (_jsx(ExplorerApiContext.Provider, { value: api, children: _jsx(ExplorerContext.Provider, { value: value, children: _jsxs("div", { ref: rootRef, "data-dagr-explorer": "root",
|
|
398
|
+
// Where focus goes when the drawer closes with nothing else to take it.
|
|
399
|
+
tabIndex: -1, className: className, style: { position: 'relative', ...style }, onKeyDownCapture: onKeyDownCapture, onKeyDown: onKeyDown, children: [children, _jsx("div", { "data-dagr-explorer": "announcer", "aria-live": "polite", style: VISUALLY_HIDDEN, children: detailsOpen && selectedNode !== null ? selectedNode.label : '' })] }) }) }));
|
|
400
|
+
}
|
|
401
|
+
//# sourceMappingURL=root.js.map
|
package/dist/root.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"root.js","sourceRoot":"","sources":["../src/root.tsx"],"names":[],"mappings":"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"}
|
package/dist/search.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ExplorerNode } from './types.js';
|
|
2
|
+
/** What search reads when the caller gives no accessor: the id, then the label. */
|
|
3
|
+
export declare function defaultSearchText(node: ExplorerNode): string;
|
|
4
|
+
/**
|
|
5
|
+
* The nodes whose text contains every token of the query, in data order.
|
|
6
|
+
*
|
|
7
|
+
* Tokens are the query split on whitespace and lowercased. They are matched as
|
|
8
|
+
* text with `includes`, never compiled into a pattern, so a query of `(v2.*)`
|
|
9
|
+
* finds exactly those characters and a query of `[` is not an error.
|
|
10
|
+
*
|
|
11
|
+
* An empty or blank query matches nothing, which is what lets the explorer
|
|
12
|
+
* treat "no query" and "no dimming" as the same state.
|
|
13
|
+
*
|
|
14
|
+
* `searchText` is the caller's accessor over the caller's node type. Whatever
|
|
15
|
+
* it returns is coerced to a string, so an accessor with a missing branch
|
|
16
|
+
* costs a miss, not a crash in the middle of typing.
|
|
17
|
+
*/
|
|
18
|
+
export declare function searchNodes<N extends ExplorerNode>(nodes: readonly N[], query: string, searchText?: (node: N) => string): N[];
|
|
19
|
+
//# sourceMappingURL=search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,mFAAmF;AACnF,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAE5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,WAAW,CAAC,CAAC,SAAS,YAAY,EAChD,KAAK,EAAE,SAAS,CAAC,EAAE,EACnB,KAAK,EAAE,MAAM,EACb,UAAU,GAAE,CAAC,IAAI,EAAE,CAAC,KAAK,MAA0B,GAClD,CAAC,EAAE,CAUL"}
|
package/dist/search.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/** What search reads when the caller gives no accessor: the id, then the label. */
|
|
2
|
+
export function defaultSearchText(node) {
|
|
3
|
+
return `${node.id} ${node.label}`;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The nodes whose text contains every token of the query, in data order.
|
|
7
|
+
*
|
|
8
|
+
* Tokens are the query split on whitespace and lowercased. They are matched as
|
|
9
|
+
* text with `includes`, never compiled into a pattern, so a query of `(v2.*)`
|
|
10
|
+
* finds exactly those characters and a query of `[` is not an error.
|
|
11
|
+
*
|
|
12
|
+
* An empty or blank query matches nothing, which is what lets the explorer
|
|
13
|
+
* treat "no query" and "no dimming" as the same state.
|
|
14
|
+
*
|
|
15
|
+
* `searchText` is the caller's accessor over the caller's node type. Whatever
|
|
16
|
+
* it returns is coerced to a string, so an accessor with a missing branch
|
|
17
|
+
* costs a miss, not a crash in the middle of typing.
|
|
18
|
+
*/
|
|
19
|
+
export function searchNodes(nodes, query, searchText = defaultSearchText) {
|
|
20
|
+
const tokens = query
|
|
21
|
+
.toLowerCase()
|
|
22
|
+
.split(/\s+/)
|
|
23
|
+
.filter((token) => token !== '');
|
|
24
|
+
if (tokens.length === 0)
|
|
25
|
+
return [];
|
|
26
|
+
return nodes.filter((node) => {
|
|
27
|
+
const text = String(searchText(node) ?? '').toLowerCase();
|
|
28
|
+
return tokens.every((token) => text.includes(token));
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"search.js","sourceRoot":"","sources":["../src/search.ts"],"names":[],"mappings":"AAEA,mFAAmF;AACnF,MAAM,UAAU,iBAAiB,CAAC,IAAkB;IAClD,OAAO,GAAG,IAAI,CAAC,EAAE,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;AACpC,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,UAAU,WAAW,CACzB,KAAmB,EACnB,KAAa,EACb,aAAkC,iBAAiB;IAEnD,MAAM,MAAM,GAAG,KAAK;SACjB,WAAW,EAAE;SACb,KAAK,CAAC,KAAK,CAAC;SACZ,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,EAAE,CAAC,CAAC;IACnC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;QAAE,OAAO,EAAE,CAAC;IACnC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,IAAI,EAAE,EAAE;QAC3B,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QAC1D,OAAO,MAAM,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;IACvD,CAAC,CAAC,CAAC;AACL,CAAC"}
|
package/dist/size.d.ts
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ExplorerLayoutOptions, ExplorerNode, Size } from './types.js';
|
|
2
|
+
/** The size of a node that declares none, in world pixels. */
|
|
3
|
+
export declare const DEFAULT_NODE_SIZE: Size;
|
|
4
|
+
/**
|
|
5
|
+
* A node's size: its own `size`, else the view's `nodeSize`, else the default.
|
|
6
|
+
*
|
|
7
|
+
* Sizes are declared and never measured, because a virtualized node has no
|
|
8
|
+
* element to measure. This is the one place that order is written down, so
|
|
9
|
+
* validation, layout and the shape key cannot disagree about it.
|
|
10
|
+
*/
|
|
11
|
+
export declare function resolveNodeSize<N extends ExplorerNode>(layout: ExplorerLayoutOptions<N> | undefined, node: N): Size;
|
|
12
|
+
//# sourceMappingURL=size.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"size.d.ts","sourceRoot":"","sources":["../src/size.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,qBAAqB,EAAE,YAAY,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAE5E,8DAA8D;AAC9D,eAAO,MAAM,iBAAiB,EAAE,IAAiD,CAAC;AAElF;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS,YAAY,EACpD,MAAM,EAAE,qBAAqB,CAAC,CAAC,CAAC,GAAG,SAAS,EAC5C,IAAI,EAAE,CAAC,GACN,IAAI,CAON"}
|