@crewlethq/ui 0.28.0 → 0.30.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 (95) hide show
  1. package/README.md +45 -4
  2. package/dist/AccessDeniedCard/index.js +3 -3
  3. package/dist/Accordion/index.js +3 -3
  4. package/dist/AppShell/index.js +1 -1
  5. package/dist/{AppShell-APHZKJYH.css → AppShell-GCM4TDVY.css} +4 -1
  6. package/dist/ArtifactBar/ArtifactBar.d.ts +143 -0
  7. package/dist/ArtifactBar/index.d.ts +3 -0
  8. package/dist/ArtifactBar/index.js +25 -0
  9. package/dist/ArtifactBar-IBWB5POL.css +358 -0
  10. package/dist/ArtifactCard/index.js +3 -3
  11. package/dist/ArtifactCover/index.js +5 -5
  12. package/dist/ArtifactIcon/index.js +4 -4
  13. package/dist/ArtifactPanel/ArtifactPanel.d.ts +81 -0
  14. package/dist/ArtifactPanel/index.d.ts +3 -0
  15. package/dist/ArtifactPanel/index.js +5 -0
  16. package/dist/ArtifactPanel-YFXT5O77.css +132 -0
  17. package/dist/AuthLayout/index.js +3 -3
  18. package/dist/AvatarPicker/index.js +4 -4
  19. package/dist/Card/index.js +2 -2
  20. package/dist/ChangeMark/index.js +1 -1
  21. package/dist/CommandPalette/index.js +3 -3
  22. package/dist/CommentThread/index.js +5 -5
  23. package/dist/Composer/index.js +2 -2
  24. package/dist/DataView/index.js +4 -4
  25. package/dist/Disclosure/index.js +3 -3
  26. package/dist/Document/Document.d.ts +8 -1
  27. package/dist/Document/index.js +1 -1
  28. package/dist/{Document-PQGXJHB7.css → Document-G3YTZIUL.css} +71 -0
  29. package/dist/EditingStatus/EditingStatus.d.ts +25 -0
  30. package/dist/EditingStatus/index.d.ts +3 -0
  31. package/dist/EditingStatus/index.js +2 -0
  32. package/dist/EditingStatus-NFADEPSX.css +53 -0
  33. package/dist/Editor-YZ7KG2RD.js +2099 -0
  34. package/dist/HuePicker/index.js +2 -2
  35. package/dist/ListInput/index.js +2 -2
  36. package/dist/Markdown/grammar.d.ts +170 -0
  37. package/dist/Markdown/index.d.ts +2 -0
  38. package/dist/Markdown/index.js +1 -0
  39. package/dist/MarkdownEditor/index.js +1 -1
  40. package/dist/PeopleRail/PeopleRail.d.ts +8 -1
  41. package/dist/PeopleRail/index.js +1 -1
  42. package/dist/{PeopleRail-R64WVOSH.css → PeopleRail-SZGHZXVT.css} +8 -0
  43. package/dist/RichEditor/Editor.d.ts +17 -0
  44. package/dist/RichEditor/RichEditor.d.ts +26 -0
  45. package/dist/RichEditor/codec.d.ts +78 -0
  46. package/dist/RichEditor/commands.d.ts +89 -0
  47. package/dist/RichEditor/index.d.ts +4 -0
  48. package/dist/RichEditor/index.js +8 -0
  49. package/dist/RichEditor/keys.d.ts +16 -0
  50. package/dist/RichEditor/nodeviews.d.ts +60 -0
  51. package/dist/RichEditor/paste.d.ts +47 -0
  52. package/dist/RichEditor/plugins.d.ts +49 -0
  53. package/dist/RichEditor/roundtrip.d.ts +14 -0
  54. package/dist/RichEditor/schema.d.ts +23 -0
  55. package/dist/RichEditor/types.d.ts +140 -0
  56. package/dist/RichEditor-NPD2KAPS.css +419 -0
  57. package/dist/RichEditorMarkdown/index.d.ts +1 -0
  58. package/dist/RichEditorMarkdown/index.js +3 -0
  59. package/dist/SheetGrid/index.js +1 -1
  60. package/dist/ThemeSwitcher/index.js +1 -1
  61. package/dist/VersionCompare/index.js +2 -2
  62. package/dist/chunk-3DPIU2Q7.js +28 -0
  63. package/dist/{chunk-V2Z24W2Z.js → chunk-4JUKWWUD.js} +1 -1
  64. package/dist/{chunk-MQEEQVG6.js → chunk-6AH2XJ3Q.js} +2 -2
  65. package/dist/chunk-A4E5YLXO.js +85 -0
  66. package/dist/{chunk-WENCSQ47.js → chunk-EBNI36UQ.js} +1 -1
  67. package/dist/{chunk-6J35F334.js → chunk-GOSQXEZU.js} +1 -1
  68. package/dist/{chunk-M2VJGNCD.js → chunk-GR55WT4R.js} +3 -3
  69. package/dist/chunk-I3BSQUKN.js +121 -0
  70. package/dist/chunk-IDBHX5SR.js +12 -0
  71. package/dist/{chunk-WI6K5M5X.js → chunk-M3LUNN7F.js} +1 -1
  72. package/dist/{chunk-S4RCG44T.js → chunk-MICH6QSJ.js} +1 -1
  73. package/dist/chunk-QMBP23BL.js +347 -0
  74. package/dist/{chunk-G2AVKPSL.js → chunk-RIAZM6L3.js} +1 -1
  75. package/dist/chunk-SKOYC2CF.js +288 -0
  76. package/dist/{chunk-PRNX5AFE.js → chunk-TGYDROIB.js} +1 -1
  77. package/dist/{chunk-G3EEUNZQ.js → chunk-UB7TJEKZ.js} +1 -1
  78. package/dist/chunk-UQHKFF2N.js +106 -0
  79. package/dist/{chunk-WHZFDS62.js → chunk-VDPJGP4Q.js} +1 -1
  80. package/dist/chunk-VOX3YRFO.js +76 -0
  81. package/dist/chunk-YFW4MTK4.js +749 -0
  82. package/dist/generated/index.d.ts +6 -0
  83. package/dist/generated/index.js +83 -75
  84. package/dist/index.js +83 -75
  85. package/dist/styles.css +8849 -7793
  86. package/package.json +13 -3
  87. package/dist/chunk-FVLCTCMV.js +0 -96
  88. package/dist/{chunk-RIEDQSA4.js → chunk-7DZDSSJS.js} +1 -1
  89. package/dist/{chunk-YZCJ63JF.js → chunk-ACA27MZH.js} +1 -1
  90. package/dist/{chunk-ENJUPIND.js → chunk-FZVJDJFN.js} +1 -1
  91. package/dist/{chunk-SGIQCI6Y.js → chunk-LIXSV5YI.js} +1 -1
  92. package/dist/{chunk-NWW4IQJU.js → chunk-OC46246T.js} +0 -0
  93. package/dist/{chunk-VOMYRJV5.js → chunk-RODMM35O.js} +2 -2
  94. package/dist/{chunk-HCKJGBQH.js → chunk-VVRL27HM.js} +1 -1
  95. package/dist/{chunk-D5JZN3ML.js → chunk-Z6VW6CXX.js} +1 -1
