@loomwork/blueprint-runtime 0.0.0-stage → 0.1.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/LICENSE +202 -0
- package/NOTICE +8 -0
- package/README.md +83 -2
- package/dist/Blueprint.d.ts +14 -0
- package/dist/Blueprint.d.ts.map +1 -0
- package/dist/Blueprint.js +18 -0
- package/dist/Blueprint.js.map +1 -0
- package/dist/RendererRegistry.d.ts +9 -0
- package/dist/RendererRegistry.d.ts.map +1 -0
- package/dist/RendererRegistry.js +39 -0
- package/dist/RendererRegistry.js.map +1 -0
- package/dist/catalog.d.ts +129 -0
- package/dist/catalog.d.ts.map +1 -0
- package/dist/catalog.js +435 -0
- package/dist/catalog.js.map +1 -0
- package/dist/coverage.d.ts +18 -0
- package/dist/coverage.d.ts.map +1 -0
- package/dist/coverage.js +22 -0
- package/dist/coverage.js.map +1 -0
- package/dist/customWidget.d.ts +10 -0
- package/dist/customWidget.d.ts.map +1 -0
- package/dist/customWidget.js +34 -0
- package/dist/customWidget.js.map +1 -0
- package/dist/esm/Blueprint.js +15 -0
- package/dist/esm/Blueprint.js.map +1 -0
- package/dist/esm/RendererRegistry.js +35 -0
- package/dist/esm/RendererRegistry.js.map +1 -0
- package/dist/esm/catalog.js +430 -0
- package/dist/esm/catalog.js.map +1 -0
- package/dist/esm/coverage.js +19 -0
- package/dist/esm/coverage.js.map +1 -0
- package/dist/esm/customWidget.js +31 -0
- package/dist/esm/customWidget.js.map +1 -0
- package/dist/esm/identity.js +116 -0
- package/dist/esm/identity.js.map +1 -0
- package/dist/esm/index.js +15 -0
- package/dist/esm/index.js.map +1 -0
- package/dist/esm/irVersion.js +150 -0
- package/dist/esm/irVersion.js.map +1 -0
- package/dist/esm/layout.js +63 -0
- package/dist/esm/layout.js.map +1 -0
- package/dist/esm/normalize.js +115 -0
- package/dist/esm/normalize.js.map +1 -0
- package/dist/esm/pins.js +82 -0
- package/dist/esm/pins.js.map +1 -0
- package/dist/esm/traverseBlueprint.js +38 -0
- package/dist/esm/traverseBlueprint.js.map +1 -0
- package/dist/esm/traverseBlueprintAsync.js +48 -0
- package/dist/esm/traverseBlueprintAsync.js.map +1 -0
- package/dist/esm/types.js +2 -0
- package/dist/esm/types.js.map +1 -0
- package/dist/esm/widgetStatus.js +137 -0
- package/dist/esm/widgetStatus.js.map +1 -0
- package/dist/esm/widgets.js +105 -0
- package/dist/esm/widgets.js.map +1 -0
- package/dist/identity.d.ts +58 -0
- package/dist/identity.d.ts.map +1 -0
- package/dist/identity.js +122 -0
- package/dist/identity.js.map +1 -0
- package/dist/index.d.ts +24 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +61 -0
- package/dist/index.js.map +1 -0
- package/dist/irVersion.d.ts +23 -0
- package/dist/irVersion.d.ts.map +1 -0
- package/dist/irVersion.js +153 -0
- package/dist/irVersion.js.map +1 -0
- package/dist/layout.d.ts +57 -0
- package/dist/layout.d.ts.map +1 -0
- package/dist/layout.js +71 -0
- package/dist/layout.js.map +1 -0
- package/dist/normalize.d.ts +29 -0
- package/dist/normalize.d.ts.map +1 -0
- package/dist/normalize.js +126 -0
- package/dist/normalize.js.map +1 -0
- package/dist/pins.d.ts +27 -0
- package/dist/pins.d.ts.map +1 -0
- package/dist/pins.js +86 -0
- package/dist/pins.js.map +1 -0
- package/dist/traverseBlueprint.d.ts +27 -0
- package/dist/traverseBlueprint.d.ts.map +1 -0
- package/dist/traverseBlueprint.js +40 -0
- package/dist/traverseBlueprint.js.map +1 -0
- package/dist/traverseBlueprintAsync.d.ts +18 -0
- package/dist/traverseBlueprintAsync.d.ts.map +1 -0
- package/dist/traverseBlueprintAsync.js +51 -0
- package/dist/traverseBlueprintAsync.js.map +1 -0
- package/dist/types.d.ts +176 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/widgetStatus.d.ts +66 -0
- package/dist/widgetStatus.d.ts.map +1 -0
- package/dist/widgetStatus.js +141 -0
- package/dist/widgetStatus.js.map +1 -0
- package/dist/widgets.d.ts +101 -0
- package/dist/widgets.d.ts.map +1 -0
- package/dist/widgets.js +115 -0
- package/dist/widgets.js.map +1 -0
- package/package.json +60 -3
- package/src/Blueprint.ts +28 -0
- package/src/RendererRegistry.ts +38 -0
- package/src/catalog.ts +638 -0
- package/src/coverage.ts +52 -0
- package/src/customWidget.ts +42 -0
- package/src/identity.ts +178 -0
- package/src/index.ts +84 -0
- package/src/irVersion.ts +195 -0
- package/src/layout.ts +105 -0
- package/src/normalize.ts +130 -0
- package/src/pins.ts +84 -0
- package/src/traverseBlueprint.bench.ts +47 -0
- package/src/traverseBlueprint.ts +94 -0
- package/src/traverseBlueprintAsync.ts +92 -0
- package/src/types.ts +195 -0
- package/src/widgetStatus.ts +231 -0
- package/src/widgets.ts +213 -0
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
import type { BindingStatus, Widget } from "./types";
|
|
2
|
+
|
|
3
|
+
// ── The canonical binding-status matrix, as one pure decision ─────────────────
|
|
4
|
+
//
|
|
5
|
+
// redacted > error > empty > contract > stale > pending/loading > ready (IR 2.0.0; `empty` since 2.3.0,
|
|
6
|
+
// ADR 0100). Every first-party renderer (React, terminal, DOM) used to carry its own copy of
|
|
7
|
+
// this ordering, its `degradedFrom` chain and its tolerance for a malformed `source`. They now
|
|
8
|
+
// DRAW from this descriptor and own only their output format (ADR 0127). The function reads
|
|
9
|
+
// nothing but its arguments and never throws on a malformed widget: a `source.degradedFrom` that
|
|
10
|
+
// is not an array of objects yields `{ tag: "invalid" }`, which every renderer draws as its
|
|
11
|
+
// error placeholder.
|
|
12
|
+
|
|
13
|
+
/** A caller-supplied value-contract check — the slot the matrix leaves between `empty` and `stale`. */
|
|
14
|
+
export type WidgetValueCheck = (
|
|
15
|
+
widget: Widget,
|
|
16
|
+
value: unknown
|
|
17
|
+
) => { code: string; message: string } | undefined;
|
|
18
|
+
|
|
19
|
+
/** What a widget with a declared status channel is showing. */
|
|
20
|
+
export type WidgetShownState =
|
|
21
|
+
| "redacted"
|
|
22
|
+
| "error"
|
|
23
|
+
| "empty"
|
|
24
|
+
| "stale"
|
|
25
|
+
| "pending"
|
|
26
|
+
| "loading"
|
|
27
|
+
| "ready";
|
|
28
|
+
|
|
29
|
+
/** The decided status of one widget. `inert` = no status channel declared (IR 1.0.0 behaviour). */
|
|
30
|
+
export type WidgetStatusDescriptor =
|
|
31
|
+
| {
|
|
32
|
+
/** The widget (or its `source`) is malformed; draw the error placeholder, never the cause. */
|
|
33
|
+
readonly tag: "invalid";
|
|
34
|
+
readonly reason: string;
|
|
35
|
+
}
|
|
36
|
+
| {
|
|
37
|
+
readonly tag: "inert" | WidgetShownState;
|
|
38
|
+
/** The finding message (a failed contract check wins), with the matrix default applied. */
|
|
39
|
+
readonly message: string;
|
|
40
|
+
/** The raw finding message, no default: what a `stale` marker carries as its tooltip. */
|
|
41
|
+
readonly finding: string | undefined;
|
|
42
|
+
/** Whether a value is present beside the status. */
|
|
43
|
+
readonly hasValue: boolean;
|
|
44
|
+
/** Whether the widget's own body is drawn (inert, ready, pending, or stale with a value). */
|
|
45
|
+
readonly showBody: boolean;
|
|
46
|
+
/** `type@version › …`, outermost first; undefined when the widget is not degraded. */
|
|
47
|
+
readonly degradedChain: string | undefined;
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const DEFAULT_MESSAGE: Record<WidgetShownState, string> = {
|
|
51
|
+
redacted: "redacted",
|
|
52
|
+
error: "error",
|
|
53
|
+
empty: "no data",
|
|
54
|
+
stale: "stale",
|
|
55
|
+
pending: "",
|
|
56
|
+
loading: "",
|
|
57
|
+
ready: "",
|
|
58
|
+
};
|
|
59
|
+
|
|
60
|
+
const INVALID = Symbol("invalid");
|
|
61
|
+
|
|
62
|
+
const degradedChainOf = (widget: Widget): string | undefined | typeof INVALID => {
|
|
63
|
+
const degraded: unknown = widget.source?.degradedFrom;
|
|
64
|
+
if (degraded === undefined) return undefined;
|
|
65
|
+
if (!Array.isArray(degraded)) return INVALID;
|
|
66
|
+
const parts: string[] = [];
|
|
67
|
+
for (const d of degraded as unknown[]) {
|
|
68
|
+
if (typeof d !== "object" || d === null) return INVALID;
|
|
69
|
+
const { type, version } = d as { type: unknown; version: unknown };
|
|
70
|
+
parts.push(`${String(type)}@${String(version)}`);
|
|
71
|
+
}
|
|
72
|
+
return parts.join(" › ") || undefined;
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Decide what a widget shows. `check` is the optional caller value-contract check; it runs only
|
|
77
|
+
* for a widget whose binding declares a status channel, and only when there is a subject to check
|
|
78
|
+
* (not under `error` or `empty`). A finding outranks `stale`, `pending` and `ready`.
|
|
79
|
+
*/
|
|
80
|
+
export function describeWidgetStatus(
|
|
81
|
+
widget: Widget,
|
|
82
|
+
value: unknown,
|
|
83
|
+
status: BindingStatus | undefined,
|
|
84
|
+
check?: WidgetValueCheck
|
|
85
|
+
): WidgetStatusDescriptor {
|
|
86
|
+
// IR 2.5.0: a redacted widget outranks everything — it is decided before `value`, `status`,
|
|
87
|
+
// `check`, `binding`, `title` or a malformed `source.degradedFrom` is looked at, so none of them
|
|
88
|
+
// can reach a renderer's output. The message is the constant, never data from the widget.
|
|
89
|
+
if ((widget.source as { redacted?: unknown } | undefined)?.redacted === true) {
|
|
90
|
+
return {
|
|
91
|
+
tag: "redacted",
|
|
92
|
+
message: DEFAULT_MESSAGE.redacted,
|
|
93
|
+
finding: undefined,
|
|
94
|
+
hasValue: false,
|
|
95
|
+
showBody: false,
|
|
96
|
+
degradedChain: undefined,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
const chain = degradedChainOf(widget);
|
|
100
|
+
if (chain === INVALID)
|
|
101
|
+
return { tag: "invalid", reason: "source.degradedFrom is not an array of objects" };
|
|
102
|
+
const hasValue = value !== undefined;
|
|
103
|
+
const base = { hasValue, degradedChain: chain };
|
|
104
|
+
if (widget.binding?.status === undefined) {
|
|
105
|
+
return { tag: "inert", message: "", finding: undefined, showBody: true, ...base };
|
|
106
|
+
}
|
|
107
|
+
const noValue = status?.state === "error" || status?.state === "empty";
|
|
108
|
+
const contract = noValue ? undefined : check?.(widget, value);
|
|
109
|
+
const finding = contract ? contract.message : status?.finding?.message;
|
|
110
|
+
let tag: WidgetShownState;
|
|
111
|
+
if (status?.state === "error") tag = "error";
|
|
112
|
+
else if (status?.state === "empty") tag = "empty";
|
|
113
|
+
else if (contract) tag = "error";
|
|
114
|
+
else if (status?.state === "stale") tag = "stale";
|
|
115
|
+
// `status` undefined (not yet written, or malformed) is treated like `ready`: a value that
|
|
116
|
+
// already exists is shown rather than hidden behind a spinner.
|
|
117
|
+
else if (!hasValue) tag = "loading";
|
|
118
|
+
else tag = status?.state === "pending" ? "pending" : "ready";
|
|
119
|
+
return {
|
|
120
|
+
tag,
|
|
121
|
+
message: finding ?? DEFAULT_MESSAGE[tag],
|
|
122
|
+
finding,
|
|
123
|
+
showBody: tag === "ready" || tag === "pending" || (tag === "stale" && hasValue),
|
|
124
|
+
...base,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
// ── What every surface says about a decided status: the frame facts ───────────
|
|
129
|
+
//
|
|
130
|
+
// `describeWidgetStatus` decides WHICH state wins; this names WHAT is shown for it — the
|
|
131
|
+
// `data-binding-state` value, the marker's name / ARIA role / glyph / line, the `data-source-*`
|
|
132
|
+
// attributes and the degraded-from tooltip. A renderer draws these in its own medium (DOM
|
|
133
|
+
// elements, React elements, text) and adds nothing of its own to the vocabulary. Pure; reads only
|
|
134
|
+
// its arguments. Consumers: `@loomwork/plugin-renderer-react`, `-terminal`, `-dom` (ADR 0127).
|
|
135
|
+
|
|
136
|
+
/** The marker one status draws. `text` is the whole line for the markers that carry one. */
|
|
137
|
+
export interface WidgetStatusMarker {
|
|
138
|
+
/** `data-binding-marker`. */
|
|
139
|
+
readonly name: Exclude<WidgetShownState, "ready">;
|
|
140
|
+
/** `alert` for error; `status` for empty and redacted (a polite live region); otherwise none. */
|
|
141
|
+
readonly role: "alert" | "status" | undefined;
|
|
142
|
+
readonly glyph: string;
|
|
143
|
+
/** `glyph title: message` (error, empty), `… — no value` (stale, no value); else undefined. */
|
|
144
|
+
readonly text: string | undefined;
|
|
145
|
+
/** A stale marker beside a drawn value is glyph-only and carries the finding as its tooltip. */
|
|
146
|
+
readonly tooltip: string | undefined;
|
|
147
|
+
/** Block-level (a row) vs inline (a glyph beside the body). */
|
|
148
|
+
readonly block: boolean;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export interface WidgetStatusFrame {
|
|
152
|
+
/** `data-binding-state`; undefined for an inert widget. */
|
|
153
|
+
readonly state: WidgetShownState | undefined;
|
|
154
|
+
readonly sourceType: string | undefined;
|
|
155
|
+
readonly sourceVersion: string | undefined;
|
|
156
|
+
/** `data-degraded`: the chain, outermost first. */
|
|
157
|
+
readonly degraded: string | undefined;
|
|
158
|
+
/** The `title` attribute of a degraded widget. */
|
|
159
|
+
readonly tooltip: string | undefined;
|
|
160
|
+
/** The marker to draw before the body, or undefined (inert, ready). */
|
|
161
|
+
readonly marker: WidgetStatusMarker | undefined;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* The surface-independent facts of a decided status. A redacted widget yields the constant marker
|
|
166
|
+
* and no source/degraded facts (nothing of the widget may reach the output).
|
|
167
|
+
*/
|
|
168
|
+
export function describeWidgetFrame(
|
|
169
|
+
widget: Widget,
|
|
170
|
+
d: Exclude<WidgetStatusDescriptor, { tag: "invalid" }>
|
|
171
|
+
): WidgetStatusFrame {
|
|
172
|
+
if (d.tag === "redacted") {
|
|
173
|
+
return {
|
|
174
|
+
state: "redacted",
|
|
175
|
+
sourceType: undefined,
|
|
176
|
+
sourceVersion: undefined,
|
|
177
|
+
degraded: undefined,
|
|
178
|
+
tooltip: undefined,
|
|
179
|
+
marker: {
|
|
180
|
+
name: "redacted",
|
|
181
|
+
role: "status",
|
|
182
|
+
glyph: "⊘",
|
|
183
|
+
text: `⊘ ${d.message}`,
|
|
184
|
+
tooltip: undefined,
|
|
185
|
+
block: true,
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
const label = widget.title ?? widget.kind;
|
|
190
|
+
const degraded = d.degradedChain;
|
|
191
|
+
let marker: WidgetStatusMarker | undefined;
|
|
192
|
+
const row = (
|
|
193
|
+
name: WidgetStatusMarker["name"],
|
|
194
|
+
role: WidgetStatusMarker["role"],
|
|
195
|
+
glyph: string,
|
|
196
|
+
text: string | undefined,
|
|
197
|
+
block: boolean,
|
|
198
|
+
tooltip?: string
|
|
199
|
+
): WidgetStatusMarker => ({ name, role, glyph, text, tooltip, block });
|
|
200
|
+
switch (d.tag) {
|
|
201
|
+
case "error":
|
|
202
|
+
marker = row("error", "alert", "✗", `✗ ${label}: ${d.message}`, true);
|
|
203
|
+
break;
|
|
204
|
+
case "empty":
|
|
205
|
+
marker = row("empty", "status", "○", `○ ${label}: ${d.message}`, true);
|
|
206
|
+
break;
|
|
207
|
+
case "stale":
|
|
208
|
+
marker = d.hasValue
|
|
209
|
+
? row("stale", undefined, "~", undefined, false, d.finding)
|
|
210
|
+
: row("stale", undefined, "~", `~ ${label}: ${d.message} — no value`, true);
|
|
211
|
+
break;
|
|
212
|
+
case "pending":
|
|
213
|
+
marker = row("pending", undefined, "⋯", undefined, false);
|
|
214
|
+
break;
|
|
215
|
+
case "loading":
|
|
216
|
+
marker = row("loading", undefined, "…", undefined, true);
|
|
217
|
+
break;
|
|
218
|
+
default:
|
|
219
|
+
marker = undefined;
|
|
220
|
+
}
|
|
221
|
+
return {
|
|
222
|
+
state: d.tag === "inert" ? undefined : d.tag,
|
|
223
|
+
sourceType: widget.source?.type,
|
|
224
|
+
sourceVersion: widget.source?.version,
|
|
225
|
+
degraded,
|
|
226
|
+
tooltip: degraded
|
|
227
|
+
? `${widget.source?.type}@${widget.source?.version} shown as ${widget.kind} (degraded from ${degraded})`
|
|
228
|
+
: undefined,
|
|
229
|
+
marker,
|
|
230
|
+
};
|
|
231
|
+
}
|
package/src/widgets.ts
ADDED
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
import type { DataBinding, Widget } from "./types";
|
|
2
|
+
|
|
3
|
+
// A derived id, used when the caller supplies none. It is an IDENTITY, not a
|
|
4
|
+
// content address: a 32-bit non-cryptographic hash, scoped to one blueprint.
|
|
5
|
+
// Never treat it as an audit anchor for "which view was this" — use a real digest
|
|
6
|
+
// (`contentAddress` in @loomwork/plugin-content) for that.
|
|
7
|
+
//
|
|
8
|
+
// Because it is derived from the props, it CHANGES when any prop changes. That is
|
|
9
|
+
// correct for a view that is authored once and wrong for one a composer revises,
|
|
10
|
+
// which is why every builder accepts an explicit `id`.
|
|
11
|
+
function stableId(kind: string, props: object): string {
|
|
12
|
+
const str = kind + JSON.stringify(props, Object.keys(props as Record<string, unknown>).sort());
|
|
13
|
+
let hash = 0;
|
|
14
|
+
for (let i = 0; i < str.length; i++) {
|
|
15
|
+
hash = (Math.imul(31, hash) + str.charCodeAt(i)) | 0;
|
|
16
|
+
}
|
|
17
|
+
return `${kind}-${(hash >>> 0).toString(16)}`;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export interface MetricCardProps {
|
|
21
|
+
title: string;
|
|
22
|
+
binding: DataBinding;
|
|
23
|
+
unit?: string;
|
|
24
|
+
format?: "number" | "percent" | "bytes";
|
|
25
|
+
/**
|
|
26
|
+
* Stable node id. Supply it when a composer will REVISE this view: the derived
|
|
27
|
+
* id is a hash of kind + props, so editing any prop re-identifies the node —
|
|
28
|
+
* remounting it, and breaking anything keyed on it (a pin, an annotation, an
|
|
29
|
+
* agent's reference to it).
|
|
30
|
+
*/
|
|
31
|
+
id?: string;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export function MetricCard(props: MetricCardProps): Widget {
|
|
35
|
+
const { title, id, ...rest } = props;
|
|
36
|
+
return {
|
|
37
|
+
_tag: "Widget",
|
|
38
|
+
id: id ?? stableId("MetricCard", props),
|
|
39
|
+
kind: "MetricCard",
|
|
40
|
+
title,
|
|
41
|
+
props: rest,
|
|
42
|
+
binding: props.binding,
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export interface TimelineProps {
|
|
47
|
+
title?: string;
|
|
48
|
+
binding: DataBinding;
|
|
49
|
+
maxItems?: number;
|
|
50
|
+
/**
|
|
51
|
+
* Stable node id. Supply it when a composer will REVISE this view: the derived
|
|
52
|
+
* id is a hash of kind + props, so editing any prop re-identifies the node —
|
|
53
|
+
* remounting it, and breaking anything keyed on it (a pin, an annotation, an
|
|
54
|
+
* agent's reference to it).
|
|
55
|
+
*/
|
|
56
|
+
id?: string;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
export function Timeline(props: TimelineProps): Widget {
|
|
60
|
+
const { title, id, ...rest } = props;
|
|
61
|
+
return {
|
|
62
|
+
_tag: "Widget",
|
|
63
|
+
id: id ?? stableId("Timeline", props),
|
|
64
|
+
kind: "Timeline",
|
|
65
|
+
...(title !== undefined && { title }),
|
|
66
|
+
props: rest,
|
|
67
|
+
binding: props.binding,
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export interface ApprovalCardProps {
|
|
72
|
+
title: string;
|
|
73
|
+
binding: DataBinding;
|
|
74
|
+
approveLabel?: string;
|
|
75
|
+
rejectLabel?: string;
|
|
76
|
+
/**
|
|
77
|
+
* Stable node id. Supply it when a composer will REVISE this view: the derived
|
|
78
|
+
* id is a hash of kind + props, so editing any prop re-identifies the node —
|
|
79
|
+
* remounting it, and breaking anything keyed on it (a pin, an annotation, an
|
|
80
|
+
* agent's reference to it).
|
|
81
|
+
*/
|
|
82
|
+
id?: string;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
export function ApprovalCard(props: ApprovalCardProps): Widget {
|
|
86
|
+
const { title, id, ...rest } = props;
|
|
87
|
+
return {
|
|
88
|
+
_tag: "Widget",
|
|
89
|
+
id: id ?? stableId("ApprovalCard", props),
|
|
90
|
+
kind: "ApprovalCard",
|
|
91
|
+
title,
|
|
92
|
+
props: rest,
|
|
93
|
+
binding: props.binding,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export interface StatusBadgeProps {
|
|
98
|
+
title?: string;
|
|
99
|
+
binding: DataBinding;
|
|
100
|
+
/**
|
|
101
|
+
* Stable node id. Supply it when a composer will REVISE this view: the derived
|
|
102
|
+
* id is a hash of kind + props, so editing any prop re-identifies the node —
|
|
103
|
+
* remounting it, and breaking anything keyed on it (a pin, an annotation, an
|
|
104
|
+
* agent's reference to it).
|
|
105
|
+
*/
|
|
106
|
+
id?: string;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
export function StatusBadge(props: StatusBadgeProps): Widget {
|
|
110
|
+
const { title, id, ...rest } = props;
|
|
111
|
+
return {
|
|
112
|
+
_tag: "Widget",
|
|
113
|
+
id: id ?? stableId("StatusBadge", props),
|
|
114
|
+
kind: "StatusBadge",
|
|
115
|
+
...(title !== undefined && { title }),
|
|
116
|
+
props: rest,
|
|
117
|
+
binding: props.binding,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
export interface ProgressBarProps {
|
|
122
|
+
title?: string;
|
|
123
|
+
binding: DataBinding;
|
|
124
|
+
max?: number;
|
|
125
|
+
/**
|
|
126
|
+
* Stable node id. Supply it when a composer will REVISE this view: the derived
|
|
127
|
+
* id is a hash of kind + props, so editing any prop re-identifies the node —
|
|
128
|
+
* remounting it, and breaking anything keyed on it (a pin, an annotation, an
|
|
129
|
+
* agent's reference to it).
|
|
130
|
+
*/
|
|
131
|
+
id?: string;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export function ProgressBar(props: ProgressBarProps): Widget {
|
|
135
|
+
const { title, id, ...rest } = props;
|
|
136
|
+
return {
|
|
137
|
+
_tag: "Widget",
|
|
138
|
+
id: id ?? stableId("ProgressBar", props),
|
|
139
|
+
kind: "ProgressBar",
|
|
140
|
+
...(title !== undefined && { title }),
|
|
141
|
+
props: rest,
|
|
142
|
+
binding: props.binding,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
export interface DataTableProps {
|
|
147
|
+
title?: string;
|
|
148
|
+
binding: DataBinding;
|
|
149
|
+
columns?: string[];
|
|
150
|
+
/**
|
|
151
|
+
* Stable node id. Supply it when a composer will REVISE this view: the derived
|
|
152
|
+
* id is a hash of kind + props, so editing any prop re-identifies the node —
|
|
153
|
+
* remounting it, and breaking anything keyed on it (a pin, an annotation, an
|
|
154
|
+
* agent's reference to it).
|
|
155
|
+
*/
|
|
156
|
+
id?: string;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
export function DataTable(props: DataTableProps): Widget {
|
|
160
|
+
const { title, id, ...rest } = props;
|
|
161
|
+
return {
|
|
162
|
+
_tag: "Widget",
|
|
163
|
+
id: id ?? stableId("DataTable", props),
|
|
164
|
+
kind: "DataTable",
|
|
165
|
+
...(title !== undefined && { title }),
|
|
166
|
+
props: rest,
|
|
167
|
+
binding: props.binding,
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export interface AlertCardProps {
|
|
172
|
+
title?: string;
|
|
173
|
+
binding: DataBinding;
|
|
174
|
+
severity?: "info" | "warning" | "error" | "critical";
|
|
175
|
+
/**
|
|
176
|
+
* Stable node id. Supply it when a composer will REVISE this view: the derived
|
|
177
|
+
* id is a hash of kind + props, so editing any prop re-identifies the node —
|
|
178
|
+
* remounting it, and breaking anything keyed on it (a pin, an annotation, an
|
|
179
|
+
* agent's reference to it).
|
|
180
|
+
*/
|
|
181
|
+
id?: string;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export function AlertCard(props: AlertCardProps): Widget {
|
|
185
|
+
const { title, id, ...rest } = props;
|
|
186
|
+
return {
|
|
187
|
+
_tag: "Widget",
|
|
188
|
+
id: id ?? stableId("AlertCard", props),
|
|
189
|
+
kind: "AlertCard",
|
|
190
|
+
...(title !== undefined && { title }),
|
|
191
|
+
props: rest,
|
|
192
|
+
binding: props.binding,
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
export interface StreamingTextProps {
|
|
197
|
+
title?: string;
|
|
198
|
+
binding: DataBinding;
|
|
199
|
+
placeholder?: string;
|
|
200
|
+
id?: string;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
export function StreamingText(props: StreamingTextProps): Widget {
|
|
204
|
+
const { title, id, ...rest } = props;
|
|
205
|
+
return {
|
|
206
|
+
_tag: "Widget",
|
|
207
|
+
id: id ?? stableId("StreamingText", props),
|
|
208
|
+
kind: "StreamingText",
|
|
209
|
+
...(title !== undefined && { title }),
|
|
210
|
+
props: rest,
|
|
211
|
+
binding: props.binding,
|
|
212
|
+
};
|
|
213
|
+
}
|