@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.
Files changed (219) hide show
  1. package/README.md +3 -3
  2. package/dist/components/collections/table.d.ts +57 -3
  3. package/dist/components/collections/table.js +339 -20
  4. package/dist/components/feedback/due-badge.d.ts +38 -0
  5. package/dist/components/feedback/due-badge.js +168 -0
  6. package/dist/components/feedback/due-types.d.ts +32 -0
  7. package/dist/components/feedback/due-types.js +91 -0
  8. package/dist/components/feedback/progress-steps.d.ts +51 -5
  9. package/dist/components/feedback/progress-steps.js +200 -22
  10. package/dist/components/feedback/stage-path.d.ts +44 -0
  11. package/dist/components/feedback/stage-path.js +235 -0
  12. package/dist/components/forms/select.d.ts +21 -0
  13. package/dist/components/forms/select.js +100 -3
  14. package/dist/components/forms/text-field.d.ts +21 -0
  15. package/dist/components/forms/text-field.js +100 -1
  16. package/dist/components/layout/nav-sidebar.d.ts +14 -0
  17. package/dist/components/layout/nav-sidebar.js +49 -0
  18. package/dist/components/layout/split-view.d.ts +14 -0
  19. package/dist/components/layout/split-view.js +80 -1
  20. package/dist/components/overlays/command-palette.d.ts +62 -0
  21. package/dist/components/overlays/command-palette.js +537 -0
  22. package/dist/components/overlays/command-types.d.ts +90 -0
  23. package/dist/components/overlays/command-types.js +259 -0
  24. package/dist/components/overlays/drawer.d.ts +18 -0
  25. package/dist/components/overlays/drawer.js +135 -9
  26. package/dist/components/overlays/shortcuts-overlay.d.ts +48 -0
  27. package/dist/components/overlays/shortcuts-overlay.js +385 -0
  28. package/dist/components/overlays/tooltip.js +1 -1
  29. package/dist/element-maps.d.ts +292 -0
  30. package/dist/element-maps.js +1 -0
  31. package/dist/entries/activity-density.d.ts +1 -0
  32. package/dist/entries/activity-density.js +1 -0
  33. package/dist/entries/agent-chat.d.ts +1 -0
  34. package/dist/entries/agent-chat.js +1 -0
  35. package/dist/entries/audit-log.d.ts +1 -0
  36. package/dist/entries/audit-log.js +1 -0
  37. package/dist/entries/command-palette.d.ts +1 -0
  38. package/dist/entries/command-palette.js +1 -0
  39. package/dist/entries/compare-view.d.ts +1 -0
  40. package/dist/entries/compare-view.js +1 -0
  41. package/dist/entries/diff-viewer.d.ts +1 -0
  42. package/dist/entries/diff-viewer.js +1 -0
  43. package/dist/entries/due-badge.d.ts +1 -0
  44. package/dist/entries/due-badge.js +1 -0
  45. package/dist/entries/form-wizard.d.ts +1 -0
  46. package/dist/entries/form-wizard.js +1 -0
  47. package/dist/entries/lineage-graph.d.ts +1 -0
  48. package/dist/entries/lineage-graph.js +1 -0
  49. package/dist/entries/notification-bell.d.ts +1 -0
  50. package/dist/entries/notification-bell.js +1 -0
  51. package/dist/entries/notification-inbox.d.ts +1 -0
  52. package/dist/entries/notification-inbox.js +1 -0
  53. package/dist/entries/provenance-strip.d.ts +1 -0
  54. package/dist/entries/provenance-strip.js +1 -0
  55. package/dist/entries/run-trace.d.ts +1 -0
  56. package/dist/entries/run-trace.js +1 -0
  57. package/dist/entries/shortcuts-overlay.d.ts +1 -0
  58. package/dist/entries/shortcuts-overlay.js +1 -0
  59. package/dist/entries/signature-ceremony.d.ts +1 -0
  60. package/dist/entries/signature-ceremony.js +1 -0
  61. package/dist/entries/stage-path.d.ts +1 -0
  62. package/dist/entries/stage-path.js +1 -0
  63. package/dist/entries/timeline.d.ts +1 -0
  64. package/dist/entries/timeline.js +1 -0
  65. package/dist/entries/version-graph.d.ts +1 -0
  66. package/dist/entries/version-graph.js +1 -0
  67. package/dist/entries/version-list.d.ts +1 -0
  68. package/dist/entries/version-list.js +1 -0
  69. package/dist/entries/wizard-summary.d.ts +1 -0
  70. package/dist/entries/wizard-summary.js +1 -0
  71. package/dist/entries/work-queue.d.ts +1 -0
  72. package/dist/entries/work-queue.js +1 -0
  73. package/dist/entries/workload-board.d.ts +1 -0
  74. package/dist/entries/workload-board.js +1 -0
  75. package/dist/index.d.ts +21 -0
  76. package/dist/index.js +21 -0
  77. package/dist/patterns/agent-chat/agent-chat.d.ts +75 -0
  78. package/dist/patterns/agent-chat/agent-chat.js +820 -0
  79. package/dist/patterns/agent-chat/controller.d.ts +27 -0
  80. package/dist/patterns/agent-chat/controller.js +182 -0
  81. package/dist/patterns/agent-chat/index.d.ts +3 -0
  82. package/dist/patterns/agent-chat/index.js +6 -0
  83. package/dist/patterns/agent-chat/types.d.ts +109 -0
  84. package/dist/patterns/agent-chat/types.js +1 -0
  85. package/dist/patterns/audit/activity-density.d.ts +68 -0
  86. package/dist/patterns/audit/activity-density.js +428 -0
  87. package/dist/patterns/audit/audit-log.d.ts +81 -0
  88. package/dist/patterns/audit/audit-log.js +794 -0
  89. package/dist/patterns/audit/index.d.ts +3 -0
  90. package/dist/patterns/audit/index.js +7 -0
  91. package/dist/patterns/audit/shared.d.ts +10 -0
  92. package/dist/patterns/audit/shared.js +50 -0
  93. package/dist/patterns/audit/types.d.ts +143 -0
  94. package/dist/patterns/audit/types.js +327 -0
  95. package/dist/patterns/content-explorer/actions/controller.js +12 -2
  96. package/dist/patterns/content-explorer/box-transport.js +117 -25
  97. package/dist/patterns/content-explorer/content-explorer.d.ts +13 -1
  98. package/dist/patterns/content-explorer/content-explorer.js +36 -3
  99. package/dist/patterns/content-explorer/contracts.d.ts +24 -1
  100. package/dist/patterns/content-explorer/contracts.js +68 -11
  101. package/dist/patterns/content-explorer/controller.d.ts +16 -1
  102. package/dist/patterns/content-explorer/controller.js +130 -4
  103. package/dist/patterns/content-explorer/navigation/controller.js +11 -9
  104. package/dist/patterns/content-explorer/types.d.ts +58 -1
  105. package/dist/patterns/content-picker/content-picker.d.ts +71 -0
  106. package/dist/patterns/content-picker/content-picker.js +747 -0
  107. package/dist/patterns/content-picker/controller.d.ts +38 -0
  108. package/dist/patterns/content-picker/controller.js +141 -0
  109. package/dist/patterns/content-picker/index.d.ts +3 -0
  110. package/dist/patterns/content-picker/index.js +6 -0
  111. package/dist/patterns/content-picker/types.d.ts +52 -0
  112. package/dist/patterns/content-picker/types.js +26 -0
  113. package/dist/patterns/content-sidebar/content-sidebar.d.ts +43 -0
  114. package/dist/patterns/content-sidebar/content-sidebar.js +293 -0
  115. package/dist/patterns/content-sidebar/index.d.ts +2 -0
  116. package/dist/patterns/content-sidebar/index.js +4 -0
  117. package/dist/patterns/content-sidebar/types.d.ts +18 -0
  118. package/dist/patterns/content-sidebar/types.js +20 -0
  119. package/dist/patterns/content-uploader/box-transport.d.ts +14 -0
  120. package/dist/patterns/content-uploader/box-transport.js +54 -0
  121. package/dist/patterns/content-uploader/content-uploader.d.ts +62 -0
  122. package/dist/patterns/content-uploader/content-uploader.js +559 -0
  123. package/dist/patterns/content-uploader/controller.d.ts +39 -0
  124. package/dist/patterns/content-uploader/controller.js +227 -0
  125. package/dist/patterns/content-uploader/index.d.ts +4 -0
  126. package/dist/patterns/content-uploader/index.js +8 -0
  127. package/dist/patterns/content-uploader/types.d.ts +120 -0
  128. package/dist/patterns/content-uploader/types.js +38 -0
  129. package/dist/patterns/diff/compare-view.d.ts +47 -0
  130. package/dist/patterns/diff/compare-view.js +276 -0
  131. package/dist/patterns/diff/diff-viewer.d.ts +42 -0
  132. package/dist/patterns/diff/diff-viewer.js +434 -0
  133. package/dist/patterns/diff/engine.d.ts +22 -0
  134. package/dist/patterns/diff/engine.js +276 -0
  135. package/dist/patterns/diff/index.d.ts +4 -0
  136. package/dist/patterns/diff/index.js +8 -0
  137. package/dist/patterns/diff/types.d.ts +69 -0
  138. package/dist/patterns/diff/types.js +24 -0
  139. package/dist/patterns/form-wizard/controller.d.ts +39 -0
  140. package/dist/patterns/form-wizard/controller.js +157 -0
  141. package/dist/patterns/form-wizard/form-wizard.d.ts +63 -0
  142. package/dist/patterns/form-wizard/form-wizard.js +468 -0
  143. package/dist/patterns/form-wizard/index.d.ts +4 -0
  144. package/dist/patterns/form-wizard/index.js +8 -0
  145. package/dist/patterns/form-wizard/types.d.ts +109 -0
  146. package/dist/patterns/form-wizard/types.js +83 -0
  147. package/dist/patterns/form-wizard/wizard-summary.d.ts +62 -0
  148. package/dist/patterns/form-wizard/wizard-summary.js +324 -0
  149. package/dist/patterns/internal/safe-href.d.ts +17 -0
  150. package/dist/patterns/internal/safe-href.js +17 -0
  151. package/dist/patterns/lineage/index.d.ts +3 -0
  152. package/dist/patterns/lineage/index.js +6 -0
  153. package/dist/patterns/lineage/lineage-graph.d.ts +30 -0
  154. package/dist/patterns/lineage/lineage-graph.js +434 -0
  155. package/dist/patterns/lineage/provenance-strip.d.ts +22 -0
  156. package/dist/patterns/lineage/provenance-strip.js +194 -0
  157. package/dist/patterns/lineage/types.d.ts +53 -0
  158. package/dist/patterns/lineage/types.js +49 -0
  159. package/dist/patterns/notifications/index.d.ts +3 -0
  160. package/dist/patterns/notifications/index.js +6 -0
  161. package/dist/patterns/notifications/notification-bell.d.ts +38 -0
  162. package/dist/patterns/notifications/notification-bell.js +198 -0
  163. package/dist/patterns/notifications/notification-inbox.d.ts +46 -0
  164. package/dist/patterns/notifications/notification-inbox.js +537 -0
  165. package/dist/patterns/notifications/types.d.ts +61 -0
  166. package/dist/patterns/notifications/types.js +108 -0
  167. package/dist/patterns/preview/annotation-inspector.d.ts +25 -6
  168. package/dist/patterns/preview/annotation-inspector.js +239 -94
  169. package/dist/patterns/preview/annotation-thread.d.ts +25 -5
  170. package/dist/patterns/preview/annotation-thread.js +233 -82
  171. package/dist/patterns/preview/annotation-toolbar.d.ts +20 -6
  172. package/dist/patterns/preview/annotation-toolbar.js +162 -96
  173. package/dist/patterns/preview/content-preview-adapter.d.ts +10 -1
  174. package/dist/patterns/preview/content-preview-adapter.js +26 -1
  175. package/dist/patterns/preview/preview-element.d.ts +15 -2
  176. package/dist/patterns/preview/preview-element.js +223 -52
  177. package/dist/patterns/preview/provider-adapter.d.ts +47 -0
  178. package/dist/patterns/preview/provider-adapter.js +17 -0
  179. package/dist/patterns/run/index.d.ts +2 -0
  180. package/dist/patterns/run/index.js +4 -0
  181. package/dist/patterns/run/run-trace.d.ts +40 -0
  182. package/dist/patterns/run/run-trace.js +441 -0
  183. package/dist/patterns/run/types.d.ts +66 -0
  184. package/dist/patterns/run/types.js +152 -0
  185. package/dist/patterns/signature/index.d.ts +2 -0
  186. package/dist/patterns/signature/index.js +4 -0
  187. package/dist/patterns/signature/signature-ceremony.d.ts +33 -0
  188. package/dist/patterns/signature/signature-ceremony.js +317 -0
  189. package/dist/patterns/signature/types.d.ts +68 -0
  190. package/dist/patterns/signature/types.js +89 -0
  191. package/dist/patterns/timeline/index.d.ts +2 -0
  192. package/dist/patterns/timeline/index.js +4 -0
  193. package/dist/patterns/timeline/timeline.d.ts +27 -0
  194. package/dist/patterns/timeline/timeline.js +430 -0
  195. package/dist/patterns/timeline/types.d.ts +36 -0
  196. package/dist/patterns/timeline/types.js +27 -0
  197. package/dist/patterns/versions/graph-layout.d.ts +43 -0
  198. package/dist/patterns/versions/graph-layout.js +159 -0
  199. package/dist/patterns/versions/index.d.ts +4 -0
  200. package/dist/patterns/versions/index.js +8 -0
  201. package/dist/patterns/versions/shared.d.ts +4 -0
  202. package/dist/patterns/versions/shared.js +13 -0
  203. package/dist/patterns/versions/types.d.ts +37 -0
  204. package/dist/patterns/versions/types.js +39 -0
  205. package/dist/patterns/versions/version-graph.d.ts +36 -0
  206. package/dist/patterns/versions/version-graph.js +438 -0
  207. package/dist/patterns/versions/version-list.d.ts +39 -0
  208. package/dist/patterns/versions/version-list.js +407 -0
  209. package/dist/patterns/work-queue/controller.d.ts +26 -0
  210. package/dist/patterns/work-queue/controller.js +150 -0
  211. package/dist/patterns/work-queue/index.d.ts +4 -0
  212. package/dist/patterns/work-queue/index.js +7 -0
  213. package/dist/patterns/work-queue/types.d.ts +128 -0
  214. package/dist/patterns/work-queue/types.js +45 -0
  215. package/dist/patterns/work-queue/work-queue.d.ts +48 -0
  216. package/dist/patterns/work-queue/work-queue.js +534 -0
  217. package/dist/patterns/work-queue/workload-board.d.ts +53 -0
  218. package/dist/patterns/work-queue/workload-board.js +608 -0
  219. 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("&", "&amp;")
7
+ .replaceAll("<", "&lt;")
8
+ .replaceAll(">", "&gt;")
9
+ .replaceAll('"', "&quot;")
10
+ .replaceAll("'", "&#39;");
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,3 @@
1
+ export * from "./types.js";
2
+ export * from "./lineage-graph.js";
3
+ export * from "./provenance-strip.js";
@@ -0,0 +1,6 @@
1
+ // Lineage model + validation
2
+ export * from "./types.js";
3
+ // Provenance DAG with deviation-toned edges
4
+ export * from "./lineage-graph.js";
5
+ // Linear ancestry strip for record headers
6
+ export * from "./provenance-strip.js";
@@ -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
+ }