@crewlethq/ui 0.27.1 → 0.29.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 (114) hide show
  1. package/README.md +42 -2
  2. package/dist/AccessDeniedCard/index.js +3 -3
  3. package/dist/Accordion/index.js +3 -3
  4. package/dist/AppShell/index.js +3 -3
  5. package/dist/{AppShell-APHZKJYH.css → AppShell-GCM4TDVY.css} +4 -1
  6. package/dist/ArrangeGrid/ArrangeGrid.d.ts +22 -0
  7. package/dist/ArrangeGrid/index.d.ts +3 -0
  8. package/dist/ArrangeGrid/index.js +2 -0
  9. package/dist/ArrangeGrid-XM4ZFTED.css +17 -0
  10. package/dist/ArrangeGroup/index.js +1 -1
  11. package/dist/{ArrangeGroup-SHFHA7BE.css → ArrangeGroup-GY5YMP6E.css} +3 -4
  12. package/dist/ArtifactBar/ArtifactBar.d.ts +143 -0
  13. package/dist/ArtifactBar/index.d.ts +3 -0
  14. package/dist/ArtifactBar/index.js +25 -0
  15. package/dist/ArtifactBar-IBWB5POL.css +358 -0
  16. package/dist/ArtifactCard/index.js +3 -3
  17. package/dist/ArtifactCover/index.js +4 -4
  18. package/dist/ArtifactIcon/index.js +4 -4
  19. package/dist/ArtifactPanel/ArtifactPanel.d.ts +81 -0
  20. package/dist/ArtifactPanel/index.d.ts +3 -0
  21. package/dist/ArtifactPanel/index.js +5 -0
  22. package/dist/ArtifactPanel-YFXT5O77.css +132 -0
  23. package/dist/AuthLayout/index.js +3 -3
  24. package/dist/AvatarPicker/index.js +4 -4
  25. package/dist/Canvas/index.js +2 -2
  26. package/dist/CanvasBoard/index.js +4 -4
  27. package/dist/Card/index.js +2 -2
  28. package/dist/ChangeMark/index.js +1 -1
  29. package/dist/Charts/index.js +1 -1
  30. package/dist/{Charts-JYW4X5ZL.css → Charts-RY4JN5FC.css} +12 -0
  31. package/dist/CommandPalette/index.js +5 -5
  32. package/dist/CommentThread/index.js +4 -4
  33. package/dist/Composer/index.js +2 -2
  34. package/dist/DataTable/DataTable.d.ts +9 -0
  35. package/dist/DataTable/index.js +4 -4
  36. package/dist/DataView/index.js +10 -10
  37. package/dist/DatasetSource/index.js +1 -1
  38. package/dist/{DatasetSource-47LBDMPR.css → DatasetSource-XFPZBRXL.css} +12 -4
  39. package/dist/DateTimePicker/index.js +3 -3
  40. package/dist/Disclosure/index.js +3 -3
  41. package/dist/FollowBanner/index.js +2 -2
  42. package/dist/HuePicker/index.js +2 -2
  43. package/dist/LinkInterstitial/index.js +3 -3
  44. package/dist/ListInput/index.js +2 -2
  45. package/dist/MarkdownEditor/index.js +1 -1
  46. package/dist/Menu/index.js +2 -2
  47. package/dist/Modal/index.js +2 -2
  48. package/dist/Note/Note.d.ts +10 -0
  49. package/dist/Note/index.js +1 -1
  50. package/dist/{Note-RT4L6VUT.css → Note-ONSKKTOA.css} +10 -0
  51. package/dist/PeopleRail/PeopleRail.d.ts +8 -1
  52. package/dist/PeopleRail/index.js +2 -2
  53. package/dist/{PeopleRail-R64WVOSH.css → PeopleRail-SZGHZXVT.css} +8 -0
  54. package/dist/PresenceStack/index.js +1 -1
  55. package/dist/PresenterView/index.js +1 -1
  56. package/dist/ShareDialog/index.js +4 -4
  57. package/dist/SheetGrid/index.js +4 -4
  58. package/dist/SlideCompare/index.js +1 -1
  59. package/dist/Switcher/index.js +4 -4
  60. package/dist/ThemeSwitcher/index.js +1 -1
  61. package/dist/TimeWindowPicker/index.js +3 -3
  62. package/dist/TreeCanvas/index.js +3 -3
  63. package/dist/VersionCompare/index.js +2 -2
  64. package/dist/WidgetFrame/WidgetFrame.d.ts +14 -1
  65. package/dist/WidgetFrame/index.js +1 -1
  66. package/dist/WidgetFrame-LRZIL62O.css +206 -0
  67. package/dist/{chunk-V2Z24W2Z.js → chunk-4JUKWWUD.js} +1 -1
  68. package/dist/{chunk-MLT2HBPN.js → chunk-77DRMDXR.js} +7 -2
  69. package/dist/{chunk-BQYQWJPK.js → chunk-AAOH2P6Y.js} +8 -2
  70. package/dist/{chunk-35XVR5JQ.js → chunk-B4EBHPK3.js} +2 -2
  71. package/dist/chunk-CJKMURZO.js +31 -0
  72. package/dist/{chunk-INTEH4F3.js → chunk-CT4EZF62.js} +2 -2
  73. package/dist/{chunk-SVW3VG72.js → chunk-EBJREOKS.js} +5 -4
  74. package/dist/{chunk-BFQK7CYJ.js → chunk-EBNI36UQ.js} +2 -2
  75. package/dist/{chunk-M2VJGNCD.js → chunk-FKULOLKG.js} +2 -2
  76. package/dist/{chunk-6J35F334.js → chunk-GOSQXEZU.js} +1 -1
  77. package/dist/{chunk-5OY4LJFH.js → chunk-HVNTQ36V.js} +2 -2
  78. package/dist/chunk-I3BSQUKN.js +121 -0
  79. package/dist/{chunk-3D7PSL2L.js → chunk-JODJS7MR.js} +2 -2
  80. package/dist/{chunk-URUGEAFB.js → chunk-JQLTG4KH.js} +1 -1
  81. package/dist/{chunk-S4RCG44T.js → chunk-MICH6QSJ.js} +1 -1
  82. package/dist/chunk-QBA5B2Z5.js +17 -0
  83. package/dist/chunk-QMBP23BL.js +347 -0
  84. package/dist/{chunk-G2AVKPSL.js → chunk-RIAZM6L3.js} +1 -1
  85. package/dist/{chunk-OJRDEVHV.js → chunk-RODMM35O.js} +5 -5
  86. package/dist/{chunk-RSC7UJCR.js → chunk-S6VG5ZFZ.js} +1 -1
  87. package/dist/{chunk-PRNX5AFE.js → chunk-TGYDROIB.js} +1 -1
  88. package/dist/{chunk-G3EEUNZQ.js → chunk-UB7TJEKZ.js} +1 -1
  89. package/dist/chunk-UQHKFF2N.js +106 -0
  90. package/dist/{chunk-WHZFDS62.js → chunk-VDPJGP4Q.js} +1 -1
  91. package/dist/{chunk-GTLJXJ3U.js → chunk-VVRL27HM.js} +2 -2
  92. package/dist/{chunk-MQEEQVG6.js → chunk-XALUCIG5.js} +1 -1
  93. package/dist/{chunk-ZZDY4XL7.js → chunk-ZB5O3ELS.js} +12 -12
  94. package/dist/{chunk-L2OQRPXJ.js → chunk-ZR5VN5IV.js} +1 -1
  95. package/dist/generated/index.d.ts +3 -0
  96. package/dist/generated/index.js +91 -88
  97. package/dist/index.js +91 -88
  98. package/dist/styles.css +658 -23
  99. package/package.json +3 -3
  100. package/dist/WidgetFrame-4EFJOJMW.css +0 -127
  101. package/dist/chunk-63WJLRB2.js +0 -24
  102. package/dist/chunk-FVLCTCMV.js +0 -96
  103. package/dist/{chunk-UFKUWVMV.js → chunk-2HIOJ4YZ.js} +1 -1
  104. package/dist/{chunk-RIEDQSA4.js → chunk-7DZDSSJS.js} +1 -1
  105. package/dist/{chunk-YZCJ63JF.js → chunk-ACA27MZH.js} +1 -1
  106. package/dist/{chunk-ENJUPIND.js → chunk-FZVJDJFN.js} +1 -1
  107. package/dist/{chunk-F4DPAJCN.js → chunk-I3KKZ2O3.js} +1 -1
  108. package/dist/{chunk-SLRKS5PF.js → chunk-IFNQKWUO.js} +0 -0
  109. package/dist/{chunk-FW7HN6AP.js → chunk-LDJ3J4TQ.js} +1 -1
  110. package/dist/{chunk-SGIQCI6Y.js → chunk-LIXSV5YI.js} +1 -1
  111. package/dist/{chunk-KZOGQXSP.js → chunk-OJ45PPCV.js} +1 -1
  112. package/dist/{chunk-LREN6TUG.js → chunk-UZ6MA2V6.js} +2 -2
  113. package/dist/{chunk-WG5WUFBX.js → chunk-Y5NQ2LMS.js} +1 -1
  114. package/dist/{chunk-D5JZN3ML.js → chunk-Z6VW6CXX.js} +1 -1
