@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.
- package/dist/components/feedback/alert.js +2 -22
- package/dist/components/feedback/nudge.js +0 -1
- package/dist/components/feedback/path.d.ts +84 -0
- package/dist/components/feedback/path.js +455 -0
- package/dist/components/feedback/skeleton.d.ts +70 -0
- package/dist/components/feedback/skeleton.js +231 -1
- package/dist/components/feedback/toast.d.ts +37 -0
- package/dist/components/feedback/toast.js +182 -17
- package/dist/components/feedback/tone.d.ts +16 -0
- package/dist/components/feedback/tone.js +31 -0
- package/dist/components/layout/grid.d.ts +41 -0
- package/dist/components/layout/grid.js +152 -0
- package/dist/element-maps.d.ts +7 -3
- package/dist/entries/comment-thread.d.ts +1 -0
- package/dist/entries/comment-thread.js +1 -0
- package/dist/entries/grid.d.ts +1 -0
- package/dist/entries/grid.js +1 -0
- package/dist/entries/path.d.ts +1 -0
- package/dist/entries/path.js +1 -0
- package/dist/foundations/layout/grid.d.ts +70 -0
- package/dist/foundations/layout/grid.js +84 -0
- package/dist/foundations/layout/index.d.ts +1 -0
- package/dist/foundations/layout/index.js +3 -0
- package/dist/index.d.ts +5 -1
- package/dist/index.js +6 -1
- package/dist/patterns/audit/audit-log.js +0 -1
- package/dist/patterns/comments/comment-thread.d.ts +79 -0
- package/dist/patterns/comments/comment-thread.js +561 -0
- package/dist/patterns/comments/index.d.ts +2 -0
- package/dist/patterns/comments/index.js +5 -0
- package/dist/patterns/comments/types.d.ts +39 -0
- package/dist/patterns/comments/types.js +8 -0
- package/dist/patterns/lineage/lineage-graph.d.ts +7 -0
- package/dist/patterns/lineage/lineage-graph.js +67 -6
- package/dist/patterns/lineage/provenance-strip.js +106 -15
- package/dist/patterns/notifications/notification-inbox.js +2 -18
- package/dist/patterns/preview/annotation-thread.d.ts +67 -48
- package/dist/patterns/preview/annotation-thread.js +96 -440
- package/dist/patterns/timeline/timeline.js +44 -12
- package/dist/patterns/versions/graph-arrows.d.ts +22 -0
- package/dist/patterns/versions/graph-arrows.js +13 -0
- package/dist/patterns/versions/index.d.ts +1 -0
- package/dist/patterns/versions/index.js +1 -0
- package/dist/patterns/versions/version-graph.d.ts +7 -0
- package/dist/patterns/versions/version-graph.js +54 -6
- package/package.json +1 -1
- package/dist/components/feedback/stage-path.d.ts +0 -44
- package/dist/components/feedback/stage-path.js +0 -235
- package/dist/entries/stage-path.d.ts +0 -1
- 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
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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.
|
|
70
|
+
gap: 0.35rem;
|
|
45
71
|
font: inherit;
|
|
46
|
-
font-size: 0.
|
|
72
|
+
font-size: 0.78rem;
|
|
47
73
|
font-weight: 600;
|
|
48
|
-
padding: 0.
|
|
49
|
-
|
|
50
|
-
|
|
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
|
|
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:
|
|
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
|
-
|
|
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"
|
|
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,
|
|
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(">", ">")
|
|
11
11
|
.replaceAll('"', """)
|
|
12
12
|
.replaceAll("'", "'");
|
|
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)}"
|
|
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 {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
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
|
-
|
|
17
|
-
|
|
18
|
-
|
|
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
|
-
|
|
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
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
private
|
|
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
|
}
|