@unofficialbox/box-open-elements 0.10.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.
Files changed (50) hide show
  1. package/dist/components/feedback/alert.js +2 -22
  2. package/dist/components/feedback/nudge.js +0 -1
  3. package/dist/components/feedback/path.d.ts +84 -0
  4. package/dist/components/feedback/path.js +455 -0
  5. package/dist/components/feedback/skeleton.d.ts +70 -0
  6. package/dist/components/feedback/skeleton.js +231 -1
  7. package/dist/components/feedback/toast.d.ts +37 -0
  8. package/dist/components/feedback/toast.js +182 -17
  9. package/dist/components/feedback/tone.d.ts +16 -0
  10. package/dist/components/feedback/tone.js +31 -0
  11. package/dist/components/layout/grid.d.ts +41 -0
  12. package/dist/components/layout/grid.js +152 -0
  13. package/dist/element-maps.d.ts +7 -3
  14. package/dist/entries/comment-thread.d.ts +1 -0
  15. package/dist/entries/comment-thread.js +1 -0
  16. package/dist/entries/grid.d.ts +1 -0
  17. package/dist/entries/grid.js +1 -0
  18. package/dist/entries/path.d.ts +1 -0
  19. package/dist/entries/path.js +1 -0
  20. package/dist/foundations/layout/grid.d.ts +70 -0
  21. package/dist/foundations/layout/grid.js +84 -0
  22. package/dist/foundations/layout/index.d.ts +1 -0
  23. package/dist/foundations/layout/index.js +3 -0
  24. package/dist/index.d.ts +5 -1
  25. package/dist/index.js +6 -1
  26. package/dist/patterns/audit/audit-log.js +0 -1
  27. package/dist/patterns/comments/comment-thread.d.ts +79 -0
  28. package/dist/patterns/comments/comment-thread.js +561 -0
  29. package/dist/patterns/comments/index.d.ts +2 -0
  30. package/dist/patterns/comments/index.js +5 -0
  31. package/dist/patterns/comments/types.d.ts +39 -0
  32. package/dist/patterns/comments/types.js +8 -0
  33. package/dist/patterns/lineage/lineage-graph.d.ts +7 -0
  34. package/dist/patterns/lineage/lineage-graph.js +67 -6
  35. package/dist/patterns/lineage/provenance-strip.js +106 -15
  36. package/dist/patterns/notifications/notification-inbox.js +2 -18
  37. package/dist/patterns/preview/annotation-thread.d.ts +67 -48
  38. package/dist/patterns/preview/annotation-thread.js +96 -440
  39. package/dist/patterns/timeline/timeline.js +44 -12
  40. package/dist/patterns/versions/graph-arrows.d.ts +22 -0
  41. package/dist/patterns/versions/graph-arrows.js +13 -0
  42. package/dist/patterns/versions/index.d.ts +1 -0
  43. package/dist/patterns/versions/index.js +1 -0
  44. package/dist/patterns/versions/version-graph.d.ts +7 -0
  45. package/dist/patterns/versions/version-graph.js +54 -6
  46. package/package.json +1 -1
  47. package/dist/components/feedback/stage-path.d.ts +0 -44
  48. package/dist/components/feedback/stage-path.js +0 -235
  49. package/dist/entries/stage-path.d.ts +0 -1
  50. package/dist/entries/stage-path.js +0 -1
@@ -1,5 +1,6 @@
1
1
  import { isLineageNodeRecord, resolveLineageDeviation } from "./types.js";
2
2
  import { computeVersionGraphLayout } from "../versions/graph-layout.js";
3
+ import { hasEndArrow, hasStartArrow, resolveGraphArrows } from "../versions/graph-arrows.js";
3
4
  import { formatItemDate } from "../content-explorer/adapters/item-summary.js";
4
5
  import { BaseElement } from "../../core/index.js";
5
6
  import { boeMotionDuration, boeMotionEasing } from "../../foundations/motion/index.js";
@@ -14,6 +15,14 @@ const escapeHtml = (value) => value
14
15
  const LANE_WIDTH = 26;