@@ -0,0 +1,347 @@
1
+ import { isApplePlatform, Kbd } from './chunk-SMBKXWML.js';
2
+ import { Tooltip } from './chunk-QWOPX2MN.js';
3
+ import { SegmentedControl } from './chunk-RCQXUT5K.js';
4
+ import { ArtifactIcon } from './chunk-4JUKWWUD.js';
5
+ import { Menu } from './chunk-2HIOJ4YZ.js';
6
+ import { Button } from './chunk-OG6CL3EB.js';
7
+ import { IconButton } from './chunk-4FQT6ZAY.js';
8
+ import { VisuallyHidden } from './chunk-BZFWDIV6.js';
9
+ import { cx } from './chunk-ODEQTPFM.js';
10
+ import './ArtifactBar-IBWB5POL.css';
11
+ import { useId, useState, useRef, useEffect } from 'react';
12
+ import { ChevronLeftGlyph, EllipsisGlyph, ChevronDownGlyph } from '@crewlethq/icons/glyphs';
13
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
14
+
15
+ var ARTIFACT_BAR_LABELS = {
16
+ more: (title) => `More for \u201C${title}\u201D`,
17
+ renameHint: "Rename",
18
+ titleField: "Title",
19
+ emptyTitle: "A title cannot be empty."
20
+ };
21
+ function ArtifactBar({
22
+ title,
23
+ kind,
24
+ icon,
25
+ kindLabel,
26
+ back,
27
+ start,
28
+ onRename,
29
+ renaming,
30
+ onRenamingChange,
31
+ version,
32
+ modes,
33
+ presence,
34
+ kindTools = [],
35
+ tools = [],
36
+ menu = [],
37
+ as = "header",
38
+ headingLevel = 1,
39
+ pending = false,
40
+ labels,
41
+ className
42
+ }) {
43
+ const words = { ...ARTIFACT_BAR_LABELS, ...labels };
44
+ const headingId = useId();
45
+ const Root = as;
46
+ const apple = isApplePlatform();
47
+ const folding = [...kindTools, ...tools].filter((t) => !t.labelled);
48
+ const pinned = [...kindTools, ...tools].filter((t) => t.labelled);
49
+ const folded = [
50
+ ...modes ? modes.options.map(
51
+ (option) => ({
52
+ key: `mode:${option.value}`,
53
+ label: option.label,
54
+ icon: option.icon,
55
+ checked: option.value === modes.value,
56
+ onSelect: () => modes.onValueChange(option.value)
57
+ })
58
+ ) : [],
59
+ ...modes && folding.length > 0 ? [{ kind: "separator", key: "sep:modes" }] : [],
60
+ ...folding.map(
61
+ (tool) => ({
62
+ key: `tool:${tool.key}`,
63
+ label: tool.label,
64
+ icon: tool.icon,
65
+ onSelect: tool.onSelect,
66
+ ...tool.disabledReason !== void 0 ? { disabled: true, description: tool.disabledReason } : {},
67
+ ...tool.keys ? { hint: /* @__PURE__ */ jsx(Kbd, { keys: tool.keys, subtle: true, apple }) } : {}
68
+ })
69
+ )
70
+ ];
71
+ const narrowMenu = [
72
+ ...folded,
73
+ ...folded.length > 0 && menu.length > 0 ? [{ kind: "separator", key: "sep:menu" }] : [],
74
+ ...menu
75
+ ];
76
+ return /* @__PURE__ */ jsx(
77
+ Root,
78
+ {
79
+ className: cx("crewlet-artifact-bar", presence ? "crewlet-artifact-bar--present" : null, className),
80
+ "aria-labelledby": pending ? void 0 : headingId,
81
+ children: /* @__PURE__ */ jsxs("div", { className: cx("crewlet-artifact-bar__row", modes && "crewlet-artifact-bar__row--centred"), children: [
82
+ /* @__PURE__ */ jsxs("div", { className: "crewlet-artifact-bar__lead", children: [
83
+ start,
84
+ back ? /* @__PURE__ */ jsx(Tooltip, { content: back.label, placement: "bottom", children: /* @__PURE__ */ jsx(IconButton, { asChild: true, label: back.label, size: "sm", variant: "ghost", title: "", children: /* @__PURE__ */ jsx("a", { href: back.href, children: /* @__PURE__ */ jsx(ChevronLeftGlyph, { size: "sm" }) }) }) }) : null,
85
+ /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__glyph", role: "img", "aria-label": kindLabel, title: kindLabel, children: /* @__PURE__ */ jsx(ArtifactIcon, { icon: icon ?? void 0, kind, size: "sm" }) }),
86
+ pending ? /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__placeholder", "aria-hidden": true }) : /* @__PURE__ */ jsx(
87
+ BarTitle,
88
+ {
89
+ title,
90
+ id: headingId,
91
+ level: headingLevel,
92
+ onRename,
93
+ renaming,
94
+ onRenamingChange,
95
+ words
96
+ }
97
+ ),
98
+ version ? /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__version", children: version }) : null
99
+ ] }),
100
+ modes ? /* @__PURE__ */ jsx("div", { className: "crewlet-artifact-bar__modes crewlet-artifact-bar__wide", children: /* @__PURE__ */ jsx(
101
+ SegmentedControl,
102
+ {
103
+ label: modes.label,
104
+ semantics: "radio",
105
+ size: "sm",
106
+ options: modes.options.map((o) => ({ value: o.value, label: o.label, ...o.icon ? { icon: o.icon } : {} })),
107
+ value: modes.value,
108
+ onValueChange: modes.onValueChange
109
+ }
110
+ ) }) : null,
111
+ /* @__PURE__ */ jsxs("div", { className: "crewlet-artifact-bar__end", children: [
112
+ presence ? /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__presence", children: presence }) : null,
113
+ kindTools.some((t) => !t.labelled) ? /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__tools crewlet-artifact-bar__wide", children: kindTools.filter((t) => !t.labelled).map((tool) => /* @__PURE__ */ jsx(ToolButton, { tool, apple }, tool.key)) }) : null,
114
+ tools.some((t) => !t.labelled) ? /* @__PURE__ */ jsxs("span", { className: "crewlet-artifact-bar__tools crewlet-artifact-bar__wide", children: [
115
+ kindTools.some((t) => !t.labelled) ? /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__rule", "aria-hidden": true }) : null,
116
+ tools.filter((t) => !t.labelled).map((tool) => /* @__PURE__ */ jsx(ToolButton, { tool, apple }, tool.key))
117
+ ] }) : null,
118
+ pinned.length > 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__tools", children: pinned.map((tool) => /* @__PURE__ */ jsx(LabelledTool, { tool, apple }, tool.key)) }) : null,
119
+ menu.length > 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__wide", children: /* @__PURE__ */ jsx(Menu, { label: words.more(title), icon: /* @__PURE__ */ jsx(EllipsisGlyph, { size: "sm" }), triggerVariant: "ghost", align: "end", items: menu }) }) : null,
120
+ narrowMenu.length > 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__narrow", children: /* @__PURE__ */ jsx(
121
+ Menu,
122
+ {
123
+ label: words.more(title),
124
+ icon: /* @__PURE__ */ jsx(EllipsisGlyph, { size: "sm" }),
125
+ triggerVariant: "ghost",
126
+ align: "end",
127
+ items: narrowMenu
128
+ }
129
+ ) }) : null
130
+ ] })
131
+ ] })
132
+ }
133
+ );
134
+ }
135
+ function ariaKeys(keys, apple) {
136
+ return keys.map((key) => {
137
+ if (key === "Mod") return apple ? "Meta" : "Control";
138
+ return key.length === 1 ? key.toUpperCase() : key;
139
+ }).join("+");
140
+ }
141
+ function Tip({ tool, apple }) {
142
+ return /* @__PURE__ */ jsxs("span", { className: "crewlet-artifact-bar__tip", children: [
143
+ tool.label,
144
+ tool.keys ? /* @__PURE__ */ jsx(Kbd, { keys: tool.keys, subtle: true, apple }) : null
145
+ ] });
146
+ }
147
+ function ToolButton({ tool, apple }) {
148
+ return /* @__PURE__ */ jsxs("span", { className: "crewlet-artifact-bar__tool", children: [
149
+ /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(Tip, { tool, apple }), placement: "bottom", children: /* @__PURE__ */ jsx(
150
+ IconButton,
151
+ {
152
+ label: tool.label,
153
+ icon: tool.icon,
154
+ size: "sm",
155
+ variant: "ghost",
156
+ title: "",
157
+ pressed: tool.pressed,
158
+ disabledReason: tool.disabledReason,
159
+ "aria-keyshortcuts": tool.keys ? ariaKeys(tool.keys, apple) : void 0,
160
+ onClick: tool.onSelect
161
+ }
162
+ ) }),
163
+ tool.badge !== void 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__badge", "aria-hidden": true, children: tool.badge }) : null
164
+ ] });
165
+ }
166
+ function LabelledTool({ tool, apple }) {
167
+ const shortcut = tool.keys ? ariaKeys(tool.keys, apple) : void 0;
168
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
169
+ /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__roomy", children: /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(Tip, { tool, apple }), placement: "bottom", disabled: !tool.keys, children: /* @__PURE__ */ jsx(
170
+ Button,
171
+ {
172
+ size: "small",
173
+ variant: "secondary",
174
+ leadingIcon: tool.icon,
175
+ pressed: tool.pressed,
176
+ disabledReason: tool.disabledReason,
177
+ "aria-keyshortcuts": shortcut,
178
+ onClick: tool.onSelect,
179
+ children: tool.label
180
+ }
181
+ ) }) }),
182
+ /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__tight", children: /* @__PURE__ */ jsx(Tooltip, { content: /* @__PURE__ */ jsx(Tip, { tool, apple }), placement: "bottom", children: /* @__PURE__ */ jsx(
183
+ IconButton,
184
+ {
185
+ label: tool.label,
186
+ icon: tool.icon,
187
+ size: "sm",
188
+ variant: "ghost",
189
+ title: "",
190
+ pressed: tool.pressed,
191
+ disabledReason: tool.disabledReason,
192
+ "aria-keyshortcuts": shortcut,
193
+ onClick: tool.onSelect
194
+ }
195
+ ) }) })
196
+ ] });
197
+ }
198
+ function BarTitle({
199
+ title,
200
+ id,
201
+ level,
202
+ onRename,
203
+ renaming,
204
+ onRenamingChange,
205
+ words
206
+ }) {
207
+ const Heading = `h${level}`;
208
+ const hintId = useId();
209
+ const errorId = useId();
210
+ const [own, setOwn] = useState(false);
211
+ const editing = (renaming ?? own) && onRename !== void 0;
212
+ const setEditing = (on) => {
213
+ if (renaming === void 0) setOwn(on);
214
+ onRenamingChange?.(on);
215
+ };
216
+ const [draft, setDraft] = useState(title);
217
+ const [error, setError] = useState(null);
218
+ const [busy, setBusy] = useState(false);
219
+ const field = useRef(null);
220
+ const button = useRef(null);
221
+ const settled = useRef(false);
222
+ useEffect(() => {
223
+ if (!editing) return;
224
+ settled.current = false;
225
+ setDraft(title);
226
+ setError(null);
227
+ const el = field.current;
228
+ el?.focus();
229
+ el?.select();
230
+ }, [editing]);
231
+ if (onRename === void 0) {
232
+ return /* @__PURE__ */ jsx(Heading, { id, className: "crewlet-artifact-bar__title", title, children: title });
233
+ }
234
+ const finish = (refocus) => {
235
+ settled.current = true;
236
+ setEditing(false);
237
+ setError(null);
238
+ if (refocus) requestAnimationFrame(() => button.current?.focus());
239
+ };
240
+ const commit = async (refocus) => {
241
+ if (settled.current || busy) return;
242
+ const next = draft.trim();
243
+ if (next === title) {
244
+ finish(refocus);
245
+ return;
246
+ }
247
+ if (next === "") {
248
+ setError(words.emptyTitle);
249
+ return;
250
+ }
251
+ setBusy(true);
252
+ try {
253
+ const answer = await onRename(next);
254
+ if (typeof answer === "string" && answer !== "") {
255
+ setError(answer);
256
+ field.current?.focus();
257
+ return;
258
+ }
259
+ finish(refocus);
260
+ } finally {
261
+ setBusy(false);
262
+ }
263
+ };
264
+ const onKeyDown = (event) => {
265
+ if (event.nativeEvent.isComposing) return;
266
+ if (event.key === "Enter") {
267
+ event.preventDefault();
268
+ void commit(true);
269
+ } else if (event.key === "Escape") {
270
+ event.preventDefault();
271
+ event.stopPropagation();
272
+ finish(true);
273
+ }
274
+ };
275
+ if (editing) {
276
+ return /* @__PURE__ */ jsxs(Heading, { id, className: "crewlet-artifact-bar__title crewlet-artifact-bar__title--editing", children: [
277
+ /* @__PURE__ */ jsx("span", { className: "crewlet-artifact-bar__sizer", "data-value": draft || " ", children: /* @__PURE__ */ jsx(
278
+ "input",
279
+ {
280
+ ref: field,
281
+ className: "crewlet-artifact-bar__field",
282
+ "aria-label": words.titleField,
283
+ "aria-invalid": error ? true : void 0,
284
+ "aria-describedby": error ? errorId : void 0,
285
+ "aria-busy": busy || void 0,
286
+ readOnly: busy,
287
+ value: draft,
288
+ size: 1,
289
+ onChange: (event) => {
290
+ setDraft(event.target.value);
291
+ if (error) setError(null);
292
+ },
293
+ onKeyDown,
294
+ onBlur: () => void commit(false)
295
+ }
296
+ ) }),
297
+ error ? /* @__PURE__ */ jsx("span", { id: errorId, role: "alert", className: "crewlet-artifact-bar__error", children: error }) : null
298
+ ] });
299
+ }
300
+ return /* @__PURE__ */ jsxs(Fragment, { children: [
301
+ /* @__PURE__ */ jsx(Heading, { id, className: "crewlet-artifact-bar__title", children: /* @__PURE__ */ jsx(
302
+ "button",
303
+ {
304
+ ref: button,
305
+ type: "button",
306
+ className: "crewlet-artifact-bar__rename",
307
+ title,
308
+ "aria-describedby": hintId,
309
+ onClick: () => setEditing(true),
310
+ children: title
311
+ }
312
+ ) }),
313
+ /* @__PURE__ */ jsx(VisuallyHidden, { id: hintId, children: words.renameHint })
314
+ ] });
315
+ }
316
+ function ArtifactVersionChip({
317
+ version,
318
+ latest,
319
+ items,
320
+ label = "Versions",
321
+ format = (v, l) => v === l ? `v${v}` : `v${v} of ${l}`
322
+ }) {
323
+ const older = version !== latest;
324
+ return /* @__PURE__ */ jsx(
325
+ Menu,
326
+ {
327
+ label,
328
+ items,
329
+ align: "start",
330
+ renderTrigger: (props) => /* @__PURE__ */ jsxs(
331
+ "button",
332
+ {
333
+ ...props,
334
+ type: "button",
335
+ className: cx("crewlet-version-chip", older && "crewlet-version-chip--older"),
336
+ "aria-label": `${label}: ${format(version, latest)}`,
337
+ children: [
338
+ /* @__PURE__ */ jsx("span", { className: "crewlet-version-chip__words", children: format(version, latest) }),
339
+ /* @__PURE__ */ jsx(ChevronDownGlyph, { size: "xs" })
340
+ ]
341
+ }
342
+ )
343
+ }
344
+ );
345
+ }
346
+
347
+ export { ARTIFACT_BAR_LABELS, ArtifactBar, ArtifactVersionChip };
@@ -1,4 +1,4 @@
1
- import { DisclosureAnatomy } from './chunk-ENJUPIND.js';
1
+ import { DisclosureAnatomy } from './chunk-FZVJDJFN.js';
2
2
  import { useHeadingLevel } from './chunk-PQADV6P6.js';
