@unofficialbox/box-open-elements 0.20.0 → 0.21.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 (57) hide show
  1. package/dist/components/actions/menu-item.d.ts +2 -0
  2. package/dist/components/actions/menu-item.js +4 -0
  3. package/dist/components/collections/card.js +6 -0
  4. package/dist/components/collections/result-blocks.js +4 -1
  5. package/dist/components/feedback/alert.d.ts +2 -0
  6. package/dist/components/feedback/alert.js +17 -13
  7. package/dist/components/feedback/toast.d.ts +10 -1
  8. package/dist/components/feedback/toast.js +69 -27
  9. package/dist/components/forms/number-input.d.ts +1 -0
  10. package/dist/components/forms/number-input.js +9 -6
  11. package/dist/components/forms/search-field.js +16 -0
  12. package/dist/components/overlays/context-menu.d.ts +2 -0
  13. package/dist/components/overlays/context-menu.js +7 -0
  14. package/dist/components/overlays/dialog.js +19 -3
  15. package/dist/components/overlays/popover.js +6 -1
  16. package/dist/element-maps.d.ts +11 -1
  17. package/dist/foundations/a11y/announcer.d.ts +12 -0
  18. package/dist/foundations/a11y/announcer.js +75 -0
  19. package/dist/foundations/a11y/focus.js +46 -25
  20. package/dist/foundations/a11y/index.d.ts +2 -0
  21. package/dist/foundations/a11y/index.js +1 -0
  22. package/dist/foundations/icons/box-iconography.d.ts +472 -472
  23. package/dist/foundations/icons/box-iconography.generated.d.ts +1151 -679
  24. package/dist/foundations/icons/box-iconography.generated.js +1006 -3588
  25. package/dist/foundations/icons/glyphs/index.d.ts +1 -0
  26. package/dist/foundations/icons/glyphs/index.js +2 -0
  27. package/dist/foundations/icons/glyphs/package.json +1 -0
  28. package/dist/foundations/overlay/positioning.js +7 -0
  29. package/dist/foundations/status/index.d.ts +1 -1
  30. package/dist/foundations/status/index.js +8 -6
  31. package/dist/foundations/tokens/box-dark.js +4 -1
  32. package/dist/foundations/tokens/box-defaults.js +3 -0
  33. package/dist/foundations/tokens/registry.d.ts +3 -0
  34. package/dist/foundations/tokens/registry.js +3 -0
  35. package/dist/foundations/tokens/types.d.ts +3 -0
  36. package/dist/index.d.ts +2 -0
  37. package/dist/index.js +2 -0
  38. package/dist/patterns/agent-chat/agent-chat.js +12 -4
  39. package/dist/patterns/call-console/call-console.d.ts +3 -0
  40. package/dist/patterns/call-console/call-console.js +114 -20
  41. package/dist/patterns/content-explorer/adapters/action-menu.js +7 -5
  42. package/dist/patterns/content-explorer/adapters/toolbar.js +6 -2
  43. package/dist/patterns/file-request/file-request-builder.js +3 -0
  44. package/dist/patterns/flow-builder/flow-builder.d.ts +48 -0
  45. package/dist/patterns/flow-builder/flow-builder.js +200 -0
  46. package/dist/patterns/flow-builder/index.d.ts +3 -0
  47. package/dist/patterns/flow-builder/index.js +3 -0
  48. package/dist/patterns/flow-builder/model.d.ts +33 -0
  49. package/dist/patterns/flow-builder/model.js +28 -0
  50. package/dist/patterns/flow-builder/primitives.d.ts +47 -0
  51. package/dist/patterns/flow-builder/primitives.js +192 -0
  52. package/dist/patterns/lineage/lineage-graph.js +26 -6
  53. package/dist/patterns/notifications/notification-inbox.js +19 -3
  54. package/dist/patterns/preview/annotation-inspector.js +2 -2
  55. package/dist/patterns/undo/index.d.ts +19 -0
  56. package/dist/patterns/undo/index.js +106 -0
  57. package/package.json +11 -2
