@unofficialbox/box-open-elements 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +3 -3
- package/dist/components/collections/table.d.ts +57 -3
- package/dist/components/collections/table.js +339 -20
- package/dist/components/feedback/due-badge.d.ts +38 -0
- package/dist/components/feedback/due-badge.js +168 -0
- package/dist/components/feedback/due-types.d.ts +32 -0
- package/dist/components/feedback/due-types.js +91 -0
- package/dist/components/feedback/progress-steps.d.ts +51 -5
- package/dist/components/feedback/progress-steps.js +200 -22
- package/dist/components/feedback/stage-path.d.ts +44 -0
- package/dist/components/feedback/stage-path.js +235 -0
- package/dist/components/forms/select.d.ts +21 -0
- package/dist/components/forms/select.js +100 -3
- package/dist/components/forms/text-field.d.ts +21 -0
- package/dist/components/forms/text-field.js +100 -1
- package/dist/components/layout/nav-sidebar.d.ts +14 -0
- package/dist/components/layout/nav-sidebar.js +49 -0
- package/dist/components/layout/split-view.d.ts +14 -0
- package/dist/components/layout/split-view.js +80 -1
- package/dist/components/overlays/command-palette.d.ts +62 -0
- package/dist/components/overlays/command-palette.js +537 -0
- package/dist/components/overlays/command-types.d.ts +90 -0
- package/dist/components/overlays/command-types.js +259 -0
- package/dist/components/overlays/drawer.d.ts +18 -0
- package/dist/components/overlays/drawer.js +135 -9
- package/dist/components/overlays/shortcuts-overlay.d.ts +48 -0
- package/dist/components/overlays/shortcuts-overlay.js +385 -0
- package/dist/components/overlays/tooltip.js +1 -1
- package/dist/element-maps.d.ts +292 -0
- package/dist/element-maps.js +1 -0
- package/dist/entries/activity-density.d.ts +1 -0
- package/dist/entries/activity-density.js +1 -0
- package/dist/entries/agent-chat.d.ts +1 -0
- package/dist/entries/agent-chat.js +1 -0
- package/dist/entries/audit-log.d.ts +1 -0
- package/dist/entries/audit-log.js +1 -0
- package/dist/entries/command-palette.d.ts +1 -0
- package/dist/entries/command-palette.js +1 -0
- package/dist/entries/compare-view.d.ts +1 -0
- package/dist/entries/compare-view.js +1 -0
- package/dist/entries/diff-viewer.d.ts +1 -0
- package/dist/entries/diff-viewer.js +1 -0
- package/dist/entries/due-badge.d.ts +1 -0
- package/dist/entries/due-badge.js +1 -0
- package/dist/entries/form-wizard.d.ts +1 -0
- package/dist/entries/form-wizard.js +1 -0
- package/dist/entries/lineage-graph.d.ts +1 -0
- package/dist/entries/lineage-graph.js +1 -0
- package/dist/entries/notification-bell.d.ts +1 -0
- package/dist/entries/notification-bell.js +1 -0
- package/dist/entries/notification-inbox.d.ts +1 -0
- package/dist/entries/notification-inbox.js +1 -0
- package/dist/entries/provenance-strip.d.ts +1 -0
- package/dist/entries/provenance-strip.js +1 -0
- package/dist/entries/run-trace.d.ts +1 -0
- package/dist/entries/run-trace.js +1 -0
- package/dist/entries/shortcuts-overlay.d.ts +1 -0
- package/dist/entries/shortcuts-overlay.js +1 -0
- package/dist/entries/signature-ceremony.d.ts +1 -0
- package/dist/entries/signature-ceremony.js +1 -0
- package/dist/entries/stage-path.d.ts +1 -0
- package/dist/entries/stage-path.js +1 -0
- package/dist/entries/timeline.d.ts +1 -0
- package/dist/entries/timeline.js +1 -0
- package/dist/entries/version-graph.d.ts +1 -0
- package/dist/entries/version-graph.js +1 -0
- package/dist/entries/version-list.d.ts +1 -0
- package/dist/entries/version-list.js +1 -0
- package/dist/entries/wizard-summary.d.ts +1 -0
- package/dist/entries/wizard-summary.js +1 -0
- package/dist/entries/work-queue.d.ts +1 -0
- package/dist/entries/work-queue.js +1 -0
- package/dist/entries/workload-board.d.ts +1 -0
- package/dist/entries/workload-board.js +1 -0
- package/dist/index.d.ts +21 -0
- package/dist/index.js +21 -0
- package/dist/patterns/agent-chat/agent-chat.d.ts +75 -0
- package/dist/patterns/agent-chat/agent-chat.js +820 -0
- package/dist/patterns/agent-chat/controller.d.ts +27 -0
- package/dist/patterns/agent-chat/controller.js +182 -0
- package/dist/patterns/agent-chat/index.d.ts +3 -0
- package/dist/patterns/agent-chat/index.js +6 -0
- package/dist/patterns/agent-chat/types.d.ts +109 -0
- package/dist/patterns/agent-chat/types.js +1 -0
- package/dist/patterns/audit/activity-density.d.ts +68 -0
- package/dist/patterns/audit/activity-density.js +428 -0
- package/dist/patterns/audit/audit-log.d.ts +81 -0
- package/dist/patterns/audit/audit-log.js +794 -0
- package/dist/patterns/audit/index.d.ts +3 -0
- package/dist/patterns/audit/index.js +7 -0
- package/dist/patterns/audit/shared.d.ts +10 -0
- package/dist/patterns/audit/shared.js +50 -0
- package/dist/patterns/audit/types.d.ts +143 -0
- package/dist/patterns/audit/types.js +327 -0
- package/dist/patterns/content-explorer/actions/controller.js +12 -2
- package/dist/patterns/content-explorer/box-transport.js +117 -25
- package/dist/patterns/content-explorer/content-explorer.d.ts +13 -1
- package/dist/patterns/content-explorer/content-explorer.js +36 -3
- package/dist/patterns/content-explorer/contracts.d.ts +24 -1
- package/dist/patterns/content-explorer/contracts.js +68 -11
- package/dist/patterns/content-explorer/controller.d.ts +16 -1
- package/dist/patterns/content-explorer/controller.js +130 -4
- package/dist/patterns/content-explorer/navigation/controller.js +11 -9
- package/dist/patterns/content-explorer/types.d.ts +58 -1
- package/dist/patterns/content-picker/content-picker.d.ts +71 -0
- package/dist/patterns/content-picker/content-picker.js +747 -0
- package/dist/patterns/content-picker/controller.d.ts +38 -0
- package/dist/patterns/content-picker/controller.js +141 -0
- package/dist/patterns/content-picker/index.d.ts +3 -0
- package/dist/patterns/content-picker/index.js +6 -0
- package/dist/patterns/content-picker/types.d.ts +52 -0
- package/dist/patterns/content-picker/types.js +26 -0
- package/dist/patterns/content-sidebar/content-sidebar.d.ts +43 -0
- package/dist/patterns/content-sidebar/content-sidebar.js +293 -0
- package/dist/patterns/content-sidebar/index.d.ts +2 -0
- package/dist/patterns/content-sidebar/index.js +4 -0
- package/dist/patterns/content-sidebar/types.d.ts +18 -0
- package/dist/patterns/content-sidebar/types.js +20 -0
- package/dist/patterns/content-uploader/box-transport.d.ts +14 -0
- package/dist/patterns/content-uploader/box-transport.js +54 -0
- package/dist/patterns/content-uploader/content-uploader.d.ts +62 -0
- package/dist/patterns/content-uploader/content-uploader.js +559 -0
- package/dist/patterns/content-uploader/controller.d.ts +39 -0
- package/dist/patterns/content-uploader/controller.js +227 -0
- package/dist/patterns/content-uploader/index.d.ts +4 -0
- package/dist/patterns/content-uploader/index.js +8 -0
- package/dist/patterns/content-uploader/types.d.ts +120 -0
- package/dist/patterns/content-uploader/types.js +38 -0
- package/dist/patterns/diff/compare-view.d.ts +47 -0
- package/dist/patterns/diff/compare-view.js +276 -0
- package/dist/patterns/diff/diff-viewer.d.ts +42 -0
- package/dist/patterns/diff/diff-viewer.js +434 -0
- package/dist/patterns/diff/engine.d.ts +22 -0
- package/dist/patterns/diff/engine.js +276 -0
- package/dist/patterns/diff/index.d.ts +4 -0
- package/dist/patterns/diff/index.js +8 -0
- package/dist/patterns/diff/types.d.ts +69 -0
- package/dist/patterns/diff/types.js +24 -0
- package/dist/patterns/form-wizard/controller.d.ts +39 -0
- package/dist/patterns/form-wizard/controller.js +157 -0
- package/dist/patterns/form-wizard/form-wizard.d.ts +63 -0
- package/dist/patterns/form-wizard/form-wizard.js +468 -0
- package/dist/patterns/form-wizard/index.d.ts +4 -0
- package/dist/patterns/form-wizard/index.js +8 -0
- package/dist/patterns/form-wizard/types.d.ts +109 -0
- package/dist/patterns/form-wizard/types.js +83 -0
- package/dist/patterns/form-wizard/wizard-summary.d.ts +62 -0
- package/dist/patterns/form-wizard/wizard-summary.js +324 -0
- package/dist/patterns/internal/safe-href.d.ts +17 -0
- package/dist/patterns/internal/safe-href.js +17 -0
- package/dist/patterns/lineage/index.d.ts +3 -0
- package/dist/patterns/lineage/index.js +6 -0
- package/dist/patterns/lineage/lineage-graph.d.ts +30 -0
- package/dist/patterns/lineage/lineage-graph.js +434 -0
- package/dist/patterns/lineage/provenance-strip.d.ts +22 -0
- package/dist/patterns/lineage/provenance-strip.js +194 -0
- package/dist/patterns/lineage/types.d.ts +53 -0
- package/dist/patterns/lineage/types.js +49 -0
- package/dist/patterns/notifications/index.d.ts +3 -0
- package/dist/patterns/notifications/index.js +6 -0
- package/dist/patterns/notifications/notification-bell.d.ts +38 -0
- package/dist/patterns/notifications/notification-bell.js +198 -0
- package/dist/patterns/notifications/notification-inbox.d.ts +46 -0
- package/dist/patterns/notifications/notification-inbox.js +537 -0
- package/dist/patterns/notifications/types.d.ts +61 -0
- package/dist/patterns/notifications/types.js +108 -0
- package/dist/patterns/preview/annotation-inspector.d.ts +25 -6
- package/dist/patterns/preview/annotation-inspector.js +239 -94
- package/dist/patterns/preview/annotation-thread.d.ts +25 -5
- package/dist/patterns/preview/annotation-thread.js +233 -82
- package/dist/patterns/preview/annotation-toolbar.d.ts +20 -6
- package/dist/patterns/preview/annotation-toolbar.js +162 -96
- package/dist/patterns/preview/content-preview-adapter.d.ts +10 -1
- package/dist/patterns/preview/content-preview-adapter.js +26 -1
- package/dist/patterns/preview/preview-element.d.ts +15 -2
- package/dist/patterns/preview/preview-element.js +223 -52
- package/dist/patterns/preview/provider-adapter.d.ts +47 -0
- package/dist/patterns/preview/provider-adapter.js +17 -0
- package/dist/patterns/run/index.d.ts +2 -0
- package/dist/patterns/run/index.js +4 -0
- package/dist/patterns/run/run-trace.d.ts +40 -0
- package/dist/patterns/run/run-trace.js +441 -0
- package/dist/patterns/run/types.d.ts +66 -0
- package/dist/patterns/run/types.js +152 -0
- package/dist/patterns/signature/index.d.ts +2 -0
- package/dist/patterns/signature/index.js +4 -0
- package/dist/patterns/signature/signature-ceremony.d.ts +33 -0
- package/dist/patterns/signature/signature-ceremony.js +317 -0
- package/dist/patterns/signature/types.d.ts +68 -0
- package/dist/patterns/signature/types.js +89 -0
- package/dist/patterns/timeline/index.d.ts +2 -0
- package/dist/patterns/timeline/index.js +4 -0
- package/dist/patterns/timeline/timeline.d.ts +27 -0
- package/dist/patterns/timeline/timeline.js +430 -0
- package/dist/patterns/timeline/types.d.ts +36 -0
- package/dist/patterns/timeline/types.js +27 -0
- package/dist/patterns/versions/graph-layout.d.ts +43 -0
- package/dist/patterns/versions/graph-layout.js +159 -0
- package/dist/patterns/versions/index.d.ts +4 -0
- package/dist/patterns/versions/index.js +8 -0
- package/dist/patterns/versions/shared.d.ts +4 -0
- package/dist/patterns/versions/shared.js +13 -0
- package/dist/patterns/versions/types.d.ts +37 -0
- package/dist/patterns/versions/types.js +39 -0
- package/dist/patterns/versions/version-graph.d.ts +36 -0
- package/dist/patterns/versions/version-graph.js +438 -0
- package/dist/patterns/versions/version-list.d.ts +39 -0
- package/dist/patterns/versions/version-list.js +407 -0
- package/dist/patterns/work-queue/controller.d.ts +26 -0
- package/dist/patterns/work-queue/controller.js +150 -0
- package/dist/patterns/work-queue/index.d.ts +4 -0
- package/dist/patterns/work-queue/index.js +7 -0
- package/dist/patterns/work-queue/types.d.ts +128 -0
- package/dist/patterns/work-queue/types.js +45 -0
- package/dist/patterns/work-queue/work-queue.d.ts +48 -0
- package/dist/patterns/work-queue/work-queue.js +534 -0
- package/dist/patterns/work-queue/workload-board.d.ts +53 -0
- package/dist/patterns/work-queue/workload-board.js +608 -0
- package/package.json +89 -5
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { summarizeWizardValues } from "./types.js";
|
|
2
|
+
import type { WizardStepConfig, WizardSummaryField } from "./types.js";
|
|
3
|
+
import { BaseElement } from "../../core/index.js";
|
|
4
|
+
/**
|
|
5
|
+
* The review step of a `box-form-wizard`: everything collected so far, grouped
|
|
6
|
+
* by the step that collected it, with an Edit link per group.
|
|
7
|
+
*
|
|
8
|
+
* The card is read-only and emits `edit-requested` rather than navigating
|
|
9
|
+
* itself, so the host stays in charge of the wizard — the same intent contract
|
|
10
|
+
* the rest of the patterns use.
|
|
11
|
+
*
|
|
12
|
+
* Two details carry the weight:
|
|
13
|
+
*
|
|
14
|
+
* - Sections follow **step order**, so the summary reads back in the sequence
|
|
15
|
+
* the user filled it in rather than in whatever order the fields were
|
|
16
|
+
* declared.
|
|
17
|
+
* - A field naming a step that does not exist lands in a trailing section
|
|
18
|
+
* instead of vanishing. A review card exists so someone can confirm what
|
|
19
|
+
* they are submitting; silently dropping a row would let them confirm a
|
|
20
|
+
* value they were never shown.
|
|
21
|
+
*/
|
|
22
|
+
export declare class WizardSummary extends BaseElement {
|
|
23
|
+
static readonly tagName: string;
|
|
24
|
+
static get observedAttributes(): string[];
|
|
25
|
+
private hostEl;
|
|
26
|
+
private fieldsRaw;
|
|
27
|
+
private fieldsCache;
|
|
28
|
+
private stepsRaw;
|
|
29
|
+
private stepsCache;
|
|
30
|
+
private valuesRaw;
|
|
31
|
+
private valuesCache;
|
|
32
|
+
get heading(): string;
|
|
33
|
+
set heading(value: string);
|
|
34
|
+
/** Verb on the per-section control. The step label is appended for its accessible name. */
|
|
35
|
+
get editLabel(): string;
|
|
36
|
+
set editLabel(value: string);
|
|
37
|
+
/** Placeholder for a field with nothing collected. */
|
|
38
|
+
get emptyText(): string;
|
|
39
|
+
set emptyText(value: string);
|
|
40
|
+
/**
|
|
41
|
+
* Fields to summarise. Note that `format` cannot survive the attribute
|
|
42
|
+
* round-trip — set the property directly when a field needs one.
|
|
43
|
+
*/
|
|
44
|
+
get fields(): WizardSummaryField[];
|
|
45
|
+
/**
|
|
46
|
+
* Setting any of `fields`, `steps`, or `values` as a **property** stores the
|
|
47
|
+
* value as-is and re-renders. It is not mirrored to the attribute, because
|
|
48
|
+
* these carry things a JSON round-trip destroys — a field's `format`
|
|
49
|
+
* function, a `Date` in the collected values. The attributes remain the
|
|
50
|
+
* declarative path for plain records; whichever is set last wins.
|
|
51
|
+
*/
|
|
52
|
+
set fields(value: WizardSummaryField[]);
|
|
53
|
+
get steps(): WizardStepConfig[];
|
|
54
|
+
set steps(value: WizardStepConfig[]);
|
|
55
|
+
get values(): Record<string, unknown>;
|
|
56
|
+
set values(value: Record<string, unknown>);
|
|
57
|
+
/** The sections as rendered — same order, so a host can mirror the card. */
|
|
58
|
+
get sections(): ReturnType<typeof summarizeWizardValues>;
|
|
59
|
+
protected renderTemplate(): void;
|
|
60
|
+
protected setupListeners(): void;
|
|
61
|
+
protected update(): void;
|
|
62
|
+
}
|
|
@@ -0,0 +1,324 @@
|
|
|
1
|
+
import { isWizardSummaryFieldRecord, summarizeWizardValues, } from "./types.js";
|
|
2
|
+
import { BaseElement } from "../../core/index.js";
|
|
3
|
+
import { boePanel, boeRadius } from "../../foundations/geometry/index.js";
|
|
4
|
+
const DEFAULT_TAG_NAME = "box-wizard-summary";
|
|
5
|
+
const escapeHtml = (value) => value
|
|
6
|
+
.replaceAll("&", "&")
|
|
7
|
+
.replaceAll("<", "<")
|
|
8
|
+
.replaceAll(">", ">")
|
|
9
|
+
.replaceAll('"', """)
|
|
10
|
+
.replaceAll("'", "'");
|
|
11
|
+
const elementStyles = `
|
|
12
|
+
:host {
|
|
13
|
+
display: block;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
[part="card"] {
|
|
17
|
+
border: ${boePanel.border};
|
|
18
|
+
border-radius: ${boePanel.radius};
|
|
19
|
+
background: ${boePanel.background};
|
|
20
|
+
overflow: hidden;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
[part="heading"] {
|
|
24
|
+
margin: 0;
|
|
25
|
+
padding: 0.85rem 1rem;
|
|
26
|
+
font: inherit;
|
|
27
|
+
font-size: 0.95rem;
|
|
28
|
+
font-weight: 700;
|
|
29
|
+
color: var(--boe-token-text-text, #1f1e1b);
|
|
30
|
+
border-block-end: 1px solid color-mix(in srgb, var(--boe-token-stroke-stroke, #e8e8e8) 70%, transparent);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
[part="sections"] {
|
|
34
|
+
margin: 0;
|
|
35
|
+
padding: 0;
|
|
36
|
+
list-style: none;
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
[part="section"] + [part="section"] {
|
|
40
|
+
border-block-start: 1px solid color-mix(in srgb, var(--boe-token-stroke-stroke, #e8e8e8) 55%, transparent);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
[part="section-header"] {
|
|
44
|
+
display: flex;
|
|
45
|
+
align-items: baseline;
|
|
46
|
+
gap: 0.75rem;
|
|
47
|
+
padding: 0.7rem 1rem 0.3rem;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
[part="section-label"] {
|
|
51
|
+
font-size: 0.72rem;
|
|
52
|
+
font-weight: 700;
|
|
53
|
+
letter-spacing: 0.08em;
|
|
54
|
+
text-transform: uppercase;
|
|
55
|
+
color: var(--boe-token-text-text-secondary, #6f6f6f);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
[part="edit"] {
|
|
59
|
+
margin-inline-start: auto;
|
|
60
|
+
appearance: none;
|
|
61
|
+
font: inherit;
|
|
62
|
+
font-size: 0.78rem;
|
|
63
|
+
padding: 0.15rem 0.5rem;
|
|
64
|
+
border: 1px solid var(--boe-token-stroke-stroke, #e8e8e8);
|
|
65
|
+
border-radius: ${boeRadius.control};
|
|
66
|
+
background: var(--boe-token-surface-surface, #ffffff);
|
|
67
|
+
color: var(--boe-token-surface-surface-brand, #0061d5);
|
|
68
|
+
cursor: pointer;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
[part="edit"]:hover {
|
|
72
|
+
background: var(--boe-token-surface-surface-hover, #f4f4f4);
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
[part="edit"]:focus-visible {
|
|
76
|
+
outline: none;
|
|
77
|
+
box-shadow: 0 0 0 3px color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 18%, transparent);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
[part="rows"] {
|
|
81
|
+
margin: 0;
|
|
82
|
+
padding: 0 1rem 0.8rem;
|
|
83
|
+
display: grid;
|
|
84
|
+
grid-template-columns: minmax(8rem, 14rem) 1fr;
|
|
85
|
+
gap: 0.3rem 1rem;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
[part="row-label"] {
|
|
89
|
+
margin: 0;
|
|
90
|
+
font-size: 0.85rem;
|
|
91
|
+
color: var(--boe-token-text-text-secondary, #6f6f6f);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
[part="row-value"] {
|
|
95
|
+
margin: 0;
|
|
96
|
+
font-size: 0.85rem;
|
|
97
|
+
color: var(--boe-token-text-text, #1f1e1b);
|
|
98
|
+
overflow-wrap: anywhere;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
[part="row-value"][data-empty="true"] {
|
|
102
|
+
color: var(--boe-token-text-text-secondary, #6f6f6f);
|
|
103
|
+
font-style: italic;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
[part="empty"] {
|
|
107
|
+
padding: 1.2rem 1rem;
|
|
108
|
+
text-align: center;
|
|
109
|
+
color: var(--boe-token-text-text-secondary, #6f6f6f);
|
|
110
|
+
}
|
|
111
|
+
`;
|
|
112
|
+
/**
|
|
113
|
+
* The review step of a `box-form-wizard`: everything collected so far, grouped
|
|
114
|
+
* by the step that collected it, with an Edit link per group.
|
|
115
|
+
*
|
|
116
|
+
* The card is read-only and emits `edit-requested` rather than navigating
|
|
117
|
+
* itself, so the host stays in charge of the wizard — the same intent contract
|
|
118
|
+
* the rest of the patterns use.
|
|
119
|
+
*
|
|
120
|
+
* Two details carry the weight:
|
|
121
|
+
*
|
|
122
|
+
* - Sections follow **step order**, so the summary reads back in the sequence
|
|
123
|
+
* the user filled it in rather than in whatever order the fields were
|
|
124
|
+
* declared.
|
|
125
|
+
* - A field naming a step that does not exist lands in a trailing section
|
|
126
|
+
* instead of vanishing. A review card exists so someone can confirm what
|
|
127
|
+
* they are submitting; silently dropping a row would let them confirm a
|
|
128
|
+
* value they were never shown.
|
|
129
|
+
*/
|
|
130
|
+
export class WizardSummary extends BaseElement {
|
|
131
|
+
static tagName = DEFAULT_TAG_NAME;
|
|
132
|
+
static get observedAttributes() {
|
|
133
|
+
return ["edit-label", "empty-text", "fields", "heading", "steps", "values"];
|
|
134
|
+
}
|
|
135
|
+
hostEl;
|
|
136
|
+
fieldsRaw = null;
|
|
137
|
+
fieldsCache = [];
|
|
138
|
+
stepsRaw = null;
|
|
139
|
+
stepsCache = [];
|
|
140
|
+
valuesRaw = null;
|
|
141
|
+
valuesCache = {};
|
|
142
|
+
get heading() {
|
|
143
|
+
return this.getAttribute("heading") ?? "Review your answers";
|
|
144
|
+
}
|
|
145
|
+
set heading(value) {
|
|
146
|
+
this.setAttribute("heading", value);
|
|
147
|
+
}
|
|
148
|
+
/** Verb on the per-section control. The step label is appended for its accessible name. */
|
|
149
|
+
get editLabel() {
|
|
150
|
+
return this.getAttribute("edit-label") ?? "Edit";
|
|
151
|
+
}
|
|
152
|
+
set editLabel(value) {
|
|
153
|
+
this.setAttribute("edit-label", value);
|
|
154
|
+
}
|
|
155
|
+
/** Placeholder for a field with nothing collected. */
|
|
156
|
+
get emptyText() {
|
|
157
|
+
return this.getAttribute("empty-text") ?? "Not provided";
|
|
158
|
+
}
|
|
159
|
+
set emptyText(value) {
|
|
160
|
+
this.setAttribute("empty-text", value);
|
|
161
|
+
}
|
|
162
|
+
/**
|
|
163
|
+
* Fields to summarise. Note that `format` cannot survive the attribute
|
|
164
|
+
* round-trip — set the property directly when a field needs one.
|
|
165
|
+
*/
|
|
166
|
+
get fields() {
|
|
167
|
+
const raw = this.getAttribute("fields");
|
|
168
|
+
if (!raw) {
|
|
169
|
+
return [...this.fieldsCache];
|
|
170
|
+
}
|
|
171
|
+
if (raw !== this.fieldsRaw) {
|
|
172
|
+
this.fieldsRaw = raw;
|
|
173
|
+
try {
|
|
174
|
+
const parsed = JSON.parse(raw);
|
|
175
|
+
this.fieldsCache =
|
|
176
|
+
Array.isArray(parsed) && parsed.every(isWizardSummaryFieldRecord)
|
|
177
|
+
? parsed
|
|
178
|
+
: [];
|
|
179
|
+
}
|
|
180
|
+
catch {
|
|
181
|
+
this.fieldsCache = [];
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
return [...this.fieldsCache];
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Setting any of `fields`, `steps`, or `values` as a **property** stores the
|
|
188
|
+
* value as-is and re-renders. It is not mirrored to the attribute, because
|
|
189
|
+
* these carry things a JSON round-trip destroys — a field's `format`
|
|
190
|
+
* function, a `Date` in the collected values. The attributes remain the
|
|
191
|
+
* declarative path for plain records; whichever is set last wins.
|
|
192
|
+
*/
|
|
193
|
+
set fields(value) {
|
|
194
|
+
this.fieldsCache = [...value];
|
|
195
|
+
this.fieldsRaw = null;
|
|
196
|
+
this.removeAttribute("fields");
|
|
197
|
+
this.update();
|
|
198
|
+
}
|
|
199
|
+
get steps() {
|
|
200
|
+
const raw = this.getAttribute("steps");
|
|
201
|
+
if (!raw) {
|
|
202
|
+
return [...this.stepsCache];
|
|
203
|
+
}
|
|
204
|
+
if (raw !== this.stepsRaw) {
|
|
205
|
+
this.stepsRaw = raw;
|
|
206
|
+
try {
|
|
207
|
+
const parsed = JSON.parse(raw);
|
|
208
|
+
this.stepsCache = Array.isArray(parsed)
|
|
209
|
+
? parsed.filter(step => typeof step === "object" &&
|
|
210
|
+
step !== null &&
|
|
211
|
+
typeof step.id === "string" &&
|
|
212
|
+
typeof step.label === "string")
|
|
213
|
+
: [];
|
|
214
|
+
}
|
|
215
|
+
catch {
|
|
216
|
+
this.stepsCache = [];
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
return [...this.stepsCache];
|
|
220
|
+
}
|
|
221
|
+
set steps(value) {
|
|
222
|
+
this.stepsCache = [...value];
|
|
223
|
+
this.stepsRaw = null;
|
|
224
|
+
this.removeAttribute("steps");
|
|
225
|
+
this.update();
|
|
226
|
+
}
|
|
227
|
+
get values() {
|
|
228
|
+
const raw = this.getAttribute("values");
|
|
229
|
+
if (!raw) {
|
|
230
|
+
return { ...this.valuesCache };
|
|
231
|
+
}
|
|
232
|
+
if (raw !== this.valuesRaw) {
|
|
233
|
+
this.valuesRaw = raw;
|
|
234
|
+
try {
|
|
235
|
+
const parsed = JSON.parse(raw);
|
|
236
|
+
this.valuesCache =
|
|
237
|
+
typeof parsed === "object" && parsed !== null && !Array.isArray(parsed)
|
|
238
|
+
? parsed
|
|
239
|
+
: {};
|
|
240
|
+
}
|
|
241
|
+
catch {
|
|
242
|
+
this.valuesCache = {};
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
return { ...this.valuesCache };
|
|
246
|
+
}
|
|
247
|
+
set values(value) {
|
|
248
|
+
this.valuesCache = { ...value };
|
|
249
|
+
this.valuesRaw = null;
|
|
250
|
+
this.removeAttribute("values");
|
|
251
|
+
this.update();
|
|
252
|
+
}
|
|
253
|
+
/** The sections as rendered — same order, so a host can mirror the card. */
|
|
254
|
+
get sections() {
|
|
255
|
+
return summarizeWizardValues(this.fields, this.values, this.steps);
|
|
256
|
+
}
|
|
257
|
+
renderTemplate() {
|
|
258
|
+
if (!this.shadowRoot) {
|
|
259
|
+
return;
|
|
260
|
+
}
|
|
261
|
+
this.shadowRoot.innerHTML = `<style>${elementStyles}</style><div part="host"></div>`;
|
|
262
|
+
this.hostEl = this.shadowRoot.querySelector('[part="host"]');
|
|
263
|
+
}
|
|
264
|
+
setupListeners() {
|
|
265
|
+
this.hostEl.addEventListener("click", event => {
|
|
266
|
+
const trigger = event.target.closest('[part="edit"]');
|
|
267
|
+
if (!trigger) {
|
|
268
|
+
return;
|
|
269
|
+
}
|
|
270
|
+
const stepId = trigger.getAttribute("data-step-id");
|
|
271
|
+
if (stepId === null) {
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
274
|
+
this.dispatchEvent(new CustomEvent("edit-requested", {
|
|
275
|
+
detail: { stepId },
|
|
276
|
+
bubbles: true,
|
|
277
|
+
composed: true,
|
|
278
|
+
}));
|
|
279
|
+
});
|
|
280
|
+
}
|
|
281
|
+
update() {
|
|
282
|
+
if (!this.hostEl) {
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
const sections = this.sections;
|
|
286
|
+
const body = sections.length
|
|
287
|
+
? `<ul part="sections" role="list">${sections
|
|
288
|
+
.map(section => {
|
|
289
|
+
const rows = section.rows
|
|
290
|
+
.map(row => {
|
|
291
|
+
const shown = row.empty ? this.emptyText : row.value;
|
|
292
|
+
return `
|
|
293
|
+
<dt part="row-label">${escapeHtml(row.label)}</dt>
|
|
294
|
+
<dd part="row-value" data-empty="${String(row.empty)}" data-key="${escapeHtml(row.key)}">${escapeHtml(shown)}</dd>
|
|
295
|
+
`;
|
|
296
|
+
})
|
|
297
|
+
.join("");
|
|
298
|
+
// The accessible name carries the step, because a screen-reader
|
|
299
|
+
// user hearing five buttons all called "Edit" learns nothing about
|
|
300
|
+
// which one goes where.
|
|
301
|
+
const edit = section.unknownStep
|
|
302
|
+
? ""
|
|
303
|
+
: `<button type="button" part="edit" data-step-id="${escapeHtml(section.stepId)}" aria-label="${escapeHtml(`${this.editLabel} ${section.label}`)}">${escapeHtml(this.editLabel)}</button>`;
|
|
304
|
+
return `
|
|
305
|
+
<li part="section" data-step-id="${escapeHtml(section.stepId)}" data-unknown-step="${String(section.unknownStep)}">
|
|
306
|
+
<div part="section-header">
|
|
307
|
+
<span part="section-label">${escapeHtml(section.label)}</span>
|
|
308
|
+
${edit}
|
|
309
|
+
</div>
|
|
310
|
+
<dl part="rows">${rows}</dl>
|
|
311
|
+
</li>
|
|
312
|
+
`;
|
|
313
|
+
})
|
|
314
|
+
.join("")}</ul>`
|
|
315
|
+
: `<div part="empty">Nothing to review yet.</div>`;
|
|
316
|
+
this.hostEl.innerHTML = `
|
|
317
|
+
<section part="card" aria-label="${escapeHtml(this.heading)}">
|
|
318
|
+
<h3 part="heading">${escapeHtml(this.heading)}</h3>
|
|
319
|
+
${body}
|
|
320
|
+
</section>
|
|
321
|
+
`;
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
WizardSummary.register();
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One definition of "may this author-supplied href become a real link?",
|
|
3
|
+
* shared by every surface that renders evidence or citation chips
|
|
4
|
+
* (`box-timeline`, `box-agent-chat`, `box-audit-log`). Internal: it is not
|
|
5
|
+
* re-exported from any pattern barrel.
|
|
6
|
+
*
|
|
7
|
+
* Three copies of this check previously drifted apart, which is exactly how
|
|
8
|
+
* the protocol-relative hole below survived in all of them.
|
|
9
|
+
*
|
|
10
|
+
* Allowed: absolute `http(s)`, a same-document fragment, and a rooted path.
|
|
11
|
+
* The path branch requires a *single* leading slash — `//evil.example/x` is
|
|
12
|
+
* protocol-relative and a browser resolves it to an external origin, and
|
|
13
|
+
* `/\evil.example` is normalized to that same form by some parsers. Anything
|
|
14
|
+
* else (including `javascript:`, `data:`, and leading-whitespace tricks)
|
|
15
|
+
* fails the test, and the caller renders a button instead of an anchor.
|
|
16
|
+
*/
|
|
17
|
+
export declare const isSafeHref: (value: string) => boolean;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One definition of "may this author-supplied href become a real link?",
|
|
3
|
+
* shared by every surface that renders evidence or citation chips
|
|
4
|
+
* (`box-timeline`, `box-agent-chat`, `box-audit-log`). Internal: it is not
|
|
5
|
+
* re-exported from any pattern barrel.
|
|
6
|
+
*
|
|
7
|
+
* Three copies of this check previously drifted apart, which is exactly how
|
|
8
|
+
* the protocol-relative hole below survived in all of them.
|
|
9
|
+
*
|
|
10
|
+
* Allowed: absolute `http(s)`, a same-document fragment, and a rooted path.
|
|
11
|
+
* The path branch requires a *single* leading slash — `//evil.example/x` is
|
|
12
|
+
* protocol-relative and a browser resolves it to an external origin, and
|
|
13
|
+
* `/\evil.example` is normalized to that same form by some parsers. Anything
|
|
14
|
+
* else (including `javascript:`, `data:`, and leading-whitespace tricks)
|
|
15
|
+
* fails the test, and the caller renders a button instead of an anchor.
|
|
16
|
+
*/
|
|
17
|
+
export const isSafeHref = (value) => /^https?:\/\//i.test(value) || /^\/(?![/\\])/.test(value) || value.startsWith("#");
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { LineageNode } from "./types.js";
|
|
2
|
+
import { BaseElement } from "../../core/index.js";
|
|
3
|
+
/**
|
|
4
|
+
* Provenance DAG for clause lineage (opportunity 2): source clause →
|
|
5
|
+
* template versions → executed contracts, laid out by the versions
|
|
6
|
+
* pattern's `computeVersionGraphLayout` and rendered with tone-coloured
|
|
7
|
+
* deviation edges. Every node is an HTML button (`node-selected`), and every
|
|
8
|
+
* derivation edge is ALSO a per-row chip button (`edge-selected` with the
|
|
9
|
+
* parent/child pair — the diff viewer's input), so edge activation is
|
|
10
|
+
* keyboard-accessible without SVG hit targets: the row rail is the
|
|
11
|
+
* accessible contract, the SVG is presentation.
|
|
12
|
+
*/
|
|
13
|
+
export declare class LineageGraph extends BaseElement {
|
|
14
|
+
static readonly tagName: string;
|
|
15
|
+
static get observedAttributes(): string[];
|
|
16
|
+
private nodesValue;
|
|
17
|
+
private rovingId;
|
|
18
|
+
private hostEl;
|
|
19
|
+
get heading(): string;
|
|
20
|
+
set heading(value: string);
|
|
21
|
+
get nodes(): LineageNode[];
|
|
22
|
+
set nodes(value: LineageNode[]);
|
|
23
|
+
attributeChangedCallback(name: string, oldValue: string | null, newValue: string | null): void;
|
|
24
|
+
private parseNodesAttribute;
|
|
25
|
+
private getNode;
|
|
26
|
+
private nodeButtons;
|
|
27
|
+
protected renderTemplate(): void;
|
|
28
|
+
protected setupListeners(): void;
|
|
29
|
+
protected update(): void;
|
|
30
|
+
}
|