3
3
  import { cx } from './chunk-ODEQTPFM.js';
4
4
  import './Disclosure-VKBJJIZ7.css';
@@ -1,14 +1,14 @@
1
1
  import { PageHeader } from './chunk-HOXGBLEY.js';
2
2
  import { Toolbar } from './chunk-PGRPNDWM.js';
3
- import { DataTable } from './chunk-SVW3VG72.js';
4
- import { DateTimePicker } from './chunk-WG5WUFBX.js';
3
+ import { DateTimePicker } from './chunk-Y5NQ2LMS.js';
4
+ import { DataTable } from './chunk-EBJREOKS.js';
5
5
  import { useListbox, useOptionKeys } from './chunk-F73MC7EZ.js';
6
- import { Kbd } from './chunk-SMBKXWML.js';
6
+ import { Popover } from './chunk-BWRGFKJP.js';
7
7
  import { Input } from './chunk-6QFAK2WV.js';
8
+ import { Kbd } from './chunk-SMBKXWML.js';
8
9
  import { RelativeTime } from './chunk-3CZ7XAVY.js';
9
- import { Popover } from './chunk-BWRGFKJP.js';
10
10
  import { Count } from './chunk-BHHIIK3M.js';
11
- import { Menu } from './chunk-UFKUWVMV.js';
11
+ import { Menu } from './chunk-2HIOJ4YZ.js';
12
12
  import { Button } from './chunk-OG6CL3EB.js';
