@unofficialbox/box-open-elements 0.18.0 → 0.20.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 (217) hide show
  1. package/dist/components/actions/button-group.js +6 -0
  2. package/dist/components/actions/button.js +6 -0
  3. package/dist/components/actions/icon-button.js +6 -0
  4. package/dist/components/actions/link-button.js +6 -0
  5. package/dist/components/actions/menu-item.js +6 -0
  6. package/dist/components/actions/menu.js +6 -0
  7. package/dist/components/actions/segmented-control.js +6 -0
  8. package/dist/components/actions/toolbar.js +6 -0
  9. package/dist/components/collections/card.js +6 -0
  10. package/dist/components/collections/carousel.js +6 -0
  11. package/dist/components/collections/check-list.d.ts +10 -0
  12. package/dist/components/collections/check-list.js +8 -0
  13. package/dist/components/collections/datalist-item.js +6 -0
  14. package/dist/components/collections/document-list.d.ts +10 -0
  15. package/dist/components/collections/document-list.js +8 -0
  16. package/dist/components/collections/draggable-list.js +6 -0
  17. package/dist/components/collections/fact-list.d.ts +10 -0
  18. package/dist/components/collections/fact-list.js +8 -0
  19. package/dist/components/collections/grid-view.js +6 -0
  20. package/dist/components/collections/pagination.js +6 -0
  21. package/dist/components/collections/result-blocks.d.ts +54 -0
  22. package/dist/components/collections/result-blocks.js +71 -0
  23. package/dist/components/collections/table.js +6 -0
  24. package/dist/components/collections/thumbnail-card.js +6 -0
  25. package/dist/components/collections/tree-grid.js +6 -0
  26. package/dist/components/collections/tree.js +6 -0
  27. package/dist/components/feedback/alert.js +1 -1
  28. package/dist/components/feedback/badge.js +1 -1
  29. package/dist/components/feedback/badgeable.js +6 -0
  30. package/dist/components/feedback/chip.js +6 -0
  31. package/dist/components/feedback/due-badge.js +6 -0
  32. package/dist/components/feedback/empty-state.js +6 -0
  33. package/dist/components/feedback/error-mask.js +6 -0
  34. package/dist/components/feedback/help-text.js +6 -0
  35. package/dist/components/feedback/indicator.js +1 -1
  36. package/dist/components/feedback/nudge.js +6 -0
  37. package/dist/components/feedback/path.js +6 -0
  38. package/dist/components/feedback/progress-bar.d.ts +9 -0
  39. package/dist/components/feedback/progress-bar.js +35 -3
  40. package/dist/components/feedback/progress-ring.js +6 -0
  41. package/dist/components/feedback/progress-steps.js +6 -0
  42. package/dist/components/feedback/skeleton.js +6 -0
  43. package/dist/components/feedback/spinner.js +6 -0
  44. package/dist/components/feedback/status-icon.d.ts +10 -0
  45. package/dist/components/feedback/status-icon.js +26 -0
  46. package/dist/components/feedback/toast.js +1 -1
  47. package/dist/components/files/drop-zone.js +1 -1
  48. package/dist/components/forms/calendar.js +6 -0
  49. package/dist/components/forms/category-selector.js +6 -0
  50. package/dist/components/forms/checkbox-group.js +6 -0
  51. package/dist/components/forms/checkbox.js +6 -0
  52. package/dist/components/forms/color-picker.js +6 -0
  53. package/dist/components/forms/combobox.js +6 -0
  54. package/dist/components/forms/date-field.js +6 -0
  55. package/dist/components/forms/dropdown.js +6 -0
  56. package/dist/components/forms/dual-listbox.js +6 -0
  57. package/dist/components/forms/fieldset.js +6 -0
  58. package/dist/components/forms/multi-select.js +6 -0
  59. package/dist/components/forms/number-input.js +6 -0
  60. package/dist/components/forms/pill-cloud.js +6 -0
  61. package/dist/components/forms/pill-selector-dropdown.js +6 -0
  62. package/dist/components/forms/radio-group.js +6 -0
  63. package/dist/components/forms/range-slider.js +6 -0
  64. package/dist/components/forms/rating.js +6 -0
  65. package/dist/components/forms/rich-text-input.js +6 -0
  66. package/dist/components/forms/search-field.js +6 -0
  67. package/dist/components/forms/select.js +6 -0
  68. package/dist/components/forms/slider.js +6 -0
  69. package/dist/components/forms/spin-button.js +6 -0
  70. package/dist/components/forms/switch.js +6 -0
  71. package/dist/components/forms/tag-input.js +6 -0
  72. package/dist/components/forms/text-area.js +6 -0
  73. package/dist/components/forms/text-field.js +6 -0
  74. package/dist/components/forms/tile-group.js +1 -1
  75. package/dist/components/forms/time-field.js +6 -0
  76. package/dist/components/identity/avatar.js +6 -0
  77. package/dist/components/identity/contact-datalist-item.js +6 -0
  78. package/dist/components/identity/persona.js +6 -0
  79. package/dist/components/layout/app-shell.js +6 -0
  80. package/dist/components/layout/divider.js +6 -0
  81. package/dist/components/layout/grid.js +1 -1
  82. package/dist/components/layout/nav-sidebar.js +6 -0
  83. package/dist/components/layout/section.js +6 -0
  84. package/dist/components/layout/sidebar-toggle-button.js +6 -0
  85. package/dist/components/layout/split-view.js +6 -0
  86. package/dist/components/navigation/accordion.js +6 -0
  87. package/dist/components/navigation/breadcrumb.js +6 -0
  88. package/dist/components/navigation/tabs.js +6 -0
  89. package/dist/components/output/code-block.js +1 -1
  90. package/dist/components/output/formatted-value.js +1 -1
  91. package/dist/components/overlays/command-palette.js +6 -0
  92. package/dist/components/overlays/context-menu.js +6 -0
  93. package/dist/components/overlays/guide-tooltip.js +6 -0
  94. package/dist/components/overlays/popover.js +6 -0
  95. package/dist/components/overlays/shortcuts-overlay.js +6 -0
  96. package/dist/components/overlays/tooltip.js +6 -0
  97. package/dist/components/visuals/illustration.js +6 -0
  98. package/dist/element-maps.d.ts +39 -19
  99. package/dist/entries/agent-workspace.d.ts +1 -0
  100. package/dist/entries/agent-workspace.js +1 -0
  101. package/dist/entries/call-console.d.ts +1 -0
  102. package/dist/entries/call-console.js +1 -0
  103. package/dist/entries/check-list.d.ts +1 -0
  104. package/dist/entries/check-list.js +1 -0
  105. package/dist/entries/document-list.d.ts +1 -0
  106. package/dist/entries/document-list.js +1 -0
  107. package/dist/entries/fact-list.d.ts +1 -0
  108. package/dist/entries/fact-list.js +1 -0
  109. package/dist/entries/result-blocks.d.ts +1 -0
  110. package/dist/entries/result-blocks.js +1 -0
  111. package/dist/entries/run-summary.d.ts +1 -0
  112. package/dist/entries/run-summary.js +1 -0
  113. package/dist/entries/status-icon.d.ts +1 -0
  114. package/dist/entries/status-icon.js +1 -0
  115. package/dist/foundations/motion/behaviors.d.ts +8 -0
  116. package/dist/foundations/motion/behaviors.js +24 -0
  117. package/dist/foundations/motion/index.d.ts +2 -0
  118. package/dist/foundations/motion/index.js +2 -0
  119. package/dist/foundations/motion/scroll-pin.d.ts +19 -0
  120. package/dist/foundations/motion/scroll-pin.js +60 -0
  121. package/dist/foundations/motion/tokens.d.ts +2 -0
  122. package/dist/foundations/motion/tokens.js +2 -0
  123. package/dist/foundations/profiles/registry.d.ts +3 -0
  124. package/dist/foundations/profiles/registry.js +3 -0
  125. package/dist/foundations/profiles/types.d.ts +3 -0
  126. package/dist/foundations/status/index.d.ts +6 -0
  127. package/dist/foundations/status/index.js +33 -0
  128. package/dist/index.d.ts +10 -0
  129. package/dist/index.js +10 -0
  130. package/dist/patterns/agent-chat/agent-chat.d.ts +9 -0
  131. package/dist/patterns/agent-chat/agent-chat.js +141 -21
  132. package/dist/patterns/agent-chat/controller.d.ts +3 -1
  133. package/dist/patterns/agent-chat/controller.js +92 -16
  134. package/dist/patterns/agent-chat/index.d.ts +1 -0
  135. package/dist/patterns/agent-chat/index.js +1 -0
  136. package/dist/patterns/agent-chat/ndjson.d.ts +5 -0
  137. package/dist/patterns/agent-chat/ndjson.js +41 -0
  138. package/dist/patterns/agent-chat/types.d.ts +44 -1
  139. package/dist/patterns/agent-workspace/agent-workspace.d.ts +28 -0
  140. package/dist/patterns/agent-workspace/agent-workspace.js +215 -0
  141. package/dist/patterns/agent-workspace/controller.d.ts +38 -0
  142. package/dist/patterns/agent-workspace/controller.js +65 -0
  143. package/dist/patterns/agent-workspace/index.d.ts +2 -0
  144. package/dist/patterns/agent-workspace/index.js +2 -0
  145. package/dist/patterns/audit/activity-density.js +6 -0
  146. package/dist/patterns/audit/audit-log.js +6 -0
  147. package/dist/patterns/call-console/call-console.d.ts +17 -0
  148. package/dist/patterns/call-console/call-console.js +107 -0
  149. package/dist/patterns/call-console/controller.d.ts +23 -0
  150. package/dist/patterns/call-console/controller.js +50 -0
  151. package/dist/patterns/call-console/http-transport.d.ts +3 -0
  152. package/dist/patterns/call-console/http-transport.js +26 -0
  153. package/dist/patterns/call-console/index.d.ts +4 -0
  154. package/dist/patterns/call-console/index.js +4 -0
  155. package/dist/patterns/call-console/types.d.ts +32 -0
  156. package/dist/patterns/call-console/types.js +8 -0
  157. package/dist/patterns/comments/comment-thread.js +6 -0
  158. package/dist/patterns/content-explorer/adapters/action-menu.js +6 -0
  159. package/dist/patterns/content-explorer/adapters/breadcrumbs.js +6 -0
  160. package/dist/patterns/content-explorer/adapters/list.js +6 -0
  161. package/dist/patterns/content-explorer/adapters/table.js +6 -0
  162. package/dist/patterns/content-explorer/adapters/toolbar.js +6 -0
  163. package/dist/patterns/content-explorer/content-explorer.js +6 -0
  164. package/dist/patterns/content-picker/content-picker.js +6 -0
  165. package/dist/patterns/content-sidebar/content-sidebar.js +6 -0
  166. package/dist/patterns/content-uploader/content-uploader.js +8 -1
  167. package/dist/patterns/diff/compare-view.js +6 -0
  168. package/dist/patterns/diff/diff-viewer.js +6 -0
  169. package/dist/patterns/file-request/file-request-builder.js +6 -0
  170. package/dist/patterns/form-wizard/form-wizard.js +6 -0
  171. package/dist/patterns/form-wizard/wizard-summary.js +6 -0
  172. package/dist/patterns/governance/governance-panel.js +6 -0
  173. package/dist/patterns/insights/bar-chart.js +6 -0
  174. package/dist/patterns/insights/chart-panel.js +6 -0
  175. package/dist/patterns/insights/donut-chart.js +6 -0
  176. package/dist/patterns/insights/line-chart.js +6 -0
  177. package/dist/patterns/insights/metric-card.js +6 -0
  178. package/dist/patterns/item/bulk-action-bar.js +6 -0
  179. package/dist/patterns/item/item-details-panel.js +6 -0
  180. package/dist/patterns/item/item-form.js +6 -0
  181. package/dist/patterns/item/preview-header.js +6 -0
  182. package/dist/patterns/lineage/lineage-graph.js +6 -0
  183. package/dist/patterns/lineage/provenance-strip.js +6 -0
  184. package/dist/patterns/metadata/metadata-filter-builder.js +6 -0
  185. package/dist/patterns/metadata/metadata-inspector.js +6 -0
  186. package/dist/patterns/notifications/notification-bell.js +6 -0
  187. package/dist/patterns/notifications/notification-inbox.js +6 -0
  188. package/dist/patterns/preview/annotation-inspector.js +6 -0
  189. package/dist/patterns/preview/annotation-toolbar.js +6 -0
  190. package/dist/patterns/preview/preview-element.js +6 -0
  191. package/dist/patterns/run/index.d.ts +2 -0
  192. package/dist/patterns/run/index.js +2 -0
  193. package/dist/patterns/run/progress.d.ts +24 -0
  194. package/dist/patterns/run/progress.js +32 -0
  195. package/dist/patterns/run/run-summary.d.ts +21 -0
  196. package/dist/patterns/run/run-summary.js +82 -0
  197. package/dist/patterns/run/run-trace.d.ts +1 -0
  198. package/dist/patterns/run/run-trace.js +20 -3
  199. package/dist/patterns/search/filter-bar.js +6 -0
  200. package/dist/patterns/search/saved-view-picker.js +6 -0
  201. package/dist/patterns/search/search-results-header.js +6 -0
  202. package/dist/patterns/share/access-stats.js +6 -0
  203. package/dist/patterns/share/collaborator-avatars.js +6 -0
  204. package/dist/patterns/share/invite-collaborators-modal.js +6 -0
  205. package/dist/patterns/share/permission-matrix.js +6 -0
  206. package/dist/patterns/share/presence.js +6 -0
  207. package/dist/patterns/share/share-panel.js +6 -0
  208. package/dist/patterns/share/unified-share-modal.js +6 -0
  209. package/dist/patterns/signature/signature-ceremony.js +6 -0
  210. package/dist/patterns/task/review-queue-item.js +6 -0
  211. package/dist/patterns/task/task-assignment-panel.js +6 -0
  212. package/dist/patterns/timeline/timeline.js +6 -0
  213. package/dist/patterns/versions/version-graph.js +6 -0
  214. package/dist/patterns/versions/version-list.js +6 -0
  215. package/dist/patterns/work-queue/work-queue.js +6 -0
  216. package/dist/patterns/work-queue/workload-board.js +6 -0
  217. package/package.json +13 -1