@@ -17,6 +17,8 @@ const elementStyles = `
17
17
 
18
18
  :host {
19
19
  display: block;
20
+ min-inline-size: 0;
21
+ container: boe-notification-inbox / inline-size;
20
22
  color: inherit;
21
23
  font: inherit;
22
24
  }
@@ -29,6 +31,7 @@ const elementStyles = `
29
31
 
30
32
  [part="panel"] {
31
33
  display: grid;
34
+ grid-template-columns: minmax(0, 1fr);
32
35
  grid-template-rows: auto auto 1fr;
33
36
  gap: ${boePanel.gap};
34
37
  padding: ${boePanel.padding};
@@ -40,11 +43,13 @@ const elementStyles = `
40
43
 
41
44
  [part="header"] {
42
45
  display: flex;
46
+ flex-wrap: wrap;
43
47
  align-items: center;
44
48
  gap: 0.5rem;
45
49
  }
46
50
 
47
51
  [part="title"] {
52
+ overflow-wrap: anywhere;
48
53
  margin: 0;
49
54
  font: inherit;
50
55
  font-size: 1.05rem;
@@ -56,7 +61,7 @@ const elementStyles = `
56
61
  padding: 0.1rem 0.45rem;
57
62
  border-radius: 999px;
58
63
  background: color-mix(in srgb, var(--boe-token-surface-status-surface-error, #ed3757) 14%, transparent);
59
- color: color-mix(in srgb, var(--boe-token-surface-status-surface-error, #ed3757) 78%, black 22%);
64
+ color: var(--boe-token-text-status-text-error, #b92340);
60
65
  font-size: 0.72rem;
61
66
  font-weight: 700;
62
67
  }
@@ -134,7 +139,7 @@ const elementStyles = `
134
139
  text-transform: none;
135
140
  letter-spacing: normal;
136
141
  font-size: 0.7rem;
137
- color: color-mix(in srgb, var(--boe-token-surface-status-surface-error, #ed3757) 78%, black 22%);
142
+ color: var(--boe-token-text-status-text-error, #b92340);
138
143
  }
139
144
 
140
145
  [part="items"] {
@@ -147,7 +152,7 @@ const elementStyles = `
147
152
 
148
153
  [part="item"] {
149
154
  display: grid;
150
- grid-template-columns: auto 1fr auto;
155
+ grid-template-columns: auto minmax(0, 1fr) auto;
151
156
  gap: 0.5rem;
152
157
  align-items: start;
153
158
  padding: 0.5rem 0.55rem;
@@ -174,6 +179,7 @@ const elementStyles = `
174
179
 
175
180
  [part="item-body"] {
176
181
  display: grid;
182
+ overflow-wrap: anywhere;
177
183
  gap: 0.15rem;
178
184
  min-inline-size: 0;
179
185
  }
@@ -223,6 +229,7 @@ const elementStyles = `
223
229
 
224
230
  [part="item-actions"] {
225
231
  display: flex;
232
+ flex-wrap: wrap;
226
233
  gap: 0.25rem;
227
234
  }
228
235
 
@@ -251,6 +258,15 @@ const elementStyles = `
251
258
  text-align: center;
252
259
  }
253
260
 
261
+ @container boe-notification-inbox (max-width: 32rem) {
262
+ [part="item"] {
263
+ grid-template-columns: auto minmax(0, 1fr);
264
+ }
265
+ [part="item-actions"] {
266
+ grid-column: 2;
267
+ }
268
+ }
269
+
254
270
  [part="filter"]:focus-visible,
255
271
  [part="mark-all"]:focus-visible,
256
272
  [part="item-title"]:focus-visible,
@@ -66,7 +66,7 @@ const elementStyles = `
66
66
  padding: 0.65rem;
67
67
  border-radius: ${boePanel.radius};
68
68
  border: 1px solid color-mix(in srgb, var(--boe-token-stroke-stroke, #e8e8e8) 48%, transparent);
69
- background: rgba(255, 255, 255, 0.72);
69
+ background: var(--boe-token-surface-surface, #ffffff);
70
70
  }
71
71
 
72
72
  [part="annotation-header"] {
@@ -254,7 +254,7 @@ const elementStyles = `
254
254
  [part="action"][data-tone="primary"] {
255
255
  border-color: transparent;
256
256
  background: var(--boe-token-surface-surface-brand, #0061d5);
257
- color: #fff;
257
+ color: var(--boe-token-text-text-on-brand, #ffffff);
258
258
  }
259
259
  `;
260
260
  export class AnnotationInspector extends BaseElement {
@@ -0,0 +1,19 @@
1
+ import { Toast } from "../../components/feedback/toast.js";
2
+ /** Remove once and return an idempotent restore preserving the original object's identity. */
3
+ export declare function removeAt<T>(list: T[], index: number): () => void;
4
+ /** Never overwrite a key recreated after removal. */
5
+ export declare function removeKey<T>(map: Record<string, T>, key: string): () => void;
6
+ /** Restore into the current list, preserving intervening edits and clamping the index. */
7
+ export declare function removeFromMapList<T>(map: Record<string, T[]>, key: string, index: number): () => void;
8
+ export interface UndoOffer {
9
+ readonly toast: Toast | null;
10
+ undo(): void;
11
+ dispose(): void;
12
+ }
13
+ export interface UndoOptions {
14
+ container?: HTMLElement;
15
+ duration?: number;
16
+ onRestore?: () => void;
17
+ }
18
+ /** Offer a single document-scoped undo. Hosts call dispose on teardown. SSR-safe. */
19
+ export declare function offerUndo(message: string, restore: () => void, options?: UndoOptions): UndoOffer;
@@ -0,0 +1,106 @@
1
+ import { Toast } from "../../components/feedback/toast.js";
2
+ import { announce } from "../../foundations/a11y/index.js";
3
+ /** Remove once and return an idempotent restore preserving the original object's identity. */
4
+ export function removeAt(list, index) {
5
+ if (!Number.isInteger(index) || index < 0 || index >= list.length)
6
+ return () => { };
7
+ const item = list.splice(index, 1)[0];
8
+ let restored = false;
9
+ return () => {
10
+ if (restored)
11
+ return;
12
+ restored = true;
13
+ list.splice(Math.min(index, list.length), 0, item);
14
+ };
15
+ }
16
+ /** Never overwrite a key recreated after removal. */
17
+ export function removeKey(map, key) {
18
+ if (!Object.hasOwn(map, key))
19
+ return () => { };
20
+ const value = map[key];
21
+ delete map[key];
22
+ let restored = false;
23
+ return () => {
24
+ if (restored)
25
+ return;
26
+ restored = true;
27
+ if (!Object.hasOwn(map, key))
28
+ Object.defineProperty(map, key, { value, writable: true, enumerable: true, configurable: true });
29
+ };
30
+ }
31
+ /** Restore into the current list, preserving intervening edits and clamping the index. */
32
+ export function removeFromMapList(map, key, index) {
33
+ const list = Object.hasOwn(map, key) ? map[key] : undefined;
34
+ if (!list || !Number.isInteger(index) || index < 0 || index >= list.length)
35
+ return () => { };
36
+ const item = list.splice(index, 1)[0];
37
+ if (!list.length)
38
+ delete map[key];
39
+ let restored = false;
40
+ return () => {
41
+ if (restored)
42
+ return;
43
+ restored = true;
44
+ if (!Object.hasOwn(map, key))
45
+ Object.defineProperty(map, key, { value: list, writable: true, enumerable: true, configurable: true });
46
+ const target = map[key];
47
+ target.splice(Math.min(index, target.length), 0, item);
48
+ };
49
+ }
50
+ const offers = new WeakMap();
51
+ /** Offer a single document-scoped undo. Hosts call dispose on teardown. SSR-safe. */
52
+ export function offerUndo(message, restore, options = {}) {
53
+ const doc = options.container?.ownerDocument ?? globalThis.document;
54
+ if (!doc?.body)
55
+ return { toast: null, undo() { }, dispose() { } };
56
+ offers.get(doc)?.dispose();
57
+ const toast = doc.createElement(Toast.tagName);
58
+ const action = doc.createElement("button");
59
+ action.type = "button";
60
+ action.slot = "action";
61
+ action.textContent = "Undo";
62
+ const mac = /Mac|iPhone|iPad/.test(doc.defaultView?.navigator.platform ?? "");
63
+ const shortcut = mac ? "Command-Z" : "Control-Z";
64
+ action.setAttribute("aria-keyshortcuts", mac ? "Meta+Z" : "Control+Z");
65
+ toast.append(action);
66
+ let live = true;
67
+ const dispose = () => {
68
+ if (!live)
69
+ return;
70
+ live = false;
71
+ doc.removeEventListener("keydown", onKey);
72
+ toast.removeEventListener("open-changed", onOpen);
73
+ toast.hide();
74
+ toast.remove();
75
+ if (offers.get(doc) === offer)
76
+ offers.delete(doc);
77
+ };
78
+ const undo = () => {
79
+ if (!live)
80
+ return;
81
+ dispose();
82
+ restore();
83
+ options.onRestore?.();
84
+ announce("Restored", "polite", doc);
85
+ };
86
+ const onKey = (event) => {
87
+ if (event.defaultPrevented || event.isComposing || event.shiftKey || event.altKey || !(event.metaKey || event.ctrlKey) || event.key.toLowerCase() !== "z")
88
+ return;
89
+ const editing = event.composedPath().some(target => target instanceof HTMLElement && (target.matches("input, textarea, select, [role=textbox]") || target.isContentEditable));
90
+ if (editing)
91
+ return;
92
+ event.preventDefault();
93
+ undo();
94
+ };
95
+ const onOpen = (event) => { if (!event.detail.open)
96
+ dispose(); };
97
+ const offer = { toast, undo, dispose };
98
+ offers.set(doc, offer);
99
+ action.addEventListener("click", undo);
100
+ toast.addEventListener("open-changed", onOpen);
101
+ doc.addEventListener("keydown", onKey);
102
+ (options.container ?? doc.body).append(toast);
103
+ // Toast owns the one persistent announcement, avoiding duplicate live messages.
104
+ toast.show(`${message}. Undo available with ${shortcut}.`, { duration: options.duration ?? 8000 });
105
+ return offer;
106
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@unofficialbox/box-open-elements",
3
- "version": "0.20.0",
3
+ "version": "0.21.0",
4
4
  "description": "Box Open Elements: an open, framework-agnostic design system and web component library for Box-style experiences",
5
5
  "license": "MIT",
6
6
  "homepage": "https://unofficialbox.github.io/box-open-elements",
@@ -28,6 +28,14 @@
28
28
  "main": "dist/index.js",
29
29
  "types": "dist/index.d.ts",
30
30
  "exports": {
31
+ "./patterns/undo": {
32
+ "types": "./dist/patterns/undo/index.d.ts",
33
+ "import": "./dist/patterns/undo/index.js"
34
+ },
35
+ "./patterns/flow-builder": {
36
+ "types": "./dist/patterns/flow-builder/index.d.ts",
37
+ "import": "./dist/patterns/flow-builder/index.js"
38
+ },
31
39
  ".": {
32
40
  "types": "./dist/index.d.ts",
33
41
  "import": "./dist/index.js"
@@ -173,8 +181,9 @@
173
181
  "dist"
174
182
  ],
175
183
  "scripts": {
184
+ "bundles:check": "bun tools/adapters/bundle-check.ts",
176
185
  "build": "bun run build:core && bun run build:adapters",
177
- "build:core": "tsc -p tsconfig.json",
186
+ "build:core": "tsc -p tsconfig.json && cp src/foundations/icons/glyphs/package.json dist/foundations/icons/glyphs/package.json",
178
187
  "build:adapters": "bun run adapters:version && bun run --cwd packages/react build && bun run --cwd packages/angular build && bun run --cwd packages/vue build && bun run --cwd packages/svelte build",
179
188
  "build:watch": "tsc -p tsconfig.json --watch --preserveWatchOutput",
180
189
  "prepublishOnly": "bun run build",