13
13
  import { IconButton } from './chunk-4FQT6ZAY.js';
14
14
  import { VisuallyHidden } from './chunk-BZFWDIV6.js';
@@ -1,5 +1,5 @@
1
1
  import { useTreeState, useMeasuredSizes, layoutForest, treeAncestors, useLayoutAnchor, treeExpandable, layoutConnectors, treeItemAction, treeStep, treePosInSet, treeSetSize, treeLevel, placeGroups } from './chunk-MY374UUD.js';
2
- import { CANVAS_COMPOSE_CONTEXT, CANVAS_FIT_MAX_ZOOM, Canvas } from './chunk-KZOGQXSP.js';
2
+ import { CANVAS_COMPOSE_CONTEXT, CANVAS_FIT_MAX_ZOOM, Canvas } from './chunk-OJ45PPCV.js';
3
3
  import { focusables } from './chunk-R25RGPUB.js';
4
4
  import { cx } from './chunk-ODEQTPFM.js';
5
5
  import './TreeCanvas-L2XYONWL.css';
@@ -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';
@@ -1,7 +1,7 @@
1
- import { Modal } from './chunk-F4DPAJCN.js';
1
+ import { Modal } from './chunk-I3KKZ2O3.js';
2
2
  import { useListbox, useHighlightRest } from './chunk-F73MC7EZ.js';