15
16
  const ROW_HEIGHT = 56;
16
17
  const EDGE_PAD = 8;
18
+ /**
19
+ * How far short of a node's centre an edge stops.
20
+ *
21
+ * The arrowhead marks the path's end vertex, so an edge running to the centre
22
+ * would bury its head under the node disc. The largest node here is ~1.05rem
23
+ * across, so backing off 9px leaves the head just clear of the biggest one.
24
+ */
25
+ const NODE_EDGE_OFFSET = 9;
17
26
  const DEVIATION_LABELS = {
18
27
  none: "in sync",
19
28
  minor: "minor deviation",
@@ -59,6 +68,21 @@ const elementStyles = `
59
68
  pointer-events: none;
60
69
  }
61
70
 
71
+ /* The arrowhead. Same colour as the stroke it terminates, stated
72
+ rather than inherited: context-stroke is not supported everywhere. */
73
+ [part="edge-arrow"] {
74
+ fill: color-mix(in srgb, var(--boe-token-text-text-secondary, #6f6f6f) 45%, transparent);
75
+ stroke: none;
76
+ }
77
+
78
+ [part="edge-arrow"][data-deviation="minor"] {
79
+ fill: color-mix(in srgb, var(--boe-token-surface-status-surface-warning, #f5b31b) 75%, transparent);
80
+ }
81
+
82
+ [part="edge-arrow"][data-deviation="major"] {
83
+ fill: color-mix(in srgb, var(--boe-token-surface-status-surface-error, #ed3757) 70%, transparent);
84
+ }
85
+
62
86
  [part="edge"] {
63
87
  fill: none;
64
88
  stroke: color-mix(in srgb, var(--boe-token-text-text-secondary, #6f6f6f) 45%, transparent);
@@ -196,7 +220,17 @@ const elementStyles = `
196
220
  export class LineageGraph extends BaseElement {
197
221
  static tagName = DEFAULT_TAG_NAME;
198
222
  static get observedAttributes() {
199
- return ["heading", "nodes"];
223
+ return ["arrows", "heading", "nodes"];
224
+ }
225
+ /**
226
+ * Which ends of each edge carry an arrowhead. Defaults to `end`, the head on
227
+ * the derived node, because the layout builds edges source → derived.
228
+ */
229
+ get arrows() {
230
+ return resolveGraphArrows(this.getAttribute("arrows"));
231
+ }
232
+ set arrows(value) {
233
+ this.setAttribute("arrows", value);
200
234
  }
201
235
  nodesValue = [];
202
236
  rovingId = null;
@@ -352,16 +386,43 @@ export class LineageGraph extends BaseElement {
352
386
  const graphHeight = layout.rowCount * ROW_HEIGHT;
353
387
  const centerX = (lane) => EDGE_PAD + lane * LANE_WIDTH + LANE_WIDTH / 2;
354
388
  const centerY = (row) => row * ROW_HEIGHT + ROW_HEIGHT / 2;
389
+ const arrows = this.arrows;
355
390
  const edgePaths = layout.edges
356
391
  .map(edge => {
357
392
  const x1 = centerX(edge.fromLane);
358
393
  const y1 = centerY(edge.fromRow);
359
394
  const x2 = centerX(edge.toLane);
360
395
  const y2 = centerY(edge.toRow);
361
- const d = edge.fromLane === edge.toLane
362
- ? `M ${x1} ${y1} L ${x2} ${y2}`
363
- : `M ${x1} ${y1} C ${x1} ${y1 - ROW_HEIGHT / 2}, ${x2} ${y2 + ROW_HEIGHT / 2}, ${x2} ${y2}`;
364
- return `<path part="edge" data-deviation="${deviationFor(edge.fromId, edge.toId)}" d="${d}"></path>`;
396
+ // One curve rule for every edge, rather than a straight line for
397
+ // same-lane edges and a cubic for lane changes: two rules made the
398
+ // graph read as two different diagrams. A cubic whose ends share an x
399
+ // degenerates to a straight vertical on its own, so same-lane edges
400
+ // still render straight without being a special case.
401
+ //
402
+ // Control points are pulled *along* the direction of travel — half the
403
+ // vertical distance each — so the bend always leaves the parent
404
+ // downward and enters the child from above. The previous version
405
+ // offset them by a fixed half-row in the wrong direction (up from the
406
+ // start, down from the end on a downward edge), so an edge spanning
407
+ // one row bowed backwards into an S while a longer one looked almost
408
+ // straight.
409
+ // Stop at each node's edge rather than its centre. A marker sits on
410
+ // the path's end vertex, so a vertex inside the node disc buries it —
411
+ // and an edge that starts and ends at the rim reads as connecting two
412
+ // nodes rather than as passing through them, which is what React Flow
413
+ // gets from anchoring edges to handles.
414
+ const yStart = y1 + Math.sign(y2 - y1) * NODE_EDGE_OFFSET;
415
+ const yEnd = y2 + Math.sign(y1 - y2) * NODE_EDGE_OFFSET;
416
+ const dy = (yEnd - yStart) / 2;
417
+ const d = `M ${x1} ${yStart} C ${x1} ${yStart + dy}, ${x2} ${yEnd - dy}, ${x2} ${yEnd}`;
418
+ const deviation = deviationFor(edge.fromId, edge.toId);
419
+ // One marker per deviation rather than context-stroke, which is not
420
+ // supported everywhere: an arrowhead in the wrong colour reads as a
421
+ // different edge.
422
+ const marker = deviation === "minor" || deviation === "major" ? `boe-graph-arrow-${deviation}` : "boe-graph-arrow";
423
+ const startMarker = hasStartArrow(arrows) ? ` marker-start="url(#${marker})"` : "";
424
+ const endMarker = hasEndArrow(arrows) ? ` marker-end="url(#${marker})"` : "";
425
+ return `<path part="edge" data-deviation="${deviation}" d="${d}"${startMarker}${endMarker}></path>`;
365
426
  })
366
427
  .join("");
367
428
  const rovingId = this.rovingId && byId.has(this.rovingId)
@@ -415,7 +476,7 @@ export class LineageGraph extends BaseElement {
415
476
  ${layout.placements.length > 0
416
477
  ? `
417
478
  <div part="graph">
418
- <svg part="edges" width="${String(graphWidth)}" height="${String(graphHeight)}" viewBox="0 0 ${String(graphWidth)} ${String(graphHeight)}" aria-hidden="true">${edgePaths}</svg>
479
+ <svg part="edges" width="${String(graphWidth)}" height="${String(graphHeight)}" viewBox="0 0 ${String(graphWidth)} ${String(graphHeight)}" aria-hidden="true"><defs><marker id="boe-graph-arrow" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="4" markerHeight="4" orient="auto-start-reverse"><path part="edge-arrow" d="M 0 0 L 8 4 L 0 8 z"></path></marker><marker id="boe-graph-arrow-minor" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="4" markerHeight="4" orient="auto-start-reverse"><path part="edge-arrow" data-deviation="minor" d="M 0 0 L 8 4 L 0 8 z"></path></marker><marker id="boe-graph-arrow-major" viewBox="0 0 8 8" refX="7" refY="4" markerWidth="4" markerHeight="4" orient="auto-start-reverse"><path part="edge-arrow" data-deviation="major" d="M 0 0 L 8 4 L 0 8 z"></path></marker></defs>${edgePaths}</svg>
419
480
  <ol part="rows" role="list">${rows}</ol>
420
481
  </div>
421
482
  `
@@ -21,37 +21,100 @@ const elementStyles = `
21
21
  font: inherit;
22
22
  }
23
23
 
24
+ /* Read as a flow diagram rather than a breadcrumb. The anatomy is
25
+ React Flow's, taken from its stylesheet: nodes are bordered boxes
26
+ with a small radius (not pills), ports are 6px circles sitting on
27
+ the node's edge, and the connection between them is a drawn edge
28
+ with an arrowhead rather than a text glyph.
29
+
30
+ The canvas dot grid is the other half of the signal — a node graph
31
+ reads as a canvas, not as a line of text. */
24
32
  [part="strip"] {
25
33
  display: flex;
26
- flex-wrap: wrap;
34
+ /* A canvas scrolls; it does not reflow. Wrapping put an edge at the
35
+ start of the second line with its arrow pointing into nothing,
36
+ which reads as broken rather than as a continuation. */
37
+ flex-wrap: nowrap;
38
+ overflow-x: auto;
27
39
  align-items: center;
28
- gap: 0.35rem;
40
+ gap: 0;
29
41
  margin: 0;
30
- padding: 0;
42
+ padding: 0.75rem;
31
43
  list-style: none;
44
+ border-radius: ${boeRadius.large};
45
+ background-image: radial-gradient(
46
+ color-mix(in srgb, var(--boe-token-stroke-stroke, #e8e8e8) 85%, transparent) 1px,
47
+ transparent 1px
48
+ );
49
+ background-size: 12px 12px;
50
+ background-position: -1px -1px;
32
51
  }
33
52
 
34
53
  [part="item"] {
35
54
  display: inline-flex;
36
55
  align-items: center;
37
- gap: 0.35rem;
56
+ /* No shrinking: with nowrap a long chain must scroll, not compress
57
+ the nodes until their labels ellipsize. */
58
+ flex: 0 0 auto;
38
59
  }
39
60
 
61
+ /* The node. React Flow's default: 10px padding, a small radius, a 1px
62
+ border and a centred 12px label. Width is left to the content —
63
+ React Flow fixes it at 150px because it lays out on a free canvas,
64
+ whereas this strip is a row in a header and the labels are short. */
40
65
  [part="chip"] {
41
66
  appearance: none;
67
+ position: relative;
42
68
  display: inline-flex;
43
69
  align-items: center;
44
- gap: 0.3rem;
70
+ gap: 0.35rem;
45
71
  font: inherit;
46
- font-size: 0.8rem;
72
+ font-size: 0.78rem;
47
73
  font-weight: 600;
48
- padding: 0.22rem 0.55rem;
49
- border-radius: 999px;
50
- border: 1px solid color-mix(in srgb, var(--boe-token-stroke-stroke, #e8e8e8) 60%, transparent);
74
+ padding: 0.4rem 0.6rem;
75
+ /* 4px, the nearest token to React Flow's 3px. The control radius is
76
+ 20px here, which rendered the nodes as stadium pills — the shape
77
+ the strip was moving away from. */
78
+ border-radius: ${boeRadius.size};
79
+ border: 1px solid color-mix(in srgb, var(--boe-token-stroke-stroke, #e8e8e8) 90%, var(--boe-token-text-text, #222222));
51
80
  background: var(--boe-token-surface-surface, #ffffff);
52
- color: var(--boe-token-text-text-secondary, #6f6f6f);
81
+ color: var(--boe-token-text-text, #222222);
82
+ box-shadow: 0 1px 2px rgb(0 0 0 / 6%);
53
83
  cursor: pointer;
54
- transition: background ${boeMotionDuration.interactive} ${boeMotionEasing.standard};
84
+ transition: background ${boeMotionDuration.interactive} ${boeMotionEasing.standard},
85
+ border-color ${boeMotionDuration.interactive} ${boeMotionEasing.standard};
86
+ }
87
+
88
+ /* Ports. 6px circles straddling the node's edge, ringed in the surface
89
+ colour so they read as attached to the node rather than floating —
90
+ the same construction React Flow uses for its handles. */
91
+ [part="chip"]::before,
92
+ [part="chip"]::after {
93
+ content: "";
94
+ position: absolute;
95
+ inset-block-start: 50%;
96
+ inline-size: 6px;
97
+ block-size: 6px;
98
+ border-radius: 100%;
99
+ background: var(--boe-token-text-text-secondary, #6f6f6f);
100
+ border: 1px solid var(--boe-token-surface-surface, #ffffff);
101
+ transform: translateY(-50%);
102
+ }
103
+
104
+ [part="chip"]::before {
105
+ inset-inline-start: -4px;
106
+ }
107
+
108
+ [part="chip"]::after {
109
+ inset-inline-end: -4px;
110
+ }
111
+
112
+ /* The first node has nothing feeding it and the last nothing leaving
113
+ it, so they carry one port each — React Flow's input and output
114
+ nodes do the same. */
115
+ [part="item"]:first-child [part="chip"]::before,
116
+ [part="item"]:last-child [part="chip"]::after {
117
+ display: none;
55
118
  }
56
119
 
57
120
  [part="chip"]:hover {
@@ -59,15 +122,19 @@ const elementStyles = `
59
122
  }
60
123
 
61
124
  [part="chip"][aria-current="true"] {
62
- border-color: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 45%, transparent);
125
+ border-color: var(--boe-token-surface-surface-brand, #0061d5);
63
126
  color: var(--boe-token-surface-surface-brand, #0061d5);
64
127
  background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 8%, var(--boe-token-surface-surface, #ffffff));
65
128
  }
66
129
 
130
+ [part="chip"][aria-current="true"]::before,
131
+ [part="chip"][aria-current="true"]::after {
132
+ background: var(--boe-token-surface-surface-brand, #0061d5);
133
+ }
134
+
67
135
  [part="chip"]:focus-visible {
68
136
  outline: none;
69
137
  box-shadow: 0 0 0 3px color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 18%, transparent);
70
- border-radius: ${boeRadius.large};
71
138
  }
72
139
 
73
140
  [part="kind-dot"] {
@@ -85,10 +152,34 @@ const elementStyles = `
85
152
  border-radius: 2px;
86
153
  }
87
154
 
155
+ /* The edge: a drawn line between two ports with an arrowhead, in place
156
+ of the "→" character the strip used to print. Two co-linear handles
157
+ are exactly the case where React Flow's bezier degenerates to a
158
+ straight line, so a straight edge is the faithful shape here rather
159
+ than a simplification. */
88
160
  [part="separator"] {
89
- color: var(--boe-token-text-text-secondary, #6f6f6f);
161
+ position: relative;
162
+ display: inline-flex;
163
+ align-items: center;
164
+ inline-size: 1.6rem;
165
+ block-size: 2px;
166
+ margin-inline: 4px;
167
+ background: color-mix(in srgb, var(--boe-token-stroke-stroke, #e8e8e8) 90%, var(--boe-token-text-text, #222222));
90
168
  user-select: none;
91
169
  }
170
+
171
+ [part="separator"]::after {
172
+ content: "";
173
+ position: absolute;
174
+ inset-inline-end: -1px;
175
+ inset-block-start: 50%;
176
+ inline-size: 0;
177
+ block-size: 0;
178
+ border-block: 4px solid transparent;
179
+ border-inline-start: 6px solid color-mix(in srgb, var(--boe-token-stroke-stroke, #e8e8e8) 90%, var(--boe-token-text-text, #222222));
180
+ transform: translateY(-50%);
181
+ }
182
+
92
183
  `;
93
184
  /**
94
185
  * The cheap, high-frequency lineage sibling: a linear ancestry strip
@@ -175,7 +266,7 @@ export class ProvenanceStrip extends BaseElement {
175
266
  const kind = node.kind ?? "";
176
267
  return `
177
268
  <li part="item"${kind ? ` data-kind="${escapeHtml(kind)}"` : ""}>
178
- ${index > 0 ? `<span part="separator" aria-hidden="true">→</span>` : ""}
269
+ ${index > 0 ? `<span part="separator" aria-hidden="true"></span>` : ""}
179
270
  <button
180
271
  type="button"
181
272
  part="chip"
@@ -1,4 +1,4 @@
1
- import { countUnreadNotifications, groupNotifications, isNotificationItemRecord, resolveNotificationFilter, resolveNotificationTone, } from "./types.js";
1
+ import { countUnreadNotifications, groupNotifications, isNotificationItemRecord, resolveNotificationFilter, } from "./types.js";
2
2
  import { BaseElement } from "../../core/index.js";
3
3
  import { isSafeHref } from "../internal/safe-href.js";
4
4
  import { boePanel, boeRadius } from "../../foundations/geometry/index.js";
@@ -10,20 +10,6 @@ const escapeHtml = (value) => value
10
10
  .replaceAll(">", "&gt;")
11
11
  .replaceAll('"', "&quot;")
12
12
  .replaceAll("'", "&#39;");
13
- const toneColor = (tone) => {
14
- switch (tone) {
15
- case "brand":
16
- return "var(--boe-token-surface-surface-brand, #0061d5)";
17
- case "success":
18
- return "var(--boe-token-surface-status-surface-success, #26a27b)";
19
- case "warning":
20
- return "var(--boe-token-surface-status-surface-warning, #f5b31b)";
21
- case "error":
22
- return "var(--boe-token-surface-status-surface-error, #ed3757)";
23
- default:
24
- return "var(--boe-token-text-text-secondary, #6f6f6f)";
25
- }
26
- };
27
13
  const elementStyles = `
28
14
  [hidden] {
29
15
  display: none !important;
@@ -160,7 +146,6 @@ const elementStyles = `
160
146
  align-items: start;
161
147
  padding: 0.5rem 0.55rem;
162
148
  border-radius: ${boeRadius.med};
163
- border-left: 3px solid var(--notification-tone, transparent);
164
149
  background: color-mix(in srgb, var(--boe-token-surface-surface-brand, #0061d5) 6%, transparent);
165
150
  transition: background ${boeMotionDuration.interactive} ${boeMotionEasing.standard};
166
151
  }
@@ -381,7 +366,6 @@ export class NotificationInbox extends BaseElement {
381
366
  this.dispatchEvent(new CustomEvent(name, { bubbles: true, composed: true, detail }));
382
367
  }
383
368
  itemHtml(item) {
384
- const tone = resolveNotificationTone(item.tone);
385
369
  const read = Boolean(item.read);
386
370
  const entity = item.entityRef;
387
371
  const entityHtml = entity
@@ -390,7 +374,7 @@ export class NotificationInbox extends BaseElement {
390
374
  : `<span part="entity">${escapeHtml(entity.label)}</span>`
391
375
  : "";
392
376
  return `
393
- <li part="item" data-item-id="${escapeHtml(item.id)}" data-read="${String(read)}" data-type="${escapeHtml(item.type)}" style="--notification-tone:${toneColor(tone)};">
377
+ <li part="item" data-item-id="${escapeHtml(item.id)}" data-read="${String(read)}" data-type="${escapeHtml(item.type)}">
394
378
  <span part="unread-dot" aria-hidden="true"></span>
395
379
  <span part="item-body">
396
380
  <button type="button" part="item-title" data-item-id="${escapeHtml(item.id)}">${escapeHtml(item.title)}</button>
@@ -1,57 +1,76 @@
1
- import { BaseElement } from "../../core/index.js";
2
- export type AnnotationThreadAction = {
3
- id: string;
4
- label: string;
5
- tone?: string;
6
- };
7
- export type AnnotationThreadEntry = {
8
- author: string;
9
- body: string;
10
- createdAt?: string;
11
- id: string;
12
- initials?: string;
13
- status?: string;
1
+ import { CommentThread } from "../comments/index.js";
2
+ import type { CommentAction, CommentEntry, CommentSubmittedDetail } from "../comments/index.js";
3
+ /** @deprecated Prefer `CommentAction`; kept so existing hosts keep compiling. */
4
+ export type AnnotationThreadAction = CommentAction;
5
+ /** @deprecated Prefer `CommentSubmittedDetail`. */
6
+ export type AnnotationThreadEntrySubmittedDetail = CommentSubmittedDetail;
7
+ /**
8
+ * An annotation comment.
9
+ *
10
+ * A comment plus `toolLabel` — which annotation tool produced it (highlight,
11
+ * draw, stamp). That field is the only thing an annotation entry adds, which is
12
+ * why the rest of the model lives in `patterns/comments`.
13
+ */
14
+ export type AnnotationThreadEntry = CommentEntry & {
14
15
  toolLabel?: string;
15
16
  };
16
- export type AnnotationThreadEntrySubmittedDetail = {
17
- body: string;
18
- inReplyToId: string | null;
17
+ /**
18
+ * Where in the document a thread is attached.
19
+ *
20
+ * Every field is optional because anchors arrive in different shapes: a page
21
+ * number alone for a page-level note, a region for a drawn box, a quote for
22
+ * selected text. A thread with no anchor at all is a comment, and belongs on
23
+ * `box-comment-thread` instead.
24
+ */
25
+ export type AnnotationAnchor = {
26
+ page?: number;
27
+ quote?: string;
28
+ region?: {
29
+ height: number;
30
+ width: number;
31
+ x: number;
32
+ y: number;
33
+ };
19
34
  };
20
- export declare class AnnotationThread extends BaseElement {
35
+ /**
36
+ * A comment thread anchored to a place in a document.
37
+ *
38
+ * This is `box-comment-thread` plus the anchor. The distinction is the whole
39
+ * point: comments stand on their own — on a file, a task, a contract clause —
40
+ * and only become annotations when something ties them to a page, a region, or
41
+ * a run of selected text. Hosts that want the former should reach for
42
+ * `box-comment-thread` directly rather than for an annotation with no anchor.
43
+ *
44
+ * Every attribute, part and event of the underlying thread is inherited
45
+ * unchanged, so this remains a drop-in for the previous implementation.
46
+ */
47
+ export declare class AnnotationThread extends CommentThread {
21
48
  static readonly tagName: string;
22
49
  static get observedAttributes(): string[];
23
- private titleEl;
24
- private messageEl;
25
- private entriesEl;
26
- private emptyEl;
27
- private actionsEl;
28
- private composerEl;
29
- private composerInputEl;
30
- private entriesSignature;
31
- private actionsSignature;
32
- get actions(): AnnotationThreadAction[];
33
- set actions(value: AnnotationThreadAction[]);
34
- get composable(): boolean;
35
- set composable(value: boolean);
50
+ private anchorEl;
51
+ protected threadStyles(): string;
52
+ protected headerExtras(): string;
53
+ protected defaultHeading(): string;
54
+ protected emptyText(): string;
55
+ protected defaultComposerLabel(): string;
56
+ protected defaultPlaceholder(): string;
57
+ /**
58
+ * Annotations name their pill `toolLabel`. Mapping it here keeps that
59
+ * vocabulary for existing hosts while the base model stays generic.
60
+ */
61
+ protected entryBadge(entry: AnnotationThreadEntry): string | undefined;
62
+ /** Where in the document this thread sits. Null when unanchored. */
63
+ get anchor(): AnnotationAnchor | null;
64
+ set anchor(value: AnnotationAnchor | null);
36
65
  get entries(): AnnotationThreadEntry[];
37
66
  set entries(value: AnnotationThreadEntry[]);
38
- get message(): string;
39
- set message(value: string);
40
- get selectedEntryId(): string;
41
- set selectedEntryId(value: string);
42
- get heading(): string;
43
- set heading(value: string);
44
- private parseJsonAttribute;
45
- private emitAction;
46
- private emitEntrySelected;
47
- private submitComposer;
48
- private entriesKey;
49
- private actionsKey;
50
- private rebuildEntries;
51
- private patchEntrySelection;
52
- private rebuildActions;
53
- private patchActionLabels;
54
- protected renderTemplate(): void;
55
- protected setupListeners(): void;
67
+ /**
68
+ * The anchor in words.
69
+ *
70
+ * A region is described by its page rather than by its coordinates: the
71
+ * numbers locate the highlight for the renderer, but they tell a reader
72
+ * nothing, and a screen reader least of all.
73
+ */
74
+ private anchorLocation;
56
75
  protected update(): void;
57
76
  }