@deltarobotics/uhd-viewer 0.0.0-stage → 0.2.1
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 +74 -0
- package/LICENSE +202 -0
- package/NOTICE +22 -0
- package/README.md +168 -2
- package/bin/serve.d.mts +62 -0
- package/bin/serve.mjs +257 -0
- package/bin/uhd-viewer.mjs +75 -0
- package/dist/app/assets/KodeMono-Bold-DdIivhPN.woff2 +0 -0
- package/dist/app/assets/KodeMono-Medium-CVnTuv5A.ttf +0 -0
- package/dist/app/assets/KodeMono-Regular-Bdr_-rJX.woff2 +0 -0
- package/dist/app/assets/KodeMono-SemiBold-JAfn5Dpm.ttf +0 -0
- package/dist/app/assets/index-CEJyT8hF.css +2 -0
- package/dist/app/assets/index-DWZ-48wc.js +3853 -0
- package/dist/app/index.html +16 -0
- package/dist/components/components.css +6372 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/index.js +26609 -0
- package/dist/components/index.js.map +1 -0
- package/dist/components/types/uhd-viewer/src/api.d.ts +286 -0
- package/dist/components/types/uhd-viewer/src/cad/CadView.d.ts +52 -0
- package/dist/components/types/uhd-viewer/src/cad/ModelView.d.ts +30 -0
- package/dist/components/types/uhd-viewer/src/cad/explode.d.ts +110 -0
- package/dist/components/types/uhd-viewer/src/cad/explodeSample.d.ts +25 -0
- package/dist/components/types/uhd-viewer/src/cad/findings.d.ts +41 -0
- package/dist/components/types/uhd-viewer/src/cad/labels.d.ts +76 -0
- package/dist/components/types/uhd-viewer/src/cad/model.d.ts +132 -0
- package/dist/components/types/uhd-viewer/src/cad/row.d.ts +15 -0
- package/dist/components/types/uhd-viewer/src/cad/scene.d.ts +95 -0
- package/dist/components/types/uhd-viewer/src/cad/scope.d.ts +89 -0
- package/dist/components/types/uhd-viewer/src/canvas/Canvas.d.ts +90 -0
- package/dist/components/types/uhd-viewer/src/canvas/Icon.d.ts +5 -0
- package/dist/components/types/uhd-viewer/src/canvas/LinkEdge.d.ts +40 -0
- package/dist/components/types/uhd-viewer/src/canvas/Port.d.ts +18 -0
- package/dist/components/types/uhd-viewer/src/canvas/actions.d.ts +5 -0
- package/dist/components/types/uhd-viewer/src/canvas/geometry.d.ts +72 -0
- package/dist/components/types/uhd-viewer/src/canvas/interaction.d.ts +162 -0
- package/dist/components/types/uhd-viewer/src/canvas/nodes.d.ts +43 -0
- package/dist/components/types/uhd-viewer/src/canvas/reveal.d.ts +55 -0
- package/dist/components/types/uhd-viewer/src/canvas/rightDrag.d.ts +51 -0
- package/dist/components/types/uhd-viewer/src/canvas/routing.d.ts +28 -0
- package/dist/components/types/uhd-viewer/src/chrome/ArtifactCards.d.ts +30 -0
- package/dist/components/types/uhd-viewer/src/chrome/Artifacts.d.ts +44 -0
- package/dist/components/types/uhd-viewer/src/chrome/BoardInspector.d.ts +53 -0
- package/dist/components/types/uhd-viewer/src/chrome/Chrome.d.ts +126 -0
- package/dist/components/types/uhd-viewer/src/chrome/Evidence.d.ts +20 -0
- package/dist/components/types/uhd-viewer/src/chrome/InterfaceCards.d.ts +66 -0
- package/dist/components/types/uhd-viewer/src/chrome/PairView.d.ts +37 -0
- package/dist/components/types/uhd-viewer/src/chrome/Sections.d.ts +128 -0
- package/dist/components/types/uhd-viewer/src/components.d.ts +60 -0
- package/dist/components/types/uhd-viewer/src/host/channel.d.ts +49 -0
- package/dist/components/types/uhd-viewer/src/host/context.d.ts +29 -0
- package/dist/components/types/uhd-viewer/src/host/protocol.d.ts +22 -0
- package/dist/components/types/uhd-viewer/src/host/targets.d.ts +101 -0
- package/dist/components/types/uhd-viewer/src/layout/board-layout.d.ts +69 -0
- package/dist/components/types/uhd-viewer/src/layout/card-body.d.ts +64 -0
- package/dist/components/types/uhd-viewer/src/layout/layout.d.ts +94 -0
- package/dist/components/types/uhd-viewer/src/layout/module-layout.d.ts +32 -0
- package/dist/components/types/uhd-viewer/src/layout/router.d.ts +55 -0
- package/dist/components/types/uhd-viewer/src/layout/taps.d.ts +20 -0
- package/dist/components/types/uhd-viewer/src/model/artifacts.d.ts +129 -0
- package/dist/components/types/uhd-viewer/src/model/classification.d.ts +41 -0
- package/dist/components/types/uhd-viewer/src/model/diagnostics.d.ts +27 -0
- package/dist/components/types/uhd-viewer/src/model/evidence.d.ts +63 -0
- package/dist/components/types/uhd-viewer/src/model/from-uhd.d.ts +58 -0
- package/dist/components/types/uhd-viewer/src/model/hierarchy.d.ts +173 -0
- package/dist/components/types/uhd-viewer/src/model/isolate.d.ts +33 -0
- package/dist/components/types/uhd-viewer/src/model/level.d.ts +7 -0
- package/dist/components/types/uhd-viewer/src/model/nets.d.ts +53 -0
- package/dist/components/types/uhd-viewer/src/model/outputs.d.ts +79 -0
- package/dist/components/types/uhd-viewer/src/model/slots.d.ts +184 -0
- package/dist/components/types/uhd-viewer/src/model/types.d.ts +213 -0
- package/dist/components/types/uhd-viewer/src/options.d.ts +27 -0
- package/dist/components/types/uhd-viewer/src/source/source.d.ts +109 -0
- package/dist/components/types/uhd-viewer/src/source/tolerant.d.ts +45 -0
- package/dist/components/types/uhd-viewer/src/theme/ThemeProvider.d.ts +33 -0
- package/dist/components/types/uhd-viewer/src/theme/adapters.d.ts +28 -0
- package/dist/components/types/uhd-viewer/src/theme/resolve.d.ts +19 -0
- package/dist/components/types/uhd-viewer/src/theme/themes.d.ts +67 -0
- package/dist/components/types/uhd-viewer/src/theme/tokens.d.ts +175 -0
- package/dist/components/types/uhd-viewer/src/ui/Inspector.d.ts +45 -0
- package/dist/components/types/uhd-viewer/src/ui/Legend.d.ts +59 -0
- package/dist/components/types/uhd-viewer/src/ui/ScrollArea.d.ts +16 -0
- package/dist/components/types/uhd-viewer/src/ui/Toolbar.d.ts +49 -0
- package/dist/components/types/uhd-viewer/src/ui/Tooltips.d.ts +3 -0
- package/dist/components/types/uhd-viewer/src/ui/cx.d.ts +2 -0
- package/dist/components/types/uhd-viewer/src/ui/legendFit.d.ts +55 -0
- package/dist/components/types/uhd-viewer/src/viewer/controller.d.ts +219 -0
- package/dist/components/types/uhd-viewer/src/viewer/details.d.ts +81 -0
- package/dist/components/types/uhd-viewer/src/viewer/hierarchy.d.ts +82 -0
- package/dist/components/types/uhd-viewer/src/viewer/mount.d.ts +12 -0
- package/dist/components/types/uhd-viewer/src/viewer/views.d.ts +187 -0
- package/dist/headless/index.d.ts +71 -0
- package/dist/headless/index.js +7425 -0
- package/dist/headless/index.js.map +1 -0
- package/dist/lib/api.d.ts +252 -0
- package/dist/lib/uhd-viewer.css +3 -0
- package/dist/lib/uhd-viewer.d.ts +4 -0
- package/dist/lib/uhd-viewer.js +97787 -0
- package/package.json +110 -4
- package/src/styles/fonts/OFL.txt +93 -0
- package/src/styles/tailwind-theme.css +48 -0
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The inspector's details for one thing of a bundle, without a viewer around
|
|
3
|
+
* it: what `ViewerInspector` shows for a selected module, link or net, for a
|
|
4
|
+
* host that has an inspector of its own (a native side view) and selects by
|
|
5
|
+
* path. The same components draw both, so a host's inspector and the
|
|
6
|
+
* viewer's show a module the same way.
|
|
7
|
+
*
|
|
8
|
+
* <ThemeProvider adapter={vscodeThemeAdapter()}>
|
|
9
|
+
* <SelectionDetails bundle={bundle} target={{ kind: "module", path: "stack/esc" }} host={{ openArtifact }} />
|
|
10
|
+
* </ThemeProvider>
|
|
11
|
+
*
|
|
12
|
+
* The level that holds the target is modelled as the viewer models it (its
|
|
13
|
+
* links, nets and checks), but nothing is laid out or drawn.
|
|
14
|
+
*/
|
|
15
|
+
import { type ReactNode } from "react";
|
|
16
|
+
import type { ModuleDef } from "@deltarobotics/uhd";
|
|
17
|
+
import type { UhdBundle } from "@deltarobotics/uhd";
|
|
18
|
+
import type { ArtifactResolver } from "../api";
|
|
19
|
+
import { type HostActions } from "../host/context";
|
|
20
|
+
import type { Classification } from "../model/classification";
|
|
21
|
+
import { type HostFinding } from "../model/slots";
|
|
22
|
+
/** An interface card's request to its host: the module's path, the interface, and the links that end on it as their module declares them. */
|
|
23
|
+
export interface InterfaceRequest {
|
|
24
|
+
/** The module's instance path from the root. */
|
|
25
|
+
path: string;
|
|
26
|
+
interfaceId: string;
|
|
27
|
+
/** The module that declares the links (the level's), from the root. */
|
|
28
|
+
owner: string;
|
|
29
|
+
/** Its stored links by their local ids ("rx_fc_pads"). */
|
|
30
|
+
links: string[];
|
|
31
|
+
}
|
|
32
|
+
/** What to show: a module instance by its path from the root (`""`: the root), a link on the level of its owner, or a definition on its own. */
|
|
33
|
+
export type DetailsTarget = {
|
|
34
|
+
kind: "module";
|
|
35
|
+
path: string;
|
|
36
|
+
} | {
|
|
37
|
+
kind: "link";
|
|
38
|
+
owner: string;
|
|
39
|
+
ids: string[];
|
|
40
|
+
} | {
|
|
41
|
+
kind: "definition";
|
|
42
|
+
id: string;
|
|
43
|
+
};
|
|
44
|
+
export interface SelectionDetailsProps {
|
|
45
|
+
/** The bundle the target is in. Not given: only `definition` targets among `definitions` can be shown. */
|
|
46
|
+
bundle?: UhdBundle;
|
|
47
|
+
/** Definitions outside the bundle (a library part shown on its own), by their ids. */
|
|
48
|
+
definitions?: ModuleDef[];
|
|
49
|
+
target: DetailsTarget;
|
|
50
|
+
/** URL of a definition's artifact file; not given, files do not resolve (their cards show icons). */
|
|
51
|
+
resolveArtifact?: ArtifactResolver;
|
|
52
|
+
/** What the host takes over, and how artifacts are shown (host/context.ts). */
|
|
53
|
+
host?: HostActions;
|
|
54
|
+
/** How interface swatches are coloured (default: by domain). */
|
|
55
|
+
mode?: Classification;
|
|
56
|
+
/** A board's drawings with pan and zoom, as in the viewer (default false: the drawings are cards, nothing is fetched). */
|
|
57
|
+
boardDrawings?: boolean;
|
|
58
|
+
/** The user picked something else in the details (an end of a link, a net's member, a functional link): canonical ids from the root. */
|
|
59
|
+
onSelect?: (selection: {
|
|
60
|
+
kind: "node" | "link";
|
|
61
|
+
id: string;
|
|
62
|
+
}) => void;
|
|
63
|
+
/** The user asked for the pair view of the link shown. */
|
|
64
|
+
onPair?: (request: {
|
|
65
|
+
linkId: string;
|
|
66
|
+
a: string;
|
|
67
|
+
b: string;
|
|
68
|
+
}) => void;
|
|
69
|
+
/** Shown when the target is not in the bundle. */
|
|
70
|
+
missing?: ReactNode;
|
|
71
|
+
/** The host's findings for the interface cards (with the keys its Locate takes); not given, the viewer's own checks. */
|
|
72
|
+
findings?: HostFinding[];
|
|
73
|
+
/** A finding's Locate on an interface card. */
|
|
74
|
+
onFinding?: (key: string) => void;
|
|
75
|
+
/** An interface card's Open in source: the line of its link, else of the interface. */
|
|
76
|
+
onInterfaceSource?: (request: InterfaceRequest) => void;
|
|
77
|
+
/** An open slot's Connect…. */
|
|
78
|
+
onConnect?: (request: InterfaceRequest) => void;
|
|
79
|
+
className?: string;
|
|
80
|
+
}
|
|
81
|
+
export declare function SelectionDetails({ bundle, definitions, target, resolveArtifact, host, mode, boardDrawings, onSelect, onPair, missing, className, findings, onFinding, onInterfaceSource, onConnect }: SelectionDetailsProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import { type HierarchyNode, type HierarchyPanelState } from "../model/hierarchy";
|
|
2
|
+
/** What a host asks of the panel: show a module's row, put the keyboard in the filter, open or fold it. */
|
|
3
|
+
export interface HierarchyCommand {
|
|
4
|
+
type: "reveal" | "filter" | "open" | "close" | "toggle";
|
|
5
|
+
/** For `reveal`: the module's instance path. */
|
|
6
|
+
path?: string;
|
|
7
|
+
/** A new number for every command (the same command twice is two). */
|
|
8
|
+
seq: number;
|
|
9
|
+
}
|
|
10
|
+
export interface ViewerHierarchyProps {
|
|
11
|
+
/** What the host kept for this tab (`onStateChange` gave it); anything malformed is ignored. */
|
|
12
|
+
state?: unknown;
|
|
13
|
+
/** The panel's state changed (open, width, open rows): a host keeps it per tab. */
|
|
14
|
+
onStateChange?: (state: HierarchyPanelState) => void;
|
|
15
|
+
/** The panel opened or folded (at once). */
|
|
16
|
+
onOpenChange?: (open: boolean) => void;
|
|
17
|
+
command?: HierarchyCommand;
|
|
18
|
+
/** Attributes a host puts on every row (`data-*`), e.g. for its own context menu. */
|
|
19
|
+
rowAttributes?: (node: HierarchyNode) => Record<`data-${string}`, string>;
|
|
20
|
+
/** Show the panel's own context menu (default). A host with a menu of its own passes false: a right-click then only selects the row. */
|
|
21
|
+
ownMenu?: boolean;
|
|
22
|
+
/** Below this width of the window the panel starts folded when nothing was kept (default 640). */
|
|
23
|
+
narrow?: number;
|
|
24
|
+
className?: string;
|
|
25
|
+
}
|
|
26
|
+
/** What the folded panel keeps of the view's width: nothing (its button to open it again floats over the view). */
|
|
27
|
+
export declare const RAIL_WIDTH = 0;
|
|
28
|
+
/** The gap between the floating card and the view's edges, the host's header above it and the canvas beside it (px). */
|
|
29
|
+
export declare const CARD_GAP = 4;
|
|
30
|
+
/** How long the card takes to open or fold (ms); none when the system asks for reduced motion. */
|
|
31
|
+
export declare const FOLD_MS = 200;
|
|
32
|
+
/**
|
|
33
|
+
* The panel's look, in one place (PB-1042, PB-1070): a floating card like the
|
|
34
|
+
* host's header, 4 px from the view's edges and below the header, with the
|
|
35
|
+
* panel radius, a border all round and the panel shadow; rows highlighted in
|
|
36
|
+
* the theme's selection colour. Only the viewer's tokens, so a host's theme
|
|
37
|
+
* decides the colours (orange only under the Protoboard theme). Swap these to
|
|
38
|
+
* restyle it.
|
|
39
|
+
*/
|
|
40
|
+
export declare const HIERARCHY_LOOK: {
|
|
41
|
+
readonly dock: "uhd-hierarchy-dock absolute bottom-1 left-1 z-30 flex flex-col top-[calc(var(--uhd-inset-top,0px)+4px)] transition-[transform,opacity] duration-200 ease-out motion-reduce:transition-none";
|
|
42
|
+
/** The dock while it opens or folds (and while folded): slid out to the left, faded. */
|
|
43
|
+
readonly dockAway: "pointer-events-none -translate-x-[calc(100%+8px)] opacity-0";
|
|
44
|
+
readonly panel: "relative flex min-h-0 flex-1 flex-col overflow-hidden rounded-panel border border-line bg-surface font-ui text-fg shadow-panel outline outline-1 -outline-offset-1 outline-contrast";
|
|
45
|
+
/**
|
|
46
|
+
* The folded panel: the icon alone, floating over the canvas at the card's
|
|
47
|
+
* corner (no border, face or shadow of its own), that opens it again. On
|
|
48
|
+
* hover it takes a soft rounded fill with a faint glow, in the theme's
|
|
49
|
+
* toolbar hover colour (high contrast: a dashed outline instead). It fades
|
|
50
|
+
* in as the card leaves and out as it comes.
|
|
51
|
+
*/
|
|
52
|
+
readonly folded: "uhd-hierarchy-reopen absolute left-1 z-30 top-[calc(var(--uhd-inset-top,0px)+4px)] grid size-8 cursor-pointer place-items-center rounded-md border-0 bg-transparent p-0 text-fg-muted transition-[opacity,background-color,color,box-shadow] duration-200 ease-out motion-reduce:transition-none hover:bg-hover hover:text-fg hover:shadow-[0_0_10px_1px_var(--uhd-hover)] hover:outline hover:outline-1 hover:outline-dashed hover:-outline-offset-1 hover:outline-contrast-active focus-visible:outline focus-visible:outline-1 focus-visible:-outline-offset-1 focus-visible:outline-focus";
|
|
53
|
+
/** The button while it fades in or out (and while the panel is open). */
|
|
54
|
+
readonly foldedAway: "pointer-events-none opacity-0";
|
|
55
|
+
readonly header: "flex h-8 shrink-0 items-center gap-0.5 pr-1 pl-3";
|
|
56
|
+
readonly title: "min-w-0 flex-1 truncate font-label text-[11px] tracking-[0.08em] text-fg-muted uppercase";
|
|
57
|
+
readonly filterBox: "mx-2 mb-1.5 flex h-7 shrink-0 items-center gap-1.5 rounded-md border border-line bg-sunken px-2 focus-within:outline focus-within:outline-1 focus-within:-outline-offset-1 focus-within:outline-focus";
|
|
58
|
+
readonly row: "uhd-tree-row group relative flex h-[26px] cursor-pointer items-center gap-1.5 pr-3 text-[12.5px] leading-none outline-none select-none";
|
|
59
|
+
readonly rowSelected: "bg-selection text-selection-fg outline outline-1 -outline-offset-1 outline-focus";
|
|
60
|
+
readonly rowIdle: "text-fg hover:bg-hover";
|
|
61
|
+
/** Filtering: a row that only leads to what matches. */
|
|
62
|
+
readonly rowDim: "text-fg-faint hover:bg-hover hover:text-fg";
|
|
63
|
+
readonly rowFocus: "focus-visible:outline focus-visible:outline-1 focus-visible:-outline-offset-1 focus-visible:outline-focus";
|
|
64
|
+
readonly groupRow: "mt-1 border-t border-line-subtle text-fg-muted";
|
|
65
|
+
readonly badge: "shrink-0 rounded border border-line px-1.5 font-code text-[10px] leading-[16px] text-fg-muted";
|
|
66
|
+
readonly legend: "flex shrink-0 flex-wrap items-center gap-x-3 gap-y-1 border-t border-line-subtle px-3 py-1.5 text-[10.5px] text-fg-muted";
|
|
67
|
+
};
|
|
68
|
+
/** The panel, docked at the left of the view: render it beside the shell's `.workspace` (its sibling, before it), which then starts after it. */
|
|
69
|
+
export declare function ViewerHierarchy({ state: given, onStateChange, onOpenChange, command, rowAttributes, ownMenu, narrow, className }: ViewerHierarchyProps): import("react").JSX.Element;
|
|
70
|
+
/**
|
|
71
|
+
* A toolbar button that opens and folds the panel from a host's header.
|
|
72
|
+
*
|
|
73
|
+
* @deprecated The panel has its own fold button and, folded, its own button to
|
|
74
|
+
* open it again (PB-1070); a host needs no toggle of its own. Kept for hosts
|
|
75
|
+
* written against 0.2.0; it will be removed in a later minor release.
|
|
76
|
+
*/
|
|
77
|
+
export declare function HierarchyToggle({ open, onClick, disabled, className }: {
|
|
78
|
+
open: boolean;
|
|
79
|
+
onClick: () => void;
|
|
80
|
+
disabled?: boolean;
|
|
81
|
+
className?: string;
|
|
82
|
+
}): import("react").JSX.Element;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Renders a viewer shell into an element: the standalone app (app/main.tsx,
|
|
3
|
+
* lib.tsx's mountViewer) or a host's own shell built from the library's views
|
|
4
|
+
* (`renderViewer(el, options, Shell)`). The handle carries the host channel:
|
|
5
|
+
* its methods send host messages, events go to the options' callbacks and,
|
|
6
|
+
* with `parentWindow`, to the parent window. The shell receives the options
|
|
7
|
+
* and the channel (`host`) as props and passes them to `UhdViewer`.
|
|
8
|
+
*/
|
|
9
|
+
import { type ComponentType } from "react";
|
|
10
|
+
import type { AppProps } from "./controller";
|
|
11
|
+
import type { ViewerHandle } from "../api";
|
|
12
|
+
export declare function renderViewer<P extends AppProps>(element: HTMLElement, props: P, Shell: ComponentType<P>): ViewerHandle;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The library's views of a loaded model, each reading the viewer's state
|
|
3
|
+
* (`useViewer`): the diagram canvas with its toolbar and legend, the 3D
|
|
4
|
+
* scene, the inspector panels and a module's context menu. Shells place them;
|
|
5
|
+
* none of them is app chrome.
|
|
6
|
+
*/
|
|
7
|
+
import { type ReactNode } from "react";
|
|
8
|
+
export interface DiagramCanvasProps {
|
|
9
|
+
/** Draw the floating toolbar (fit, zoom, reset layout). Default true. */
|
|
10
|
+
toolbar?: boolean;
|
|
11
|
+
/** Draw the classification's legend. Default true. */
|
|
12
|
+
legend?: boolean;
|
|
13
|
+
/** A panel floats over the canvas's right side: fitting leaves room for it. Default: the inspector panel is open. */
|
|
14
|
+
coveredRight?: boolean;
|
|
15
|
+
/** What the shell adds to the notice about definitions the bundle does not hold (how its producer gets them). */
|
|
16
|
+
missingHint?: ReactNode;
|
|
17
|
+
/**
|
|
18
|
+
* What a level with no modules offers: a dashed box with a plus and this
|
|
19
|
+
* label, a button (the shell's way to add one, such as its parts library).
|
|
20
|
+
* Without it the empty level only says so.
|
|
21
|
+
*/
|
|
22
|
+
emptyAction?: {
|
|
23
|
+
label: string;
|
|
24
|
+
onClick: () => void;
|
|
25
|
+
};
|
|
26
|
+
className?: string;
|
|
27
|
+
}
|
|
28
|
+
/** The diagram of the current level: modules, interfaces, links and harnesses. */
|
|
29
|
+
export declare function DiagramCanvas({ toolbar, legend, coveredRight, missingHint, emptyAction, className }: DiagramCanvasProps): import("react").JSX.Element;
|
|
30
|
+
/** The scenario being shown, when it is not the nominal build. */
|
|
31
|
+
export declare function ScenarioBanner(): import("react").JSX.Element | null;
|
|
32
|
+
/**
|
|
33
|
+
* Definitions the bundle names and does not hold (source/tolerant.ts): they are
|
|
34
|
+
* drawn as placeholders, and this says which. It can be put away; a bundle
|
|
35
|
+
* that lacks something else brings it back.
|
|
36
|
+
*/
|
|
37
|
+
export declare function MissingNotice({ hint, className }: {
|
|
38
|
+
hint?: ReactNode;
|
|
39
|
+
className?: string;
|
|
40
|
+
}): import("react").JSX.Element | null;
|
|
41
|
+
/** The diagram's view controls as icon toggles (each with a tooltip). */
|
|
42
|
+
export declare const CLASSIFICATION_OPTIONS: readonly [{
|
|
43
|
+
readonly id: "domain";
|
|
44
|
+
readonly icon: "layers";
|
|
45
|
+
readonly label: "Colour by domain";
|
|
46
|
+
}, {
|
|
47
|
+
readonly id: "drc";
|
|
48
|
+
readonly icon: "shield-check";
|
|
49
|
+
readonly label: "Colour by DRC health";
|
|
50
|
+
}, {
|
|
51
|
+
readonly id: "signal";
|
|
52
|
+
readonly icon: "activity";
|
|
53
|
+
readonly label: "Colour by signal type";
|
|
54
|
+
}];
|
|
55
|
+
export declare const DETAIL_OPTIONS: readonly [{
|
|
56
|
+
readonly id: "bundled";
|
|
57
|
+
readonly icon: "minus";
|
|
58
|
+
readonly label: "One line per link";
|
|
59
|
+
}, {
|
|
60
|
+
readonly id: "conductors";
|
|
61
|
+
readonly icon: "rows-3";
|
|
62
|
+
readonly label: "Every conductor";
|
|
63
|
+
}];
|
|
64
|
+
/**
|
|
65
|
+
* The pointer's tool: select (a drag on the empty canvas draws a selection
|
|
66
|
+
* box) or pan (a drag moves the view). For a shell's own toolbar.
|
|
67
|
+
*/
|
|
68
|
+
export declare function ToolToggle({ tooltipSide, size }: {
|
|
69
|
+
tooltipSide?: "top" | "bottom" | "left" | "right";
|
|
70
|
+
size?: "sm" | "md";
|
|
71
|
+
}): import("react").JSX.Element;
|
|
72
|
+
/** Fit and zoom, as the canvas does them (a fit asked for here is also what the level opens on next time). */
|
|
73
|
+
export declare function ViewButtons({ tooltipSide }: {
|
|
74
|
+
tooltipSide?: "top" | "bottom" | "left" | "right";
|
|
75
|
+
}): import("react").JSX.Element;
|
|
76
|
+
/**
|
|
77
|
+
* The diagram's controls (classification, detail, grounds; `controls={false}` leaves them out), then fit, zoom and reset.
|
|
78
|
+
* When the legend has no room beside it, it starts with the legend's button (`legend`: what that opens; default the
|
|
79
|
+
* viewer's legend).
|
|
80
|
+
*/
|
|
81
|
+
export declare function DiagramToolbar({ coveredRight, className, controls, legend }: {
|
|
82
|
+
coveredRight?: boolean;
|
|
83
|
+
className?: string;
|
|
84
|
+
controls?: boolean;
|
|
85
|
+
legend?: ReactNode;
|
|
86
|
+
}): import("react").JSX.Element;
|
|
87
|
+
/**
|
|
88
|
+
* The entries of the current classification's legend, as buttons: a click
|
|
89
|
+
* isolates one (its links stay, with the interfaces and modules they touch;
|
|
90
|
+
* the rest of the level fades), a click on it again shows everything, a
|
|
91
|
+
* click on another switches, and Shift, Ctrl or Cmd holds several. Each
|
|
92
|
+
* reads as its name and, under it, what it stands for. For a shell that
|
|
93
|
+
* draws its own legend card.
|
|
94
|
+
*/
|
|
95
|
+
export declare function DiagramLegendItems({ compact, columns }?: {
|
|
96
|
+
compact?: boolean;
|
|
97
|
+
columns?: number;
|
|
98
|
+
}): import("react").JSX.Element;
|
|
99
|
+
/** The way back from an isolated legend entry to everything (shown only while something is isolated). */
|
|
100
|
+
export declare function IsolationClear({ className }: {
|
|
101
|
+
className?: string;
|
|
102
|
+
}): import("react").JSX.Element | null;
|
|
103
|
+
/**
|
|
104
|
+
* The legend's fold button, at the right of its header: the legend becomes a
|
|
105
|
+
* tab at the right edge. Nothing where the legend does not fold (the
|
|
106
|
+
* toolbar's popover).
|
|
107
|
+
*/
|
|
108
|
+
export declare function LegendFold({ className }: {
|
|
109
|
+
className?: string;
|
|
110
|
+
}): import("react").JSX.Element | null;
|
|
111
|
+
/**
|
|
112
|
+
* What the legend shows in a form: `full` the title and the entries with their
|
|
113
|
+
* names and meanings; `compact` the classification's icon and the swatches
|
|
114
|
+
* alone (each named by its label).
|
|
115
|
+
*/
|
|
116
|
+
export declare function DiagramLegendBody({ form }: {
|
|
117
|
+
form: "full" | "compact";
|
|
118
|
+
}): import("react").JSX.Element;
|
|
119
|
+
/** What the link colours mean in the current classification; a click on an entry isolates it. It gives way to the toolbar as the canvas narrows (`FittedLegend`). */
|
|
120
|
+
export declare function DiagramLegend({ className, coveredRight }: {
|
|
121
|
+
className?: string;
|
|
122
|
+
coveredRight?: boolean;
|
|
123
|
+
}): import("react").JSX.Element;
|
|
124
|
+
export interface FittedLegendProps {
|
|
125
|
+
label: string;
|
|
126
|
+
/** Draws a form of the card. `LegendFold` inside it folds the legend. */
|
|
127
|
+
render: (form: "full" | "compact") => ReactNode;
|
|
128
|
+
className?: string;
|
|
129
|
+
/** Open (the card) or folded (the tab at the right edge). Given: the shell keeps it, with `onOpenChange`; else the legend does, from `defaultOpen`. */
|
|
130
|
+
open?: boolean;
|
|
131
|
+
onOpenChange?: (open: boolean) => void;
|
|
132
|
+
/** Where an uncontrolled legend starts. Default open. */
|
|
133
|
+
defaultOpen?: boolean;
|
|
134
|
+
/** A panel floats over the canvas's right side (an inspector): the legend sits left of it. */
|
|
135
|
+
coveredRight?: boolean;
|
|
136
|
+
}
|
|
137
|
+
/**
|
|
138
|
+
* A legend card at the canvas's bottom right that stays there and gives way
|
|
139
|
+
* to the bottom toolbar (ui/legendFit.ts): the full form while it fits beside
|
|
140
|
+
* the toolbar, then the compact one, and at its smallest none, the toolbar
|
|
141
|
+
* then offering it behind a button (`LegendToolbarButton`). Folded, it is a
|
|
142
|
+
* tab at the right edge with a dot per colour, which opens it; a canvas
|
|
143
|
+
* shorter than `LEGEND_SHORT` folds it until the user opens it there. It
|
|
144
|
+
* measures the room it has (a `ResizeObserver` on the canvas, the toolbar and
|
|
145
|
+
* every form) from hidden copies of the forms, so it never overlaps the
|
|
146
|
+
* toolbar. `render` draws a form; the card is a sibling of the toolbar
|
|
147
|
+
* (`.toolbar`).
|
|
148
|
+
*/
|
|
149
|
+
export declare function FittedLegend({ label, render, className, open: given, onOpenChange, defaultOpen, coveredRight }: FittedLegendProps): import("react").JSX.Element;
|
|
150
|
+
/**
|
|
151
|
+
* The legend's button in the toolbar, shown only when the legend has no room
|
|
152
|
+
* beside it (`FittedLegend`): it opens the legend (`children`) as a popover
|
|
153
|
+
* above the toolbar. Escape, a click elsewhere or the button closes it, and
|
|
154
|
+
* the keyboard goes back to the button.
|
|
155
|
+
*/
|
|
156
|
+
export declare function LegendToolbarButton({ children, label }: {
|
|
157
|
+
children: ReactNode;
|
|
158
|
+
label?: string;
|
|
159
|
+
}): import("react").JSX.Element | null;
|
|
160
|
+
export interface Scene3DProps {
|
|
161
|
+
/** Show the 3D view's own inspector card. Default: the inspector panel is open. */
|
|
162
|
+
inspector?: boolean;
|
|
163
|
+
/**
|
|
164
|
+
* The module to show, by instance path from the root. Default: the level
|
|
165
|
+
* the viewer is on (`drill`), so the root shows the whole assembly and a
|
|
166
|
+
* module shows that module alone. A shell whose tab is on a module with no
|
|
167
|
+
* level of its own (a part) passes that module's path.
|
|
168
|
+
*/
|
|
169
|
+
scope?: string[];
|
|
170
|
+
/** What the shell adds where a module has nothing to draw (how its 3D model is made). */
|
|
171
|
+
emptyHint?: ReactNode;
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* The 3D model of what is being viewed: the whole assembly at the root, one
|
|
175
|
+
* module alone (in its own coordinates) on that module's level. With its own
|
|
176
|
+
* toolbar and (optionally) its inspector.
|
|
177
|
+
*/
|
|
178
|
+
export declare function Scene3D({ inspector, scope, emptyHint }: Scene3DProps): import("react").JSX.Element;
|
|
179
|
+
/**
|
|
180
|
+
* The inspector of the current level: the selected module or link, else the
|
|
181
|
+
* hierarchy or the system checks (`panel`). Hidden while no panel is open.
|
|
182
|
+
*/
|
|
183
|
+
export declare function ViewerInspector({ className }: {
|
|
184
|
+
className?: string;
|
|
185
|
+
}): import("react").JSX.Element | null;
|
|
186
|
+
/** A module's context menu, where the pointer opened it. */
|
|
187
|
+
export declare function ViewerNodeMenu(): import("react").JSX.Element | null;
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import type { UhdBundle } from "@deltarobotics/uhd";
|
|
2
|
+
import type { LinkLayout } from "../lib/api.js";
|
|
3
|
+
|
|
4
|
+
export interface Box { x: number; y: number; w: number; h: number }
|
|
5
|
+
/** One level of `diagram.layouts` in the display file. */
|
|
6
|
+
export interface LevelLayout {
|
|
7
|
+
nodes: Record<string, { x?: number; y?: number; w?: number; h?: number }>;
|
|
8
|
+
ports?: Record<string, "left" | "right" | "top" | "bottom">;
|
|
9
|
+
links?: Record<string, LinkLayout>;
|
|
10
|
+
}
|
|
11
|
+
/** A level layout with the nodes the layout step must not move (the viewer ignores the list). */
|
|
12
|
+
export type PinnedLevelLayout = LevelLayout & { pinned?: string[] };
|
|
13
|
+
export interface LayoutMetrics {
|
|
14
|
+
cards: number;
|
|
15
|
+
boundary: number;
|
|
16
|
+
links: number;
|
|
17
|
+
crossings: number;
|
|
18
|
+
overlaps: number;
|
|
19
|
+
aspect: number;
|
|
20
|
+
width: number;
|
|
21
|
+
height: number;
|
|
22
|
+
strip: number;
|
|
23
|
+
stripAxis: "row" | "column";
|
|
24
|
+
stripCards: string[];
|
|
25
|
+
underCards: number;
|
|
26
|
+
length: number;
|
|
27
|
+
detail: { overlaps: [string, string][]; underCards: { link: string; card: string }[] };
|
|
28
|
+
}
|
|
29
|
+
export interface LayoutFinding {
|
|
30
|
+
severity: "warning" | "info";
|
|
31
|
+
code: "strip" | "crossings" | "overlaps" | "under-cards" | "aspect";
|
|
32
|
+
message: string;
|
|
33
|
+
}
|
|
34
|
+
export interface LayoutLimits {
|
|
35
|
+
strip: (cards: number) => number;
|
|
36
|
+
crossings: (links: number) => number;
|
|
37
|
+
aspect: [number, number];
|
|
38
|
+
}
|
|
39
|
+
export declare const LAYOUT_LIMITS: LayoutLimits;
|
|
40
|
+
export declare function layoutFindings(m: LayoutMetrics, limits?: LayoutLimits): LayoutFinding[];
|
|
41
|
+
export interface DiagramLevel { level: string; label: string; board: boolean }
|
|
42
|
+
export declare function diagramLevels(bundle: UhdBundle, maxDepth?: number): DiagramLevel[];
|
|
43
|
+
export interface LevelOptions {
|
|
44
|
+
layout?: LevelLayout | null;
|
|
45
|
+
expanded?: string[];
|
|
46
|
+
legacy?: boolean;
|
|
47
|
+
}
|
|
48
|
+
export interface MeasuredLevel {
|
|
49
|
+
level: string;
|
|
50
|
+
saved: boolean;
|
|
51
|
+
metrics: LayoutMetrics;
|
|
52
|
+
findings: LayoutFinding[];
|
|
53
|
+
/** What the viewer draws (internal shapes: read `layout.boxes` and `layout.routes` only). */
|
|
54
|
+
view: { nodes: { id: string; label: string; parent?: string; kind: string }[] };
|
|
55
|
+
layout: { boxes: Record<string, Box>; routes: Record<string, [number, number][]> };
|
|
56
|
+
}
|
|
57
|
+
export declare function measureLevel(bundle: UhdBundle, level: string, opts?: LevelOptions): MeasuredLevel;
|
|
58
|
+
export interface ProposeOptions extends LevelOptions {
|
|
59
|
+
mode?: "default" | "tidy";
|
|
60
|
+
pinned?: string[];
|
|
61
|
+
}
|
|
62
|
+
export interface Proposal {
|
|
63
|
+
level: string;
|
|
64
|
+
before: MeasuredLevel;
|
|
65
|
+
after: MeasuredLevel;
|
|
66
|
+
layout: PinnedLevelLayout;
|
|
67
|
+
better: boolean;
|
|
68
|
+
}
|
|
69
|
+
export declare function proposeLevel(bundle: UhdBundle, level: string, opts?: ProposeOptions): Proposal;
|
|
70
|
+
export declare function reads(m: LayoutMetrics): number;
|
|
71
|
+
export declare function readsBetter(a: LayoutMetrics, b: LayoutMetrics): boolean;
|