@deltarobotics/uhd-viewer 0.2.0 → 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 +33 -0
- package/dist/app/assets/index-CEJyT8hF.css +2 -0
- package/dist/app/assets/{index-CkpIRYgM.js → index-DWZ-48wc.js} +35 -35
- package/dist/app/index.html +2 -2
- package/dist/components/components.css +320 -56
- package/dist/components/index.js +1166 -605
- package/dist/components/index.js.map +1 -1
- package/dist/components/types/uhd-viewer/src/cad/ModelView.d.ts +3 -1
- package/dist/components/types/uhd-viewer/src/canvas/Canvas.d.ts +5 -1
- package/dist/components/types/uhd-viewer/src/canvas/interaction.d.ts +2 -2
- package/dist/components/types/uhd-viewer/src/canvas/reveal.d.ts +18 -0
- package/dist/components/types/uhd-viewer/src/chrome/Chrome.d.ts +12 -2
- package/dist/components/types/uhd-viewer/src/chrome/InterfaceCards.d.ts +11 -1
- package/dist/components/types/uhd-viewer/src/chrome/Sections.d.ts +22 -1
- package/dist/components/types/uhd-viewer/src/components.d.ts +4 -4
- package/dist/components/types/uhd-viewer/src/host/targets.d.ts +16 -0
- package/dist/components/types/uhd-viewer/src/model/classification.d.ts +3 -0
- package/dist/components/types/uhd-viewer/src/model/from-uhd.d.ts +3 -2
- package/dist/components/types/uhd-viewer/src/model/hierarchy.d.ts +10 -6
- package/dist/components/types/uhd-viewer/src/model/level.d.ts +7 -0
- package/dist/components/types/uhd-viewer/src/model/slots.d.ts +2 -0
- package/dist/components/types/uhd-viewer/src/ui/Legend.d.ts +23 -4
- package/dist/components/types/uhd-viewer/src/ui/legendFit.d.ts +26 -13
- package/dist/components/types/uhd-viewer/src/viewer/controller.d.ts +1 -0
- package/dist/components/types/uhd-viewer/src/viewer/hierarchy.d.ts +34 -12
- package/dist/components/types/uhd-viewer/src/viewer/views.d.ts +49 -18
- package/dist/headless/index.js.map +1 -1
- package/dist/lib/uhd-viewer.css +1 -1
- package/dist/lib/uhd-viewer.js +11291 -10973
- package/package.json +1 -1
- package/dist/app/assets/index-Boi2erhd.css +0 -2
|
@@ -15,6 +15,8 @@ export interface ModelViewProps {
|
|
|
15
15
|
error?: string;
|
|
16
16
|
/** Called once the model is on screen, with what the card shows. */
|
|
17
17
|
onReady?: (info: ModelInfo) => void;
|
|
18
|
+
/** Show the card with the name and size from the start (default: folded into the toolbar's Model info button). */
|
|
19
|
+
infoOpen?: boolean;
|
|
18
20
|
/** Extra buttons at the toolbar's end (a host's "open in the system viewer"). */
|
|
19
21
|
actions?: React.ReactNode;
|
|
20
22
|
className?: string;
|
|
@@ -25,4 +27,4 @@ export interface ModelInfo {
|
|
|
25
27
|
meshes: number;
|
|
26
28
|
triangles: number;
|
|
27
29
|
}
|
|
28
|
-
export declare function ModelView({ url, object, name, detail, error, onReady, actions, className }: ModelViewProps): import("react").JSX.Element;
|
|
30
|
+
export declare function ModelView({ url, object, name, detail, error, onReady, actions, infoOpen, className }: ModelViewProps): import("react").JSX.Element;
|
|
@@ -45,10 +45,14 @@ export interface CanvasProps {
|
|
|
45
45
|
onMove: (id: string, x: number, y: number) => void;
|
|
46
46
|
/** A drag starts (what moves) or ends (null): the layout reroutes only what moves meanwhile. */
|
|
47
47
|
onLive: (live: Live | null) => void;
|
|
48
|
-
/**
|
|
48
|
+
/**
|
|
49
|
+
* A node to bring into view (a host's focus, a row of the hierarchy), once it is drawn; `seq` tells repeats
|
|
50
|
+
* apart. With `lines`, a harness drawn along lines (no card of its own): those lines are framed.
|
|
51
|
+
*/
|
|
49
52
|
centre?: {
|
|
50
53
|
id: string;
|
|
51
54
|
seq: number;
|
|
55
|
+
lines?: readonly string[];
|
|
52
56
|
};
|
|
53
57
|
/** A selection to bring into view if it is not (a host's select): panned to, zoomed out only if it must; `seq` tells repeats apart. */
|
|
54
58
|
reveal?: {
|
|
@@ -64,12 +64,12 @@ export declare const rightRelease: (press: RightPress) => "menu" | "pan";
|
|
|
64
64
|
export declare const TOOL_OPTIONS: readonly [{
|
|
65
65
|
readonly id: "select";
|
|
66
66
|
readonly icon: "mouse-pointer-2";
|
|
67
|
-
readonly label: "Select
|
|
67
|
+
readonly label: "Select";
|
|
68
68
|
readonly shortcut: "V";
|
|
69
69
|
}, {
|
|
70
70
|
readonly id: "pan";
|
|
71
71
|
readonly icon: "hand";
|
|
72
|
-
readonly label: "Pan
|
|
72
|
+
readonly label: "Pan";
|
|
73
73
|
readonly shortcut: "H";
|
|
74
74
|
}];
|
|
75
75
|
/** What a key press asks of the canvas. */
|
|
@@ -18,6 +18,24 @@ export type Rect = {
|
|
|
18
18
|
};
|
|
19
19
|
/** Where a selection is drawn, in flow coordinates: a node's box, or every line of a link (a derived link: the lines it runs over). */
|
|
20
20
|
export declare function selectionBounds(vm: ViewModel, layout: ComputedLayout, selection: RevealSelection): Rect | undefined;
|
|
21
|
+
/** Where several lines are drawn together (a harness along the lines that carry it), in flow coordinates. */
|
|
22
|
+
export declare function linesBounds(layout: ComputedLayout, lineIds: readonly string[]): Rect | undefined;
|
|
23
|
+
/**
|
|
24
|
+
* The viewport that frames `rect`, as a module is framed when it is focused:
|
|
25
|
+
* centred in the view clear of the floating chrome, zoomed to fit it, never
|
|
26
|
+
* past `maxZoom`.
|
|
27
|
+
*/
|
|
28
|
+
export declare function frameViewport(rect: Rect, pane: {
|
|
29
|
+
width: number;
|
|
30
|
+
height: number;
|
|
31
|
+
}, inspector: boolean, { maxZoom, minZoom }?: {
|
|
32
|
+
maxZoom?: number;
|
|
33
|
+
minZoom?: number;
|
|
34
|
+
}): {
|
|
35
|
+
x: number;
|
|
36
|
+
y: number;
|
|
37
|
+
zoom: number;
|
|
38
|
+
};
|
|
21
39
|
/**
|
|
22
40
|
* The viewport that shows `rect` clear of the floating chrome (the inspector
|
|
23
41
|
* too, when open), or undefined when it is in view already. It keeps the zoom
|
|
@@ -9,8 +9,11 @@ import { type HostFinding } from "../model/slots";
|
|
|
9
9
|
import { type InterfaceCardActions } from "./InterfaceCards";
|
|
10
10
|
import type { Selection } from "../canvas/Canvas";
|
|
11
11
|
export type Panel = "hierarchy" | "checks";
|
|
12
|
-
/**
|
|
13
|
-
|
|
12
|
+
/**
|
|
13
|
+
* "4 models · 2 docs · 1 evidence": what a definition's own artifacts are, by group. A parent's are its own only
|
|
14
|
+
* (PB-1088): its children's are theirs, a selection away.
|
|
15
|
+
*/
|
|
16
|
+
export declare function artifactSummary(def: ModuleDef | undefined, _lookup?: (id?: string) => ModuleDef | undefined): {
|
|
14
17
|
count: number;
|
|
15
18
|
text: string;
|
|
16
19
|
};
|
|
@@ -101,8 +104,15 @@ declare function InspectorView(props: {
|
|
|
101
104
|
onNodeContext?: (id: string, x: number, y: number) => void;
|
|
102
105
|
}): import("react").JSX.Element;
|
|
103
106
|
export interface NodeMenuItem {
|
|
107
|
+
/** Title case, a few words. */
|
|
104
108
|
label: string;
|
|
105
109
|
run: () => void;
|
|
110
|
+
/** A Lucide icon name, at the item's left. */
|
|
111
|
+
icon?: string;
|
|
112
|
+
/** The key that does the same, at the item's right (`F`, `Ctrl+A`). */
|
|
113
|
+
shortcut?: string;
|
|
114
|
+
/** A rule above the item: it starts a group. */
|
|
115
|
+
separator?: boolean;
|
|
106
116
|
}
|
|
107
117
|
/** A small menu at the pointer; any click elsewhere, Escape, or a choice closes it. */
|
|
108
118
|
export declare function NodeMenu({ x, y, items, onClose }: {
|
|
@@ -10,6 +10,16 @@ export declare const CARD_LOOK: {
|
|
|
10
10
|
readonly toggle: "min-w-0 truncate text-left text-[12px] leading-[18px] text-fg outline-none after:absolute after:inset-0 after:content-[''] cursor-pointer";
|
|
11
11
|
readonly chip: "inline-flex h-[18px] shrink-0 items-center rounded-[4px] bg-[color-mix(in_oklab,var(--uhd-text)_8%,transparent)] px-1.5 text-[10px] leading-none text-fg-muted";
|
|
12
12
|
readonly pin: "inline-flex h-4 shrink-0 items-center rounded-[4px] border border-line px-1 text-[10px] leading-none text-fg-muted";
|
|
13
|
+
/**
|
|
14
|
+
* The pin mapping's columns, shared by its rows: the pin as wide as the widest (at least 44 px, its cell's
|
|
15
|
+
* minimum; at most 40 % of the card), the leaf (when any pin binds one) at most 30 %, and what it meets in the rest.
|
|
16
|
+
*/
|
|
17
|
+
readonly pinMap: "grid gap-x-2 gap-y-[3px] text-[11px] leading-none";
|
|
18
|
+
readonly pinMapPins: "grid-cols-[fit-content(40%)_minmax(0,1fr)]";
|
|
19
|
+
readonly pinMapLeaves: "grid-cols-[fit-content(40%)_fit-content(30%)_minmax(0,1fr)]";
|
|
20
|
+
readonly pinRow: "col-span-full grid min-h-5 grid-cols-subgrid items-center";
|
|
21
|
+
/** A pin in the mapping: a chip that ends in an ellipsis when the column is narrower than its name. */
|
|
22
|
+
readonly pinName: "inline-block h-4 max-w-full truncate rounded-[4px] border border-line px-1 align-middle text-[10px] leading-[14px] text-fg-muted";
|
|
13
23
|
readonly meta: "mt-[5px] flex min-w-0 items-center gap-1";
|
|
14
24
|
readonly role: "ml-auto shrink-0 text-[10px] leading-none text-fg-faint";
|
|
15
25
|
readonly linked: "mt-[5px] flex min-w-0 items-center gap-1.5 text-[11px] leading-[16px]";
|
|
@@ -48,7 +58,7 @@ export declare function InterfaceCard({ slot, open, onToggle, actions }: {
|
|
|
48
58
|
onToggle: () => void;
|
|
49
59
|
actions: InterfaceCardActions;
|
|
50
60
|
}): import("react").JSX.Element;
|
|
51
|
-
/** The cards,
|
|
61
|
+
/** The cards, ten at a time (PB-1088): "Show 10 more" adds the next ten, "Show fewer" goes back to the first ten. */
|
|
52
62
|
export declare function InterfaceCards({ slots, actions, first }: {
|
|
53
63
|
slots: InterfaceSlot[];
|
|
54
64
|
actions: InterfaceCardActions;
|
|
@@ -99,7 +99,28 @@ export declare function KeyValues({ rows, limit }: {
|
|
|
99
99
|
}[];
|
|
100
100
|
limit?: number;
|
|
101
101
|
}): import("react").JSX.Element;
|
|
102
|
-
/**
|
|
102
|
+
/** How many rows of a long list are shown at first, and how many more each "Show more" adds (PB-1088). */
|
|
103
|
+
export declare const LIST_STEP = 10;
|
|
104
|
+
/**
|
|
105
|
+
* A long list shown `step` rows at a time (PB-1088): "Show 10 more" under the
|
|
106
|
+
* rows adds the next ones, "Show fewer" goes back to the first `step`.
|
|
107
|
+
* `keep`: rows that must stay shown (an expanded card), counted from the top.
|
|
108
|
+
*/
|
|
109
|
+
export declare function useLoadMore(total: number, step?: number, keep?: number): {
|
|
110
|
+
limit: number;
|
|
111
|
+
footer: ReactNode;
|
|
112
|
+
};
|
|
113
|
+
/**
|
|
114
|
+
* A long free text (a module's description) cut to `lines` lines, with "More"
|
|
115
|
+
* to read it all and "Less" to cut it again (PB-1088). The toggle shows only
|
|
116
|
+
* when the text is cut.
|
|
117
|
+
*/
|
|
118
|
+
export declare function ClampedText({ text, lines, className }: {
|
|
119
|
+
text: string;
|
|
120
|
+
lines?: number;
|
|
121
|
+
className?: string;
|
|
122
|
+
}): import("react").JSX.Element;
|
|
123
|
+
/** A section's rows shown in part, and the header action that shows them all. Lists use `useLoadMore` (PB-1088). */
|
|
103
124
|
export declare function useShowAll(total: number, limit: number): {
|
|
104
125
|
limit: number | undefined;
|
|
105
126
|
aside: ReactNode;
|
|
@@ -32,12 +32,12 @@ export type { Panel, Goto } from "./chrome/Chrome";
|
|
|
32
32
|
export { initialInteraction, interactionReducer, interactionProps, canvasCommand, applySelectChanges, firstView, TOOL_OPTIONS, type CanvasTool, type InteractionState, type InteractionAction, type CanvasCommand, type Viewport } from "./canvas/interaction";
|
|
33
33
|
export { openAction } from "./viewer/controller";
|
|
34
34
|
export { cardWidth, labelIsCut, CARD_W, CARD_W_MAX } from "./layout/card-body";
|
|
35
|
-
export { DiagramCanvas, DiagramToolbar, ToolToggle, ViewButtons, DiagramLegend, DiagramLegendBody, DiagramLegendItems, FittedLegend, LegendToolbarButton, IsolationClear, MissingNotice, ScenarioBanner, Scene3D, ViewerInspector, ViewerNodeMenu, CLASSIFICATION_OPTIONS, DETAIL_OPTIONS, type DiagramCanvasProps, type Scene3DProps } from "./viewer/views";
|
|
35
|
+
export { DiagramCanvas, DiagramToolbar, ToolToggle, ViewButtons, DiagramLegend, DiagramLegendBody, DiagramLegendItems, FittedLegend, LegendFold, LegendToolbarButton, IsolationClear, MissingNotice, ScenarioBanner, Scene3D, ViewerInspector, ViewerNodeMenu, CLASSIFICATION_OPTIONS, DETAIL_OPTIONS, type DiagramCanvasProps, type FittedLegendProps, type Scene3DProps } from "./viewer/views";
|
|
36
36
|
export { ModelView, type ModelViewProps, type ModelInfo } from "./cad/ModelView";
|
|
37
37
|
export { ViewerHierarchy, HierarchyToggle, RAIL_WIDTH, HIERARCHY_LOOK, type ViewerHierarchyProps, type HierarchyCommand } from "./viewer/hierarchy";
|
|
38
38
|
export { buildHierarchy, filterHierarchy, visibleRows, treeKey, selectedPath, rowTarget, drillInto, revealPaths, ancestorsOf, hierarchyIndex, walkHierarchy, panelState, groupWiring, markLegend, WIRING_PATH, kindOf, KIND_ICON, KIND_LABEL as HIERARCHY_KIND_LABEL, HIERARCHY_WIDTH, type HierarchyNode, type HierarchyKind, type HierarchyRow, type HierarchyPanelState, type HierarchyOptions, type TreeKeyResult, } from "./model/hierarchy";
|
|
39
39
|
export { SelectionDetails, type SelectionDetailsProps, type DetailsTarget, type InterfaceRequest } from "./viewer/details";
|
|
40
|
-
export { Sections, DetailsSection, KeyValues, useShowAll, useSectionOpen, useExpandedCards, SelectionKey, keptInspectorState, navTarget, onNavKey, SECTION_LOOK, type DetailsSectionProps } from "./chrome/Sections";
|
|
40
|
+
export { Sections, DetailsSection, KeyValues, useShowAll, useLoadMore, ClampedText, LIST_STEP, useSectionOpen, useExpandedCards, SelectionKey, keptInspectorState, navTarget, onNavKey, SECTION_LOOK, type DetailsSectionProps } from "./chrome/Sections";
|
|
41
41
|
export { InterfaceCards, InterfaceCard, SlotGlyph, CARD_LOOK, SLOT_COLOR, type InterfaceCardActions } from "./chrome/InterfaceCards";
|
|
42
42
|
export { interfaceSlots, slotSummary, groupSlots, checkFindings, levelNames, humanize, sentence, paramValue, type InterfaceSlot, type SlotKind, type SlotState, type SlotPin, type SlotLink, type SlotFinding, type SlotNote, type HostFinding, type SlotOptions } from "./model/slots";
|
|
43
43
|
export { ArtifactCard, ArtifactCards, ArtifactGrid, type ArtifactCardProps } from "./chrome/ArtifactCards";
|
|
@@ -47,8 +47,8 @@ export type { EvidenceFiles, SourceRow, Verification } from "./model/evidence";
|
|
|
47
47
|
export { HostContext, type HostActions } from "./host/context";
|
|
48
48
|
export { ScrollArea, type ScrollAreaProps } from "./ui/ScrollArea";
|
|
49
49
|
export { Toolbar, ToolbarSeparator, IconButton, ToggleGroup, type ToolbarProps, type IconButtonProps, type ToggleGroupProps } from "./ui/Toolbar";
|
|
50
|
-
export { Legend, LegendItem, LegendSwatches, type LegendItemProps, type LegendProps } from "./ui/Legend";
|
|
51
|
-
export { legendStage, legendRoom, type LegendStage } from "./ui/legendFit";
|
|
50
|
+
export { Legend, LegendItem, LegendSwatches, LegendTab, type LegendItemProps, type LegendProps, type LegendTabProps } from "./ui/Legend";
|
|
51
|
+
export { legendStage, legendRoom, legendFolded, LEGEND_SHORT, type LegendStage } from "./ui/legendFit";
|
|
52
52
|
export { InspectorPanel, Section, PropertyRow, Badge, StatusDot, EmptyState, type InspectorPanelProps, type Tone } from "./ui/Inspector";
|
|
53
53
|
export { Tooltips } from "./ui/Tooltips";
|
|
54
54
|
export { Icon } from "./canvas/Icon";
|
|
@@ -51,6 +51,22 @@ export declare function cadSelectTarget(root: ModuleDef, lookup: ModuleLookup, d
|
|
|
51
51
|
} | undefined;
|
|
52
52
|
/** A stored or derived link id as the view selects it: the line that draws it, or the derived link itself. */
|
|
53
53
|
export declare function selectableLink(vm: ViewModel, id: string): LevelSelection;
|
|
54
|
+
/**
|
|
55
|
+
* The lines a harness is drawn along on this level, when it has no card of
|
|
56
|
+
* its own: a cable between two parts is one line with the harness as a region
|
|
57
|
+
* along it, and the links that name a harness carry its region too. Empty for
|
|
58
|
+
* a harness drawn as a card (and for anything else).
|
|
59
|
+
*/
|
|
60
|
+
export declare function harnessLines(vm: ViewModel, id: string): ViewModel["links"];
|
|
61
|
+
/**
|
|
62
|
+
* A module selection as the diagram can show it: a harness drawn along its
|
|
63
|
+
* lines (no card of its own) is selected as the line that carries its name
|
|
64
|
+
* tab, so a row of the hierarchy or a host's focus on it selects and frames
|
|
65
|
+
* something drawn. Anything else as it is.
|
|
66
|
+
*/
|
|
67
|
+
export declare function drawnSelection(vm: ViewModel, selection: LevelSelection): LevelSelection;
|
|
68
|
+
/** The harness a selected line runs through (its path on the level), if any: its row in the hierarchy. */
|
|
69
|
+
export declare function selectedHarness(vm: ViewModel, selection: LevelSelection): string | undefined;
|
|
54
70
|
/**
|
|
55
71
|
* The first of `ids` drawn on this level: a node (module instance path, net,
|
|
56
72
|
* boundary port) or a link. `node:` and `link:` prefixes pick the kind. Ids
|
|
@@ -19,7 +19,10 @@ export declare function isFaded(item: Colorable, mode: Classification): boolean;
|
|
|
19
19
|
/** One entry of a classification's legend. `key` is what `classKey` gives the items it stands for. */
|
|
20
20
|
export interface LegendEntry {
|
|
21
21
|
key: string;
|
|
22
|
+
/** Its name, as the legend shows it. */
|
|
22
23
|
label: string;
|
|
24
|
+
/** What it stands for, in a few words (the legend's second line). */
|
|
25
|
+
meaning: string;
|
|
23
26
|
color: string;
|
|
24
27
|
}
|
|
25
28
|
/** The legend entry an item belongs to in a classification (the key of its colour). */
|
|
@@ -9,10 +9,11 @@
|
|
|
9
9
|
* they carry is drawn in two segments through them. System diagnostics
|
|
10
10
|
* (checkSystem) are overlaid onto link state for DRC colouring.
|
|
11
11
|
*/
|
|
12
|
-
import type { ChildLink, ModuleDef } from "@deltarobotics/uhd";
|
|
12
|
+
import type { ChildLink, InterfaceDef, ModuleDef } from "@deltarobotics/uhd";
|
|
13
13
|
import { type LinkResult, type ModuleLookup } from "@deltarobotics/uhd";
|
|
14
14
|
import type { SystemDiagnostic } from "@deltarobotics/uhd";
|
|
15
|
-
import type { ViewLink, ViewModel } from "./types";
|
|
15
|
+
import type { ViewLink, ViewModel, ViewPort } from "./types";
|
|
16
|
+
export declare function toPort(iface: InterfaceDef, owner: ModuleDef, exported?: ViewPort["exported"]): ViewPort;
|
|
16
17
|
/** Link ids whose child links are stored overrides. */
|
|
17
18
|
type Overrides = Record<string, ChildLink[]>;
|
|
18
19
|
export interface LevelLinks {
|
|
@@ -153,15 +153,19 @@ export declare const HIERARCHY_WIDTH: {
|
|
|
153
153
|
/** A kept state, checked; anything malformed falls back to the default. */
|
|
154
154
|
export declare function panelState(v: unknown, fallbackOpen?: boolean): HierarchyPanelState;
|
|
155
155
|
export declare const clampWidth: (w: number, room?: number) => number;
|
|
156
|
-
/** The row that holds the
|
|
156
|
+
/** The row "Harnesses & links" that holds the harnesses, cables and fastener stacks: not a module of the system. */
|
|
157
157
|
export declare const WIRING_PATH = "#wiring";
|
|
158
158
|
/**
|
|
159
|
-
* The tree as the panel shows it: the system's structure first, and
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
*
|
|
159
|
+
* The tree as the panel shows it: the system's structure first, and the
|
|
160
|
+
* harnesses and links (harnesses, cables and fastener stacks) folded into one
|
|
161
|
+
* group row at the bottom, `WIRING_PATH`. With `level` (the instance path of
|
|
162
|
+
* the level on screen, "" for the root), the group holds only that level's own
|
|
163
|
+
* harnesses, not those of the modules inside it: they show once that module is
|
|
164
|
+
* the level. Without `level`, every harness, wherever it sits, each with the
|
|
165
|
+
* module it belongs to. Harnesses never show in the structure. Without any for
|
|
166
|
+
* the group, the structure alone.
|
|
163
167
|
*/
|
|
164
|
-
export declare function groupWiring(nodes: readonly HierarchyNode[]): HierarchyNode[];
|
|
168
|
+
export declare function groupWiring(nodes: readonly HierarchyNode[], level?: string): HierarchyNode[];
|
|
165
169
|
/** The marks the tree shows, once each, in the order of their tones: a legend (the first sentence of a mark's label names it). */
|
|
166
170
|
export declare function markLegend(nodes: readonly HierarchyNode[]): {
|
|
167
171
|
tone: NodeMark["tone"];
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { ViewNode } from "./types";
|
|
2
|
+
/**
|
|
3
|
+
* The modules a level draws: its nodes less what is not a module of its own
|
|
4
|
+
* (the drilled-into module's boundary ports, a board's net junctions and
|
|
5
|
+
* their taps). A level with none is empty, whatever ports it shows.
|
|
6
|
+
*/
|
|
7
|
+
export declare function levelModules(nodes: readonly ViewNode[]): ViewNode[];
|
|
@@ -83,6 +83,8 @@ export interface InterfaceSlot {
|
|
|
83
83
|
usedBy?: string;
|
|
84
84
|
/** Exported to the boundary of the module it is in, by that name: linked from outside, not open. */
|
|
85
85
|
exportedAs?: string;
|
|
86
|
+
/** A pin bound into another interface of the module (a UART's RX inside its pad group), by that one's name: not on the outline, not linked on its own. */
|
|
87
|
+
partOf?: string;
|
|
86
88
|
/** The worst state of its links. */
|
|
87
89
|
state?: SlotState;
|
|
88
90
|
pinMap: SlotPin[];
|
|
@@ -1,10 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Legend primitives: a floating card with a title and swatches. A swatch is
|
|
3
3
|
* a short line (links) or a dot (states). An item given `onSelect` is a
|
|
4
|
-
* button: the legend then isolates what it stands for.
|
|
5
|
-
*
|
|
4
|
+
* button: the legend then isolates what it stands for. An item with a
|
|
5
|
+
* `meaning` reads as two lines, its name and what it stands for. A compact
|
|
6
|
+
* item is its swatch alone, named by its label (`LegendSwatches` lays them
|
|
7
|
+
* out). Folded, a legend is a tab at the right edge (`LegendTab`): a chevron
|
|
8
|
+
* and a dot per colour.
|
|
6
9
|
*/
|
|
7
|
-
import type { HTMLAttributes, ReactNode, Ref } from "react";
|
|
10
|
+
import type { ButtonHTMLAttributes, HTMLAttributes, ReactNode, Ref } from "react";
|
|
8
11
|
export interface LegendProps extends Omit<HTMLAttributes<HTMLDivElement>, "title"> {
|
|
9
12
|
title?: ReactNode;
|
|
10
13
|
ref?: Ref<HTMLDivElement>;
|
|
@@ -30,11 +33,27 @@ export interface LegendItemProps {
|
|
|
30
33
|
hintShortcut?: string;
|
|
31
34
|
/** The swatch alone (a narrow legend): the label names the button and is its tooltip. */
|
|
32
35
|
compact?: boolean;
|
|
36
|
+
/** What the entry stands for, in a few words: a second, muted line under the label. */
|
|
37
|
+
meaning?: string;
|
|
33
38
|
}
|
|
34
|
-
export declare function LegendItem({ color, label, shape, onSelect, pressed, dimmed, absent, hint, hintShortcut, compact }: LegendItemProps): import("react").JSX.Element;
|
|
39
|
+
export declare function LegendItem({ color, label, shape, onSelect, pressed, dimmed, absent, hint, hintShortcut, compact, meaning }: LegendItemProps): import("react").JSX.Element;
|
|
35
40
|
/** Compact items side by side, `columns` to a row: a legend as narrow as its swatches. */
|
|
36
41
|
export declare function LegendSwatches({ columns, children, label }: {
|
|
37
42
|
columns?: number;
|
|
38
43
|
children?: ReactNode;
|
|
39
44
|
label?: string;
|
|
40
45
|
}): import("react").JSX.Element;
|
|
46
|
+
export interface LegendTabProps extends Omit<ButtonHTMLAttributes<HTMLButtonElement>, "children"> {
|
|
47
|
+
/** A dot per colour the legend explains (`dimmed`: it steps back, as an entry does while another is isolated). */
|
|
48
|
+
dots: {
|
|
49
|
+
key: string;
|
|
50
|
+
color: string;
|
|
51
|
+
dimmed?: boolean;
|
|
52
|
+
}[];
|
|
53
|
+
ref?: Ref<HTMLButtonElement>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* A folded legend: a narrow tab at the right edge, a chevron and the
|
|
57
|
+
* colours it explains as dots. A click opens the legend; its label names it.
|
|
58
|
+
*/
|
|
59
|
+
export declare function LegendTab({ dots, className, ...rest }: LegendTabProps): import("react").JSX.Element;
|
|
@@ -1,15 +1,19 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* How much of the diagram's legend fits beside the bottom toolbar. The legend
|
|
3
|
-
* stays where it is (bottom
|
|
3
|
+
* stays where it is (bottom right) and gives way as the toolbar comes near:
|
|
4
4
|
* the full card, then a compact one (swatches without their labels), then,
|
|
5
|
-
* at its smallest, a button in the toolbar that opens it.
|
|
6
|
-
*
|
|
5
|
+
* at its smallest, a button in the toolbar that opens it. Folded, it is a
|
|
6
|
+
* narrow tab at the right edge, which gives way to the button the same way.
|
|
7
|
+
* A short canvas folds it (`legendShort`). No DOM here: the legend measures,
|
|
8
|
+
* this decides.
|
|
7
9
|
*/
|
|
8
10
|
export type LegendStage = "full" | "compact" | "button";
|
|
9
11
|
/** Space kept between the legend and the toolbar (px). */
|
|
10
12
|
export declare const LEGEND_GAP = 8;
|
|
11
13
|
/** A larger form comes back only with this much room to spare (px), so a width at the edge does not flicker between two. */
|
|
12
14
|
export declare const LEGEND_HYSTERESIS = 6;
|
|
15
|
+
/** Below this canvas height (px) the legend folds by itself: open, it would cover much of the drawing. */
|
|
16
|
+
export declare const LEGEND_SHORT = 500;
|
|
13
17
|
export interface Box {
|
|
14
18
|
left: number;
|
|
15
19
|
top: number;
|
|
@@ -17,26 +21,35 @@ export interface Box {
|
|
|
17
21
|
bottom: number;
|
|
18
22
|
}
|
|
19
23
|
export interface LegendMeasure {
|
|
20
|
-
/** Where the legend's
|
|
21
|
-
|
|
22
|
-
/** Each form's box, as it would sit (bottom
|
|
24
|
+
/** Where the legend's right edge is (the same for every form). */
|
|
25
|
+
right: number;
|
|
26
|
+
/** Each form's box, as it would sit (bottom right). */
|
|
23
27
|
full: Box;
|
|
24
28
|
compact: Box;
|
|
29
|
+
/** The folded tab's box, as it would sit (at the right edge). */
|
|
30
|
+
tab?: Box;
|
|
25
31
|
/** The toolbar's box, or none (no toolbar, or hidden). */
|
|
26
32
|
toolbar?: Box | null;
|
|
27
33
|
/** The legend's button in the toolbar takes this much of it (its width and gap), when it is there: the toolbar is measured as if it were not. */
|
|
28
34
|
slot?: number;
|
|
29
35
|
}
|
|
30
36
|
/**
|
|
31
|
-
* The room the legend has before the toolbar (px): from
|
|
32
|
-
* the
|
|
33
|
-
* legend moves its
|
|
34
|
-
* and the room is the same whether or not the button is in it.
|
|
37
|
+
* The room the legend has before the toolbar (px): from the toolbar's right
|
|
38
|
+
* edge to the legend's, less the gap. The toolbar is centred, so its button
|
|
39
|
+
* for the legend moves its right edge by half the button: that half is taken
|
|
40
|
+
* back, and the room is the same whether or not the button is in it.
|
|
35
41
|
*/
|
|
36
|
-
export declare function legendRoom(m: Pick<LegendMeasure, "
|
|
42
|
+
export declare function legendRoom(m: Pick<LegendMeasure, "right" | "toolbar" | "slot">): number;
|
|
37
43
|
/**
|
|
38
44
|
* The largest form that does not run into the toolbar. A form fits when it is
|
|
39
45
|
* clear of the toolbar's height, or narrower than the room. Moving up to a
|
|
40
|
-
* larger form than `current` takes `LEGEND_HYSTERESIS` more.
|
|
46
|
+
* larger form than `current` takes `LEGEND_HYSTERESIS` more. Folded
|
|
47
|
+
* (`folded`), the tab is the only form: "full" while it fits, else "button".
|
|
48
|
+
*/
|
|
49
|
+
export declare function legendStage(m: LegendMeasure, current?: LegendStage, folded?: boolean): LegendStage;
|
|
50
|
+
/**
|
|
51
|
+
* Whether the legend shows folded: the user folded it, or the canvas is
|
|
52
|
+
* shorter than `LEGEND_SHORT` and the user has not opened it since it became
|
|
53
|
+
* so (`peek`).
|
|
41
54
|
*/
|
|
42
|
-
export declare function
|
|
55
|
+
export declare function legendFolded(open: boolean, canvasHeight: number, peek: boolean): boolean;
|
|
@@ -12,7 +12,7 @@ export interface ViewerHierarchyProps {
|
|
|
12
12
|
state?: unknown;
|
|
13
13
|
/** The panel's state changed (open, width, open rows): a host keeps it per tab. */
|
|
14
14
|
onStateChange?: (state: HierarchyPanelState) => void;
|
|
15
|
-
/** The panel opened or folded (at once
|
|
15
|
+
/** The panel opened or folded (at once). */
|
|
16
16
|
onOpenChange?: (open: boolean) => void;
|
|
17
17
|
command?: HierarchyCommand;
|
|
18
18
|
/** Attributes a host puts on every row (`data-*`), e.g. for its own context menu. */
|
|
@@ -23,19 +23,35 @@ export interface ViewerHierarchyProps {
|
|
|
23
23
|
narrow?: number;
|
|
24
24
|
className?: string;
|
|
25
25
|
}
|
|
26
|
-
/**
|
|
27
|
-
export declare const RAIL_WIDTH =
|
|
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;
|
|
28
32
|
/**
|
|
29
|
-
* The panel's look, in one place (PB-1042
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* the viewer's tokens, so a host's theme
|
|
33
|
-
* under the Protoboard theme). Swap these to
|
|
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.
|
|
34
39
|
*/
|
|
35
40
|
export declare const HIERARCHY_LOOK: {
|
|
36
|
-
readonly dock: "uhd-hierarchy-dock absolute
|
|
37
|
-
|
|
38
|
-
readonly
|
|
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";
|
|
39
55
|
readonly header: "flex h-8 shrink-0 items-center gap-0.5 pr-1 pl-3";
|
|
40
56
|
readonly title: "min-w-0 flex-1 truncate font-label text-[11px] tracking-[0.08em] text-fg-muted uppercase";
|
|
41
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";
|
|
@@ -51,7 +67,13 @@ export declare const HIERARCHY_LOOK: {
|
|
|
51
67
|
};
|
|
52
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. */
|
|
53
69
|
export declare function ViewerHierarchy({ state: given, onStateChange, onOpenChange, command, rowAttributes, ownMenu, narrow, className }: ViewerHierarchyProps): import("react").JSX.Element;
|
|
54
|
-
/**
|
|
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
|
+
*/
|
|
55
77
|
export declare function HierarchyToggle({ open, onClick, disabled, className }: {
|
|
56
78
|
open: boolean;
|
|
57
79
|
onClick: () => void;
|
|
@@ -14,10 +14,19 @@ export interface DiagramCanvasProps {
|
|
|
14
14
|
coveredRight?: boolean;
|
|
15
15
|
/** What the shell adds to the notice about definitions the bundle does not hold (how its producer gets them). */
|
|
16
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
|
+
};
|
|
17
26
|
className?: string;
|
|
18
27
|
}
|
|
19
28
|
/** The diagram of the current level: modules, interfaces, links and harnesses. */
|
|
20
|
-
export declare function DiagramCanvas({ toolbar, legend, coveredRight, missingHint, className }: DiagramCanvasProps): import("react").JSX.Element;
|
|
29
|
+
export declare function DiagramCanvas({ toolbar, legend, coveredRight, missingHint, emptyAction, className }: DiagramCanvasProps): import("react").JSX.Element;
|
|
21
30
|
/** The scenario being shown, when it is not the nominal build. */
|
|
22
31
|
export declare function ScenarioBanner(): import("react").JSX.Element | null;
|
|
23
32
|
/**
|
|
@@ -46,11 +55,11 @@ export declare const CLASSIFICATION_OPTIONS: readonly [{
|
|
|
46
55
|
export declare const DETAIL_OPTIONS: readonly [{
|
|
47
56
|
readonly id: "bundled";
|
|
48
57
|
readonly icon: "minus";
|
|
49
|
-
readonly label: "
|
|
58
|
+
readonly label: "One line per link";
|
|
50
59
|
}, {
|
|
51
60
|
readonly id: "conductors";
|
|
52
61
|
readonly icon: "rows-3";
|
|
53
|
-
readonly label: "
|
|
62
|
+
readonly label: "Every conductor";
|
|
54
63
|
}];
|
|
55
64
|
/**
|
|
56
65
|
* The pointer's tool: select (a drag on the empty canvas draws a selection
|
|
@@ -79,8 +88,9 @@ export declare function DiagramToolbar({ coveredRight, className, controls, lege
|
|
|
79
88
|
* The entries of the current classification's legend, as buttons: a click
|
|
80
89
|
* isolates one (its links stay, with the interfaces and modules they touch;
|
|
81
90
|
* the rest of the level fades), a click on it again shows everything, a
|
|
82
|
-
* click on another switches, and Shift, Ctrl or Cmd holds several.
|
|
83
|
-
*
|
|
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.
|
|
84
94
|
*/
|
|
85
95
|
export declare function DiagramLegendItems({ compact, columns }?: {
|
|
86
96
|
compact?: boolean;
|
|
@@ -90,32 +100,53 @@ export declare function DiagramLegendItems({ compact, columns }?: {
|
|
|
90
100
|
export declare function IsolationClear({ className }: {
|
|
91
101
|
className?: string;
|
|
92
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;
|
|
93
111
|
/**
|
|
94
112
|
* What the legend shows in a form: `full` the title and the entries with their
|
|
95
|
-
*
|
|
96
|
-
* named by its label).
|
|
113
|
+
* names and meanings; `compact` the classification's icon and the swatches
|
|
114
|
+
* alone (each named by its label).
|
|
97
115
|
*/
|
|
98
116
|
export declare function DiagramLegendBody({ form }: {
|
|
99
117
|
form: "full" | "compact";
|
|
100
118
|
}): import("react").JSX.Element;
|
|
101
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`). */
|
|
102
|
-
export declare function DiagramLegend({ className }: {
|
|
120
|
+
export declare function DiagramLegend({ className, coveredRight }: {
|
|
103
121
|
className?: string;
|
|
122
|
+
coveredRight?: boolean;
|
|
104
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
|
+
}
|
|
105
137
|
/**
|
|
106
|
-
* A legend card at the canvas's bottom
|
|
138
|
+
* A legend card at the canvas's bottom right that stays there and gives way
|
|
107
139
|
* to the bottom toolbar (ui/legendFit.ts): the full form while it fits beside
|
|
108
140
|
* the toolbar, then the compact one, and at its smallest none, the toolbar
|
|
109
|
-
* then offering it behind a button (`LegendToolbarButton`).
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
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`).
|
|
113
148
|
*/
|
|
114
|
-
export declare function FittedLegend({ label, render, className }:
|
|
115
|
-
label: string;
|
|
116
|
-
render: (form: "full" | "compact") => ReactNode;
|
|
117
|
-
className?: string;
|
|
118
|
-
}): import("react").JSX.Element;
|
|
149
|
+
export declare function FittedLegend({ label, render, className, open: given, onOpenChange, defaultOpen, coveredRight }: FittedLegendProps): import("react").JSX.Element;
|
|
119
150
|
/**
|
|
120
151
|
* The legend's button in the toolbar, shown only when the legend has no room
|
|
121
152
|
* beside it (`FittedLegend`): it opens the legend (`children`) as a popover
|