3
- import { Kbd } from './chunk-SMBKXWML.js';
4
3
  import { Input } from './chunk-6QFAK2WV.js';
4
+ import { Kbd } from './chunk-SMBKXWML.js';
5
5
  import { Count } from './chunk-BHHIIK3M.js';
6
6
  import { isComposing } from './chunk-R25RGPUB.js';
7
7
  import { VisuallyHidden } from './chunk-BZFWDIV6.js';
@@ -1,5 +1,5 @@
1
1
  import { Document } from './chunk-WI6K5M5X.js';
2
- import { ArtifactKindGlyph } from './chunk-6J35F334.js';
2
+ import { ArtifactKindGlyph } from './chunk-GOSQXEZU.js';
3
3
  import { cx } from './chunk-ODEQTPFM.js';
4
4
  import './ArtifactCover-D4MBEJ5H.css';
5
5
  import './DashboardCover-RMINBODB.css';
@@ -2,7 +2,7 @@ import { Tag } from './chunk-GFV4LJHH.js';
2
2
  import { RelativeTime } from './chunk-3CZ7XAVY.js';
3
3
  import { VisuallyHidden } from './chunk-BZFWDIV6.js';
4
4
  import { cx } from './chunk-ODEQTPFM.js';
5
- import './DatasetSource-47LBDMPR.css';
5
+ import './DatasetSource-XFPZBRXL.css';
6
6
  import { useId, Children, isValidElement } from 'react';
