@unofficialbox/box-open-elements 0.11.0 → 0.12.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.
@@ -22,32 +22,27 @@ const alertStyles = `
22
22
  gap: ${boeSpace[3]};
23
23
  margin: ${boeSpace[3]} 0;
24
24
  padding: 14px 10px;
25
- border: 1px solid var(--boe-token-text-text-secondary, #6f6f6f);
26
25
  border-radius: ${boeRadius.large};
27
26
  background: var(--boe-token-surface-surface-secondary, #f4f4f4);
28
27
  color: var(--boe-token-text-text, #222222);
29
- transition: background ${boeMotionDuration.interactive} ${boeMotionEasing.standard}, border-color ${boeMotionDuration.interactive} ${boeMotionEasing.standard};
28
+ transition: background ${boeMotionDuration.interactive} ${boeMotionEasing.standard};
30
29
  }
31
30
 
32
31
  [part="alert"][data-tone="info"] {
33
32
  background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 10%, #fff);
34
- border-color: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 50%, #fff);
35
33
  }
36
34
 
37
35
  [part="alert"][data-tone="success"] {
38
36
  background: color-mix(in srgb, var(--boe-token-surface-status-surface-success, #26c281) 10%, #fff);
39
- border-color: var(--boe-token-surface-status-surface-success, #26c281);
40
37
  }
41
38
 
42
39
  [part="alert"][data-tone="error"] {
43
40
  background: color-mix(in srgb, var(--boe-token-surface-status-surface-error, #ed3757) 10%, #fff);
44
- border-color: color-mix(in srgb, var(--boe-token-surface-status-surface-error, #ed3757) 50%, #fff);
45
41
  }
46
42
 
47
43
  [part="alert"][data-tone="warning"],
48
44
  [part="alert"][data-tone="inprogress"] {
49
45
  background: color-mix(in srgb, var(--boe-token-surface-status-surface-inprogress, #f5b31b) 10%, #fff);
50
- border-color: color-mix(in srgb, var(--boe-token-surface-status-surface-inprogress, #f5b31b) 50%, #fff);
51
46
  }
52
47
 
53
48
  [part="content"] {
@@ -14,7 +14,6 @@ const nudgeStyles = `
14
14
  align-items: flex-start;
15
15
  gap: 0.55rem;
16
16
  padding: 0.55rem 0.7rem;