@@ -0,0 +1,288 @@
1
+ // src/Markdown/grammar.ts
2
+ var MARKDOWN_CALLOUT_TONES = ["note", "tip", "important", "warning", "caution"];
3
+ var MARKDOWN_CALLOUT_NAMES = {
4
+ note: "Note",
5
+ tip: "Tip",
6
+ important: "Important",
7
+ warning: "Warning",
8
+ caution: "Caution"
9
+ };
10
+ var SAFE_SCHEME = /^(https?:|mailto:)/i;
11
+ var URL_NOISE = /[\u0000- ]/g;
12
+ function safeHref(raw) {
13
+ const href = raw.trim();
14
+ if (href === "") return null;
15
+ const clean = href.replace(URL_NOISE, "");
16
+ if (clean.startsWith("#/")) return clean;
17
+ if (SAFE_SCHEME.test(clean)) return clean;
18
+ return null;
19
+ }
20
+ var HEADING = /^(#{1,6})\s+(.*)$/;
21
+ var FENCE = /^(```|~~~)\s*([A-Za-z0-9_+-]*)\s*$/;
22
+ var RULE = /^(?:\s*(?:-{3,}|\*{3,}|_{3,})\s*)$/;
23
+ var BULLET = /^(\s*)([-*+])\s+(.*)$/;
24
+ var ORDERED = /^(\s*)(\d{1,9})([.)])\s+(.*)$/;
25
+ var QUOTE = /^\s{0,3}>\s?(.*)$/;
26
+ var TABLE_RULE = /^\s*\|?\s*:?-{1,}:?\s*(\|\s*:?-{1,}:?\s*)*\|?\s*$/;
27
+ var CALLOUT = /^\[!(note|tip|important|warning|caution)\]\s*$/i;
28
+ var TASK = /^\[([ xX])\]\s+(.*)$/;
29
+ var FENCE_CLOSE = {
30
+ "```": /^`{3,}[ \t]*$/,
31
+ "~~~": /^~{3,}[ \t]*$/
32
+ };
33
+ function markdownClosesFence(line, marker) {
34
+ return FENCE_CLOSE[marker].test(line);
35
+ }
36
+ function markdownFenceOf(line) {
37
+ const m = FENCE.exec(line);
38
+ return m ? { marker: m[1] ?? "```", lang: m[2] ?? "" } : null;
39
+ }
40
+ function markdownHeadingOf(line) {
41
+ const m = HEADING.exec(line);
42
+ if (!m) return null;
43
+ return { level: (m[1] ?? "#").length, title: (m[2] ?? "").replace(/\s+#+\s*$/, "").trim() };
44
+ }
45
+ function markdownLines(source) {
46
+ return (source ?? "").replace(/\r\n?/g, "\n").split("\n");
47
+ }
48
+ function parseMarkdown(source) {
49
+ return blocksOf(markdownLines(source)).map((span) => span.block);
50
+ }
51
+ function parseMarkdownSpans(source) {
52
+ const lines = markdownLines(source);
53
+ return { lines, spans: blocksOf(lines) };
54
+ }
55
+ function blocksOf(lines) {
56
+ const out = [];
57
+ let i = 0;
58
+ const paragraph = [];
59
+ let paragraphStart = 0;
60
+ const flush = () => {
61
+ if (paragraph.length) {
62
+ out.push({
63
+ block: { kind: "paragraph", text: paragraph.join("\n") },
64
+ start: paragraphStart,
65
+ end: paragraphStart + paragraph.length
66
+ });
67
+ paragraph.length = 0;
68
+ }
69
+ };
70
+ while (i < lines.length) {
71
+ const line = lines[i] ?? "";
72
+ const start = i;
73
+ if (line.trim() === "") {
74
+ flush();
75
+ i++;
76
+ continue;
77
+ }
78
+ const fence = markdownFenceOf(line);
79
+ if (fence) {
80
+ flush();
81
+ const body = [];
82
+ i++;
83
+ while (i < lines.length && !markdownClosesFence(lines[i] ?? "", fence.marker)) {
84
+ body.push(lines[i] ?? "");
85
+ i++;
86
+ }
87
+ if (i >= lines.length && body.length > 0 && body[body.length - 1] === "") {
88
+ body.pop();
89
+ }
90
+ i = Math.min(i + 1, lines.length);
91
+ out.push({
92
+ block: { kind: "code", lang: fence.lang, text: body.join("\n"), fence: fence.marker },
93
+ start,
94
+ end: i
95
+ });
96
+ continue;
97
+ }
98
+ if (RULE.test(line)) {
99
+ flush();
100
+ i++;
101
+ out.push({ block: { kind: "rule" }, start, end: i });
102
+ continue;
103
+ }
104
+ const heading = markdownHeadingOf(line);
105
+ if (heading) {
106
+ flush();
107
+ i++;
108
+ out.push({ block: { kind: "heading", level: heading.level, text: heading.title }, start, end: i });
109
+ continue;
110
+ }
111
+ if (QUOTE.test(line)) {
112
+ flush();
113
+ const inner = [];
114
+ while (i < lines.length && QUOTE.test(lines[i] ?? "")) {
115
+ inner.push(QUOTE.exec(lines[i] ?? "")?.[1] ?? "");
116
+ i++;
117
+ }
118
+ const tone = CALLOUT.exec(inner[0] ?? "");
119
+ out.push({
120
+ block: tone ? {
121
+ kind: "callout",
122
+ tone: (tone[1] ?? "note").toLowerCase(),
123
+ blocks: parseMarkdown(inner.slice(1).join("\n"))
124
+ } : { kind: "quote", blocks: parseMarkdown(inner.join("\n")) },
125
+ start,
126
+ end: i
127
+ });
128
+ continue;
129
+ }
130
+ if (line.includes("|") && TABLE_RULE.test(lines[i + 1] ?? "")) {
131
+ flush();
132
+ const head = splitRow(line);
133
+ const align = splitRow(lines[i + 1] ?? "").map(alignOf);
134
+ i += 2;
135
+ const rows = [];
136
+ while (i < lines.length && (lines[i] ?? "").includes("|") && (lines[i] ?? "").trim() !== "") {
137
+ rows.push(splitRow(lines[i] ?? ""));
138
+ i++;
139
+ }
140
+ out.push({ block: { kind: "table", head, align, rows }, start, end: i });
141
+ continue;
142
+ }
143
+ if (BULLET.test(line) || ORDERED.test(line)) {
144
+ flush();
145
+ const [list, next] = parseList(lines, i);
146
+ out.push({ block: list, start, end: next });
147
+ i = next;
148
+ continue;
149
+ }
150
+ if (paragraph.length === 0) paragraphStart = i;
151
+ paragraph.push(line);
152
+ i++;
153
+ }
154
+ flush();
155
+ return out;
156
+ }
157
+ function alignOf(cell) {
158
+ const t = cell.trim();
159
+ if (t.startsWith(":") && t.endsWith(":")) return "center";
160
+ if (t.endsWith(":")) return "right";
161
+ return "left";
162
+ }
163
+ function splitRow(line) {
164
+ let t = line.trim();
165
+ if (t.startsWith("|")) t = t.slice(1);
166
+ if (t.endsWith("|") && !t.endsWith("\\|")) t = t.slice(0, -1);
167
+ const cells = [];
168
+ let cell = "";
169
+ for (let i = 0; i < t.length; i++) {
170
+ const c = t[i];
171
+ if (c === "\\" && t[i + 1] === "|") {
172
+ cell += "|";
173
+ i++;
174
+ } else if (c === "|") {
175
+ cells.push(cell.trim());
176
+ cell = "";
177
+ } else {
178
+ cell += c;
179
+ }
180
+ }
181
+ cells.push(cell.trim());
182
+ return cells;
183
+ }
184
+ function parseList(lines, start) {
185
+ const head = lines[start] ?? "";
186
+ const firstBullet = BULLET.exec(head);
187
+ const firstOrdered = ORDERED.exec(head);
188
+ const baseIndent = ((firstBullet ?? firstOrdered)?.[1] ?? "").length;
189
+ const ordered = firstOrdered !== null && firstBullet === null;
190
+ const startNumber = ordered ? Number(firstOrdered?.[2] ?? 1) : 1;
191
+ const marker = ordered ? firstOrdered?.[3] ?? "." : firstBullet?.[2] ?? "-";
192
+ const items = [];
193
+ let i = start;
194
+ let own = [];
195
+ let checked = null;
196
+ let open = false;
197
+ let loose = false;
198
+ const close = () => {
199
+ if (!open) return;
200
+ items.push({ checked, blocks: parseMarkdown(own.join("\n")) });
201
+ own = [];
202
+ checked = null;
203
+ open = false;
204
+ };
205
+ while (i < lines.length) {
206
+ const line = lines[i] ?? "";
207
+ const bullet = BULLET.exec(line);
208
+ const numbered = ORDERED.exec(line);
209
+ const found = bullet ?? numbered;
210
+ const indent = (found?.[1] ?? "").length;
211
+ if (found && indent === baseIndent) {
212
+ if (ordered !== (numbered !== null && bullet === null)) break;
213
+ close();
214
+ open = true;
215
+ const body = (bullet ? bullet[3] : numbered?.[4]) ?? "";
216
+ const task = TASK.exec(body);
217
+ if (task) {
218
+ checked = (task[1] ?? " ").toLowerCase() === "x";
219
+ own.push(task[2] ?? "");
220
+ } else {
221
+ own.push(body);
222
+ }
223
+ i++;
224
+ continue;
225
+ }
226
+ if (found && indent > baseIndent) {
227
+ own.push(line.slice(baseIndent));
228
+ i++;
229
+ continue;
230
+ }
231
+ if (line.trim() === "") {
232
+ const following = lines[i + 1] ?? "";
233
+ const continues = BULLET.test(following) || ORDERED.test(following) || /^\s{2,}\S/.test(following);
234
+ if (!continues) break;
235
+ const sibling = BULLET.exec(following) ?? ORDERED.exec(following);
236
+ if (sibling && (sibling[1] ?? "").length === baseIndent) loose = true;
237
+ own.push("");
238
+ i++;
239
+ continue;
240
+ }
241
+ if (found === null && /^\s{2,}\S/.test(line) && open) {
242
+ own.push(line.slice(baseIndent));
243
+ i++;
244
+ continue;
245
+ }
246
+ break;
247
+ }
248
+ close();
249
+ return [{ kind: "list", ordered, start: startNumber, marker, loose, items }, i];
250
+ }
251
+ var NOT_WP = String.raw`[^\s\p{P}\p{S}]`;
252
+ var WP = String.raw`[\s\p{P}\p{S}]`;
253
+ var PUNCT = String.raw`[\p{P}\p{S}]`;
254
+ var leftFlanking = (d) => String.raw`(?:(?<!${NOT_WP})${d}(?!\s|$)|(?<=${NOT_WP})${d}(?!${WP}|$))`;
255
+ var rightFlanking = (d) => String.raw`(?:(?<=${NOT_WP})${d}|(?<=${PUNCT})${d}(?!${NOT_WP}))`;
256
+ var underOpens = (d) => String.raw`(?<!${NOT_WP})${d}(?!\s|$)`;
257
+ var underCloses = (d) => String.raw`(?<!\s)${d}(?!${NOT_WP})`;
258
+ var label = (name) => String.raw`(?<${name}>(?:\\[\s\S]|[^\]\\])*)`;
259
+ var destination = (name, title) => String.raw`(?<${name}>(?:[^()\s]|\([^()\s]*\))*)(?:\s+"(?<${title}>[^"]*)")?\)`;
260
+ var ASCII_PUNCTUATION = String.raw`[!-\/:-@\[-\x60{-~]`;
261
+ var INLINE_SOURCE = [
262
+ String.raw`\\(?<esc>${ASCII_PUNCTUATION})`,
263
+ String.raw`(?<tick>\x60+)(?<code>[\s\S]*?)\k<tick>`,
264
+ String.raw`!\[` + label("alt") + String.raw`\]\(` + destination("src", "srcTitle"),
265
+ String.raw`\[` + label("label") + String.raw`\]\(` + destination("href", "hrefTitle"),
266
+ String.raw`<(?<auto>(?:https?:|mailto:)[^>\s]+)>`,
267
+ // A strong run closes on a `**` no third asterisk follows, so `***both***`
268
+ // is strong around emphasis rather than strong around `*both` and a stray.
269
+ leftFlanking(String.raw`\*\*`) + String.raw`(?<strong>[\s\S]+?)` + rightFlanking(String.raw`\*\*(?!\*)`),
270
+ underOpens("__") + String.raw`(?<strongUnder>[\s\S]+?)` + underCloses("__"),
271
+ leftFlanking(String.raw`\*`) + String.raw`(?<em>[\s\S]+?)` + rightFlanking(String.raw`\*`),
272
+ underOpens("_") + String.raw`(?<emUnder>[\s\S]+?)` + underCloses("_"),
273
+ String.raw`~~(?<del>[\s\S]+?)~~`
274
+ ].join("|");
275
+ function* markdownInline(text) {
276
+ const pattern = new RegExp(INLINE_SOURCE, "gu");
277
+ for (let m = pattern.exec(text); m !== null; m = pattern.exec(text)) {
278
+ yield { index: m.index, end: m.index + m[0].length, groups: m.groups ?? {} };
279
+ }
280
+ }
281
+ function markdownCodeText(code) {
282
+ return code.replace(/^ | $/g, "");
283
+ }
284
+ function markdownBreaks(text, hard = false) {
285
+ return text.split(hard ? /(?: +|\\)?\n/ : /(?: +|\\)\n/);
286
+ }
287
+
288
+ export { MARKDOWN_CALLOUT_NAMES, MARKDOWN_CALLOUT_TONES, markdownBreaks, markdownClosesFence, markdownCodeText, markdownFenceOf, markdownHeadingOf, markdownInline, markdownLines, parseMarkdown, parseMarkdownSpans, safeHref };
@@ -1,4 +1,4 @@
1
- import { HuePicker } from './chunk-SGIQCI6Y.js';
1
+ import { HuePicker } from './chunk-LIXSV5YI.js';
2
2
  import { Popover } from './chunk-BWRGFKJP.js';
3
3
  import { NODE_HUE_NAMES } from './chunk-AYKXMIOR.js';
4
4
  import { CharacterPicker } from './chunk-HVIX5ECM.js';
@@ -1,5 +1,5 @@
1
1
  import { EmptyState } from './chunk-RA2ULG6H.js';
2
- import { Card } from './chunk-YZCJ63JF.js';
2
+ import { Card } from './chunk-ACA27MZH.js';
3
3
  import { cx } from './chunk-ODEQTPFM.js';
4
4
  import './AccessDeniedCard-WXM5DBDZ.css';
5
5
  import { ShieldGlyph, LockGlyph, EyeOffGlyph } from '@crewlethq/icons/glyphs';
@@ -0,0 +1,106 @@
1
+ import { PRESENCE_LABELS, presenceOrder, collapseSessions } from './chunk-Z7JYG5TF.js';
2
+ import { Avatar } from './chunk-5OM447RW.js';
3
+ import { headingTag, useHeadingLevel } from './chunk-PQADV6P6.js';
4
+ import { Button } from './chunk-OG6CL3EB.js';
5
+ import { IconButton } from './chunk-4FQT6ZAY.js';
6
+ import { cx } from './chunk-ODEQTPFM.js';
7
+ import './PeopleRail-SZGHZXVT.css';
8
+ import { useId } from 'react';
9
+ import { isCrewletCharacter } from '@crewlethq/icons/characters';
10
+ import { XGlyph } from '@crewlethq/icons/glyphs';
11
+ import { jsxs, jsx } from 'react/jsx-runtime';
12
+
13
+ var PEOPLE_RAIL_LABELS = {
14
+ title: "People here",
15
+ close: "Close people",
16
+ you: "You",
17
+ nobody: "Nobody else is here right now.",
18
+ follow: "Follow",
19
+ following: "Following",
20
+ followName: (name) => `Follow ${name}`,
21
+ stopFollowingName: (name) => `Stop following ${name}`,
22
+ activity: PRESENCE_LABELS.activity
23
+ };
24
+ function peopleRailKey(member) {
25
+ return member.seat ?? member.id;
26
+ }
27
+ function PeopleRail({
28
+ members,
29
+ self,
30
+ following,
31
+ onFollow,
32
+ onClose,
33
+ actions,
34
+ labels: overrides,
35
+ variant = "card",
36
+ className
37
+ }) {
38
+ const labels = overrides ? { ...PEOPLE_RAIL_LABELS, ...overrides } : PEOPLE_RAIL_LABELS;
39
+ const headingID = useId();
40
+ const Heading = headingTag(useHeadingLevel());
41
+ const others = presenceOrder(collapseSessions(members));
42
+ const plain = variant === "plain";
43
+ const Root = plain ? "div" : "aside";
44
+ return /* @__PURE__ */ jsxs(
45
+ Root,
46
+ {
47
+ className: cx("crewlet-people-rail", plain && "crewlet-people-rail--plain", className),
48
+ "aria-labelledby": plain ? void 0 : headingID,
49
+ children: [
50
+ plain ? null : /* @__PURE__ */ jsxs("div", { className: "crewlet-people-rail__head", children: [
51
+ /* @__PURE__ */ jsx(Heading, { className: "crewlet-people-rail__title", id: headingID, children: labels.title }),
52
+ onClose && /* @__PURE__ */ jsx(IconButton, { size: "sm", variant: "ghost", label: labels.close, icon: /* @__PURE__ */ jsx(XGlyph, { size: "sm" }), onClick: onClose })
53
+ ] }),
54
+ /* @__PURE__ */ jsxs("ul", { role: "list", className: "crewlet-people-rail__list", children: [
55
+ self && /* @__PURE__ */ jsxs("li", { className: "crewlet-people-rail__person", children: [
56
+ /* @__PURE__ */ jsx(PresenceBadge, { member: self }),
57
+ /* @__PURE__ */ jsx("span", { className: "crewlet-people-rail__text", children: /* @__PURE__ */ jsx("span", { className: "crewlet-people-rail__name", children: labels.you }) })
58
+ ] }),
59
+ others.map((member) => {
60
+ const key = peopleRailKey(member);
61
+ const followed = following !== void 0 && following === key;
62
+ const extra = actions?.(member);
63
+ return /* @__PURE__ */ jsxs("li", { className: "crewlet-people-rail__person", children: [
64
+ /* @__PURE__ */ jsx(PresenceBadge, { member }),
65
+ /* @__PURE__ */ jsxs("span", { className: "crewlet-people-rail__text", children: [
66
+ /* @__PURE__ */ jsx("span", { className: "crewlet-people-rail__name", children: member.name }),
67
+ /* @__PURE__ */ jsx("span", { className: "crewlet-people-rail__where", children: member.location ?? labels.activity(member.activity, member.kind) })
68
+ ] }),
69
+ extra !== void 0 && extra !== null || onFollow ? /* @__PURE__ */ jsxs("span", { className: "crewlet-people-rail__actions", children: [
70
+ extra,
71
+ onFollow && /* @__PURE__ */ jsx(
72
+ Button,
73
+ {
74
+ size: "small",
75
+ variant: followed ? "primary" : "secondary",
76
+ pressed: followed,
77
+ "aria-label": followed ? labels.stopFollowingName(member.name) : labels.followName(member.name),
78
+ onClick: () => onFollow(followed ? null : member),
79
+ children: followed ? labels.following : labels.follow
80
+ }
81
+ )
82
+ ] }) : null
83
+ ] }, key);
84
+ })
85
+ ] }),
86
+ others.length === 0 && /* @__PURE__ */ jsx("p", { className: "crewlet-people-rail__note", children: labels.nobody })
87
+ ]
88
+ }
89
+ );
90
+ }
91
+ function PresenceBadge({ member }) {
92
+ return /* @__PURE__ */ jsx(
93
+ Avatar,
94
+ {
95
+ name: member.name,
96
+ kind: member.kind,
97
+ src: member.src,
98
+ character: member.character !== void 0 && isCrewletCharacter(member.character) ? member.character : void 0,
99
+ hue: member.kind === "agent" ? member.hue : void 0,
100
+ size: "sm",
101
+ decorative: true
102
+ }
103
+ );
104
+ }
105
+
106
+ export { PEOPLE_RAIL_LABELS, PeopleRail, peopleRailKey };
@@ -1,5 +1,5 @@
1
1
  import { BrandLockup } from './chunk-7KBNFFM3.js';
2
- import { Card } from './chunk-YZCJ63JF.js';
2
+ import { Card } from './chunk-ACA27MZH.js';
3
3
  import { cx } from './chunk-ODEQTPFM.js';
4
4
  import './AuthLayout-ODHBUPHQ.css';
5
5
  import { useId } from 'react';
@@ -0,0 +1,76 @@
1
+ import { richEditorLabels } from './chunk-A4E5YLXO.js';
2
+ import { Skeleton } from './chunk-W5J7R5EB.js';
3
+ import { Callout } from './chunk-SVSCLHHI.js';
4
+ import { Button } from './chunk-OG6CL3EB.js';
5
+ import './RichEditor-NPD2KAPS.css';
6
+ import { forwardRef, useState, useEffect } from 'react';
7
+ import { jsx } from 'react/jsx-runtime';
8
+
9
+ var engine = null;
10
+ var loading = null;
11
+ function loadEngine() {
12
+ loading ??= import('./Editor-YZ7KG2RD.js').then(
13
+ (module) => {
14
+ engine = module.Editor;
15
+ return engine;
16
+ },
17
+ (error) => {
18
+ loading = null;
19
+ throw error;
20
+ }
21
+ );
22
+ return loading;
23
+ }
24
+ function preloadRichEditor() {
25
+ return loadEngine().then(
26
+ () => void 0,
27
+ () => void 0
28
+ );
29
+ }
30
+ var RichEditor = forwardRef(function RichEditor2(props, ref) {
31
+ const [Engine, setEngine] = useState(() => engine);
32
+ const [failed, setFailed] = useState(false);
33
+ const [attempt, setAttempt] = useState(0);
34
+ useEffect(() => {
35
+ if (Engine) return;
36
+ let live = true;
37
+ loadEngine().then(
38
+ (loaded) => {
39
+ if (live) setEngine(() => loaded);
40
+ },
41
+ () => {
42
+ if (live) setFailed(true);
43
+ }
44
+ );
45
+ return () => {
46
+ live = false;
47
+ };
48
+ }, [Engine, attempt]);
49
+ if (Engine) return /* @__PURE__ */ jsx(Engine, { ref, ...props });
50
+ const text = richEditorLabels(props.labels);
51
+ if (failed) {
52
+ return /* @__PURE__ */ jsx(
53
+ Callout,
54
+ {
55
+ variant: "danger",
56
+ title: text.failed,
57
+ action: /* @__PURE__ */ jsx(
58
+ Button,
59
+ {
60
+ size: "small",
61
+ variant: "secondary",
62
+ onClick: () => {
63
+ setFailed(false);
64
+ setAttempt((n) => n + 1);
65
+ },
66
+ children: text.retry
67
+ }
68
+ ),
69
+ children: text.failedDetail
70
+ }
71
+ );
72
+ }
73
+ return /* @__PURE__ */ jsx("div", { className: "crewlet-rich-editor crewlet-rich-editor--loading", "aria-busy": "true", children: props.fallback ?? /* @__PURE__ */ jsx(Skeleton, { variant: "text", rows: 6, label: text.loading }) });
74
+ });
75
+
76
+ export { RichEditor, preloadRichEditor };