7
7
  import { ClockGlyph } from '@crewlethq/icons/glyphs';
8
8
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
@@ -66,18 +66,18 @@ function DatasetSource({
66
66
  rows !== void 0 && !blocked && status !== "loading" ? /* @__PURE__ */ jsxs(Fragment, { children: [
67
67
  " ",
68
68
  /* @__PURE__ */ jsx("span", { className: "crewlet-dataset-source__rows", children: text.rows(rows) })
69
- ] }) : null,
70
- refresh ? /* @__PURE__ */ jsxs(Fragment, { children: [
71
- " ",
72
- /* @__PURE__ */ jsxs("span", { className: "crewlet-dataset-source__refresh", children: [
73
- /* @__PURE__ */ jsxs(VisuallyHidden, { children: [
74
- text.refresh,
75
- " "
76
- ] }),
77
- refresh
78
- ] })
79
69
  ] }) : null
80
- ] })
70
+ ] }),
71
+ refresh ? /* @__PURE__ */ jsxs(Fragment, { children: [
72
+ " ",
73
+ /* @__PURE__ */ jsxs("span", { className: "crewlet-dataset-source__refresh", children: [
74
+ /* @__PURE__ */ jsxs(VisuallyHidden, { children: [
75
+ text.refresh,
76
+ " "
77
+ ] }),
78
+ refresh
79
+ ] })
80
+ ] }) : null
81
81
  ] });
