@unofficialbox/box-open-elements 0.21.0 → 0.23.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 +13 -12
- package/dist/components/actions/menu-item.js +1 -1
- package/dist/components/actions/menu.js +1 -1
- package/dist/components/collections/carousel.js +1 -1
- package/dist/components/collections/draggable-list.js +1 -1
- package/dist/components/collections/grid-view.js +1 -1
- package/dist/components/collections/pagination.js +1 -1
- package/dist/components/collections/result-blocks.d.ts +13 -1
- package/dist/components/collections/result-blocks.js +22 -10
- package/dist/components/collections/tree-grid.js +1 -1
- package/dist/components/feedback/alert.js +1 -1
- package/dist/components/feedback/chip.js +1 -1
- package/dist/components/feedback/empty-state.js +1 -1
- package/dist/components/feedback/nudge.js +1 -1
- package/dist/components/feedback/status-icon.d.ts +2 -0
- package/dist/components/feedback/status-icon.js +6 -5
- package/dist/components/feedback/toast.js +1 -1
- package/dist/components/files/drop-zone.js +1 -1
- package/dist/components/forms/category-selector.js +1 -1
- package/dist/components/forms/checkbox-group.js +1 -1
- package/dist/components/forms/checkbox.js +1 -1
- package/dist/components/forms/combobox.js +1 -1
- package/dist/components/forms/date-field.js +1 -1
- package/dist/components/forms/dropdown.js +1 -1
- package/dist/components/forms/multi-select.js +1 -1
- package/dist/components/forms/number-input.js +1 -1
- package/dist/components/forms/radio-group.js +1 -1
- package/dist/components/forms/range-slider.js +1 -1
- package/dist/components/forms/slider.js +1 -1
- package/dist/components/forms/tile-group.js +1 -1
- package/dist/components/layout/sidebar-toggle-button.js +1 -1
- package/dist/components/navigation/accordion.js +1 -1
- package/dist/components/navigation/tabs.js +1 -1
- package/dist/components/output/code-block.js +1 -1
- package/dist/components/overlays/dialog.js +1 -1
- package/dist/components/overlays/drawer.js +1 -1
- package/dist/components/overlays/guide-tooltip.js +1 -1
- package/dist/components/overlays/popover.js +1 -1
- package/dist/components/overlays/tooltip.js +1 -1
- package/dist/foundations/motion/scroll-pin.d.ts +10 -2
- package/dist/foundations/motion/scroll-pin.js +43 -7
- package/dist/foundations/motion/tokens.d.ts +1 -0
- package/dist/foundations/motion/tokens.js +1 -0
- package/dist/foundations/profiles/built-ins.js +8 -0
- package/dist/foundations/profiles/registry.d.ts +1 -0
- package/dist/foundations/profiles/registry.js +1 -0
- package/dist/foundations/profiles/types.d.ts +1 -0
- package/dist/foundations/status/index.d.ts +4 -2
- package/dist/foundations/status/index.js +10 -6
- package/dist/foundations/theming/controller.js +3 -1
- package/dist/foundations/tokens/box-defaults.d.ts +2 -0
- package/dist/foundations/tokens/box-defaults.js +32 -5
- package/dist/foundations/tokens/index.d.ts +1 -1
- package/dist/foundations/tokens/index.js +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/patterns/agent-chat/agent-chat.js +9 -10
- package/dist/patterns/agent-chat/controller.js +8 -4
- package/dist/patterns/agent-chat/ndjson.d.ts +1 -0
- package/dist/patterns/agent-chat/ndjson.js +20 -4
- package/dist/patterns/agent-chat/types.d.ts +7 -0
- package/dist/patterns/agent-workspace/agent-workspace.d.ts +13 -1
- package/dist/patterns/agent-workspace/agent-workspace.js +47 -15
- package/dist/patterns/agent-workspace/controller.d.ts +7 -1
- package/dist/patterns/agent-workspace/controller.js +41 -3
- package/dist/patterns/call-console/call-console.d.ts +10 -0
- package/dist/patterns/call-console/call-console.js +23 -8
- package/dist/patterns/call-console/controller.d.ts +2 -1
- package/dist/patterns/call-console/controller.js +5 -3
- package/dist/patterns/call-console/http-transport.js +13 -2
- package/dist/patterns/call-console/types.d.ts +1 -1
- package/dist/patterns/call-console/types.js +2 -2
- package/dist/patterns/comments/comment-thread.js +1 -1
- package/dist/patterns/content-explorer/adapters/action-menu.js +1 -1
- package/dist/patterns/content-explorer/adapters/list.js +1 -1
- package/dist/patterns/content-explorer/adapters/table.js +1 -1
- package/dist/patterns/content-explorer/adapters/toolbar.js +1 -1
- package/dist/patterns/content-uploader/content-uploader.js +1 -1
- package/dist/patterns/file-request/file-request-builder.js +1 -1
- package/dist/patterns/flow-builder/flow-builder.d.ts +45 -14
- package/dist/patterns/flow-builder/flow-builder.js +54 -11
- package/dist/patterns/flow-builder/model.d.ts +57 -9
- package/dist/patterns/flow-builder/model.js +20 -8
- package/dist/patterns/flow-builder/primitives.d.ts +17 -7
- package/dist/patterns/flow-builder/primitives.js +80 -16
- package/dist/patterns/governance/governance-panel.js +1 -1
- package/dist/patterns/insights/chart-panel.js +1 -1
- package/dist/patterns/insights/metric-card.js +1 -1
- package/dist/patterns/item/bulk-action-bar.js +1 -1
- package/dist/patterns/item/item-details-panel.js +1 -1
- package/dist/patterns/item/item-form.js +1 -1
- package/dist/patterns/item/preview-header.js +1 -1
- package/dist/patterns/metadata/metadata-filter-builder.js +1 -1
- package/dist/patterns/metadata/metadata-inspector.js +1 -1
- package/dist/patterns/preview/annotation-inspector.js +1 -1
- package/dist/patterns/preview/annotation-toolbar.js +1 -1
- package/dist/patterns/run/progress.d.ts +1 -1
- package/dist/patterns/run/progress.js +1 -1
- package/dist/patterns/run/run-summary.js +18 -4
- package/dist/patterns/run/run-trace.js +19 -5
- package/dist/patterns/search/filter-bar.js +1 -1
- package/dist/patterns/search/saved-view-picker.js +1 -1
- package/dist/patterns/search/search-results-header.js +1 -1
- package/dist/patterns/share/invite-collaborators-modal.js +1 -1
- package/dist/patterns/share/permission-matrix.js +1 -1
- package/dist/patterns/share/share-panel.js +1 -1
- package/dist/patterns/share/unified-share-modal.js +1 -1
- package/dist/patterns/task/review-queue-item.js +1 -1
- package/dist/patterns/task/task-assignment-panel.js +1 -1
- package/dist/patterns/undo/index.js +5 -3
- package/docs/api-guidelines.md +284 -0
- package/docs/foundations/motion.md +83 -0
- package/docs/patterns/agent-ui-guidelines.md +57 -0
- package/docs/patterns/agent-ui.md +197 -0
- package/package.json +6 -2
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { BaseElement } from "../../core/element.js";
|
|
2
2
|
import { AgentChat } from "../agent-chat/agent-chat.js";
|
|
3
3
|
import { isSafeHref } from "../internal/safe-href.js";
|
|
4
|
-
import { boeReducedMotionPolicy } from "../../foundations/motion/index.js";
|
|
4
|
+
import { boeMotionEasing, boeReducedMotionPolicy } from "../../foundations/motion/index.js";
|
|
5
5
|
import { trapTabKey } from "../../foundations/a11y/focus.js";
|
|
6
6
|
const DEFAULT_TAG_NAME = "box-agent-workspace";
|
|
7
7
|
export class AgentWorkspace extends BaseElement {
|
|
8
8
|
static tagName = DEFAULT_TAG_NAME;
|
|
9
|
-
static get observedAttributes() { return ["viewer-key"]; }
|
|
9
|
+
static get observedAttributes() { return ["viewer-key", "hide-toggles"]; }
|
|
10
10
|
model = null;
|
|
11
11
|
unsubscribe;
|
|
12
12
|
observer;
|
|
@@ -15,7 +15,20 @@ export class AgentWorkspace extends BaseElement {
|
|
|
15
15
|
detailsOpen = false;
|
|
16
16
|
initialized = false;
|
|
17
17
|
renderedActive = null;
|
|
18
|
+
chatIds = "";
|
|
19
|
+
lastPanes = null;
|
|
18
20
|
sessions = new Map();
|
|
21
|
+
/** Host-controlled pane state; mobile drawers remain mutually exclusive. */
|
|
22
|
+
get panes() { return { chats: this.chatsOpen, details: this.detailsOpen }; }
|
|
23
|
+
set panes(value) {
|
|
24
|
+
if (value.chats !== undefined)
|
|
25
|
+
this.chatsOpen = value.chats;
|
|
26
|
+
if (value.details !== undefined)
|
|
27
|
+
this.detailsOpen = value.details;
|
|
28
|
+
if (this.mobile && this.chatsOpen && this.detailsOpen)
|
|
29
|
+
this.chatsOpen = false;
|
|
30
|
+
this.syncPanes();
|
|
31
|
+
}
|
|
19
32
|
get workspaceController() { return this.model; }
|
|
20
33
|
set workspaceController(value) {
|
|
21
34
|
this.unsubscribe?.();
|
|
@@ -58,15 +71,16 @@ export class AgentWorkspace extends BaseElement {
|
|
|
58
71
|
this.syncPanes();
|
|
59
72
|
}
|
|
60
73
|
storageKey() { return `boe-workspace:${this.getAttribute("viewer-key") ?? "default"}`; }
|
|
61
|
-
toggle(pane) {
|
|
74
|
+
toggle(pane) { this.open(pane, !(pane === "chats" ? this.chatsOpen : this.detailsOpen)); }
|
|
75
|
+
open(pane, open) {
|
|
62
76
|
if (pane === "chats") {
|
|
63
|
-
this.chatsOpen =
|
|
64
|
-
if (this.mobile)
|
|
77
|
+
this.chatsOpen = open;
|
|
78
|
+
if (this.mobile && open)
|
|
65
79
|
this.detailsOpen = false;
|
|
66
80
|
}
|
|
67
81
|
else {
|
|
68
|
-
this.detailsOpen =
|
|
69
|
-
if (this.mobile)
|
|
82
|
+
this.detailsOpen = open;
|
|
83
|
+
if (this.mobile && open)
|
|
70
84
|
this.chatsOpen = false;
|
|
71
85
|
}
|
|
72
86
|
if (!this.mobile)
|
|
@@ -75,13 +89,16 @@ export class AgentWorkspace extends BaseElement {
|
|
|
75
89
|
}
|
|
76
90
|
catch { }
|
|
77
91
|
this.syncPanes();
|
|
78
|
-
if (this.mobile &&
|
|
92
|
+
if (this.mobile && open)
|
|
79
93
|
this.shadowRoot.querySelector(`#${pane} button`)?.focus({ preventScroll: true });
|
|
80
94
|
}
|
|
81
95
|
closeDrawers() { this.chatsOpen = false; this.detailsOpen = false; this.syncPanes(); this.sessions.get(this.model?.activeId ?? "")?.focusComposer(); }
|
|
82
96
|
syncPanes() {
|
|
83
97
|
if (!this.isRendered)
|
|
84
98
|
return;
|
|
99
|
+
const toggleGroup = this.shadowRoot.querySelector('[part="toggles"]');
|
|
100
|
+
if (toggleGroup)
|
|
101
|
+
toggleGroup.hidden = this.hasAttribute("hide-toggles");
|
|
85
102
|
this.toggleAttribute("data-mobile", this.mobile);
|
|
86
103
|
for (const [pane, open] of [["chats", this.chatsOpen], ["details", this.detailsOpen]]) {
|
|
87
104
|
const el = this.shadowRoot.getElementById(pane);
|
|
@@ -103,13 +120,19 @@ export class AgentWorkspace extends BaseElement {
|
|
|
103
120
|
this.shadowRoot.querySelector("#scrim").hidden = !overlaid;
|
|
104
121
|
for (const chat of this.sessions.values())
|
|
105
122
|
chat.toggleAttribute("hide-citations", this.detailsOpen);
|
|
123
|
+
for (const pane of ["chats", "details"]) {
|
|
124
|
+
const open = this.panes[pane];
|
|
125
|
+
if (this.lastPanes?.[pane] !== open)
|
|
126
|
+
this.dispatchEvent(new CustomEvent("pane-change", { bubbles: true, composed: true, detail: { pane, open, mobile: this.mobile } }));
|
|
127
|
+
}
|
|
128
|
+
this.lastPanes = this.panes;
|
|
106
129
|
}
|
|
107
130
|
renderTemplate() {
|
|
108
131
|
AgentChat.register();
|
|
109
132
|
this.shadowRoot.innerHTML = `<style>
|
|
110
133
|
:host{display:block;height:100%;min-height:30rem;color:var(--boe-token-text-text,#222);font:inherit}:host([hidden]){display:none !important}
|
|
111
134
|
*{box-sizing:border-box} section{position:relative;overflow:clip;height:100%;display:flex;min-width:0}
|
|
112
|
-
aside{width:0;overflow:clip;transition:width var(--boe-profile-motion-panel,320ms)
|
|
135
|
+
aside{width:0;overflow:clip;transition:width var(--boe-profile-motion-panel,320ms) ${boeMotionEasing.enter};background:var(--boe-token-surface-surface,#fff)} aside[data-open]{width:280px;flex-shrink:0}
|
|
113
136
|
aside>div{width:280px;height:100%;padding:1rem;overflow:auto} main{min-width:0;flex:1;overflow:clip;display:flex;flex-direction:column;background:var(--boe-token-surface-surface,#fff)} nav{display:flex;justify-content:space-between;padding:.5rem}
|
|
114
137
|
#conversation{flex:1;min-height:0} #sessions,box-agent-chat{height:100%}
|
|
115
138
|
box-agent-chat::part(panel){height:100%;box-sizing:border-box;display:flex;flex-direction:column;border:0;border-radius:0}
|
|
@@ -118,13 +141,13 @@ export class AgentWorkspace extends BaseElement {
|
|
|
118
141
|
button:focus-visible,a:focus-visible{outline:2px solid var(--boe-token-surface-surface-brand,#0061d5);outline-offset:2px}
|
|
119
142
|
[part="chat"]{display:block;text-align:left;width:100%;border:0;background:none;padding:.65rem;border-radius:6px}
|
|
120
143
|
[aria-current="page"]{background:var(--boe-token-surface-surface-secondary,#f3f3f3)} small{display:block;color:var(--boe-token-text-text-secondary,#666)}
|
|
121
|
-
#scrim{position:absolute;inset:0;background
|
|
144
|
+
#scrim{position:absolute;inset:0;background:var(--boe-workspace-scrim,rgba(0,0,0,.33));border:0;border-radius:0;z-index:2} [hidden]{display:none!important}
|
|
122
145
|
[data-close]{display:none} :host([data-mobile]) [data-close]{display:block;margin-bottom:.5rem}
|
|
123
146
|
:host([data-mobile]) aside{position:absolute;inset-block:0;z-index:3} :host([data-mobile]) #details{right:0}
|
|
124
147
|
#approvals button,#sources a{display:block;margin:.5rem 0;text-align:left} #context{white-space:pre-wrap;overflow-wrap:anywhere}
|
|
125
148
|
${boeReducedMotionPolicy}</style><section part="workspace">
|
|
126
149
|
<aside id="chats" part="chats"><div><button data-close>Close conversations</button><slot name="chats"><button id="new">New chat</button><div id="list"></div></slot></div></aside>
|
|
127
|
-
<main><nav><button data-toggle="chats" aria-controls="chats">Conversations</button><button data-toggle="details" aria-controls="details">Details</button></nav><div id="conversation" part="conversation"><slot name="conversation"><div id="sessions"></div></slot></div></main>
|
|
150
|
+
<main><nav><slot name="header"><div part="toggles" ${this.hasAttribute("hide-toggles") ? "hidden" : ""}><button data-toggle="chats" aria-controls="chats">Conversations</button><button data-toggle="details" aria-controls="details">Details</button></div></slot></nav><div id="conversation" part="conversation"><slot name="conversation"><div id="sessions"></div></slot></div></main>
|
|
128
151
|
<button id="scrim" aria-label="Close panel" hidden></button>
|
|
129
152
|
<aside id="details" part="details"><div><button data-close>Close details</button><slot name="details"><h2>Conversation details</h2><div id="context"></div><h3>Approvals</h3><div id="approvals"></div><h3>Sources</h3><div id="sources"></div></slot></div></aside></section>`;
|
|
130
153
|
}
|
|
@@ -134,6 +157,8 @@ export class AgentWorkspace extends BaseElement {
|
|
|
134
157
|
this.shadowRoot.querySelector("#scrim").addEventListener("click", () => this.closeDrawers());
|
|
135
158
|
this.shadowRoot.querySelectorAll("[data-close]").forEach(b => b.addEventListener("click", () => this.closeDrawers()));
|
|
136
159
|
this.shadowRoot.querySelectorAll("[data-toggle]").forEach(b => b.addEventListener("click", () => this.toggle(b.dataset.toggle)));
|
|
160
|
+
this.shadowRoot.querySelector('slot[name="conversation"]').addEventListener("slotchange", () => this.update());
|
|
161
|
+
this.shadowRoot.querySelector('slot[name="chats"]').addEventListener("slotchange", () => this.update());
|
|
137
162
|
this.shadowRoot.addEventListener("keydown", event => {
|
|
138
163
|
const e = event;
|
|
139
164
|
if (e.key === "Escape" && this.mobile) {
|
|
@@ -148,9 +173,15 @@ export class AgentWorkspace extends BaseElement {
|
|
|
148
173
|
if (!this.isRendered)
|
|
149
174
|
return;
|
|
150
175
|
const list = this.shadowRoot.querySelector("#list");
|
|
176
|
+
const hostChats = this.shadowRoot.querySelector('slot[name="chats"]').assignedElements().length > 0;
|
|
177
|
+
const ids = (this.model?.chats ?? []).map(chat => chat.id).join("\u0000");
|
|
178
|
+
if (ids !== this.chatIds) {
|
|
179
|
+
this.chatIds = ids;
|
|
180
|
+
this.dispatchEvent(new CustomEvent("chats-change", { bubbles: true, composed: true, detail: { ids: (this.model?.chats ?? []).map(chat => chat.id), activeId: this.model?.activeId ?? null } }));
|
|
181
|
+
}
|
|
151
182
|
const activeRow = this.shadowRoot.activeElement?.getAttribute("data-chat-id");
|
|
152
183
|
list.replaceChildren();
|
|
153
|
-
for (const summary of this.model?.summaries ?? []) {
|
|
184
|
+
for (const summary of hostChats ? [] : this.model?.summaries ?? []) {
|
|
154
185
|
const b = document.createElement("button");
|
|
155
186
|
b.setAttribute("part", "chat");
|
|
156
187
|
b.dataset.chatId = summary.id;
|
|
@@ -160,18 +191,19 @@ export class AgentWorkspace extends BaseElement {
|
|
|
160
191
|
const small = document.createElement("small");
|
|
161
192
|
small.textContent = summary.status;
|
|
162
193
|
b.append(small);
|
|
163
|
-
b.addEventListener("click", () => { this.model?.select(summary.id); if (this.mobile)
|
|
194
|
+
b.addEventListener("click", () => { this.model?.select(summary.id); this.dispatchEvent(new CustomEvent("conversation-selected", { bubbles: true, composed: true, detail: { id: summary.id } })); if (this.mobile)
|
|
164
195
|
this.closeDrawers(); });
|
|
165
196
|
list.append(b);
|
|
166
197
|
if (summary.id === activeRow)
|
|
167
198
|
b.focus({ preventScroll: true });
|
|
168
199
|
}
|
|
200
|
+
const hostConversation = this.shadowRoot.querySelector('slot[name="conversation"]').assignedElements().length > 0;
|
|
169
201
|
for (const [id, element] of this.sessions)
|
|
170
|
-
if (!this.model?.chats.some(c => c.id === id && c.controller === element.chatController)) {
|
|
202
|
+
if (hostConversation || !this.model?.chats.some(c => c.id === id && c.controller === element.chatController)) {
|
|
171
203
|
element.remove();
|
|
172
204
|
this.sessions.delete(id);
|
|
173
205
|
}
|
|
174
|
-
for (const chat of this.model?.chats ?? []) {
|
|
206
|
+
for (const chat of hostConversation ? [] : this.model?.chats ?? []) {
|
|
175
207
|
let element = this.sessions.get(chat.id);
|
|
176
208
|
if (!element) {
|
|
177
209
|
element = new AgentChat();
|
|
@@ -23,15 +23,21 @@ export declare function conversationDetails(state: Readonly<AgentChatState>): Wo
|
|
|
23
23
|
export declare class AgentWorkspaceController {
|
|
24
24
|
private readonly createSession;
|
|
25
25
|
readonly chats: WorkspaceChat[];
|
|
26
|
+
private readonly removed;
|
|
26
27
|
activeId: string | null;
|
|
27
28
|
private seq;
|
|
28
29
|
private listeners;
|
|
29
30
|
private subscriptions;
|
|
30
|
-
constructor(createSession: () => AgentChatController);
|
|
31
|
+
constructor(createSession: (id: string, seed?: unknown) => AgentChatController);
|
|
31
32
|
subscribe(listener: () => void): () => void;
|
|
32
33
|
private emit;
|
|
33
34
|
newChat(): WorkspaceChat;
|
|
34
35
|
select(id: string): void;
|
|
36
|
+
/** Temporarily remove a conversation without destroying its stream or history. */
|
|
37
|
+
remove(id: string): boolean;
|
|
38
|
+
restore(id: string, seed?: unknown): WorkspaceChat | null;
|
|
39
|
+
removeChat(id: string): boolean;
|
|
40
|
+
restoreChat(id: string, seed?: unknown): boolean;
|
|
35
41
|
get summaries(): WorkspaceSummary[];
|
|
36
42
|
get details(): WorkspaceDetails;
|
|
37
43
|
destroy(): void;
|
|
@@ -4,7 +4,8 @@ export const conversationTitle = (body, max = 48) => {
|
|
|
4
4
|
return text || "New chat";
|
|
5
5
|
const cut = text.slice(0, max);
|
|
6
6
|
const space = cut.lastIndexOf(" ");
|
|
7
|
-
|
|
7
|
+
const end = space >= max / 2 ? cut.slice(0, space) : cut;
|
|
8
|
+
return `${end.replace(/[\s,.;:!?-]+$/g, "")}…`;
|
|
8
9
|
};
|
|
9
10
|
export function conversationDetails(state) {
|
|
10
11
|
const sources = new Map();
|
|
@@ -31,6 +32,7 @@ export function conversationDetails(state) {
|
|
|
31
32
|
export class AgentWorkspaceController {
|
|
32
33
|
createSession;
|
|
33
34
|
chats = [];
|
|
35
|
+
removed = new Map();
|
|
34
36
|
activeId = null;
|
|
35
37
|
seq = 0;
|
|
36
38
|
listeners = new Set();
|
|
@@ -43,7 +45,8 @@ export class AgentWorkspaceController {
|
|
|
43
45
|
newChat() {
|
|
44
46
|
let chat = this.chats.find(c => c.controller.getState().messages.length === 0);
|
|
45
47
|
if (!chat) {
|
|
46
|
-
|
|
48
|
+
const id = `chat-${++this.seq}`;
|
|
49
|
+
chat = { id, controller: this.createSession(id) };
|
|
47
50
|
chat.controller.connect();
|
|
48
51
|
this.chats.push(chat);
|
|
49
52
|
this.subscriptions.push(chat.controller.subscribe("messagesChanged", () => this.emit()), chat.controller.subscribe("streamingChanged", () => this.emit()));
|
|
@@ -53,6 +56,41 @@ export class AgentWorkspaceController {
|
|
|
53
56
|
}
|
|
54
57
|
select(id) { if (!this.chats.some(c => c.id === id))
|
|
55
58
|
return; this.activeId = id; this.emit(); }
|
|
59
|
+
/** Temporarily remove a conversation without destroying its stream or history. */
|
|
60
|
+
remove(id) {
|
|
61
|
+
const index = this.chats.findIndex(chat => chat.id === id);
|
|
62
|
+
if (index < 0)
|
|
63
|
+
return false;
|
|
64
|
+
const [chat] = this.chats.splice(index, 1);
|
|
65
|
+
chat.controller.stop();
|
|
66
|
+
this.removed.set(id, { chat: chat, index });
|
|
67
|
+
if (this.activeId === id)
|
|
68
|
+
this.activeId = this.chats[Math.min(index, this.chats.length - 1)]?.id ?? null;
|
|
69
|
+
this.emit();
|
|
70
|
+
return true;
|
|
71
|
+
}
|
|
72
|
+
restore(id, seed) {
|
|
73
|
+
const removed = this.removed.get(id);
|
|
74
|
+
if (this.chats.some(chat => chat.id === id))
|
|
75
|
+
return null;
|
|
76
|
+
if (removed) {
|
|
77
|
+
this.removed.delete(id);
|
|
78
|
+
this.chats.splice(Math.min(removed.index, this.chats.length), 0, removed.chat);
|
|
79
|
+
this.select(id);
|
|
80
|
+
return removed.chat;
|
|
81
|
+
}
|
|
82
|
+
const chat = { id, controller: this.createSession(id, seed) };
|
|
83
|
+
chat.controller.connect();
|
|
84
|
+
this.chats.push(chat);
|
|
85
|
+
this.subscriptions.push(chat.controller.subscribe("messagesChanged", () => this.emit()), chat.controller.subscribe("streamingChanged", () => this.emit()));
|
|
86
|
+
const match = /^chat-(\d+)$/.exec(id);
|
|
87
|
+
if (match)
|
|
88
|
+
this.seq = Math.max(this.seq, Number(match[1]));
|
|
89
|
+
this.select(id);
|
|
90
|
+
return chat;
|
|
91
|
+
}
|
|
92
|
+
removeChat(id) { return this.remove(id); }
|
|
93
|
+
restoreChat(id, seed) { return this.restore(id, seed) !== null; }
|
|
56
94
|
get summaries() {
|
|
57
95
|
return this.chats.map(c => {
|
|
58
96
|
const state = c.controller.getState();
|
|
@@ -61,5 +99,5 @@ export class AgentWorkspaceController {
|
|
|
61
99
|
});
|
|
62
100
|
}
|
|
63
101
|
get details() { const chat = this.chats.find(c => c.id === this.activeId); return chat ? conversationDetails(chat.controller.getState()) : { approvals: [], sources: [] }; }
|
|
64
|
-
destroy() { this.subscriptions.forEach(fn => fn()); this.subscriptions = []; this.chats.forEach(c => { c.controller.disconnect(); c.controller.destroy(); }); this.listeners.clear(); }
|
|
102
|
+
destroy() { this.subscriptions.forEach(fn => fn()); this.subscriptions = []; [...this.chats, ...[...this.removed.values()].map(item => item.chat)].forEach(c => { c.controller.disconnect(); c.controller.destroy(); }); this.removed.clear(); this.listeners.clear(); }
|
|
65
103
|
}
|
|
@@ -1,15 +1,25 @@
|
|
|
1
1
|
import { BaseElement } from "../../core/element.js";
|
|
2
|
+
import { type CallEntry } from "./types.js";
|
|
2
3
|
import type { CallConsoleController } from "./controller.js";
|
|
3
4
|
export declare function copyCallText(text: string, doc?: Document): Promise<boolean>;
|
|
4
5
|
export declare class CallConsole extends BaseElement {
|
|
5
6
|
static readonly tagName = "box-call-console";
|
|
7
|
+
static get observedAttributes(): string[];
|
|
6
8
|
private model;
|
|
9
|
+
private labels;
|
|
10
|
+
private failureRule;
|
|
7
11
|
private unsubscribe?;
|
|
8
12
|
private selected;
|
|
9
13
|
private clearing;
|
|
10
14
|
private rowSignatures;
|
|
11
15
|
get callController(): CallConsoleController | null;
|
|
12
16
|
set callController(value: CallConsoleController | null);
|
|
17
|
+
get heading(): string;
|
|
18
|
+
set heading(value: string);
|
|
19
|
+
get serviceLabels(): Record<string, string>;
|
|
20
|
+
set serviceLabels(value: Record<string, string>);
|
|
21
|
+
get isFailed(): (entry: CallEntry) => boolean;
|
|
22
|
+
set isFailed(value: (entry: CallEntry) => boolean);
|
|
13
23
|
private listen;
|
|
14
24
|
connectedCallback(): void;
|
|
15
25
|
disconnectedCallback(): void;
|
|
@@ -30,7 +30,10 @@ export async function copyCallText(text, doc = document) {
|
|
|
30
30
|
}
|
|
31
31
|
export class CallConsole extends BaseElement {
|
|
32
32
|
static tagName = DEFAULT_TAG_NAME;
|
|
33
|
+
static get observedAttributes() { return ["heading", "hide-heading"]; }
|
|
33
34
|
model = null;
|
|
35
|
+
labels = {};
|
|
36
|
+
failureRule = callFailed;
|
|
34
37
|
unsubscribe;
|
|
35
38
|
selected = "";
|
|
36
39
|
clearing = false;
|
|
@@ -39,6 +42,14 @@ export class CallConsole extends BaseElement {
|
|
|
39
42
|
set callController(value) { this.unsubscribe?.(); this.model = value; if (this.isConnected)
|
|
40
43
|
this.listen(); if (this.isRendered)
|
|
41
44
|
this.update(); }
|
|
45
|
+
get heading() { return this.getAttribute("heading") ?? "API calls"; }
|
|
46
|
+
set heading(value) { this.setAttribute("heading", value); }
|
|
47
|
+
get serviceLabels() { return this.labels; }
|
|
48
|
+
set serviceLabels(value) { this.labels = value; if (this.isRendered)
|
|
49
|
+
this.update(); }
|
|
50
|
+
get isFailed() { return this.failureRule; }
|
|
51
|
+
set isFailed(value) { this.failureRule = value; if (this.isRendered)
|
|
52
|
+
this.update(); }
|
|
42
53
|
listen() { this.unsubscribe?.(); this.unsubscribe = this.model?.subscribe(() => this.update()); }
|
|
43
54
|
connectedCallback() { super.connectedCallback(); this.listen(); }
|
|
44
55
|
disconnectedCallback() { this.unsubscribe?.(); }
|
|
@@ -73,7 +84,7 @@ export class CallConsole extends BaseElement {
|
|
|
73
84
|
@container(max-width:640px){box-split-view::part(split-view){grid-template-columns:minmax(0,1fr)!important}box-split-view::part(separator){display:none}#list{min-height:0;max-height:17rem}#inspector{border-top:1px solid var(--boe-token-stroke-stroke,#ddd)}.search{flex-basis:100%}}
|
|
74
85
|
${boeEntranceKeyframes}${boeStatusStyles}${boeReducedMotionPolicy}</style>
|
|
75
86
|
<section part="console" aria-label="API call console">
|
|
76
|
-
<header><div><h2
|
|
87
|
+
<header><div part="heading"><h2></h2><small>Inspect requests, responses, and tool outcomes</small></div><span id="connection" role="status"></span><box-button id="retry" label="Reconnect" tone="neutral" hidden></box-button></header>
|
|
77
88
|
<div class="filters"><label class="search">Search <input id="search" type="search" placeholder="Method, URL, or summary"></label><label>Service <select id="service" aria-label="Service"><option value="">All services</option></select></label><label><input type="checkbox" id="errors"> Errors only</label><box-button id="clear" label="Clear calls" tone="neutral"></box-button></div>
|
|
78
89
|
<box-split-view resizable ratio="0.42" label="Calls and request inspector"><section slot="primary" aria-label="Calls"><div class="pane-heading"><h3>Requests</h3><span id="count" class="muted" role="status"></span></div><div id="list"></div><p id="list-empty" role="status" hidden></p></section><section aria-label="Request inspector"><div class="pane-heading"><h3>Inspector</h3><box-button data-copy="both" label="Copy both" tone="neutral"></box-button><span id="copy-status" role="status"></span></div><p id="detail-empty">Select a request to inspect its details.</p><div id="inspector" hidden><h3 id="summary"></h3><p id="metadata" class="muted"></p><p id="outcome" role="status" hidden></p><h3 class="code-heading">Request</h3><box-code-block id="request" copy-label="Copy request" wrap></box-code-block><h3 class="code-heading">Response</h3><box-code-block id="response" copy-label="Copy response" wrap></box-code-block></div></section></box-split-view></section>`;
|
|
79
90
|
}
|
|
@@ -125,6 +136,8 @@ export class CallConsole extends BaseElement {
|
|
|
125
136
|
update() {
|
|
126
137
|
if (!this.isRendered)
|
|
127
138
|
return;
|
|
139
|
+
this.shadowRoot.querySelector('[part="heading"]').hidden = this.hasAttribute("hide-heading");
|
|
140
|
+
this.shadowRoot.querySelector("h2").textContent = this.heading;
|
|
128
141
|
const state = this.model?.connection ?? "connecting";
|
|
129
142
|
const connection = this.shadowRoot.querySelector("#connection");
|
|
130
143
|
connection.textContent = this.model ? ({ live: "Live", connecting: "Connecting…", reconnecting: "Reconnecting…", unavailable: "Endpoint unavailable" }[state]) : "Not connected";
|
|
@@ -138,13 +151,15 @@ export class CallConsole extends BaseElement {
|
|
|
138
151
|
if (!Array.from(service.options).some(o => o.value === name)) {
|
|
139
152
|
const option = document.createElement("option");
|
|
140
153
|
option.value = name;
|
|
141
|
-
option.textContent = name;
|
|
142
154
|
service.append(option);
|
|
143
155
|
}
|
|
156
|
+
for (const option of Array.from(service.options))
|
|
157
|
+
if (option.value)
|
|
158
|
+
option.textContent = this.labels[option.value] ?? option.value;
|
|
144
159
|
const errors = this.shadowRoot.querySelector("#errors").checked;
|
|
145
|
-
const entries = this.model?.entries.filter(e => (!service.value || e.service === service.value) && (!errors ||
|
|
160
|
+
const entries = this.model?.entries.filter(e => (!service.value || e.service === service.value) && (!errors || this.failureRule(e))) ?? [];
|
|
146
161
|
const query = this.filters.query.trim().toLowerCase();
|
|
147
|
-
const filtered = entries.filter(e => `${e.method} ${e.url} ${e.summary} ${e.service}`.toLowerCase().includes(query));
|
|
162
|
+
const filtered = entries.filter(e => `${e.method} ${e.url} ${e.summary} ${e.service} ${this.labels[e.service] ?? ""}`.toLowerCase().includes(query));
|
|
148
163
|
entries.splice(0, entries.length, ...filtered);
|
|
149
164
|
if (!entries.some(e => e.id === this.selected))
|
|
150
165
|
this.selected = entries[0]?.id ?? "";
|
|
@@ -163,12 +178,12 @@ export class CallConsole extends BaseElement {
|
|
|
163
178
|
button.addEventListener("click", () => { this.selected = entry.id; this.update(); this.dispatchEvent(new CustomEvent("call-selected", { bubbles: true, composed: true, detail: { id: entry.id } })); });
|
|
164
179
|
}
|
|
165
180
|
button.setAttribute("aria-current", String(entry.id === this.selected));
|
|
166
|
-
const labels = [callStatus(entry), entry.service, entry.summary, entry.pending ? "In progress" : `${Math.round(entry.durationMs)} ms`];
|
|
181
|
+
const labels = [callStatus(entry, this.failureRule), this.labels[entry.service] ?? entry.service, entry.summary, entry.pending ? "In progress" : `${Math.round(entry.durationMs)} ms`];
|
|
167
182
|
const signature = JSON.stringify(labels);
|
|
168
183
|
if (this.rowSignatures.get(button) !== signature) {
|
|
169
184
|
button.replaceChildren(...labels.map((text, index) => { const span = document.createElement("span"); span.textContent = text; span.className = ["state", "muted", "summary", "duration"][index]; if (index === 0) {
|
|
170
185
|
const icon = document.createElement("span");
|
|
171
|
-
icon.innerHTML = boeStatusGlyph(entry
|
|
186
|
+
icon.innerHTML = boeStatusGlyph(this.failureRule(entry) ? "failed" : entry.pending ? "active" : entry.expected ? "skipped" : "done");
|
|
172
187
|
span.prepend(icon);
|
|
173
188
|
} return span; }));
|
|
174
189
|
this.rowSignatures.set(button, signature);
|
|
@@ -184,13 +199,13 @@ export class CallConsole extends BaseElement {
|
|
|
184
199
|
this.shadowRoot.querySelector("#count").textContent = `${entries.length} of ${this.model?.entries.length ?? 0}`;
|
|
185
200
|
const empty = this.shadowRoot.querySelector("#list-empty");
|
|
186
201
|
empty.hidden = entries.length > 0 || !!this.model && state === "connecting";
|
|
187
|
-
empty.textContent = !this.model ? "Connect a call controller to inspect requests." : state === "unavailable" ? "
|
|
202
|
+
empty.textContent = !this.model ? "Connect a call controller to inspect requests." : state === "unavailable" ? "Call history is unavailable. Reconnect when the service is ready." : state === "reconnecting" ? "Connection interrupted. Reconnect to load calls." : this.model.entries.length ? "No requests match these filters." : "No calls yet. New requests will appear here.";
|
|
188
203
|
const entry = entries.find(e => e.id === this.selected);
|
|
189
204
|
this.shadowRoot.querySelector('[data-copy="both"]').disabled = !entry;
|
|
190
205
|
this.shadowRoot.querySelector("#inspector").hidden = !entry;
|
|
191
206
|
this.shadowRoot.querySelector("#detail-empty").hidden = !!entry;
|
|
192
207
|
this.shadowRoot.querySelector("#summary").textContent = entry?.summary ?? "";
|
|
193
|
-
this.shadowRoot.querySelector("#metadata").textContent = entry ? `${entry.service} · ${entry.method} · ${entry.pending ? "In progress" : `${entry.durationMs} ms`} · ${new Date(entry.startedAt).toLocaleTimeString()}` : "";
|
|
208
|
+
this.shadowRoot.querySelector("#metadata").textContent = entry ? `${this.labels[entry.service] ?? entry.service} · ${entry.method} · ${entry.pending ? "In progress" : `${entry.durationMs} ms`} · ${new Date(entry.startedAt).toLocaleTimeString()}` : "";
|
|
194
209
|
const outcome = this.shadowRoot.querySelector("#outcome");
|
|
195
210
|
outcome.hidden = !entry || !(entry.error || entry.rpcError || entry.expected || entry.pending);
|
|
196
211
|
outcome.textContent = entry?.rpcError ? `Tool failed despite HTTP ${entry.status}: ${entry.rpcError}` : entry?.error ?? entry?.expected ?? (entry?.pending ? "Waiting for the response…" : "");
|
|
@@ -7,12 +7,13 @@ export interface CallConsoleTransport {
|
|
|
7
7
|
/** Transport injection keeps networking out of the component. */
|
|
8
8
|
export declare class CallConsoleController {
|
|
9
9
|
readonly transport: CallConsoleTransport;
|
|
10
|
+
readonly maxEntries: number;
|
|
10
11
|
entries: CallEntry[];
|
|
11
12
|
connection: CallConnection;
|
|
12
13
|
private listeners;
|
|
13
14
|
private abort?;
|
|
14
15
|
private close?;
|
|
15
|
-
constructor(transport: CallConsoleTransport);
|
|
16
|
+
constructor(transport: CallConsoleTransport, maxEntries?: number);
|
|
16
17
|
subscribe(fn: () => void): () => void;
|
|
17
18
|
private emit;
|
|
18
19
|
apply(event: CallEvent): void;
|
|
@@ -1,23 +1,25 @@
|
|
|
1
1
|
/** Transport injection keeps networking out of the component. */
|
|
2
2
|
export class CallConsoleController {
|
|
3
3
|
transport;
|
|
4
|
+
maxEntries;
|
|
4
5
|
entries = [];
|
|
5
6
|
connection = "connecting";
|
|
6
7
|
listeners = new Set();
|
|
7
8
|
abort;
|
|
8
9
|
close;
|
|
9
|
-
constructor(transport) {
|
|
10
|
+
constructor(transport, maxEntries = 300) {
|
|
10
11
|
this.transport = transport;
|
|
12
|
+
this.maxEntries = maxEntries;
|
|
11
13
|
}
|
|
12
14
|
subscribe(fn) { this.listeners.add(fn); return () => this.listeners.delete(fn); }
|
|
13
15
|
emit() { this.listeners.forEach(fn => fn()); }
|
|
14
16
|
apply(event) {
|
|
15
17
|
if (event.type === "snapshot")
|
|
16
|
-
this.entries = event.entries;
|
|
18
|
+
this.entries = event.entries.slice(0, this.maxEntries);
|
|
17
19
|
else if (event.type === "clear")
|
|
18
20
|
this.entries = [];
|
|
19
21
|
else
|
|
20
|
-
this.entries = this.entries.some(e => e.id === event.entry.id) ? this.entries.map(e => e.id === event.entry.id ? event.entry : e) : [event.entry, ...this.entries];
|
|
22
|
+
this.entries = (this.entries.some(e => e.id === event.entry.id) ? this.entries.map(e => e.id === event.entry.id ? event.entry : e) : [event.entry, ...this.entries]).slice(0, this.maxEntries);
|
|
21
23
|
this.emit();
|
|
22
24
|
}
|
|
23
25
|
async connect() {
|
|
@@ -11,8 +11,19 @@ export function createCallConsoleTransport(base = "/calls") {
|
|
|
11
11
|
events.addEventListener(type, event => {
|
|
12
12
|
try {
|
|
13
13
|
const data = JSON.parse(event.data);
|
|
14
|
-
if (data
|
|
15
|
-
|
|
14
|
+
if (data && typeof data === "object" && "type" in data) {
|
|
15
|
+
if (data.type === type)
|
|
16
|
+
onEvent(data);
|
|
17
|
+
}
|
|
18
|
+
else if (type === "call" && data && !Array.isArray(data)) {
|
|
19
|
+
onEvent({ type: "call", entry: data });
|
|
20
|
+
}
|
|
21
|
+
else if (type === "snapshot" && (Array.isArray(data) || "entries" in data)) {
|
|
22
|
+
onEvent({ type: "snapshot", entries: Array.isArray(data) ? data : data.entries });
|
|
23
|
+
}
|
|
24
|
+
else if (type === "clear") {
|
|
25
|
+
onEvent({ type: "clear" });
|
|
26
|
+
}
|
|
16
27
|
}
|
|
17
28
|
catch {
|
|
18
29
|
onConnection("reconnecting");
|
|
@@ -28,5 +28,5 @@ export type CallEvent = {
|
|
|
28
28
|
};
|
|
29
29
|
export type CallConnection = "connecting" | "live" | "reconnecting" | "unavailable";
|
|
30
30
|
export declare const callFailed: (entry: CallEntry) => boolean;
|
|
31
|
-
export declare const callStatus: (entry: CallEntry) => string;
|
|
31
|
+
export declare const callStatus: (entry: CallEntry, isFailed?: (entry: CallEntry) => boolean) => string;
|
|
32
32
|
export declare const formatCallHttp: (entry: CallEntry, side?: "request" | "response" | "both") => string;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
export const callFailed = (entry) =>
|
|
2
|
-
export const callStatus = (entry
|
|
1
|
+
export const callFailed = (entry) => Boolean(entry.rpcError || (!entry.expected && (entry.error || entry.status === 0 || entry.status >= 400)));
|
|
2
|
+
export const callStatus = (entry, isFailed = callFailed) => entry.rpcError ? "Tool error" : entry.expected && !isFailed(entry) ? "Expected" : isFailed(entry) ? "Failed" : entry.pending ? "Pending" : "Done";
|
|
3
3
|
export const formatCallHttp = (entry, side = "both") => {
|
|
4
4
|
const headers = (h) => Object.entries(h).map(([k, v]) => `${k}: ${v}`).join("\n");
|
|
5
5
|
const request = `${entry.method} ${entry.url}\n${headers(entry.requestHeaders)}\n\n${entry.requestBody ?? ""}`;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseElement } from "../../core/index.js";
|
|
2
|
-
import { boeBrandInteractiveStyles, boeFocusRingShadow, boeNeutralInteractiveStyles, } from "../../foundations/tokens/
|
|
2
|
+
import { boeBrandInteractiveStyles, boeFocusRingShadow, boeNeutralInteractiveStyles, } from "../../foundations/tokens/interaction.js";
|
|
3
3
|
import { boeMotionDuration, boeMotionEasing } from "../../foundations/motion/index.js";
|
|
4
4
|
import { boePanel } from "../../foundations/geometry/index.js";
|
|
5
5
|
const DEFAULT_TAG_NAME = "box-comment-thread";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseElement } from "../../../core/index.js";
|
|
2
2
|
import { applyRovingTabindex, handleRovingKeydown } from "../../../foundations/a11y/index.js";
|
|
3
|
-
import { boeFocusRingShadow, boeNeutralInteractiveStyles, } from "../../../foundations/tokens/
|
|
3
|
+
import { boeFocusRingShadow, boeNeutralInteractiveStyles, } from "../../../foundations/tokens/interaction.js";
|
|
4
4
|
import { boeMotionDuration, boeMotionEasing } from "../../../foundations/motion/index.js";
|
|
5
5
|
import { boePanel } from "../../../foundations/geometry/index.js";
|
|
6
6
|
const DEFAULT_TAG_NAME = "box-explorer-action-menu";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveExplorerItemGesture, shouldActivateOnClick, shouldToggleOnEnter, } from "../types.js";
|
|
2
2
|
import { formatItemMetaLine, itemSummarySignature } from "./item-summary.js";
|
|
3
3
|
import { BaseElement } from "../../../core/index.js";
|
|
4
|
-
import { boeFocusVisibleStyles, boeNeutralInteractiveStyles, } from "../../../foundations/tokens/
|
|
4
|
+
import { boeFocusVisibleStyles, boeNeutralInteractiveStyles, } from "../../../foundations/tokens/interaction.js";
|
|
5
5
|
import { boeMotionDuration, boeMotionEasing } from "../../../foundations/motion/index.js";
|
|
6
6
|
import { boePanel, boeRadius } from "../../../foundations/geometry/index.js";
|
|
7
7
|
const DEFAULT_TAG_NAME = "box-explorer-list";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { resolveExplorerItemGesture, shouldActivateOnClick, shouldToggleOnEnter, } from "../types.js";
|
|
2
2
|
import { formatItemDate, formatItemOwner, formatItemShared, formatItemSize, itemSummarySignature, } from "./item-summary.js";
|
|
3
3
|
import { BaseElement } from "../../../core/index.js";
|
|
4
|
-
import { boeFocusVisibleStyles, boeNeutralInteractiveStyles, } from "../../../foundations/tokens/
|
|
4
|
+
import { boeFocusVisibleStyles, boeNeutralInteractiveStyles, } from "../../../foundations/tokens/interaction.js";
|
|
5
5
|
import { boeMotionDuration, boeMotionEasing } from "../../../foundations/motion/index.js";
|
|
6
6
|
import { boePanel, boeRadius } from "../../../foundations/geometry/index.js";
|
|
7
7
|
const DEFAULT_TAG_NAME = "box-explorer-table";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { BaseElement } from "../../../core/index.js";
|
|
2
2
|
import { SearchField, } from "../../../components/forms/search-field.js";
|
|
3
3
|
import { applyRovingTabindex, handleRovingKeydown } from "../../../foundations/a11y/index.js";
|
|
4
|
-
import { boeNeutralInteractiveStyles } from "../../../foundations/tokens/
|
|
4
|
+
import { boeNeutralInteractiveStyles } from "../../../foundations/tokens/interaction.js";
|
|
5
5
|
import { boeMotionDuration, boeMotionEasing } from "../../../foundations/motion/index.js";
|
|
6
6
|
import { boePanel } from "../../../foundations/geometry/index.js";
|
|
7
7
|
const DEFAULT_TAG_NAME = "box-explorer-toolbar";
|
|
@@ -4,7 +4,7 @@ import { formatItemSize } from "../content-explorer/adapters/item-summary.js";
|
|
|
4
4
|
import { DropZone } from "../../components/files/drop-zone.js";
|
|
5
5
|
import { ProgressBar } from "../../components/feedback/progress-bar.js";
|
|
6
6
|
import { BaseElement } from "../../core/index.js";
|
|
7
|
-
import { DESIGN_SYSTEM_CHANGE_EVENT, resolveDesignIllustration, } from "../../foundations/tokens/
|
|
7
|
+
import { DESIGN_SYSTEM_CHANGE_EVENT, resolveDesignIllustration, } from "../../foundations/tokens/registry.js";
|
|
8
8
|
import { boeMotionDuration, boeMotionEasing } from "../../foundations/motion/index.js";
|
|
9
9
|
import { boePanel, boeRadius } from "../../foundations/geometry/index.js";
|
|
10
10
|
const DEFAULT_TAG_NAME = "box-content-uploader";
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { BaseElement } from "../../core/index.js";
|
|
2
2
|
import { boePanel } from "../../foundations/geometry/index.js";
|
|
3
|
-
import { boeBrandInteractiveStyles, boeFocusVisibleStyles, boeNeutralInteractiveStyles, } from "../../foundations/tokens/
|
|
3
|
+
import { boeBrandInteractiveStyles, boeFocusVisibleStyles, boeNeutralInteractiveStyles, } from "../../foundations/tokens/interaction.js";
|
|
4
4
|
const DEFAULT_TAG_NAME = "box-file-request-builder";
|
|
5
5
|
const escapeHtml = (value) => value
|
|
6
6
|
.replaceAll("&", "&")
|