17
- border: 1px solid color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 24%, var(--boe-token-surface-surface, #ffffff));
18
17
  border-radius: ${boeRadius.large};
19
18
  background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 7%, var(--boe-token-surface-surface, #ffffff));
20
19
  color: var(--boe-token-text-text, #222222);
@@ -38,12 +38,11 @@ export declare class Toast extends BaseElement {
38
38
  get heading(): string;
39
39
  set heading(value: string);
40
40
  /**
41
- * Drop the outline for a softer, fill-only toast.
41
+ * @deprecated Every toast is borderless now, so this does nothing.
42
42
  *
43
- * Purely presentational and handled entirely in CSS, so it is deliberately
44
- * not an observed attribute — there is nothing to re-render. The default
45
- * stays bordered: that outline tracks box-ui-elements' `.notification` and
46
- * is pinned by the colour conformance manifest.
43
+ * Kept because it shipped in 0.11.0 and removing it would break hosts that
44
+ * set it for no benefit — what they asked for is what they already get. The
45
+ * attribute is still reflected so those hosts read back what they wrote.
47
46
  */
48
47
  get borderless(): boolean;
49
48
  set borderless(value: boolean);
@@ -37,11 +37,18 @@ const toastStyles = `
37
37
  display: none;
38
38
  }
39
39
 
40
- /* Fill, border, text colour and shadow all track box-ui-elements'
41
- .notification and are pinned by the colour conformance manifest — they are
42
- deliberately not derived from the tone accent. The --toast-accent property
43
- exists only to colour the status glyph, which upstream has no equivalent
44
- for, so adding it costs no conformance. */
40
+ /* Fill, text colour and shadow track box-ui-elements' .notification and are
41
+ pinned by the colour conformance manifest — they are deliberately not
42
+ derived from the tone accent. The --toast-accent property exists only to
43
+ colour the status glyph, which upstream has no equivalent for, so adding it
44
+ costs no conformance.
45
+
46
+ There is no border. Upstream .notification has one, and box-open-elements
47
+ matched it until the outline was judged too heavy; the claim that pinned it
48
+ was retired rather than left describing something no longer painted. Tone
49
+ survives that in three places — the tinted fill, the full-strength glyph,
50
+ and the visually-hidden tone label — so it was never carried by the border
51
+ alone. */
45
52
  [part="toast"] {
46
53
  --toast-accent: var(--boe-token-text-text, #222222);
47
54
 
@@ -53,28 +60,14 @@ const toastStyles = `
53
60
  min-height: 48px;
54
61
  max-inline-size: min(100%, 572px);
55
62
  padding: 10px 10px 10px 20px;
56
- border: 2px solid var(--boe-token-text-text, #222222);
57
63
  border-radius: ${boeRadius.large};
58
64
  background: var(--boe-token-surface-surface-secondary, #f4f4f4);
59
65
  color: var(--boe-token-text-text, #222222);
60
66
  box-shadow: 0 2px 6px rgb(0 0 0 / 15%);
61
67
  }
62
68
 
63
- /* Opt-in softer treatment: the outline goes, the geometry does not. Setting
64
- the colour to transparent rather than the width to 0 keeps the 2px in the
65
- box model, so a borderless toast is exactly the size of a bordered one and
66
- the two can sit in the same stack without jumping. The background paints
67
- under the border by default, so the fill simply extends into it.
68
-
69
- The bordered default stays: the 2px solid text-colour rule below is pinned
70
- by the colour conformance manifest against upstream's .notification, and
71
- strict mode fails if that declaration goes. */
72
- :host([borderless]) [part="toast"] {
73
- border-color: transparent;
74
- }
75
-
76
- /* The neutral toast keeps upstream's grey fill and near-black border, so the
77
- glyph is the only place the "this is information" signal can live. */
69
+ /* The neutral toast keeps upstream's grey fill, so the glyph is the only
70
+ place the "this is information" signal can live. */
78
71
  [part="toast"][data-tone="info"] {
79
72
  --toast-accent: var(--boe-token-surface-surface-brand, #0061d5);
80
73
  }
@@ -82,20 +75,17 @@ const toastStyles = `
82
75
  [part="toast"][data-tone="success"] {
83
76
  --toast-accent: var(--boe-token-surface-status-surface-success, #26c281);
84
77
  background: color-mix(in srgb, var(--boe-token-surface-status-surface-success, #26c281) 20%, #fff);
85
- border-color: var(--boe-token-surface-status-surface-success, #26c281);
86
78
  }
87
79
 
88
80
  [part="toast"][data-tone="error"] {
89
81
  --toast-accent: var(--boe-token-surface-status-surface-error, #ed3757);
90
82
  background: color-mix(in srgb, var(--boe-token-surface-status-surface-error, #ed3757) 20%, #fff);
91
- border-color: var(--boe-token-surface-status-surface-error, #ed3757);
92
83
  }
93
84
 
94
85
  [part="toast"][data-tone="warning"],
95
86
  [part="toast"][data-tone="inprogress"] {
96
87
  --toast-accent: var(--boe-token-surface-status-surface-inprogress, #f5b31b);
97
88
  background: color-mix(in srgb, var(--boe-token-surface-status-surface-inprogress, #f5b31b) 20%, #fff);
98
- border-color: var(--boe-token-surface-status-surface-inprogress, #f5b31b);
99
89
  }
100
90
 
101
91
  .sr-only {
@@ -304,12 +294,11 @@ export class Toast extends BaseElement {
304
294
  this.setAttribute("heading", value);
305
295
  }
306
296
  /**
307
- * Drop the outline for a softer, fill-only toast.
297
+ * @deprecated Every toast is borderless now, so this does nothing.
308
298
  *
309
- * Purely presentational and handled entirely in CSS, so it is deliberately
310
- * not an observed attribute — there is nothing to re-render. The default
311
- * stays bordered: that outline tracks box-ui-elements' `.notification` and
312
- * is pinned by the colour conformance manifest.
299
+ * Kept because it shipped in 0.11.0 and removing it would break hosts that
300
+ * set it for no benefit — what they asked for is what they already get. The
301
+ * attribute is still reflected so those hosts read back what they wrote.
313
302
  */
314
303
  get borderless() {
315
304
  return this.hasAttribute("borderless");
@@ -36,6 +36,7 @@ import type { CollaboratorAvatars } from "./patterns/share/collaborator-avatars.
36
36
  import type { ColorPicker } from "./components/forms/color-picker.js";
37
37
  import type { Combobox } from "./components/forms/combobox.js";
38
38
  import type { CommandPalette } from "./components/overlays/command-palette.js";
39
+ import type { CommentThread } from "./patterns/comments/comment-thread.js";
39
40
  import type { CompareView } from "./patterns/diff/compare-view.js";
40
41
  import type { ContactDatalistItem } from "./components/identity/contact-datalist-item.js";
41
42
  import type { ContentExplorer } from "./patterns/content-explorer/content-explorer.js";
@@ -178,6 +179,7 @@ declare global {
178
179
  "box-color-picker": ColorPicker;
179
180
  "box-combobox": Combobox;
180
181
  "box-command-palette": CommandPalette;
182
+ "box-comment-thread": CommentThread;
181
183
  "box-compare-view": CompareView;
182
184
  "box-contact-datalist-item": ContactDatalistItem;
183
185
  "box-content-explorer": ContentExplorer;
@@ -291,4 +293,4 @@ declare global {
291
293
  }
292
294
  }
293
295
  /** Every element tag the library registers, for host-side narrowing. */
294
- export type BoxElementTagName = "box-access-stats" | "box-accordion" | "box-activity-density" | "box-agent-chat" | "box-alert" | "box-annotation-inspector" | "box-annotation-thread" | "box-annotation-toolbar" | "box-app-shell" | "box-audit-log" | "box-avatar" | "box-badge" | "box-badgeable" | "box-bar-chart" | "box-breadcrumb" | "box-bulk-action-bar" | "box-button" | "box-button-group" | "box-calendar" | "box-card" | "box-carousel" | "box-category-selector" | "box-chart-panel" | "box-checkbox" | "box-checkbox-group" | "box-chip" | "box-collaborator-avatars" | "box-color-picker" | "box-combobox" | "box-command-palette" | "box-compare-view" | "box-contact-datalist-item" | "box-content-explorer" | "box-content-picker" | "box-content-sidebar" | "box-content-uploader" | "box-context-menu" | "box-datalist-item" | "box-date-field" | "box-dialog" | "box-diff-viewer" | "box-divider" | "box-grid" | "box-donut-chart" | "box-draggable-list" | "box-drawer" | "box-drop-zone" | "box-dropdown" | "box-dual-listbox" | "box-due-badge" | "box-empty-state" | "box-error-mask" | "box-explorer-action-menu" | "box-explorer-breadcrumbs" | "box-explorer-items" | "box-explorer-list" | "box-explorer-table" | "box-explorer-toolbar" | "box-fieldset" | "box-file-request-builder" | "box-filter-bar" | "box-form-wizard" | "box-governance-panel" | "box-grid-view" | "box-guide-tooltip" | "box-help-text" | "box-icon-button" | "box-illustration" | "box-invite-collaborators-modal" | "box-item-details-panel" | "box-item-form" | "box-line-chart" | "box-lineage-graph" | "box-link-button" | "box-menu" | "box-menu-item" | "box-metadata-filter-builder" | "box-metadata-inspector" | "box-metric-card" | "box-multi-select" | "box-nav-sidebar" | "box-notification-bell" | "box-notification-inbox" | "box-nudge" | "box-number-input" | "box-pagination" | "box-permission-matrix" | "box-persona" | "box-pill-cloud" | "box-pill-selector-dropdown" | "box-popover" | "box-presence" | "box-preview-element" | "box-preview-header" | "box-progress-bar" | "box-progress-ring" | "box-progress-steps" | "box-provenance-strip" | "box-radio-group" | "box-range-slider" | "box-rating" | "box-review-queue-item" | "box-rich-text-input" | "box-run-trace" | "box-saved-view-picker" | "box-search-field" | "box-search-results-header" | "box-section" | "box-segmented-control" | "box-select" | "box-share-panel" | "box-shortcuts-overlay" | "box-sidebar-toggle-button" | "box-signature-ceremony" | "box-skeleton" | "box-slider" | "box-spin-button" | "box-spinner" | "box-split-view" | "box-path" | "box-switch" | "box-table" | "box-tabs" | "box-tag-input" | "box-task-assignment-panel" | "box-text-area" | "box-text-field" | "box-thumbnail-card" | "box-time-field" | "box-timeline" | "box-toast" | "box-tooltip" | "box-tree" | "box-tree-grid" | "box-unified-share-modal" | "box-version-graph" | "box-version-list" | "box-wizard-summary" | "box-work-queue" | "box-workload-board";
296
+ export type BoxElementTagName = "box-access-stats" | "box-accordion" | "box-activity-density" | "box-agent-chat" | "box-alert" | "box-annotation-inspector" | "box-annotation-thread" | "box-annotation-toolbar" | "box-app-shell" | "box-audit-log" | "box-avatar" | "box-badge" | "box-badgeable" | "box-bar-chart" | "box-breadcrumb" | "box-bulk-action-bar" | "box-button" | "box-button-group" | "box-calendar" | "box-card" | "box-carousel" | "box-category-selector" | "box-chart-panel" | "box-checkbox" | "box-checkbox-group" | "box-chip" | "box-collaborator-avatars" | "box-color-picker" | "box-combobox" | "box-command-palette" | "box-comment-thread" | "box-compare-view" | "box-contact-datalist-item" | "box-content-explorer" | "box-content-picker" | "box-content-sidebar" | "box-content-uploader" | "box-context-menu" | "box-datalist-item" | "box-date-field" | "box-dialog" | "box-diff-viewer" | "box-divider" | "box-grid" | "box-donut-chart" | "box-draggable-list" | "box-drawer" | "box-drop-zone" | "box-dropdown" | "box-dual-listbox" | "box-due-badge" | "box-empty-state" | "box-error-mask" | "box-explorer-action-menu" | "box-explorer-breadcrumbs" | "box-explorer-items" | "box-explorer-list" | "box-explorer-table" | "box-explorer-toolbar" | "box-fieldset" | "box-file-request-builder" | "box-filter-bar" | "box-form-wizard" | "box-governance-panel" | "box-grid-view" | "box-guide-tooltip" | "box-help-text" | "box-icon-button" | "box-illustration" | "box-invite-collaborators-modal" | "box-item-details-panel" | "box-item-form" | "box-line-chart" | "box-lineage-graph" | "box-link-button" | "box-menu" | "box-menu-item" | "box-metadata-filter-builder" | "box-metadata-inspector" | "box-metric-card" | "box-multi-select" | "box-nav-sidebar" | "box-notification-bell" | "box-notification-inbox" | "box-nudge" | "box-number-input" | "box-pagination" | "box-permission-matrix" | "box-persona" | "box-pill-cloud" | "box-pill-selector-dropdown" | "box-popover" | "box-presence" | "box-preview-element" | "box-preview-header" | "box-progress-bar" | "box-progress-ring" | "box-progress-steps" | "box-provenance-strip" | "box-radio-group" | "box-range-slider" | "box-rating" | "box-review-queue-item" | "box-rich-text-input" | "box-run-trace" | "box-saved-view-picker" | "box-search-field" | "box-search-results-header" | "box-section" | "box-segmented-control" | "box-select" | "box-share-panel" | "box-shortcuts-overlay" | "box-sidebar-toggle-button" | "box-signature-ceremony" | "box-skeleton" | "box-slider" | "box-spin-button" | "box-spinner" | "box-split-view" | "box-path" | "box-switch" | "box-table" | "box-tabs" | "box-tag-input" | "box-task-assignment-panel" | "box-text-area" | "box-text-field" | "box-thumbnail-card" | "box-time-field" | "box-timeline" | "box-toast" | "box-tooltip" | "box-tree" | "box-tree-grid" | "box-unified-share-modal" | "box-version-graph" | "box-version-list" | "box-wizard-summary" | "box-work-queue" | "box-workload-board";
@@ -0,0 +1 @@
1
+ export * from "../patterns/comments/index.js";
@@ -0,0 +1 @@
1
+ export * from "../patterns/comments/index.js";
package/dist/index.d.ts CHANGED
@@ -110,6 +110,7 @@ export * from "./patterns/versions/index.js";
110
110
  export * from "./patterns/lineage/index.js";
111
111
  export * from "./patterns/agent-chat/index.js";
112
112
  export * from "./patterns/audit/index.js";
113
+ export * from "./patterns/comments/index.js";
113
114
  export * from "./patterns/notifications/index.js";
114
115
  export * from "./patterns/search/index.js";
115
116
  export * from "./patterns/item/index.js";
package/dist/index.js CHANGED
@@ -119,6 +119,7 @@ export * from "./patterns/versions/index.js";
119
119
  export * from "./patterns/lineage/index.js";
120
120
  export * from "./patterns/agent-chat/index.js";
121
121
  export * from "./patterns/audit/index.js";
122
+ export * from "./patterns/comments/index.js";
122
123
  export * from "./patterns/notifications/index.js";
123
124
  // Patterns: compositions and workflow areas
124
125
  export * from "./patterns/search/index.js";
@@ -0,0 +1,79 @@
1
+ import { BaseElement } from "../../core/index.js";
2
+ import type { CommentAction, CommentEntry } from "./types.js";
3
+ /**
4
+ * A comment thread: authored entries, selection, actions, and a composer.
5
+ *
6
+ * Comments are a standalone concept. They hang off a file, a folder, a task or
7
+ * a contract clause just as readily as off a region of a document, so the
8
+ * thread does not know what it is attached to — a host that needs an anchor
9
+ * composes one on top. `box-annotation-thread` is exactly that: this component
10
+ * plus the document anchor, which is the only thing that makes an annotation an
11
+ * annotation.
12
+ *
13
+ * The extension points below (`threadStyles`, `headerExtras`, `defaultHeading`,
14
+ * `emptyText`, `entryBadge`, and the composer copy) exist so a subclass can
15
+ * specialise the chrome without reimplementing entry rendering, selection
16
+ * patching, or the composer.
17
+ */
18
+ export declare class CommentThread extends BaseElement {
19
+ static readonly tagName: string;
20
+ static get observedAttributes(): string[];
21
+ protected titleEl: HTMLElement;
22
+ protected messageEl: HTMLElement;
23
+ protected entriesEl: HTMLElement;
24
+ protected emptyEl: HTMLElement;
25
+ protected actionsEl: HTMLElement;
26
+ protected composerEl: HTMLElement;
27
+ protected composerLabelEl: HTMLElement;
28
+ protected composerSubmitEl: HTMLElement;
29
+ protected composerInputEl: HTMLTextAreaElement;
30
+ private entriesSignature;
31
+ private actionsSignature;
32
+ /** Styles for the thread. Subclasses append rather than replace. */
33
+ protected threadStyles(): string;
34
+ /** Extra markup inside the header, after the message. Empty by default. */
35
+ protected headerExtras(): string;
36
+ /** Heading when the host sets none. */
37
+ protected defaultHeading(): string;
38
+ /** Text shown when there are no entries. */
39
+ protected emptyText(): string;
40
+ /** Label on the composer, and on its submit button. */
41
+ protected defaultComposerLabel(): string;
42
+ /** Placeholder in the composer input. */
43
+ protected defaultPlaceholder(): string;
44
+ /**
45
+ * The pill beside the author. Reads the generic `badge`; a subclass with its
46
+ * own vocabulary overrides this rather than forcing hosts to rename fields.
47
+ */
48
+ protected entryBadge(entry: CommentEntry): string | undefined;
49
+ get actions(): CommentAction[];
50
+ set actions(value: CommentAction[]);
51
+ get composable(): boolean;
52
+ set composable(value: boolean);
53
+ get entries(): CommentEntry[];
54
+ set entries(value: CommentEntry[]);
55
+ get message(): string;
56
+ set message(value: string);
57
+ get selectedEntryId(): string;
58
+ set selectedEntryId(value: string);
59
+ get heading(): string;
60
+ set heading(value: string);
61
+ /** Composer label and submit-button text. */
62
+ get composerLabel(): string;
63
+ set composerLabel(value: string);
64
+ get placeholder(): string;
65
+ set placeholder(value: string);
66
+ protected parseJsonAttribute<T>(name: string, fallback: T): T;
67
+ private emitAction;
68
+ private emitEntrySelected;
69
+ private submitComposer;
70
+ private entriesKey;
71
+ private actionsKey;
72
+ private rebuildEntries;
73
+ private patchEntrySelection;
74
+ private rebuildActions;
75
+ private patchActionLabels;
76
+ protected renderTemplate(): void;
77
+ protected setupListeners(): void;
78
+ protected update(): void;
79
+ }