@crewlethq/ui 0.86.0 → 0.87.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/ArtifactCard/index.js +3 -3
- package/dist/DeliveryReceipt/DeliveryReceipt.d.ts +85 -0
- package/dist/DeliveryReceipt/index.d.ts +4 -0
- package/dist/DeliveryReceipt/index.js +3 -0
- package/dist/DeliveryReceipt-RMZW2DMT.css +46 -0
- package/dist/InboxList/InboxList.d.ts +14 -3
- package/dist/InboxList/index.js +1 -1
- package/dist/{InboxList-X5Q5WWAI.css → InboxList-NVPIL3WU.css} +61 -28
- package/dist/ListDetail/index.js +1 -1
- package/dist/{ListDetail-Q7SFVKSO.css → ListDetail-WXBCLONL.css} +7 -1
- package/dist/PresenterView/index.js +2 -2
- package/dist/RailList/index.js +2 -2
- package/dist/RichEditor/index.js +1 -1
- package/dist/SetupWizard/index.js +2 -2
- package/dist/{chunk-3AMWXJQX.js → chunk-AUSFKGKL.js} +1 -1
- package/dist/chunk-NGJWRR7E.js +106 -0
- package/dist/{chunk-SNJM5KPV.js → chunk-P33VNG7Q.js} +1 -1
- package/dist/{chunk-F6ZUM66S.js → chunk-VKNZQB2G.js} +44 -23
- package/dist/generated/index.d.ts +1 -0
- package/dist/generated/index.js +45 -44
- package/dist/index.js +45 -44
- package/dist/styles.css +119 -31
- package/package.json +3 -3
- package/dist/{Editor-VGNB35NJ.js → Editor-5D5Z3LBQ.js} +1 -1
- package/dist/{chunk-WRZPO4YL.js → chunk-3BVNNQZY.js} +1 -1
- package/dist/{chunk-7IWZN5Q2.js → chunk-CWCQCOIG.js} +1 -1
- package/dist/{chunk-PAGITACP.js → chunk-DWZCMMRX.js} +0 -0
- package/dist/{chunk-WCJTOKTY.js → chunk-LMEMH6DO.js} +1 -1
- package/dist/{chunk-REWKR3S4.js → chunk-M576OESX.js} +1 -1
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
export { ArtifactCard, ArtifactCardSkeleton, ArtifactPreviewGlyph } from '../chunk-
|
|
1
|
+
export { ArtifactCard, ArtifactCardSkeleton, ArtifactPreviewGlyph } from '../chunk-CWCQCOIG.js';
|
|
2
2
|
import '../chunk-I4IUX3JF.js';
|
|
3
3
|
import '../chunk-HF5L56YQ.js';
|
|
4
4
|
import '../chunk-EJNJMHQG.js';
|
|
5
5
|
import '../chunk-RE3FBGQQ.js';
|
|
6
|
-
import '../chunk-U2IQNDDR.js';
|
|
7
|
-
import '../chunk-AV2DXAEL.js';
|
|
8
6
|
import '../chunk-YTLWOHOY.js';
|
|
9
7
|
import '../chunk-XZY6S3UC.js';
|
|
8
|
+
import '../chunk-U2IQNDDR.js';
|
|
9
|
+
import '../chunk-AV2DXAEL.js';
|
|
10
10
|
import '../chunk-J5T5TDM2.js';
|
|
11
11
|
import '../chunk-YQ7Q52XU.js';
|
|
12
12
|
import '../chunk-DOY3KC6I.js';
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { HTMLAttributes, ReactNode } from "react";
|
|
2
|
+
/** One seat a message reached, or will reach. */
|
|
3
|
+
export interface DeliveryReceiptRecipient {
|
|
4
|
+
/** A stable key for the seat: its handle. */
|
|
5
|
+
id: string;
|
|
6
|
+
/** How the reader knows the seat: "pm", "Product Manager". */
|
|
7
|
+
name: string;
|
|
8
|
+
/**
|
|
9
|
+
* Why the message reached the seat, in the caller's words, drawn in
|
|
10
|
+
* brackets after the seats that share it: "every message". Leave it out
|
|
11
|
+
* where the reason needs no note (a mention, a reply to their thread).
|
|
12
|
+
*/
|
|
13
|
+
reason?: string | undefined;
|
|
14
|
+
/** The seat has answered: it replied in the thread, or in the conversation. */
|
|
15
|
+
answered?: boolean | undefined;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* `sent` is a receipt under a message that was posted ("Reached pm"); `draft`
|
|
19
|
+
* is the composer's word on what a post will do before it is sent ("Will
|
|
20
|
+
* reach pm").
|
|
21
|
+
*/
|
|
22
|
+
export type DeliveryReceiptTense = "sent" | "draft";
|
|
23
|
+
export interface DeliveryReceiptLabels {
|
|
24
|
+
/** The reach of a posted message: "Reached pm; qa, sre (every message)". */
|
|
25
|
+
reached: (who: string) => string;
|
|
26
|
+
/** The reach of a draft: "Will reach pm". */
|
|
27
|
+
reaches: (who: string) => string;
|
|
28
|
+
/** A posted message that reached no agent. */
|
|
29
|
+
none: string;
|
|
30
|
+
/** A draft that will reach no agent. */
|
|
31
|
+
noneDraft: string;
|
|
32
|
+
/** The seats that answered: "pm answered". */
|
|
33
|
+
answered: (who: string) => string;
|
|
34
|
+
/** The seats in one reason's group: "qa, sre". */
|
|
35
|
+
list: (names: readonly string[]) => string;
|
|
36
|
+
/** One reason's note: "(every message)". */
|
|
37
|
+
reason: (words: string) => string;
|
|
38
|
+
/** The groups of different reasons, joined: "pm; qa, sre (every message)". */
|
|
39
|
+
groups: (groups: readonly string[]) => string;
|
|
40
|
+
/** A routing cap left seats out. */
|
|
41
|
+
truncated: string;
|
|
42
|
+
}
|
|
43
|
+
export declare const DELIVERY_RECEIPT_LABELS: DeliveryReceiptLabels;
|
|
44
|
+
export interface DeliveryReceiptProps extends Omit<HTMLAttributes<HTMLElement>, "role" | "children"> {
|
|
45
|
+
/** The seats, in the order the routing reached them. Empty is "no agent". */
|
|
46
|
+
recipients: readonly DeliveryReceiptRecipient[];
|
|
47
|
+
/** `sent` (the default) under a message, `draft` over a composer. */
|
|
48
|
+
tense?: DeliveryReceiptTense | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* A routing cap left seats out (a whole-room address in a very large
|
|
51
|
+
* room), so the list is not everybody the message named.
|
|
52
|
+
*/
|
|
53
|
+
truncated?: boolean | undefined;
|
|
54
|
+
/**
|
|
55
|
+
* A short sentence after a "no agent" line, saying why or what to do:
|
|
56
|
+
* "This room has no agent members. Mention one to ask it."
|
|
57
|
+
*/
|
|
58
|
+
hint?: ReactNode;
|
|
59
|
+
/**
|
|
60
|
+
* Whether the line is its own polite live region (false by default). A
|
|
61
|
+
* composer's draft line that changes as a mention is typed is announced
|
|
62
|
+
* by passing true; a receipt in a transcript is not, since a log that
|
|
63
|
+
* announced every receipt would talk over the conversation.
|
|
64
|
+
*/
|
|
65
|
+
announce?: boolean | undefined;
|
|
66
|
+
labels?: Partial<DeliveryReceiptLabels> | undefined;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Who a person's message reached, and who answered: "Reached pm", then "pm
|
|
70
|
+
* answered"; "Reached qa, sre (every message)"; "Reached no agent". Over a
|
|
71
|
+
* composer, the same line in the future tense says who a post WILL reach
|
|
72
|
+
* before it is sent.
|
|
73
|
+
*
|
|
74
|
+
* QUIET BY DESIGN. It sits in a message's footer at the compact step in the
|
|
75
|
+
* tertiary ink, because it is a fact a person checks rather than reads: the
|
|
76
|
+
* one tone it raises is the warning on a message that reached no agent, the
|
|
77
|
+
* case where a person would otherwise wait for an answer nobody was asked
|
|
78
|
+
* for. Colour is never alone: the mark and the words say it.
|
|
79
|
+
*
|
|
80
|
+
* ONE STOP TO A SCREEN READER: the parts are spans in one paragraph, so a
|
|
81
|
+
* reader moving through the log hears "Reached pm. pm answered" at once. The
|
|
82
|
+
* middle dot the eye reads between the parts is hidden from it, and a full
|
|
83
|
+
* stop only it hears stands in its place; the marks are hidden too.
|
|
84
|
+
*/
|
|
85
|
+
export declare function DeliveryReceipt({ recipients, tense, truncated, hint, announce, labels: overrides, className, ...rest }: DeliveryReceiptProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import "../ChatMessage/ChatScale.css";
|
|
2
|
+
import "./DeliveryReceipt.css";
|
|
3
|
+
export { DELIVERY_RECEIPT_LABELS, DeliveryReceipt } from "./DeliveryReceipt.js";
|
|
4
|
+
export type { DeliveryReceiptLabels, DeliveryReceiptProps, DeliveryReceiptRecipient, DeliveryReceiptTense, } from "./DeliveryReceipt.js";
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Who a person's message reached and who answered, under its words; and the
|
|
3
|
+
* same line over a composer, before the message is sent.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
.crewlet-delivery-receipt {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-wrap: wrap;
|
|
9
|
+
align-items: center;
|
|
10
|
+
column-gap: var(--spacing-1);
|
|
11
|
+
max-width: 100%;
|
|
12
|
+
margin: 0;
|
|
13
|
+
color: var(--color-text-tertiary);
|
|
14
|
+
font-size: var(--crewlet-chat-meta);
|
|
15
|
+
line-height: var(--font-line-height-snug);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.crewlet-delivery-receipt__part {
|
|
19
|
+
display: inline-flex;
|
|
20
|
+
align-items: center;
|
|
21
|
+
gap: var(--spacing-1);
|
|
22
|
+
min-width: 0;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.crewlet-delivery-receipt__mark {
|
|
26
|
+
display: inline-flex;
|
|
27
|
+
flex: none;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
.crewlet-delivery-receipt__answered {
|
|
31
|
+
color: var(--color-text-secondary);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/* The one raised tone: a message nobody was asked to answer. Its mark takes
|
|
35
|
+
the warning ink, its words the secondary ink; the hint stays quiet. */
|
|
36
|
+
.crewlet-delivery-receipt--none {
|
|
37
|
+
color: var(--color-text-secondary);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.crewlet-delivery-receipt--none .crewlet-delivery-receipt__mark {
|
|
41
|
+
color: var(--color-feedback-warning-ink);
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
.crewlet-delivery-receipt__hint {
|
|
45
|
+
color: var(--color-text-tertiary);
|
|
46
|
+
}
|
|
@@ -73,13 +73,23 @@ export type InboxRowTone = 'default' | 'danger';
|
|
|
73
73
|
export interface InboxRowProps extends Omit<LiHTMLAttributes<HTMLLIElement>, 'onClick' | 'title'> {
|
|
74
74
|
/** Who the row is from: a seat's or a person's name. */
|
|
75
75
|
title: ReactNode;
|
|
76
|
-
/**
|
|
76
|
+
/**
|
|
77
|
+
* After the name, in the quiet ink: a word where the row is not a plain
|
|
78
|
+
* question or update ("coding run", "stopped"), or what the person did
|
|
79
|
+
* ("replied to a thread in Design"). The name and the qualifier read as one
|
|
80
|
+
* run of words that wraps to a second line before it stops, so a long
|
|
81
|
+
* qualifier never hides the name.
|
|
82
|
+
*/
|
|
77
83
|
qualifier?: ReactNode;
|
|
78
84
|
/** `danger` sets the qualifier in the danger ink, for a seat that has stopped. */
|
|
79
85
|
qualifierTone?: InboxRowTone | undefined;
|
|
80
86
|
/** At the end of the first line: when it arrived. */
|
|
81
87
|
meta?: ReactNode;
|
|
82
|
-
/**
|
|
88
|
+
/**
|
|
89
|
+
* Before the words: an avatar or a mark, at the target size. Its slot is at
|
|
90
|
+
* least a target square and grows to fit a larger mark, such as a 32px face,
|
|
91
|
+
* with the name's line beside its top.
|
|
92
|
+
*/
|
|
83
93
|
leading?: ReactNode;
|
|
84
94
|
/** What the row says, in up to three lines. */
|
|
85
95
|
children?: ReactNode;
|
|
@@ -159,7 +169,8 @@ export interface InboxRowProps extends Omit<LiHTMLAttributes<HTMLLIElement>, 'on
|
|
|
159
169
|
* caller names in the head (`status`): every word stays legible, and the
|
|
160
170
|
* state is never carried by a decoration alone.
|
|
161
171
|
*
|
|
162
|
-
* NOTHING IS CUT AT THE EDGE. The name
|
|
172
|
+
* NOTHING IS CUT AT THE EDGE. The name and its qualifier wrap to two lines
|
|
173
|
+
* before they stop, the time keeps a column of its own and never wraps, and
|
|
163
174
|
* the words take up to three lines before they stop, so a row says what it is
|
|
164
175
|
* rather than its first few words.
|
|
165
176
|
*/
|
package/dist/InboxList/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { INBOX_ROW_LEAVE, InboxGroup, InboxList, InboxMore, InboxRow, InboxToggle } from '../chunk-
|
|
1
|
+
export { INBOX_ROW_LEAVE, InboxGroup, InboxList, InboxMore, InboxRow, InboxToggle } from '../chunk-VKNZQB2G.js';
|
|
2
2
|
import '../chunk-RK4XPHVG.js';
|
|
3
3
|
import '../chunk-6C7GQOBV.js';
|
|
4
4
|
import '../chunk-PCAT2EFB.js';
|
|
@@ -223,19 +223,36 @@
|
|
|
223
223
|
}
|
|
224
224
|
|
|
225
225
|
/*
|
|
226
|
-
*
|
|
227
|
-
*
|
|
228
|
-
*
|
|
229
|
-
*
|
|
230
|
-
* row's edge
|
|
226
|
+
* THE LEADING SLOT FITS WHAT IT HOLDS. It is at least a target square (and at
|
|
227
|
+
* least a line tall), with its mark centred in it, and it grows to a larger
|
|
228
|
+
* mark, such as a 32px face, rather than letting it spill: a fixed one-line
|
|
229
|
+
* box let a 32px face overflow it by 8px, up and to the left, until it all but
|
|
230
|
+
* touched the row's edge.
|
|
231
|
+
*
|
|
232
|
+
* THE NAME'S LINE IS CENTRED ON A TARGET-SIZED MARK by moving the words down
|
|
233
|
+
* rather than the mark up: the words start half the difference between the
|
|
234
|
+
* target and a line lower, and the control's top pad is that much shorter, so
|
|
235
|
+
* a row with a target-sized avatar keeps its height and its name where they
|
|
236
|
+
* were, with the avatar inside the control instead of over its pad. A larger
|
|
237
|
+
* mark hangs from the same top, beside the name's line and the one under it.
|
|
231
238
|
*/
|
|
239
|
+
.crewlet-inbox-row__control--leading {
|
|
240
|
+
--crewlet-inbox-row-lift: max(0px, (var(--size-target-min) - 1lh) / 2);
|
|
241
|
+
|
|
242
|
+
padding-top: calc(var(--spacing-2) + var(--spacing-1) / 2 - var(--crewlet-inbox-row-lift));
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
.crewlet-inbox-row__control--leading > .crewlet-inbox-row__main {
|
|
246
|
+
padding-top: var(--crewlet-inbox-row-lift);
|
|
247
|
+
}
|
|
248
|
+
|
|
232
249
|
.crewlet-inbox-row__leading {
|
|
233
250
|
display: inline-flex;
|
|
234
251
|
flex: none;
|
|
235
252
|
align-items: center;
|
|
236
253
|
justify-content: center;
|
|
237
|
-
width: var(--size-target-min);
|
|
238
|
-
height: 1lh;
|
|
254
|
+
min-width: var(--size-target-min);
|
|
255
|
+
min-height: max(var(--size-target-min), 1lh);
|
|
239
256
|
}
|
|
240
257
|
|
|
241
258
|
.crewlet-inbox-row__main {
|
|
@@ -245,24 +262,49 @@
|
|
|
245
262
|
min-width: 0;
|
|
246
263
|
}
|
|
247
264
|
|
|
265
|
+
/*
|
|
266
|
+
* THE HEAD IS ONE RUN OF WORDS: who, then what they did, wrapping as words do
|
|
267
|
+
* and stopping at two lines with an ellipsis. The name comes first, so it is
|
|
268
|
+
* the last thing a long qualifier can push out of sight. As one line of boxes
|
|
269
|
+
* the name was the only one allowed to shrink, so a qualifier longer than a
|
|
270
|
+
* word ("replied to a thread in Product Manager") squeezed the name to
|
|
271
|
+
* nothing and pushed the time past the row's edge.
|
|
272
|
+
*
|
|
273
|
+
* THE TIME FLOATS AT THE END OF THE FIRST LINE, so only that line gives up
|
|
274
|
+
* room to it and the second runs the row's full width: "replied to a thread
|
|
275
|
+
* in #engineering" keeps the room's name, the part of the line most worth
|
|
276
|
+
* reading, where a column of its own took the time's width from both lines.
|
|
277
|
+
* The float sits in a block of its own inside the clamp, which is where every
|
|
278
|
+
* engine lays a float out and still counts the clamped lines.
|
|
279
|
+
*/
|
|
248
280
|
.crewlet-inbox-row__head {
|
|
249
|
-
display:
|
|
250
|
-
|
|
251
|
-
|
|
281
|
+
display: -webkit-box;
|
|
282
|
+
-webkit-box-orient: vertical;
|
|
283
|
+
-webkit-line-clamp: 2;
|
|
284
|
+
line-clamp: 2;
|
|
252
285
|
min-width: 0;
|
|
286
|
+
overflow: hidden;
|
|
287
|
+
overflow-wrap: anywhere;
|
|
288
|
+
color: var(--color-text-tertiary);
|
|
253
289
|
}
|
|
254
290
|
|
|
255
|
-
.crewlet-inbox-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
291
|
+
.crewlet-inbox-row__head-text {
|
|
292
|
+
display: block;
|
|
293
|
+
}
|
|
294
|
+
|
|
295
|
+
/* The time (and any status), in the head's own line box, so the time sits on the name's baseline. */
|
|
296
|
+
.crewlet-inbox-row__head-end {
|
|
297
|
+
float: inline-end;
|
|
298
|
+
margin-inline-start: var(--spacing-2);
|
|
259
299
|
white-space: nowrap;
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.crewlet-inbox-row__title {
|
|
260
303
|
font-weight: var(--font-weight-medium);
|
|
261
304
|
color: var(--color-text-primary);
|
|
262
305
|
}
|
|
263
306
|
|
|
264
307
|
.crewlet-inbox-row__qualifier {
|
|
265
|
-
flex: none;
|
|
266
308
|
font-size: var(--font-size-xs);
|
|
267
309
|
color: var(--color-text-tertiary);
|
|
268
310
|
}
|
|
@@ -272,8 +314,6 @@
|
|
|
272
314
|
}
|
|
273
315
|
|
|
274
316
|
.crewlet-inbox-row__meta {
|
|
275
|
-
flex: none;
|
|
276
|
-
margin-inline-start: auto;
|
|
277
317
|
font-size: var(--font-size-xs);
|
|
278
318
|
font-variant-numeric: tabular-nums;
|
|
279
319
|
white-space: nowrap;
|
|
@@ -321,21 +361,12 @@
|
|
|
321
361
|
color: var(--color-text-secondary);
|
|
322
362
|
}
|
|
323
363
|
|
|
364
|
+
/* At the end of the first line, before the time when the row has both. */
|
|
324
365
|
.crewlet-inbox-row__status {
|
|
325
366
|
display: inline-flex;
|
|
326
|
-
flex: none;
|
|
327
367
|
align-items: center;
|
|
328
368
|
}
|
|
329
369
|
|
|
330
|
-
/* With a status, the time stays at the end and the status sits beside it. */
|
|
331
|
-
.crewlet-inbox-row__status + .crewlet-inbox-row__meta {
|
|
332
|
-
margin-inline-start: 0;
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
.crewlet-inbox-row__head > .crewlet-inbox-row__status {
|
|
336
|
-
margin-inline-start: auto;
|
|
337
|
-
}
|
|
338
|
-
|
|
339
370
|
/*
|
|
340
371
|
* What came of the row: a glyph in the tone's ink, then words in the
|
|
341
372
|
* secondary ink, on one line that wraps rather than cuts.
|
|
@@ -391,7 +422,9 @@
|
|
|
391
422
|
|
|
392
423
|
/*
|
|
393
424
|
* The task, under the words and lined up with them: the control's start pad,
|
|
394
|
-
*
|
|
425
|
+
* a target-sized leading slot and the gap after it. The task sits outside the
|
|
426
|
+
* control, so it lines up with the words for a mark of the target size, the
|
|
427
|
+
* size `leading` asks for.
|
|
395
428
|
*/
|
|
396
429
|
.crewlet-inbox-row__aside {
|
|
397
430
|
min-width: 0;
|
package/dist/ListDetail/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { ListDetail } from '../chunk-
|
|
1
|
+
export { ListDetail } from '../chunk-P33VNG7Q.js';
|
|
2
2
|
import '../chunk-ODEQTPFM.js';
|
|
@@ -65,6 +65,12 @@
|
|
|
65
65
|
min-height: 0;
|
|
66
66
|
}
|
|
67
67
|
|
|
68
|
+
/* A LIST THAT GROWS SCROLLS IN ITS OWN COLUMN, whatever it holds. The pane
|
|
69
|
+
left the scrolling to its content, which a DirectoryList does for its
|
|
70
|
+
groups and an InboxList does not: an activity list taller than the screen
|
|
71
|
+
ran past the pane's end, where the screen clipped its later rows and its
|
|
72
|
+
"older" link, with nothing to scroll them into view. A list that scrolls
|
|
73
|
+
itself fills the pane and never makes it overflow. */
|
|
68
74
|
.crewlet-list-detail__list {
|
|
69
75
|
display: flex;
|
|
70
76
|
flex-direction: column;
|
|
@@ -72,6 +78,7 @@
|
|
|
72
78
|
min-height: 0;
|
|
73
79
|
padding-right: var(--crewlet-list-detail-gutter);
|
|
74
80
|
border-right: 1px solid var(--color-border-default);
|
|
81
|
+
overflow-y: auto;
|
|
75
82
|
}
|
|
76
83
|
|
|
77
84
|
/* A DIRECTORY RUNS TO THE HAIRLINE. A DirectoryList is navigation: its lines
|
|
@@ -106,7 +113,6 @@
|
|
|
106
113
|
.crewlet-list-detail__list {
|
|
107
114
|
padding-right: 0;
|
|
108
115
|
border-right: 0;
|
|
109
|
-
overflow-y: auto;
|
|
110
116
|
}
|
|
111
117
|
|
|
112
118
|
/* The list is the pane that scrolls now, and takes the detail's end where
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { PresenterView, formatStopwatch } from '../chunk-
|
|
2
|
-
import '../chunk-O6EV6GKI.js';
|
|
1
|
+
export { PresenterView, formatStopwatch } from '../chunk-LMEMH6DO.js';
|
|
3
2
|
import '../chunk-5AJR6X75.js';
|
|
3
|
+
import '../chunk-O6EV6GKI.js';
|
|
4
4
|
import '../chunk-RK4XPHVG.js';
|
|
5
5
|
import '../chunk-DGXZ635L.js';
|
|
6
6
|
import '../chunk-XSPCITPN.js';
|
package/dist/RailList/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { RAIL_LIST_LABELS, RailList } from '../chunk-
|
|
2
|
-
import '../chunk-BRK3HXGZ.js';
|
|
1
|
+
export { RAIL_LIST_LABELS, RailList } from '../chunk-M576OESX.js';
|
|
3
2
|
import '../chunk-3IWZVEXA.js';
|
|
3
|
+
import '../chunk-BRK3HXGZ.js';
|
|
4
4
|
import '../chunk-O5CEG7TQ.js';
|
|
5
5
|
import '../chunk-YGRTX67J.js';
|
|
6
6
|
import '../chunk-TEV5REGB.js';
|
package/dist/RichEditor/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { RichEditor, preloadRichEditor } from '../chunk-
|
|
1
|
+
export { RichEditor, preloadRichEditor } from '../chunk-AUSFKGKL.js';
|
|
2
2
|
export { RICH_EDITOR_LABELS, richEditorLabels } from '../chunk-2DMTW2Y3.js';
|
|
3
3
|
import '../chunk-KOJPDCGQ.js';
|
|
4
4
|
import '../chunk-KBZO4B33.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
export { SetupWizard } from '../chunk-
|
|
2
|
-
import '../chunk-TMML7BHT.js';
|
|
1
|
+
export { SetupWizard } from '../chunk-3BVNNQZY.js';
|
|
3
2
|
import '../chunk-FPDIHEM4.js';
|
|
3
|
+
import '../chunk-TMML7BHT.js';
|
|
4
4
|
import '../chunk-YJQXESOJ.js';
|
|
5
5
|
import '../chunk-CYQBDZ6M.js';
|
|
6
6
|
import '../chunk-NAHA62WD.js';
|
|
@@ -9,7 +9,7 @@ import { jsx } from 'react/jsx-runtime';
|
|
|
9
9
|
var engine = null;
|
|
10
10
|
var loading = null;
|
|
11
11
|
function loadEngine() {
|
|
12
|
-
loading ??= import('./Editor-
|
|
12
|
+
loading ??= import('./Editor-5D5Z3LBQ.js').then(
|
|
13
13
|
(module) => {
|
|
14
14
|
engine = module.Editor;
|
|
15
15
|
return engine;
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { VisuallyHidden } from './chunk-UT6CW3C7.js';
|
|
2
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
3
|
+
import './ChatScale-L4SIHSKL.css';
|
|
4
|
+
import './DeliveryReceipt-RMZW2DMT.css';
|
|
5
|
+
import { CheckGlyph, TriangleAlertGlyph } from '@crewlethq/icons/glyphs';
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
var DELIVERY_RECEIPT_LABELS = {
|
|
9
|
+
reached: (who) => `Reached ${who}`,
|
|
10
|
+
reaches: (who) => `Will reach ${who}`,
|
|
11
|
+
none: "Reached no agent",
|
|
12
|
+
noneDraft: "Will reach no agent",
|
|
13
|
+
answered: (who) => `${who} answered`,
|
|
14
|
+
list: (names) => names.join(", "),
|
|
15
|
+
reason: (words) => `(${words})`,
|
|
16
|
+
groups: (groups) => groups.join("; "),
|
|
17
|
+
truncated: "Some seats were not reached"
|
|
18
|
+
};
|
|
19
|
+
function reachOf(recipients, labels) {
|
|
20
|
+
const order = [];
|
|
21
|
+
const byReason = /* @__PURE__ */ new Map();
|
|
22
|
+
for (const r of recipients) {
|
|
23
|
+
const key = r.reason ?? "";
|
|
24
|
+
const names = byReason.get(key);
|
|
25
|
+
if (names) {
|
|
26
|
+
names.push(r.name);
|
|
27
|
+
} else {
|
|
28
|
+
order.push(key);
|
|
29
|
+
byReason.set(key, [r.name]);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
return labels.groups(
|
|
33
|
+
order.map((key) => {
|
|
34
|
+
const list = labels.list(byReason.get(key) ?? []);
|
|
35
|
+
return key ? `${list} ${labels.reason(key)}` : list;
|
|
36
|
+
})
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
function DeliveryReceipt({
|
|
40
|
+
recipients,
|
|
41
|
+
tense = "sent",
|
|
42
|
+
truncated = false,
|
|
43
|
+
hint,
|
|
44
|
+
announce = false,
|
|
45
|
+
labels: overrides,
|
|
46
|
+
className,
|
|
47
|
+
...rest
|
|
48
|
+
}) {
|
|
49
|
+
const labels = overrides ? { ...DELIVERY_RECEIPT_LABELS, ...overrides } : DELIVERY_RECEIPT_LABELS;
|
|
50
|
+
const none = recipients.length === 0;
|
|
51
|
+
const answered = tense === "sent" ? recipients.filter((r) => r.answered).map((r) => r.name) : [];
|
|
52
|
+
const reach = none ? tense === "draft" ? labels.noneDraft : labels.none : (tense === "draft" ? labels.reaches : labels.reached)(
|
|
53
|
+
reachOf(recipients, labels)
|
|
54
|
+
);
|
|
55
|
+
const parts = [
|
|
56
|
+
{
|
|
57
|
+
key: "reach",
|
|
58
|
+
mark: none ? /* @__PURE__ */ jsx(TriangleAlertGlyph, { size: "xs" }) : void 0,
|
|
59
|
+
words: reach
|
|
60
|
+
}
|
|
61
|
+
];
|
|
62
|
+
if (truncated && !none)
|
|
63
|
+
parts.push({ key: "truncated", words: labels.truncated });
|
|
64
|
+
if (answered.length > 0) {
|
|
65
|
+
parts.push({
|
|
66
|
+
key: "answered",
|
|
67
|
+
className: "crewlet-delivery-receipt__answered",
|
|
68
|
+
mark: /* @__PURE__ */ jsx(CheckGlyph, { size: "xs" }),
|
|
69
|
+
words: labels.answered(labels.list(answered))
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
if (none && hint)
|
|
73
|
+
parts.push({
|
|
74
|
+
key: "hint",
|
|
75
|
+
className: "crewlet-delivery-receipt__hint",
|
|
76
|
+
words: hint
|
|
77
|
+
});
|
|
78
|
+
return /* @__PURE__ */ jsx(
|
|
79
|
+
"p",
|
|
80
|
+
{
|
|
81
|
+
...rest,
|
|
82
|
+
role: announce ? "status" : void 0,
|
|
83
|
+
"data-tense": tense,
|
|
84
|
+
className: cx(
|
|
85
|
+
"crewlet-delivery-receipt",
|
|
86
|
+
none && "crewlet-delivery-receipt--none",
|
|
87
|
+
className
|
|
88
|
+
),
|
|
89
|
+
children: parts.map((part, i) => /* @__PURE__ */ jsxs(
|
|
90
|
+
"span",
|
|
91
|
+
{
|
|
92
|
+
className: cx("crewlet-delivery-receipt__part", part.className),
|
|
93
|
+
children: [
|
|
94
|
+
i > 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-delivery-receipt__dot", "aria-hidden": "true", children: "\xB7" }) : null,
|
|
95
|
+
part.mark ? /* @__PURE__ */ jsx("span", { className: "crewlet-delivery-receipt__mark", "aria-hidden": "true", children: part.mark }) : null,
|
|
96
|
+
/* @__PURE__ */ jsx("span", { children: part.words }),
|
|
97
|
+
i < parts.length - 1 ? /* @__PURE__ */ jsx(VisuallyHidden, { children: ". " }) : null
|
|
98
|
+
]
|
|
99
|
+
},
|
|
100
|
+
part.key
|
|
101
|
+
))
|
|
102
|
+
}
|
|
103
|
+
);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
export { DELIVERY_RECEIPT_LABELS, DeliveryReceipt };
|
|
@@ -4,7 +4,7 @@ import { usePresence, releaseFocus } from './chunk-PCAT2EFB.js';
|
|
|
4
4
|
import { useHeadingLevel, headingTag } from './chunk-PQADV6P6.js';
|
|
5
5
|
import { VisuallyHidden } from './chunk-UT6CW3C7.js';
|
|
6
6
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
7
|
-
import './InboxList-
|
|
7
|
+
import './InboxList-NVPIL3WU.css';
|
|
8
8
|
import { useId, useState, useRef, useLayoutEffect, useEffect, useCallback, cloneElement, Children, isValidElement } from 'react';
|
|
9
9
|
import { ChevronDownGlyph } from '@crewlethq/icons/glyphs';
|
|
10
10
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -222,60 +222,81 @@ function InboxRow({
|
|
|
222
222
|
told.current = true;
|
|
223
223
|
onLeft?.();
|
|
224
224
|
}, [gone, onLeft]);
|
|
225
|
+
const ids = useId();
|
|
226
|
+
const part = (name) => `${ids}-${name}`;
|
|
227
|
+
const hasQualifier = qualifier !== void 0;
|
|
228
|
+
const hasStatus = status !== void 0 && status !== null;
|
|
229
|
+
const hasMeta = meta !== void 0;
|
|
230
|
+
const hasOutcome = outcome !== void 0 && outcome !== null;
|
|
231
|
+
const labelledBy = [
|
|
232
|
+
leading === void 0 ? null : part("leading"),
|
|
233
|
+
part("title"),
|
|
234
|
+
hasQualifier ? part("qualifier") : null,
|
|
235
|
+
hasStatus || hasMeta ? part("end") : null,
|
|
236
|
+
part("text"),
|
|
237
|
+
hasOutcome ? part("outcome") : null,
|
|
238
|
+
unread ? part("unread") : null,
|
|
239
|
+
done ? part("done") : null
|
|
240
|
+
].filter(Boolean).join(" ");
|
|
225
241
|
const contents = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
226
242
|
leading === void 0 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
227
|
-
/* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__leading", children: leading }),
|
|
243
|
+
/* @__PURE__ */ jsx("span", { id: part("leading"), className: "crewlet-inbox-row__leading", children: leading }),
|
|
228
244
|
" "
|
|
229
245
|
] }),
|
|
230
246
|
/* @__PURE__ */ jsxs("span", { className: "crewlet-inbox-row__main", children: [
|
|
231
|
-
/* @__PURE__ */ jsxs("span", { className: "crewlet-inbox-row__head", children: [
|
|
232
|
-
/* @__PURE__ */
|
|
233
|
-
|
|
247
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__head", children: /* @__PURE__ */ jsxs("span", { className: "crewlet-inbox-row__head-text", children: [
|
|
248
|
+
hasStatus || hasMeta ? /* @__PURE__ */ jsxs("span", { id: part("end"), className: "crewlet-inbox-row__head-end", children: [
|
|
249
|
+
hasStatus ? /* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__status", children: status }) : null,
|
|
250
|
+
hasStatus && hasMeta ? " " : null,
|
|
251
|
+
hasMeta ? /* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__meta", children: meta }) : null
|
|
252
|
+
] }) : null,
|
|
253
|
+
/* @__PURE__ */ jsx("span", { id: part("title"), className: "crewlet-inbox-row__title", children: title }),
|
|
254
|
+
hasQualifier ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
234
255
|
" ",
|
|
235
|
-
/* @__PURE__ */ jsx(
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
] }),
|
|
256
|
+
/* @__PURE__ */ jsx(
|
|
257
|
+
"span",
|
|
258
|
+
{
|
|
259
|
+
id: part("qualifier"),
|
|
260
|
+
className: cx("crewlet-inbox-row__qualifier", qualifierTone === "danger" && "crewlet-inbox-row__qualifier--danger"),
|
|
261
|
+
children: qualifier
|
|
262
|
+
}
|
|
263
|
+
)
|
|
264
|
+
] }) : null
|
|
265
|
+
] }) }),
|
|
246
266
|
" ",
|
|
247
|
-
/* @__PURE__ */ jsxs("span", { className: "crewlet-inbox-row__text", children: [
|
|
267
|
+
/* @__PURE__ */ jsxs("span", { id: part("text"), className: "crewlet-inbox-row__text", children: [
|
|
248
268
|
children,
|
|
249
269
|
excerpt === void 0 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
250
270
|
" ",
|
|
251
271
|
/* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__excerpt", children: excerpt })
|
|
252
272
|
] })
|
|
253
273
|
] }),
|
|
254
|
-
|
|
274
|
+
hasOutcome ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
255
275
|
" ",
|
|
256
|
-
/* @__PURE__ */ jsxs("span", { className: cx("crewlet-inbox-row__outcome", `crewlet-inbox-row__outcome--${outcomeTone}`), children: [
|
|
276
|
+
/* @__PURE__ */ jsxs("span", { id: part("outcome"), className: cx("crewlet-inbox-row__outcome", `crewlet-inbox-row__outcome--${outcomeTone}`), children: [
|
|
257
277
|
outcomeIcon === void 0 ? null : /* @__PURE__ */ jsx("span", { "aria-hidden": true, className: "crewlet-inbox-row__outcome-icon", children: outcomeIcon }),
|
|
258
278
|
/* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__outcome-text", children: outcome })
|
|
259
279
|
] })
|
|
260
|
-
] }),
|
|
280
|
+
] }) : null,
|
|
261
281
|
unread ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
262
282
|
" ",
|
|
263
|
-
/* @__PURE__ */ jsx(VisuallyHidden, { children: unreadLabel })
|
|
283
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { id: part("unread"), children: unreadLabel })
|
|
264
284
|
] }) : null,
|
|
265
285
|
done ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
266
286
|
" ",
|
|
267
|
-
/* @__PURE__ */ jsx(VisuallyHidden, { children: doneLabel })
|
|
287
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { id: part("done"), children: doneLabel })
|
|
268
288
|
] }) : null
|
|
269
289
|
] })
|
|
270
290
|
] });
|
|
271
291
|
const controlClass = cx(
|
|
272
292
|
"crewlet-inbox-row__control",
|
|
293
|
+
leading !== void 0 && "crewlet-inbox-row__control--leading",
|
|
273
294
|
unread && "crewlet-inbox-row__control--unread",
|
|
274
295
|
actionable && "crewlet-inbox-row__control--actionable",
|
|
275
296
|
done && "crewlet-inbox-row__control--done"
|
|
276
297
|
);
|
|
277
298
|
const current = selected ? "true" : void 0;
|
|
278
|
-
const control = href !== void 0 ? /* @__PURE__ */ jsx("a", { className: controlClass, href, "aria-current": current, onClick, children: contents }) : /* @__PURE__ */ jsx("button", { type: "button", className: controlClass, "aria-current": current, onClick, children: contents });
|
|
299
|
+
const control = href !== void 0 ? /* @__PURE__ */ jsx("a", { className: controlClass, href, "aria-current": current, "aria-labelledby": labelledBy, onClick, children: contents }) : /* @__PURE__ */ jsx("button", { type: "button", className: controlClass, "aria-current": current, "aria-labelledby": labelledBy, onClick, children: contents });
|
|
279
300
|
if (gone) return null;
|
|
280
301
|
return /* @__PURE__ */ jsx(
|
|
281
302
|
"li",
|