82
82
  return /* @__PURE__ */ jsxs(
83
83
  "div",
@@ -1,4 +1,4 @@
1
- import { ConfirmModal } from './chunk-F4DPAJCN.js';
1
+ import { ConfirmModal } from './chunk-I3KKZ2O3.js';
2
2
  import { InlineCode } from './chunk-5CLW2CXT.js';
3
3
  import { Callout } from './chunk-SVSCLHHI.js';
4
4
  import './LinkInterstitial-ET4MSVSV.css';
@@ -5,11 +5,14 @@ export * from '../Announcer/index.js';
5
5
  export * from '../AppShell/index.js';
6
6
  export * from '../ArrangeBoard/index.js';
7
7
  export * from '../ArrangeFrame/index.js';
8
+ export * from '../ArrangeGrid/index.js';
8
9
  export * from '../ArrangeGroup/index.js';
9
10
  export * from '../ArrangeList/index.js';
11
+ export * from '../ArtifactBar/index.js';
10
12
  export * from '../ArtifactCard/index.js';
11
13
  export * from '../ArtifactCover/index.js';
12
14
  export * from '../ArtifactIcon/index.js';
15
+ export * from '../ArtifactPanel/index.js';
13
16
  export * from '../AuthLayout/index.js';
14
17
  export * from '../Avatar/index.js';
15
18
  export * from '../AvatarPicker/index.js';