@@ -16,6 +16,12 @@ const elementStyles = `
16
16
  font: inherit;
17
17
  }
18
18
 
19
+ /* The host's own display would otherwise beat the UA rule for [hidden],
20
+ leaving the element on screen when a host hides it. */
21
+ :host([hidden]) {
22
+ display: none !important;
23
+ }
24
+
19
25
  [part="panel"] {
20
26
  display: grid;
21
27
  gap: ${boePanel.gap};
@@ -14,6 +14,12 @@ const elementStyles = `
14
14
  font: inherit;
15
15
  }
16
16
 
17
+ /* The host's own display would otherwise beat the UA rule for [hidden],
18
+ leaving the element on screen when a host hides it. */
19
+ :host([hidden]) {
20
+ display: none !important;
21
+ }
22
+
17
23
  [part="panel"] {
18
24
  display: grid;
19
25
  gap: ${boePanel.gap};
@@ -15,6 +15,12 @@ const elementStyles = `
15
15
  font: inherit;
16
16
  }
17
17
 
18
+ /* The host's own display would otherwise beat the UA rule for [hidden],
19
+ leaving the element on screen when a host hides it. */
20
+ :host([hidden]) {
21
+ display: none !important;
22
+ }
23
+
18
24
  [part="card"] {
19
25
  display: grid;
20
26
  gap: ${boePanel.gap};
@@ -24,6 +24,12 @@ const elementStyles = `
24
24
  --_obp-brand-soft: color-mix(in srgb, var(--_obp-brand) 12%, var(--boe-token-surface-surface, #ffffff) 88%);
25
25
  }
26
26
 
27
+ /* The host's own display would otherwise beat the UA rule for [hidden],
28
+ leaving the element on screen when a host hides it. */
29
+ :host([hidden]) {
30
+ display: none !important;
31
+ }
32
+
27
33
  [part="bar"] {
28
34
  display: grid;
29
35
  gap: ${boePanel.gap};
@@ -23,6 +23,12 @@ const elementStyles = `
23
23
  --_obp-brand-soft: color-mix(in srgb, var(--_obp-brand) 12%, var(--boe-token-surface-surface, #ffffff) 88%);
24
24
  }
25
25
 
26
+ /* The host's own display would otherwise beat the UA rule for [hidden],
27
+ leaving the element on screen when a host hides it. */
28
+ :host([hidden]) {
29
+ display: none !important;
30
+ }
31
+
26
32
  [part="panel"] {
27
33
  display: grid;
28
34
  gap: ${boePanel.gap};
@@ -16,6 +16,12 @@ const elementStyles = `
16
16
  font: inherit;
17
17
  }
18
18
 
19
+ /* The host's own display would otherwise beat the UA rule for [hidden],
20
+ leaving the element on screen when a host hides it. */
21
+ :host([hidden]) {
22
+ display: none !important;
23
+ }
24
+
19
25
  [part="form"] {
20
26
  display: grid;
21
27
  gap: ${boePanel.gap};
@@ -23,6 +23,12 @@ const elementStyles = `
23
23
  --_obp-brand-soft: color-mix(in srgb, var(--_obp-brand) 12%, var(--boe-token-surface-surface, #ffffff) 88%);
24
24
  }
25
25
 
26
+ /* The host's own display would otherwise beat the UA rule for [hidden],
27
+ leaving the element on screen when a host hides it. */
28
+ :host([hidden]) {
29
+ display: none !important;
30
+ }
31
+
26
32
  [part="header"] {
27
33
  display: grid;
28
34
  gap: ${boePanel.gap};
@@ -39,6 +39,12 @@ const elementStyles = `
39
39
  font: inherit;
40
40
  }
41
41
 
42
+ /* The host's own display would otherwise beat the UA rule for [hidden],
43
+ leaving the element on screen when a host hides it. */
44
+ :host([hidden]) {
45
+ display: none !important;
46
+ }
47
+
42
48
  section[part="panel"] {
43
49
  display: grid;
44
50
  gap: ${boePanel.gap};
@@ -21,6 +21,12 @@ const elementStyles = `
21
21
  font: inherit;
22
22
  }
23
23
 
24
+ /* The host's own display would otherwise beat the UA rule for [hidden],
25
+ leaving the element on screen when a host hides it. */
26
+ :host([hidden]) {
27
+ display: none !important;
28
+ }
29
+
24
30
  /* Read as a flow diagram rather than a breadcrumb. The anatomy is
25
31
  React Flow's, taken from its stylesheet: nodes are bordered boxes
26
32
  with a small radius (not pills), ports are 6px circles sitting on
@@ -20,6 +20,12 @@ const builderStyles = `
20
20
  font: inherit;
21
21
  }
22
22
 
23
+ /* The host's own display would otherwise beat the UA rule for [hidden],
24
+ leaving the element on screen when a host hides it. */
25
+ :host([hidden]) {
26
+ display: none !important;
27
+ }
28
+
23
29
  [part="builder"] {
24
30
  display: grid;
25
31
  gap: ${boePanel.gap};
@@ -15,6 +15,12 @@ const elementStyles = `
15
15
  font: inherit;
16
16
  }
17
17
 
18
+ /* The host's own display would otherwise beat the UA rule for [hidden],
19
+ leaving the element on screen when a host hides it. */
20
+ :host([hidden]) {
21
+ display: none !important;
22
+ }
23
+
18
24
  [part="inspector"] {
19
25
  display: grid;
20
26
  gap: ${boePanel.gap};
@@ -18,6 +18,12 @@ const elementStyles = `
18
18
  display: inline-block;
19
19
  }
20
20
 
21
+ /* The host's own display would otherwise beat the UA rule for [hidden],
22
+ leaving the element on screen when a host hides it. */
23
+ :host([hidden]) {
24
+ display: none !important;
25
+ }
26
+
21
27
  [part="trigger"] {
22
28
  position: relative;
23
29
  appearance: none;
@@ -21,6 +21,12 @@ const elementStyles = `
21
21
  font: inherit;
22
22
  }
23
23
 
24
+ /* The host's own display would otherwise beat the UA rule for [hidden],
25
+ leaving the element on screen when a host hides it. */
26
+ :host([hidden]) {
27
+ display: none !important;
28
+ }
29
+
24
30
  [part="panel"] {
25
31
  display: grid;
26
32
  grid-template-rows: auto auto 1fr;
@@ -22,6 +22,12 @@ const elementStyles = `
22
22
  font: inherit;
23
23
  }
24
24
 
25
+ /* The host's own display would otherwise beat the UA rule for [hidden],
26
+ leaving the element on screen when a host hides it. */
27
+ :host([hidden]) {
28
+ display: none !important;
29
+ }
30
+
25
31
  [part="panel"] {
26
32
  display: grid;
27
33
  gap: ${boePanel.gap};
@@ -23,6 +23,12 @@ const elementStyles = `
23
23
  font: inherit;
24
24
  }
25
25
 
26
+ /* The host's own display would otherwise beat the UA rule for [hidden],
27
+ leaving the element on screen when a host hides it. */
28
+ :host([hidden]) {
29
+ display: none !important;
30
+ }
31
+
26
32
  [part="toolbar"] {
27
33
  display: grid;
28
34
  gap: 0.5rem;
@@ -23,6 +23,12 @@ const elementStyles = `
23
23
  --_obp-error: var(--boe-token-surface-status-surface-error, #ed3757);
24
24
  }
25
25
 
26
+ /* The host's own display would otherwise beat the UA rule for [hidden],
27
+ leaving the element on screen when a host hides it. */
28
+ :host([hidden]) {
29
+ display: none !important;
30
+ }
31
+
26
32
  [part="shell"] {
27
33
  display: grid;
28
34
  gap: 0.6rem;
@@ -1,2 +1,4 @@
1
1
  export * from "./types.js";
2
2
  export * from "./run-trace.js";
3
+ export * from "./progress.js";
4
+ export * from "./run-summary.js";
@@ -2,3 +2,5 @@
2
2
  export * from "./types.js";
3
3
  // Machine execution trace surface
4
4
  export * from "./run-trace.js";
5
+ export * from "./progress.js";
6
+ export * from "./run-summary.js";
@@ -0,0 +1,24 @@
1
+ import { type StatusKind } from "../../foundations/status/index.js";
2
+ import { type RunStep } from "./types.js";
3
+ export interface AgentTodo {
4
+ id: string;
5
+ content: string;
6
+ status: "pending" | "in_progress" | "completed" | "skipped";
7
+ }
8
+ export interface RunTurn {
9
+ steps: RunStep[];
10
+ todos: AgentTodo[];
11
+ startedAt: number;
12
+ endedAt?: number;
13
+ incomplete?: boolean;
14
+ }
15
+ export declare function formatElapsed(ms: number): string;
16
+ export declare function splitStepTitle(title: string): {
17
+ source?: string;
18
+ action: string;
19
+ };
20
+ export declare function progress(turn: RunTurn, failed?: boolean, now?: number, threshold?: number): {
21
+ kind: StatusKind;
22
+ label: string;
23
+ elapsed?: string;
24
+ };
@@ -0,0 +1,32 @@
1
+ import { toStatusKind } from "../../foundations/status/index.js";
2
+ import { resolveRunSteps } from "./types.js";
3
+ export function formatElapsed(ms) {
4
+ if (!Number.isFinite(ms) || ms < 0)
5
+ return "";
6
+ if (ms < 100)
7
+ return "<0.1 s";
8
+ if (ms < 10000)
9
+ return `${(ms / 1000).toFixed(1)} s`;
10
+ const seconds = Math.round(ms / 1000);
11
+ return seconds < 60 ? `${seconds} s` : `${Math.floor(seconds / 60)} min ${seconds % 60} s`;
12
+ }
13
+ export function splitStepTitle(title) {
14
+ const at = title.indexOf(" · ");
15
+ return at < 0 ? { action: title } : { source: title.slice(0, at), action: title.slice(at + 3) };
16
+ }
17
+ export function progress(turn, failed = false, now = Date.now(), threshold = 2000) {
18
+ const resolved = resolveRunSteps(turn.steps);
19
+ if (turn.endedAt === undefined) {
20
+ const step = [...resolved.steps].reverse().find(s => s.status === "running");
21
+ const label = turn.todos.find(t => t.status === "in_progress")?.content ?? (step ? splitStepTitle(step.step.title).action : "Thinking");
22
+ const elapsed = Math.max(0, now - turn.startedAt);
23
+ return { kind: "active", label: `${label}…`, ...(elapsed >= threshold ? { elapsed: `${Math.floor(elapsed / 1000)} s` } : {}) };
24
+ }
25
+ const took = formatElapsed(turn.endedAt - turn.startedAt);
26
+ if (failed || resolved.status === "failed")
27
+ return { kind: "failed", label: `Stopped after ${took}` };
28
+ if (turn.incomplete)
29
+ return { kind: "warning", label: `Cut short after ${took}` };
30
+ const warnings = resolved.steps.filter(s => toStatusKind(s.status) === "warning").length;
31
+ return { kind: warnings ? "warning" : "done", label: `Worked for ${took}${warnings ? ` · ${warnings} warning${warnings === 1 ? "" : "s"}` : ""}` };
32
+ }
@@ -0,0 +1,21 @@
1
+ import { BaseElement } from "../../core/element.js";
2
+ import { type RunTurn } from "./progress.js";
3
+ export declare class RunSummary extends BaseElement {
4
+ static readonly tagName = "box-run-summary";
5
+ static get observedAttributes(): string[];
6
+ private value;
7
+ private timer;
8
+ private planSignature;
9
+ private traceSignature;
10
+ get turn(): RunTurn;
11
+ set turn(turn: RunTurn);
12
+ get open(): boolean;
13
+ set open(value: boolean);
14
+ connectedCallback(): void;
15
+ disconnectedCallback(): void;
16
+ private syncTimer;
17
+ protected renderTemplate(): void;
18
+ protected setupListeners(): void;
19
+ private updateLabel;
20
+ protected update(): void;
21
+ }
@@ -0,0 +1,82 @@
1
+ import { BaseElement } from "../../core/element.js";
2
+ import { boeDisclosureStyles, boeEntranceKeyframes, boeReducedMotionPolicy } from "../../foundations/motion/index.js";
3
+ import { StatusIcon } from "../../components/feedback/status-icon.js";
4
+ import { toStatusKind } from "../../foundations/status/index.js";
5
+ import { RunTrace } from "./run-trace.js";
6
+ import { progress } from "./progress.js";
7
+ const DEFAULT_TAG_NAME = "box-run-summary";
8
+ export class RunSummary extends BaseElement {
9
+ static tagName = DEFAULT_TAG_NAME;
10
+ static get observedAttributes() { return ["open", "failed", "elapsed-threshold"]; }
11
+ value = { steps: [], todos: [], startedAt: 0, endedAt: 0 };
12
+ timer;
13
+ planSignature = "";
14
+ traceSignature = "";
15
+ get turn() { return this.value; }
16
+ set turn(turn) { this.value = turn; if (this.isRendered)
17
+ this.update(); }
18
+ get open() { return this.hasAttribute("open"); }
19
+ set open(value) { this.toggleAttribute("open", value); }
20
+ connectedCallback() { super.connectedCallback(); this.syncTimer(); }
21
+ disconnectedCallback() { clearInterval(this.timer); this.timer = undefined; }
22
+ syncTimer() {
23
+ if (this.value.endedAt === undefined && this.isConnected && !this.timer)
24
+ this.timer = setInterval(() => this.updateLabel(), 1000);
25
+ if (this.value.endedAt !== undefined) {
26
+ clearInterval(this.timer);
27
+ this.timer = undefined;
28
+ }
29
+ }
30
+ renderTemplate() {
31
+ StatusIcon.register();
32
+ RunTrace.register();
33
+ this.shadowRoot.innerHTML = `<style>:host{display:block;font:inherit;color:var(--boe-token-text-text-secondary,#666)}:host([hidden]){display:none !important}
34
+ button{font:inherit;color:inherit;background:none;border:0;cursor:pointer;padding:.5rem 0;display:flex;gap:.5rem;align-items:center}
35
+ [part="clock"]{font-variant-numeric:tabular-nums} ul{padding:0;list-style:none} li{display:flex;gap:.5rem;margin:.5rem 0}
36
+ @keyframes boe-shimmer{50%{opacity:.6}} [data-running] [part="label"]{animation:boe-shimmer 1.4s ease-in-out infinite}
37
+ ${boeDisclosureStyles()}${boeEntranceKeyframes}${boeReducedMotionPolicy}</style>
38
+ <button part="trigger" aria-expanded="false" aria-controls="details"><box-status-icon></box-status-icon><span part="label" role="status"></span><span part="clock" aria-hidden="true"></span><span aria-hidden="true">›</span></button>
39
+ <div id="details" part="disclosure" class="boe-disclosure" inert><div><ul part="plan"></ul><box-run-trace></box-run-trace></div></div>`;
40
+ }
41
+ setupListeners() { this.shadowRoot.querySelector("button").addEventListener("click", () => { this.open = !this.open; }); }
42
+ updateLabel() {
43
+ const p = progress(this.value, this.hasAttribute("failed"), Date.now(), Number(this.getAttribute("elapsed-threshold") ?? 2000));
44
+ const label = this.shadowRoot.querySelector('[part="label"]');
45
+ if (label.textContent !== p.label)
46
+ label.textContent = p.label;
47
+ this.shadowRoot.querySelector('[part="clock"]').textContent = p.elapsed ?? "";
48
+ this.shadowRoot.querySelector("box-status-icon").kind = p.kind;
49
+ this.shadowRoot.querySelector("button").toggleAttribute("data-running", p.kind === "active");
50
+ this.shadowRoot.querySelector("button").setAttribute("aria-label", p.label);
51
+ }
52
+ update() {
53
+ if (!this.isRendered)
54
+ return;
55
+ this.updateLabel();
56
+ this.syncTimer();
57
+ this.shadowRoot.querySelector("button").setAttribute("aria-expanded", String(this.open));
58
+ const disclosure = this.shadowRoot.querySelector("#details");
59
+ disclosure.toggleAttribute("data-open", this.open);
60
+ disclosure.inert = !this.open;
61
+ disclosure.setAttribute("aria-hidden", String(!this.open));
62
+ const signature = JSON.stringify(this.value.todos);
63
+ if (signature !== this.planSignature) {
64
+ this.planSignature = signature;
65
+ const list = this.shadowRoot.querySelector("ul");
66
+ list.replaceChildren();
67
+ for (const todo of this.value.todos) {
68
+ const li = document.createElement("li");
69
+ const icon = new StatusIcon();
70
+ icon.kind = toStatusKind(todo.status);
71
+ li.append(icon, document.createTextNode(todo.content));
72
+ list.append(li);
73
+ }
74
+ }
75
+ const traceSignature = JSON.stringify(this.value.steps);
76
+ if (traceSignature !== this.traceSignature) {
77
+ this.traceSignature = traceSignature;
78
+ this.shadowRoot.querySelector("box-run-trace").steps = this.value.steps;
79
+ }
80
+ }
81
+ }
82
+ RunSummary.register();
@@ -25,6 +25,7 @@ export declare class RunTrace extends BaseElement {
25
25
  private stepsRaw;
26
26
  private stepsCache;
27
27
  private readonly expandedIds;
28
+ private readonly previousStatuses;
28
29
  get heading(): string;
29
30
  set heading(value: string);
30
31
  get steps(): RunStep[];
@@ -2,6 +2,8 @@ import { formatRunDuration, formatRunSummary, isRunStepRecord, resolveRunSteps,
2
2
  import { ProgressBar } from "../../components/feedback/progress-bar.js";
3
3
  import { BaseElement } from "../../core/index.js";
4
4
  import { boePanel } from "../../foundations/geometry/index.js";
5
+ import { boeStatusGlyph, boeStatusStyles, toStatusKind } from "../../foundations/status/index.js";
6
+ import { boeEntranceKeyframes, boeReducedMotionPolicy } from "../../foundations/motion/index.js";
5
7
  const DEFAULT_TAG_NAME = "box-run-trace";
6
8
  /** Escape a value for use inside a double-quoted attribute selector. */
7
9
  const cssAttrValue = (value) => value.replaceAll("\\", "\\\\").replaceAll('"', '\\"');
@@ -33,6 +35,12 @@ const elementStyles = `
33
35
  display: block;
34
36
  }
35
37
 
38
+ /* The host's own display would otherwise beat the UA rule for [hidden],
39
+ leaving the element on screen when a host hides it. */
40
+ :host([hidden]) {
41
+ display: none !important;
42
+ }
43
+
36
44
  [part="panel"] {
37
45
  border: ${boePanel.border};
38
46
  border-radius: ${boePanel.radius};
@@ -279,6 +287,7 @@ export class RunTrace extends BaseElement {
279
287
  stepsRaw = null;
280
288
  stepsCache = [];
281
289
  expandedIds = new Set();
290
+ previousStatuses = new Map();
282
291
  get heading() {
283
292
  return this.getAttribute("heading") ?? "Run";
284
293
  }
@@ -326,7 +335,11 @@ export class RunTrace extends BaseElement {
326
335
  if (!this.shadowRoot) {
327
336
  return;
328
337
  }
329
- this.shadowRoot.innerHTML = `<style>${elementStyles}</style><div part="host"></div>`;
338
+ this.shadowRoot.innerHTML = `<style>${elementStyles}
339
+ [part="step"] [part="marker"]{border:0;background:none;display:inline-flex}
340
+ ${boeEntranceKeyframes}${boeStatusStyles}
341
+ [data-settled] .boe-status[data-kind="done"], [data-settled] .boe-status[data-kind="done"] path { animation: none; }
342
+ ${boeReducedMotionPolicy}</style><div part="host"></div>`;
330
343
  this.hostEl = this.shadowRoot.querySelector('[part="host"]');
331
344
  }
332
345
  setupListeners() {
@@ -373,7 +386,7 @@ export class RunTrace extends BaseElement {
373
386
  <span part="child-label">${escapeHtml(child.label)}</span>
374
387
  ${clamped === null
375
388
  ? "<span></span>"
376
- : `<box-progress-bar label="${escapeHtml(child.label)} progress" value="${String(clamped)}"></box-progress-bar>`}
389
+ : `<box-progress-bar label="${escapeHtml(child.label)}" value="${String(clamped)}"></box-progress-bar>`}
377
390
  <span part="child-status">${RUN_STEP_STATUS_LABEL[status]}</span>
378
391
  </li>
379
392
  `;
@@ -389,6 +402,7 @@ export class RunTrace extends BaseElement {
389
402
  const rows = resolution.steps
390
403
  .map(entry => {
391
404
  const { step, status, position } = entry;
405
+ const settled = this.previousStatuses.get(step.id) === status;
392
406
  const duration = formatRunDuration(step.startedAt, step.finishedAt);
393
407
  // Slot-only detail counts: a host projecting logs for a step with no
394
408
  // JSON description still needs the toggle that reveals them.
@@ -406,7 +420,7 @@ export class RunTrace extends BaseElement {
406
420
  `;
407
421
  return `
408
422
  <li part="step" data-status="${status}" data-step-id="${escapeHtml(step.id)}" style="--run-tone:${STATUS_TONE[status]};">
409
- <span part="marker" aria-hidden="true"></span>
423
+ <span part="marker" aria-hidden="true" ${settled ? "data-settled" : ""}>${boeStatusGlyph(toStatusKind(status))}</span>
410
424
  <div part="step-body">
411
425
  <div part="topline">
412
426
  <span part="step-title">${escapeHtml(step.title)}</span>
@@ -424,6 +438,9 @@ export class RunTrace extends BaseElement {
424
438
  })
425
439
  .join("");
426
440
  const summary = formatRunSummary(resolution);
441
+ this.previousStatuses.clear();
442
+ for (const { step, status } of resolution.steps)
443
+ this.previousStatuses.set(step.id, status);
427
444
  this.hostEl.innerHTML = `
428
445
  <section part="panel" aria-label="${escapeHtml(this.heading)}">
429
446
  <div part="header">
@@ -25,6 +25,12 @@ const elementStyles = `
25
25
  --_obp-brand-soft: color-mix(in srgb, var(--_obp-brand) 12%, var(--boe-token-surface-surface, #ffffff) 88%);
26
26
  }
27
27
 
28
+ /* The host's own display would otherwise beat the UA rule for [hidden],
29
+ leaving the element on screen when a host hides it. */
30
+ :host([hidden]) {
31
+ display: none !important;
32
+ }
33
+
28
34
  [part="bar"] {
29
35
  display: grid;
30
36
  gap: ${boePanel.gap};
@@ -23,6 +23,12 @@ const elementStyles = `
23
23
  --_obp-brand-soft: color-mix(in srgb, var(--_obp-brand) 12%, var(--boe-token-surface-surface, #ffffff) 88%);
24
24
  }
25
25
 
26
+ /* The host's own display would otherwise beat the UA rule for [hidden],
27
+ leaving the element on screen when a host hides it. */
28
+ :host([hidden]) {
29
+ display: none !important;
30
+ }
31
+
26
32
  [part="picker"] {
27
33
  display: grid;
28
34
  gap: ${boePanel.gap};
@@ -22,6 +22,12 @@ const elementStyles = `
22
22
  --_obp-brand-soft: color-mix(in srgb, var(--_obp-brand) 12%, var(--boe-token-surface-surface, #ffffff) 88%);
23
23
  }
24
24
 
25
+ /* The host's own display would otherwise beat the UA rule for [hidden],
26
+ leaving the element on screen when a host hides it. */
27
+ :host([hidden]) {
28
+ display: none !important;
29
+ }
30
+
25
31
  [part="header"] {
26
32
  display: grid;
27
33
  gap: ${boePanel.gap};
@@ -64,6 +64,12 @@ const elementStyles = `
64
64
  font: inherit;
65
65
  }
66
66
 
67
+ /* The host's own display would otherwise beat the UA rule for [hidden],
68
+ leaving the element on screen when a host hides it. */
69
+ :host([hidden]) {
70
+ display: none !important;
71
+ }
72
+
67
73
  [part="stats"] {
68
74
  margin: 0;
69
75
  padding: ${boePanel.padding};
@@ -38,6 +38,12 @@ const elementStyles = `
38
38
  font: inherit;
39
39
  }
40
40
 
41
+ /* The host's own display would otherwise beat the UA rule for [hidden],
42
+ leaving the element on screen when a host hides it. */
43
+ :host([hidden]) {
44
+ display: none !important;
45
+ }
46
+
41
47
  [part="group"] {
42
48
  display: inline-flex;
43
49
  align-items: center;
@@ -7,6 +7,12 @@ const DEFAULT_TAG_NAME = "box-invite-collaborators-modal";
7
7
  const elementStyles = `
8
8
  :host { display: contents; color: inherit; font: inherit; }
9
9
 
10
+ /* The host's own display would otherwise beat the UA rule for [hidden],
11
+ leaving the element on screen when a host hides it. */
12
+ :host([hidden]) {
13
+ display: none !important;
14
+ }
15
+
10
16
  [part="backdrop"] {
11
17
  position: fixed;
12
18
  inset: 0;
@@ -16,6 +16,12 @@ const matrixStyles = `
16
16
  font: inherit;
17
17
  }
18
18
 
19
+ /* The host's own display would otherwise beat the UA rule for [hidden],
20
+ leaving the element on screen when a host hides it. */
21
+ :host([hidden]) {
22
+ display: none !important;
23
+ }
24
+
19
25
  [part="matrix"] {
20
26
  display: grid;
21
27
  gap: ${boePanel.gap};
@@ -127,6 +127,12 @@ export class Presence extends BaseElement {
127
127
  font: inherit;
128
128
  }
129
129
 
130
+ /* The host's own display would otherwise beat the UA rule for [hidden],
131
+ leaving the element on screen when a host hides it. */
132
+ :host([hidden]) {
133
+ display: none !important;
134
+ }
135
+
130
136
  [part="presence"] {
131
137
  display: inline-flex;
132
138
  align-items: center;
@@ -16,6 +16,12 @@ const elementStyles = `
16
16
  font: inherit;
17
17
  }
18
18
 
19
+ /* The host's own display would otherwise beat the UA rule for [hidden],
20
+ leaving the element on screen when a host hides it. */
21
+ :host([hidden]) {
22
+ display: none !important;
23
+ }
24
+
19
25
  [part="panel"] {
20
26
  display: grid;
21
27
  gap: ${boePanel.gap};
@@ -18,6 +18,12 @@ const accessLabel = (access) => ACCESS_OPTIONS.find(option => option.value === a
18
18
  const elementStyles = `
19
19
  :host { display: contents; color: inherit; font: inherit; }
20
20
 
21
+ /* The host's own display would otherwise beat the UA rule for [hidden],
22
+ leaving the element on screen when a host hides it. */
23
+ :host([hidden]) {
24
+ display: none !important;
25
+ }
26
+
21
27
  [part="backdrop"] {
22
28
  position: fixed;
23
29
  inset: 0;
@@ -33,6 +33,12 @@ const elementStyles = `
33
33
  display: block;
34
34
  }
35
35
 
36
+ /* The host's own display would otherwise beat the UA rule for [hidden],
37
+ leaving the element on screen when a host hides it. */
38
+ :host([hidden]) {
39
+ display: none !important;
40
+ }
41
+
36
42
  [part="card"] {
37
43
  border: ${boePanel.border};
38
44
  border-radius: ${boePanel.radius};
@@ -15,6 +15,12 @@ const elementStyles = `
15
15
  font: inherit;
16
16
  }
17
17
 
18
+ /* The host's own display would otherwise beat the UA rule for [hidden],
19
+ leaving the element on screen when a host hides it. */
20
+ :host([hidden]) {
21
+ display: none !important;
22
+ }
23
+
18
24
  [part="item"] {
19
25
  display: grid;
20
26
  gap: 0.6rem;