@crewlethq/ui 0.38.0 → 0.40.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 (157) hide show
  1. package/README.md +79 -3
  2. package/dist/AgentHandoffPanel/index.js +3 -3
  3. package/dist/AppShell/AppShell.d.ts +13 -2
  4. package/dist/AppShell/index.js +1 -1
  5. package/dist/{AppShell-NDU4XMGF.css → AppShell-NPSWZ3XW.css} +45 -4
  6. package/dist/ArtifactBar/index.js +6 -5
  7. package/dist/{ArtifactBar-FWPBBKQ5.css → ArtifactBar-6PGWGKN2.css} +13 -1
  8. package/dist/ArtifactCard/index.js +2 -2
  9. package/dist/AuthLayout/index.js +2 -2
  10. package/dist/AvatarPicker/index.js +10 -6
  11. package/dist/Card/Card.d.ts +14 -2
  12. package/dist/Card/index.js +1 -1
  13. package/dist/{Card-G2ZGT5Z6.css → Card-JR2UPQH7.css} +20 -0
  14. package/dist/CatalogTile/CatalogTile.d.ts +47 -0
  15. package/dist/CatalogTile/index.d.ts +3 -0
  16. package/dist/CatalogTile/index.js +3 -0
  17. package/dist/CatalogTile-XL4XLFUH.css +135 -0
  18. package/dist/CharacterPicker/index.js +2 -2
  19. package/dist/Charts/Histogram.d.ts +71 -0
  20. package/dist/Charts/index.d.ts +2 -0
  21. package/dist/Charts/index.js +1 -1
  22. package/dist/{Charts-MBJG72BS.css → Charts-TZ744HT6.css} +118 -0
  23. package/dist/CodeBlock/index.js +1 -1
  24. package/dist/{CodeBlock-GYNJ2HI6.css → CodeBlock-N5ETJF24.css} +13 -0
  25. package/dist/CommandPalette/index.js +3 -3
  26. package/dist/CommentThread/index.js +3 -3
  27. package/dist/Composer/index.js +2 -2
  28. package/dist/DataGrid/DataGrid.d.ts +267 -0
  29. package/dist/DataGrid/index.d.ts +3 -0
  30. package/dist/DataGrid/index.js +7 -0
  31. package/dist/DataGrid-AQKPJD7W.css +482 -0
  32. package/dist/DataTable/index.js +2 -2
  33. package/dist/DataView/index.js +4 -4
  34. package/dist/DatasetSource/DatasetSource.d.ts +7 -1
  35. package/dist/DatasetSource/index.js +1 -1
  36. package/dist/HuePicker/index.js +11 -4
  37. package/dist/LayersList/index.js +2 -2
  38. package/dist/LinkInterstitial/index.js +2 -2
  39. package/dist/List/List.d.ts +8 -0
  40. package/dist/List/index.js +1 -1
  41. package/dist/{List-MYJIV6MP.css → List-YHLIZFK4.css} +46 -0
  42. package/dist/ListInput/ListInput.d.ts +9 -1
  43. package/dist/ListInput/index.js +2 -2
  44. package/dist/LockedLabel/LockedLabel.d.ts +34 -0
  45. package/dist/LockedLabel/index.d.ts +3 -0
  46. package/dist/LockedLabel/index.js +3 -0
  47. package/dist/LockedLabel-VQEGEB7G.css +16 -0
  48. package/dist/MarkdownEditor/index.js +8 -5
  49. package/dist/MergeConflicts/index.js +11 -5
  50. package/dist/Modal/index.js +1 -1
  51. package/dist/{Modal-7MWRCWAI.css → Modal-TOEWHDCQ.css} +5 -0
  52. package/dist/ObjectHeader/index.js +1 -1
  53. package/dist/{ObjectHeader-D7GU7QNI.css → ObjectHeader-ZOS22FKX.css} +7 -8
  54. package/dist/PageNote/PageNote.d.ts +14 -0
  55. package/dist/PageNote/index.d.ts +3 -0
  56. package/dist/PageNote/index.js +2 -0
  57. package/dist/PageNote-RHLXH3ML.css +12 -0
  58. package/dist/PropertyList/PropertyList.d.ts +88 -0
  59. package/dist/PropertyList/index.d.ts +3 -0
  60. package/dist/PropertyList/index.js +7 -0
  61. package/dist/PropertyList-SCYM66LL.css +96 -0
  62. package/dist/RelatedRow/RelatedRow.d.ts +27 -0
  63. package/dist/RelatedRow/index.d.ts +3 -0
  64. package/dist/RelatedRow/index.js +9 -0
  65. package/dist/RelatedRow-2FVS6QQA.css +6 -0
  66. package/dist/RichEditor/index.js +1 -1
  67. package/dist/SectionFrame/SectionFrame.d.ts +76 -0
  68. package/dist/SectionFrame/index.d.ts +3 -0
  69. package/dist/SectionFrame/index.js +7 -0
  70. package/dist/SectionFrame-M62UUVFQ.css +164 -0
  71. package/dist/SegmentedControl/index.js +11 -4
  72. package/dist/SettingsTable/SettingsTable.d.ts +66 -0
  73. package/dist/SettingsTable/index.d.ts +3 -0
  74. package/dist/SettingsTable/index.js +3 -0
  75. package/dist/SettingsTable-6DUFAFXG.css +160 -0
  76. package/dist/ShareDialog/index.js +2 -2
  77. package/dist/SheetColumnEditor/index.js +7 -6
  78. package/dist/SheetGrid/index.js +3 -3
  79. package/dist/SidebarNav/SidebarNav.d.ts +35 -2
  80. package/dist/SidebarNav/index.js +2 -1
  81. package/dist/{SidebarNav-7SGUZYKK.css → SidebarNav-YI74SPDC.css} +10 -0
  82. package/dist/StatCard/index.js +1 -1
  83. package/dist/{StatCard-4T7TMWMN.css → StatCard-HAA3F5GX.css} +8 -3
  84. package/dist/StatGroup/index.js +1 -1
  85. package/dist/{StatGroup-DOFHX5QJ.css → StatGroup-ZMW7VQWP.css} +27 -0
  86. package/dist/Switcher/index.js +2 -2
  87. package/dist/Tabs/Tabs.d.ts +55 -1
  88. package/dist/Tabs/fold.d.ts +54 -0
  89. package/dist/Tabs/index.d.ts +1 -1
  90. package/dist/Tabs/index.js +9 -2
  91. package/dist/Tabs/roving.d.ts +3 -3
  92. package/dist/{Tabs-WIF7457H.css → Tabs-S7F4RWAN.css} +77 -0
  93. package/dist/TagsInput/index.js +1 -1
  94. package/dist/ThemeGallery/index.js +2 -2
  95. package/dist/ThemeSwitcher/index.js +12 -5
  96. package/dist/TileGrid/TileGrid.d.ts +33 -0
  97. package/dist/TileGrid/index.d.ts +3 -0
  98. package/dist/TileGrid/index.js +2 -0
  99. package/dist/TileGrid-I6LNYD2H.css +52 -0
  100. package/dist/VersionCompare/index.js +12 -5
  101. package/dist/{chunk-B5J23C73.js → chunk-2PEXZ7L4.js} +1 -1
  102. package/dist/{chunk-S27UBCVX.js → chunk-2VOHUGUA.js} +2 -2
  103. package/dist/{chunk-XBURIXHO.js → chunk-3TXY3PJZ.js} +1 -1
  104. package/dist/{chunk-2QZ2VPHR.js → chunk-4OK4DX3V.js} +2 -2
  105. package/dist/chunk-4RKTZSEW.js +64 -0
  106. package/dist/{chunk-ECGGQX2H.js → chunk-A44YHLCQ.js} +2 -2
  107. package/dist/{chunk-F4LPQA4E.js → chunk-BA32AVKS.js} +1 -1
  108. package/dist/chunk-CV4NES3P.js +9 -0
  109. package/dist/{chunk-PPHTIKZO.js → chunk-E4BOVKNJ.js} +1 -1
  110. package/dist/{chunk-W7PAIVAP.js → chunk-E7QLG3PG.js} +30 -9
  111. package/dist/{chunk-RKKO7QHH.js → chunk-EGMQURBR.js} +5 -4
  112. package/dist/{chunk-GMW4ZHST.js → chunk-EX22Q5SH.js} +2 -2
  113. package/dist/{chunk-A23KDROH.js → chunk-FXBGEANQ.js} +1 -1
  114. package/dist/{chunk-4L2BWSHR.js → chunk-GFYQKMQZ.js} +2 -2
  115. package/dist/{chunk-HG5VF3TZ.js → chunk-HMVQQEHW.js} +91 -2
  116. package/dist/{chunk-IPWU6ERC.js → chunk-HQJ24WPM.js} +4 -2
  117. package/dist/{chunk-SVGARBDY.js → chunk-IAGYPTEJ.js} +2 -2
  118. package/dist/{chunk-ZK3VYY7L.js → chunk-INHXF2CL.js} +24 -11
  119. package/dist/chunk-INVSUFJK.js +71 -0
  120. package/dist/{chunk-6NNY5WBF.js → chunk-JKAGN4V4.js} +1 -1
  121. package/dist/{chunk-4LRAJXHL.js → chunk-JSWOXRRE.js} +1 -1
  122. package/dist/{chunk-DYB66CNM.js → chunk-KKNHMXTE.js} +6 -3
  123. package/dist/{chunk-UWRBD2YO.js → chunk-KNHUBHFX.js} +1 -1
  124. package/dist/{chunk-ZMDYQ2HH.js → chunk-KWWP3D7M.js} +1 -1
  125. package/dist/{chunk-46RL3E54.js → chunk-M6NQ4XGK.js} +1 -1
  126. package/dist/{chunk-PT6WKXKW.js → chunk-MMPKN7WV.js} +1 -1
  127. package/dist/{chunk-NRBAXRWE.js → chunk-N3TFYBN3.js} +1 -1
  128. package/dist/chunk-NNTO3TNC.js +9 -0
  129. package/dist/{chunk-DS2C73RJ.js → chunk-NZWX27J7.js} +2 -2
  130. package/dist/{chunk-VGE3G3T4.js → chunk-ODOJJGXH.js} +1 -1
  131. package/dist/chunk-OHGH7O6T.js +19 -0
  132. package/dist/{chunk-4ISUIS6F.js → chunk-OOC7Q67K.js} +1 -1
  133. package/dist/{chunk-BT5H2THK.js → chunk-OUD75UB2.js} +1 -1
  134. package/dist/chunk-PCT47E7O.js +48 -0
  135. package/dist/{chunk-X3UYTAOG.js → chunk-PFZOFAQ6.js} +1 -1
  136. package/dist/{chunk-YQG4PZGC.js → chunk-QRKT4XTT.js} +2 -2
  137. package/dist/{chunk-BJI3RFXG.js → chunk-S4DREXGM.js} +1 -1
  138. package/dist/{chunk-GDDE4UM7.js → chunk-SEC2GR2V.js} +1 -1
  139. package/dist/{chunk-YEVG2X5R.js → chunk-SNQRGH4A.js} +1 -1
  140. package/dist/chunk-T6MXORP5.js +116 -0
  141. package/dist/{chunk-OTCXRJ7D.js → chunk-U2XAJONO.js} +1 -1
  142. package/dist/{chunk-3ZUINC7C.js → chunk-WYYCPV46.js} +6 -1
  143. package/dist/chunk-X4IXXLWM.js +306 -0
  144. package/dist/{chunk-PAQXOP2M.js → chunk-XGBUUQDU.js} +2 -2
  145. package/dist/chunk-XIDD7PJO.js +416 -0
  146. package/dist/{chunk-XO7PUL4F.js → chunk-YPTTSJPM.js} +1 -1
  147. package/dist/chunk-ZUTUI27P.js +21 -0
  148. package/dist/generated/index.d.ts +9 -0
  149. package/dist/generated/index.js +83 -74
  150. package/dist/index.js +83 -74
  151. package/dist/styles.css +1627 -104
  152. package/package.json +3 -3
  153. package/dist/chunk-7SDUKCNW.js +0 -141
  154. package/dist/{Editor-QV4JP242.js → Editor-IRDQ3JDZ.js} +1 -1
  155. package/dist/{chunk-JZPK4IXR.js → chunk-3PR65I3H.js} +2 -2
  156. package/dist/{chunk-ETVEGR2Y.js → chunk-ISA2O2BK.js} +1 -1
  157. /package/dist/{chunk-4QQ3MND5.js → chunk-S3QTFUJX.js} +0 -0
@@ -1,31 +1,34 @@
1
+ import { LockedLabel } from './chunk-OHGH7O6T.js';
1
2
  import { KeyChip } from './chunk-FYTIJM2T.js';
2
3
  import { HIT_AREA_CLASS } from './chunk-2YTOOH3A.js';
3
4
  import { VisuallyHidden } from './chunk-BZFWDIV6.js';
4
5
  import { cx } from './chunk-ODEQTPFM.js';
5
6
  import './HitArea-QUOS6ZDJ.css';
6
- import './SidebarNav-7SGUZYKK.css';
7
- import { useId, useState } from 'react';
7
+ import './SidebarNav-YI74SPDC.css';
8
+ import { createContext, useId, useContext, useState } from 'react';
8
9
  import { ChevronDownGlyph } from '@crewlethq/icons/glyphs';
9
10
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
10
11
 
12
+ var GroupLocked = createContext(false);
11
13
  function SidebarNav({ label, className, children }) {
12
14
  return /* @__PURE__ */ jsx("nav", { className: cx("crewlet-sidebar-nav", className), "aria-label": label, children });
13
15
  }
14
- function NavGroup({ label, action, className, children }) {
16
+ function NavGroup({ label, action, locked, className, children }) {
15
17
  const id = useId();
16
18
  const named = label !== void 0 && label !== null && label !== false && label !== "";
19
+ const groupLocked = named && locked !== void 0 && locked !== "";
17
20
  return /* @__PURE__ */ jsxs(
18
21
  "div",
19
22
  {
20
- className: cx("crewlet-nav-group", className),
23
+ className: cx("crewlet-nav-group", groupLocked && "crewlet-nav-group--locked", className),
21
24
  role: named ? "group" : void 0,
22
25
  "aria-labelledby": named ? id : void 0,
23
26
  children: [
24
27
  named || action ? /* @__PURE__ */ jsxs("div", { className: "crewlet-nav-group__head", children: [
25
- named ? /* @__PURE__ */ jsx("span", { className: "crewlet-nav-group__label", id, children: label }) : null,
28
+ named ? /* @__PURE__ */ jsx("span", { className: "crewlet-nav-group__label", id, children: /* @__PURE__ */ jsx(LockedLabel, { reason: groupLocked ? locked : void 0, children: label }) }) : null,
26
29
  action ? /* @__PURE__ */ jsx("button", { type: "button", className: "crewlet-nav-group__action", "aria-label": action.label, onClick: action.onClick, children: /* @__PURE__ */ jsx("span", { className: "crewlet-nav-group__action-icon", "aria-hidden": true, children: action.icon }) }) : null
27
30
  ] }) : null,
28
- children
31
+ /* @__PURE__ */ jsx(GroupLocked.Provider, { value: groupLocked, children })
29
32
  ]
30
33
  }
31
34
  );
@@ -48,6 +51,9 @@ function NavItem({
48
51
  href,
49
52
  current = false,
50
53
  disabledReason,
54
+ locked,
55
+ title,
56
+ onPrefetch,
51
57
  renderLink,
52
58
  onClick,
53
59
  children,
@@ -58,6 +64,7 @@ function NavItem({
58
64
  className
59
65
  }) {
60
66
  const id = useId();
67
+ const inLockedGroup = useContext(GroupLocked);
61
68
  const [ownExpanded, setOwnExpanded] = useState(defaultExpanded);
62
69
  const open = expanded ?? ownExpanded;
63
70
  const nested = children !== void 0 && children !== null && children !== false;
@@ -72,7 +79,7 @@ function NavItem({
72
79
  lead ? /* @__PURE__ */ jsx(KeyChip, { className: "crewlet-nav-item__lead", children: lead }) : null,
73
80
  lead ? " " : null,
74
81
  /* @__PURE__ */ jsxs("span", { className: "crewlet-nav-item__label", children: [
75
- label,
82
+ /* @__PURE__ */ jsx(LockedLabel, { reason: locked, mark: !inLockedGroup, children: label }),
76
83
  count || badge ? /* @__PURE__ */ jsx(VisuallyHidden, { children: spoken([count, badge]) }) : null
77
84
  ] }),
78
85
  count ? /* @__PURE__ */ jsx(Figure, { figure: count, mark: count.mark, className: "crewlet-nav-item__count" }) : null,
@@ -99,10 +106,24 @@ function NavItem({
99
106
  children: inside,
100
107
  ...href === void 0 ? {} : { href },
101
108
  ...current ? { "aria-current": "page" } : {},
102
- ...onClick === void 0 ? {} : { onClick }
109
+ ...onClick === void 0 ? {} : { onClick },
110
+ ...title === void 0 ? {} : { title },
111
+ ...onPrefetch === void 0 ? {} : { onPointerEnter: onPrefetch, onFocus: onPrefetch }
103
112
  });
104
113
  } else if (href !== void 0) {
105
- row = /* @__PURE__ */ jsx("a", { className: rowClass, href, "aria-current": current ? "page" : void 0, onClick, children: inside });
114
+ row = /* @__PURE__ */ jsx(
115
+ "a",
116
+ {
117
+ className: rowClass,
118
+ href,
119
+ "aria-current": current ? "page" : void 0,
120
+ onClick,
121
+ title,
122
+ onPointerEnter: onPrefetch,
123
+ onFocus: onPrefetch,
124
+ children: inside
125
+ }
126
+ );
106
127
  } else {
107
128
  row = /* @__PURE__ */ jsxs(
108
129
  "button",
@@ -5,22 +5,23 @@ function tabStop(items, selected) {
5
5
  if (selected >= 0 && !items[selected]?.disabled) return selected;
6
6
  return items.findIndex((item) => !item.disabled);
7
7
  }
8
+ function reachable(el) {
9
+ return Boolean(el) && !el.disabled && !el.hasAttribute("inert");
10
+ }
8
11
  function useRoving(count, select, { followFocus = false, columns } = {}) {
9
12
  const buttons = useRef([]);
10
13
  const [landed, setLanded] = useState(null);
11
14
  function step(from, by) {
12
15
  for (let i = 0; i < count; i += 1) {
13
16
  const at = ((from + by * i) % count + count) % count;
14
- const el = buttons.current[at];
15
- if (el && !el.disabled) return at;
17
+ if (reachable(buttons.current[at])) return at;
16
18
  }
17
19
  return null;
18
20
  }
19
21
  function rowStep(at, by, across) {
20
22
  const target = at + by * across;
21
23
  if (target < 0 || target >= count) return null;
22
- const el = buttons.current[target];
23
- return el && !el.disabled ? target : null;
24
+ return reachable(buttons.current[target]) ? target : null;
24
25
  }
25
26
  function moveTo(key, at, vertical) {
26
27
  if (count === 0) return null;
@@ -1,6 +1,6 @@
1
1
  import { Toolbar } from './chunk-NR4CPM4T.js';
2
- import { SegmentedControl } from './chunk-2QZ2VPHR.js';
3
- import { tabId } from './chunk-7SDUKCNW.js';
2
+ import { SegmentedControl } from './chunk-4OK4DX3V.js';
3
+ import { tabId } from './chunk-X4IXXLWM.js';
4
4
  import { IconButton } from './chunk-4FQT6ZAY.js';
5
5
  import { cx } from './chunk-ODEQTPFM.js';
6
6
  import './MarkdownEditor-WOKV7CLK.css';
@@ -1,5 +1,5 @@
1
1
  import { useClipboard } from './chunk-STJ7QBC3.js';
2
- import { Modal } from './chunk-SVGARBDY.js';
2
+ import { Modal } from './chunk-IAGYPTEJ.js';
3
3
  import { Checkbox } from './chunk-AXS6MBNH.js';
4
4
  import { EmptyValue } from './chunk-EUCC37WY.js';
5
5
  import { useCardHeaderSlot } from './chunk-AV2DXAEL.js';
@@ -1,10 +1,10 @@
1
1
  import { Select } from './chunk-XQZ6EWOE.js';
2
2
  import { SHEET_LABELS, SHEET_COLUMN_TYPES, optionHue, retypeColumn } from './chunk-LFSIKGRQ.js';
3
- import { HueSwatch } from './chunk-F4LPQA4E.js';
3
+ import { HueSwatch } from './chunk-BA32AVKS.js';
4
4
  import { NODE_HUES, NODE_HUE_NAMES } from './chunk-AYKXMIOR.js';
5
5
  import { Checkbox } from './chunk-AXS6MBNH.js';
6
- import { Kbd } from './chunk-SMBKXWML.js';
7
6
  import { FormField, Input } from './chunk-TYONQSOK.js';
7
+ import { Kbd } from './chunk-SMBKXWML.js';
8
8
  import { Menu } from './chunk-D6FEHY5G.js';
9
9
  import { Button } from './chunk-OG6CL3EB.js';
10
10
  import { IconButton } from './chunk-4FQT6ZAY.js';
@@ -1,6 +1,6 @@
1
1
  import { VisuallyHidden } from './chunk-BZFWDIV6.js';
2
2
  import { cx } from './chunk-ODEQTPFM.js';
3
- import './Charts-MBJG72BS.css';
3
+ import './Charts-TZ744HT6.css';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import { useState, useRef, useCallback, useId } from 'react';
6
6
 
@@ -340,6 +340,95 @@ function ActivityStrip({
340
340
  )
341
341
  ] });
342
342
  }
343
+ var MAX_TICKS = 5;
344
+ function histogramTicks(bars) {
345
+ if (bars <= 0) return [];
346
+ if (bars <= MAX_TICKS) return Array.from({ length: bars }, (_, i) => i);
347
+ const span = bars - 1;
348
+ const least = Math.ceil(span / (MAX_TICKS - 1));
349
+ let stride = least;
350
+ for (let s = least; s <= Math.ceil(least * 1.5); s++) {
351
+ if (span % s === 0) {
352
+ stride = s;
353
+ break;
354
+ }
355
+ }
356
+ const out = [];
357
+ for (let at = 0; at < span; at += stride) out.push(at);
358
+ if (span - out[out.length - 1] < stride / 2) out.pop();
359
+ out.push(span);
360
+ return out;
361
+ }
362
+ function tickPlace(index, bars) {
363
+ if (index === 0) return { left: 0 };
364
+ if (index === bars - 1) return { right: 0 };
365
+ return { left: `${(index + 0.5) / bars * 100}%`, transform: "translateX(-50%)" };
366
+ }
367
+ function Histogram({
368
+ bars,
369
+ label,
370
+ summary,
371
+ formatTitle,
372
+ formatTick,
373
+ onSelect,
374
+ height = 96,
375
+ emptyLabel = "Nothing recorded in this window",
376
+ className
377
+ }) {
378
+ if (bars.length === 0) {
379
+ return /* @__PURE__ */ jsx(ChartEmpty, { className, height: `${height}px`, children: emptyLabel });
380
+ }
381
+ const peak = Math.max(1, ...bars.map((bar) => bar.v));
382
+ return /* @__PURE__ */ jsxs("div", { className: cx("crewlet-histogram", className), children: [
383
+ /* @__PURE__ */ jsxs(
384
+ "div",
385
+ {
386
+ className: "crewlet-histogram__plot",
387
+ role: "group",
388
+ "aria-label": label,
389
+ style: { "--crewlet-histogram-height": `${height}px` },
390
+ children: [
391
+ bars.map((bar, index) => {
392
+ const part = Math.min(bar.v, Math.max(0, bar.part ?? 0));
393
+ const title = formatTitle(bar, index);
394
+ const empty = bar.v === 0 ? "" : void 0;
395
+ const fill = /* @__PURE__ */ jsx(
396
+ "span",
397
+ {
398
+ className: "crewlet-histogram__fill",
399
+ style: { "--crewlet-histogram-fill": `${bar.v / peak * 100}%` },
400
+ children: part > 0 && /* @__PURE__ */ jsx(
401
+ "span",
402
+ {
403
+ className: "crewlet-histogram__part",
404
+ style: { "--crewlet-histogram-part": `${part / bar.v * 100}%` }
405
+ }
406
+ )
407
+ }
408
+ );
409
+ return onSelect ? /* @__PURE__ */ jsx(
410
+ "button",
411
+ {
412
+ type: "button",
413
+ className: "crewlet-histogram__bar",
414
+ title,
415
+ "aria-label": title,
416
+ "data-empty": empty,
417
+ onClick: () => onSelect(bar, index),
418
+ children: fill
419
+ },
420
+ bar.t
421
+ ) : /* @__PURE__ */ jsx("div", { className: "crewlet-histogram__bar", title, "data-empty": empty, children: fill }, bar.t);
422
+ }),
423
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: summary })
424
+ ]
425
+ }
426
+ ),
427
+ formatTick && // Hidden from assistive technology: every bar carries its own bucket
428
+ // in its name, and five loose dates under a chart place nothing.
429
+ /* @__PURE__ */ jsx("div", { className: "crewlet-histogram__axis", "aria-hidden": "true", children: histogramTicks(bars.length).map((index) => /* @__PURE__ */ jsx("span", { className: "crewlet-histogram__tick", style: tickPlace(index, bars.length), children: formatTick(bars[index], index) }, bars[index].t)) })
430
+ ] });
431
+ }
343
432
  function TimeSeries({
344
433
  series,
345
434
  from,
@@ -713,4 +802,4 @@ function StackedColumns({
713
802
  );
714
803
  }
715
804
 
716
- export { ActivityStrip, BarList, ChartEmpty, ChartTooltip, DATA_COLORS, DATA_COLOR_OTHER, Legend, Sparkline, StackedBar, StackedColumns, TimeSeries, dataColor, niceScale, useChartHover };
805
+ export { ActivityStrip, BarList, ChartEmpty, ChartTooltip, DATA_COLORS, DATA_COLOR_OTHER, Histogram, Legend, Sparkline, StackedBar, StackedColumns, TimeSeries, dataColor, histogramTicks, niceScale, useChartHover };
@@ -58,8 +58,10 @@ function DatasetSource({
58
58
  const summary = /* @__PURE__ */ jsxs(Fragment, { children: [
59
59
  /* @__PURE__ */ jsxs("span", { className: "crewlet-dataset-source__head", children: [
60
60
  /* @__PURE__ */ jsx("span", { id: titleId, className: "crewlet-dataset-source__title", children: title }),
61
- " ",
62
- /* @__PURE__ */ jsx(Tag, { size: "xs", appearance: "outline", className: "crewlet-dataset-source__kind", children: text.kinds[kind] })
61
+ kind === void 0 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
62
+ " ",
63
+ /* @__PURE__ */ jsx(Tag, { size: "xs", appearance: "outline", className: "crewlet-dataset-source__kind", children: text.kinds[kind] })
64
+ ] })
63
65
  ] }),
64
66
  " ",
65
67
  /* @__PURE__ */ jsx("span", { className: "crewlet-dataset-source__definition", children: definition }),
@@ -4,7 +4,7 @@ import { focusables, useModalLayer, useBodyScrollLock } from './chunk-H5XTJ7GJ.j
4
4
  import { Button } from './chunk-OG6CL3EB.js';
5
5
  import { IconButton } from './chunk-4FQT6ZAY.js';
6
6
  import { cx } from './chunk-ODEQTPFM.js';
7
- import './Modal-7MWRCWAI.css';
7
+ import './Modal-TOEWHDCQ.css';
8
8
  import { useId, useRef, useCallback } from 'react';
9
9
  import { createPortal } from 'react-dom';
10
10
  import { ChevronLeftGlyph, XGlyph } from '@crewlethq/icons/glyphs';
@@ -124,7 +124,7 @@ function ModalFrame({
124
124
  given(icon) ? /* @__PURE__ */ jsx("span", { className: "crewlet-modal__icon", "aria-hidden": "true", children: icon }) : null,
125
125
  /* @__PURE__ */ jsxs("div", { className: "crewlet-modal__heading", children: [
126
126
  given(title) ? /* @__PURE__ */ jsx(
127
- "p",
127
+ "h1",
128
128
  {
129
129
  className: cx("crewlet-modal__title", sheet ? "crewlet-modal__title--sheet" : void 0),
130
130
  id: titleId,
@@ -2,7 +2,7 @@ import { CardHeaderSlotContext } from './chunk-AV2DXAEL.js';
2
2
  import { Count } from './chunk-BHHIIK3M.js';
3
3
  import { useHeadingLevel, HeadingLevelProvider, nextHeadingLevel, headingTag } from './chunk-PQADV6P6.js';
4
4
  import { cx } from './chunk-ODEQTPFM.js';
5
- import './Card-G2ZGT5Z6.css';
5
+ import './Card-JR2UPQH7.css';
6
6
  import { createContext, useId, useState, isValidElement, useRef, useCallback, useMemo, Children, cloneElement, useContext, useEffect, Fragment } from 'react';
7
7
  import { jsx, jsxs } from 'react/jsx-runtime';
8
8
 
@@ -160,6 +160,7 @@ var CardHeader = ({
160
160
  icon,
161
161
  count,
162
162
  subtitle,
163
+ subtitlePlacement = "beside",
163
164
  actions,
164
165
  className,
165
166
  children,
@@ -173,16 +174,28 @@ var CardHeader = ({
173
174
  },
174
175
  [host]
175
176
  );
176
- return /* @__PURE__ */ jsxs("div", { ...rest, className: cx("crewlet-card__header", !divided && "crewlet-card__header--plain", className), children: [
177
- /* @__PURE__ */ jsxs("div", { className: "crewlet-card__header-main", children: [
178
- icon === void 0 ? null : /* @__PURE__ */ jsx("span", { className: "crewlet-card__header-icon", "aria-hidden": true, children: icon }),
179
- children,
180
- count === void 0 ? null : /* @__PURE__ */ jsx(Count, { value: count })
181
- ] }),
182
- subtitle === void 0 ? null : /* @__PURE__ */ jsx("span", { className: "crewlet-card__subtitle", children: subtitle }),
183
- actions === void 0 ? null : /* @__PURE__ */ jsx("div", { className: "crewlet-card__header-actions", children: actions }),
184
- card === null ? null : /* @__PURE__ */ jsx("div", { className: "crewlet-card__header-chrome", ref: chromeRef })
185
- ] });
177
+ return /* @__PURE__ */ jsxs(
178
+ "div",
179
+ {
180
+ ...rest,
181
+ className: cx(
182
+ "crewlet-card__header",
183
+ !divided && "crewlet-card__header--plain",
184
+ subtitle !== void 0 && subtitlePlacement === "below" && "crewlet-card__header--stacked",
185
+ className
186
+ ),
187
+ children: [
188
+ /* @__PURE__ */ jsxs("div", { className: "crewlet-card__header-main", children: [
189
+ icon === void 0 ? null : /* @__PURE__ */ jsx("span", { className: "crewlet-card__header-icon", "aria-hidden": true, children: icon }),
190
+ typeof children === "string" || typeof children === "number" ? /* @__PURE__ */ jsx(CardTitle, { children }) : children,
191
+ count === void 0 || count === 0 || count === "0" ? null : /* @__PURE__ */ jsx(Count, { value: count })
192
+ ] }),
193
+ subtitle === void 0 ? null : /* @__PURE__ */ jsx("span", { className: "crewlet-card__subtitle", children: subtitle }),
194
+ actions === void 0 ? null : /* @__PURE__ */ jsx("div", { className: "crewlet-card__header-actions", children: actions }),
195
+ card === null ? null : /* @__PURE__ */ jsx("div", { className: "crewlet-card__header-chrome", ref: chromeRef })
196
+ ]
197
+ }
198
+ );
186
199
  };
187
200
  var CardBody = ({ padding = "md", className, children, ...rest }) => /* @__PURE__ */ jsx("div", { ...rest, className: cx("crewlet-card__body", `crewlet-card__body--p-${padding}`, className), children });
188
201
  var CardFooter = ({ variant = "actions", padding = "sm", className, children, ...rest }) => /* @__PURE__ */ jsx(
@@ -0,0 +1,71 @@
1
+ import { SidebarNav } from './chunk-E7QLG3PG.js';
2
+ import { VisuallyHidden } from './chunk-BZFWDIV6.js';
3
+ import { cx } from './chunk-ODEQTPFM.js';
4
+ import './SectionFrame-M62UUVFQ.css';
5
+ import { useState, useId } from 'react';
6
+ import { ChevronDownGlyph } from '@crewlethq/icons/glyphs';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
+
9
+ function SectionFrame({ columnWidth, folded = false, className, children }) {
10
+ return /* @__PURE__ */ jsx(
11
+ "div",
12
+ {
13
+ className: cx("crewlet-section-frame", className),
14
+ "data-folded": folded || void 0,
15
+ style: { "--crewlet-section-frame-column": columnWidth },
16
+ children
17
+ }
18
+ );
19
+ }
20
+ function SectionFrameNav({ scope, current, location, openOnArrival = false, children }) {
21
+ const [open, setOpen] = useState(openOnArrival);
22
+ const [openedAt, setOpenedAt] = useState(location);
23
+ const [picked, setPicked] = useState(null);
24
+ if (openedAt !== location) {
25
+ setOpenedAt(location);
26
+ setOpen(picked !== location && openOnArrival);
27
+ setPicked(null);
28
+ }
29
+ const listId = useId();
30
+ function pick(event) {
31
+ const link = event.target.closest("a[href]");
32
+ if (!link) return;
33
+ setOpen(false);
34
+ const to = link.getAttribute("href");
35
+ if (to !== null && to !== location) setPicked(to);
36
+ }
37
+ return /* @__PURE__ */ jsxs("div", { className: "crewlet-section-frame__nav", "data-open": open || void 0, children: [
38
+ /* @__PURE__ */ jsxs(
39
+ "button",
40
+ {
41
+ type: "button",
42
+ className: "crewlet-section-frame__toggle",
43
+ "aria-expanded": open,
44
+ "aria-controls": listId,
45
+ onClick: () => setOpen((was) => !was),
46
+ children: [
47
+ current?.icon ? /* @__PURE__ */ jsx("span", { className: "crewlet-section-frame__toggle-icon", "aria-hidden": "true", children: current.icon }) : null,
48
+ /* @__PURE__ */ jsx("span", { className: "crewlet-section-frame__toggle-name", children: current ? /* @__PURE__ */ jsxs(Fragment, { children: [
49
+ /* @__PURE__ */ jsxs("span", { className: "crewlet-section-frame__toggle-prefix", children: [
50
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: scope }),
51
+ " Section",
52
+ /* @__PURE__ */ jsx("span", { "aria-hidden": "true", children: " \xB7" }),
53
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: ":" })
54
+ ] }),
55
+ " ",
56
+ current.label
57
+ ] }) : `${scope} sections` }),
58
+ /* @__PURE__ */ jsx(ChevronDownGlyph, { size: "xs", "aria-hidden": "true", className: "crewlet-section-frame__chevron" })
59
+ ]
60
+ }
61
+ ),
62
+ /* @__PURE__ */ jsx("div", { id: listId, className: "crewlet-section-frame__list", onClick: pick, children: /* @__PURE__ */ jsx(SidebarNav, { label: `${scope} sections`, children }) })
63
+ ] });
64
+ }
65
+ function SectionFrameBody({ children, className }) {
66
+ return /* @__PURE__ */ jsx("div", { className: cx("crewlet-section-frame__body", className), children });
67
+ }
68
+ SectionFrame.Nav = SectionFrameNav;
69
+ SectionFrame.Body = SectionFrameBody;
70
+
71
+ export { SectionFrame, SectionFrameBody, SectionFrameNav };
@@ -1,4 +1,4 @@
1
- import { Modal } from './chunk-SVGARBDY.js';
1
+ import { Modal } from './chunk-IAGYPTEJ.js';
2
2
  import { useListbox, useOptionKeys } from './chunk-7KHM2FZH.js';
3
3
  import { Popover } from './chunk-KHJIEPZV.js';
4
4
  import { KeyChip, highlightMatch } from './chunk-FYTIJM2T.js';
@@ -1,5 +1,5 @@
1
1
  import { diffLines, diffStat, collapseDiff, DiffSummary, DiffView } from './chunk-BVWSLXTY.js';
2
- import { SegmentedControl } from './chunk-2QZ2VPHR.js';
2
+ import { SegmentedControl } from './chunk-4OK4DX3V.js';
3
3
  import { EmptyState } from './chunk-RA2ULG6H.js';
4
4
  import { useHeadingLevel, headingTag, nextHeadingLevel, HeadingLevelProvider } from './chunk-PQADV6P6.js';
5
5
  import { cx } from './chunk-ODEQTPFM.js';
@@ -6,7 +6,7 @@ import { IconButton } from './chunk-4FQT6ZAY.js';
6
6
  import { VisuallyHidden } from './chunk-BZFWDIV6.js';
7
7
  import { cx } from './chunk-ODEQTPFM.js';
8
8
  import './HitArea-QUOS6ZDJ.css';
9
- import './AppShell-NDU4XMGF.css';
9
+ import './AppShell-NPSWZ3XW.css';
10
10
  import { createContext, forwardRef, useContext, useId, useState, useRef, useCallback, useEffect, useLayoutEffect } from 'react';
11
11
  import { breakpoint } from '@crewlethq/tokens';
12
12
  import { ChevronUpGlyph, ChevronsUpDownGlyph, ChevronRightGlyph, MenuGlyph } from '@crewlethq/icons/glyphs';
@@ -231,10 +231,13 @@ function ShellDrawer({
231
231
  }
232
232
  );
233
233
  }
234
- function AppShellRail({ header, footer, className, children }) {
234
+ function AppShellRail({ header, search, footer, className, children }) {
235
235
  return /* @__PURE__ */ jsxs("div", { className: cx("crewlet-app-shell__rail-inner", className), children: [
236
236
  header ? /* @__PURE__ */ jsx("div", { className: "crewlet-app-shell__rail-head", children: header }) : null,
237
- /* @__PURE__ */ jsx("div", { className: "crewlet-app-shell__rail-body", children }),
237
+ /* @__PURE__ */ jsxs("div", { className: "crewlet-app-shell__rail-body", children: [
238
+ search ? /* @__PURE__ */ jsx("div", { className: "crewlet-app-shell__rail-search", children: search }) : null,
239
+ children
240
+ ] }),
238
241
  footer ? /* @__PURE__ */ jsx("div", { className: "crewlet-app-shell__rail-foot", children: footer }) : null
239
242
  ] });
240
243
  }
@@ -1,6 +1,6 @@
1
1
  import { Select } from './chunk-XQZ6EWOE.js';
2
2
  import { CopyButton } from './chunk-W46LPU4R.js';
3
- import { Modal } from './chunk-SVGARBDY.js';
3
+ import { Modal } from './chunk-IAGYPTEJ.js';
4
4
  import { Callout } from './chunk-SZZRIHGT.js';
5
5
  import { PrincipalAvatar } from './chunk-CI3VPIJN.js';
6
6
  import { useHeadingLevel, headingTag } from './chunk-PQADV6P6.js';
@@ -1,5 +1,5 @@
1
1
  import { useThemePreference, useDensityPreference } from './chunk-Z24ZUSTX.js';
2
- import { SegmentedControl } from './chunk-2QZ2VPHR.js';
2
+ import { SegmentedControl } from './chunk-4OK4DX3V.js';
3
3
  import { SunGlyph, MonitorGlyph, MoonGlyph } from '@crewlethq/icons/glyphs';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
@@ -1,4 +1,4 @@
1
- import { useRoving } from './chunk-RKKO7QHH.js';
1
+ import { useRoving } from './chunk-EGMQURBR.js';
2
2
  import { cx } from './chunk-ODEQTPFM.js';
3
3
  import './LayersList-TBNF4XGL.css';
4
4
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -1,7 +1,7 @@
1
1
  import { PrincipalAvatar } from './chunk-CI3VPIJN.js';
2
2
  import { toInstant, RelativeTime, formatExact, toISO } from './chunk-3CZ7XAVY.js';
3
3
  import { Document } from './chunk-PWG3VHRQ.js';
4
- import { Composer } from './chunk-ETVEGR2Y.js';
4
+ import { Composer } from './chunk-ISA2O2BK.js';
5
5
  import { Count } from './chunk-BHHIIK3M.js';
6
6
  import { useHeadingLevel, headingTag } from './chunk-PQADV6P6.js';
7
7
  import { Button } from './chunk-OG6CL3EB.js';
@@ -1,4 +1,4 @@
1
- import { ConfirmModal } from './chunk-SVGARBDY.js';
1
+ import { ConfirmModal } from './chunk-IAGYPTEJ.js';
2
2
  import { InlineCode } from './chunk-5CLW2CXT.js';
3
3
  import { Callout } from './chunk-SZZRIHGT.js';
4
4
  import './LinkInterstitial-ET4MSVSV.css';
@@ -0,0 +1,9 @@
1
+ import { cx } from './chunk-ODEQTPFM.js';
2
+ import './TileGrid-I6LNYD2H.css';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ function TileGrid({ columns = 3, as: Track = "div", className, children, ...rest }) {
6
+ return /* @__PURE__ */ jsx("div", { className: cx("crewlet-tile-grid", className), "data-columns": columns, children: /* @__PURE__ */ jsx(Track, { ...rest, className: "crewlet-tile-grid__track", children }) });
7
+ }
8
+
9
+ export { TileGrid };
@@ -1,13 +1,13 @@
1
1
  import { VisuallyHidden } from './chunk-BZFWDIV6.js';
2
2
  import { cx } from './chunk-ODEQTPFM.js';
3
- import './List-MYJIV6MP.css';
3
+ import './List-YHLIZFK4.css';
4
4
  import { createContext, useContext, Children, isValidElement, cloneElement } from 'react';
5
5
  import { CircleAlertGlyph } from '@crewlethq/icons/glyphs';
6
6
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
7
 
8
8
  var ListContext = createContext({ variant: "divided", templated: false });
9
9
  function List({ variant = "divided", template, className, style, children, ...rest }) {
10
- const Tag = variant === "numbered" ? "ol" : "ul";
10
+ const Tag = variant === "numbered" || variant === "numbered-divided" ? "ol" : "ul";
11
11
  const templated = template !== void 0;
12
12
  return /* @__PURE__ */ jsx(ListContext.Provider, { value: { variant, templated }, children: /* @__PURE__ */ jsx(
13
13
  Tag,
@@ -1,6 +1,6 @@
1
1
  import { Link } from './chunk-FBSEJO2C.js';
2
2
  import { cx } from './chunk-ODEQTPFM.js';
3
- import './ObjectHeader-D7GU7QNI.css';
3
+ import './ObjectHeader-ZOS22FKX.css';
4
4
  import { ArrowUpRightGlyph } from '@crewlethq/icons/glyphs';
5
5
  import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
6
6
 
@@ -0,0 +1,19 @@
1
+ import { VisuallyHidden } from './chunk-BZFWDIV6.js';
2
+ import { cx } from './chunk-ODEQTPFM.js';
3
+ import './LockedLabel-VQEGEB7G.css';
4
+ import { KeyGlyph } from '@crewlethq/icons/glyphs';
5
+ import { jsx, Fragment, jsxs } from 'react/jsx-runtime';
6
+
7
+ function LockedLabel({ children, reason, mark = true, className }) {
8
+ if (reason === void 0 || reason === "") return /* @__PURE__ */ jsx(Fragment, { children });
9
+ return /* @__PURE__ */ jsxs("span", { className: cx("crewlet-locked-label", className), title: reason, children: [
10
+ children,
11
+ mark ? /* @__PURE__ */ jsx(KeyGlyph, { size: "xs", "aria-hidden": "true", className: "crewlet-locked-label__key" }) : null,
12
+ /* @__PURE__ */ jsxs(VisuallyHidden, { children: [
13
+ ", ",
14
+ reason
15
+ ] })
16
+ ] });
17
+ }
18
+
19
+ export { LockedLabel };
@@ -1,3 +1,3 @@
1
1
  import './HitArea-QUOS6ZDJ.css';
2
- import './Tabs-WIF7457H.css';
2
+ import './Tabs-S7F4RWAN.css';
3
3
  import './SegmentedControl-B7XCUOML.css';
@@ -1,5 +1,5 @@
1
1
  import { cx } from './chunk-ODEQTPFM.js';
2
- import './StatGroup-DOFHX5QJ.css';
2
+ import './StatGroup-ZMW7VQWP.css';
3
3
  import { jsx } from 'react/jsx-runtime';
4
4
 
5
5
  function StatGroup({ columns = 4, flush = false, className, children, ...rest }) {
@@ -0,0 +1,48 @@
1
+ import { useHeadingLevel, headingTag } from './chunk-PQADV6P6.js';
2
+ import { cx } from './chunk-ODEQTPFM.js';
3
+ import './CatalogTile-XL4XLFUH.css';
4
+ import { useId } from 'react';
5
+ import { jsxs, jsx } from 'react/jsx-runtime';
6
+
7
+ function CatalogTile({
8
+ as: Element = "article",
9
+ mark,
10
+ title,
11
+ headingLevel,
12
+ status,
13
+ description,
14
+ meta,
15
+ action,
16
+ quiet = false,
17
+ className,
18
+ ...rest
19
+ }) {
20
+ const level = useHeadingLevel();
21
+ const Heading = headingTag(headingLevel ?? level);
22
+ const titleId = useId();
23
+ const foot = meta !== void 0 || action !== void 0;
24
+ return /* @__PURE__ */ jsxs(
25
+ Element,
26
+ {
27
+ "aria-labelledby": Element === "article" ? titleId : void 0,
28
+ ...rest,
29
+ className: cx("crewlet-catalog-tile", quiet && "crewlet-catalog-tile--quiet", className),
30
+ children: [
31
+ /* @__PURE__ */ jsxs("div", { className: "crewlet-catalog-tile__head", children: [
32
+ /* @__PURE__ */ jsx("span", { className: "crewlet-catalog-tile__mark", "aria-hidden": "true", children: mark }),
33
+ /* @__PURE__ */ jsxs("span", { className: "crewlet-catalog-tile__title", children: [
34
+ /* @__PURE__ */ jsx(Heading, { id: titleId, className: "crewlet-catalog-tile__name", children: title }),
35
+ status === void 0 || status === null ? null : /* @__PURE__ */ jsx("span", { className: "crewlet-catalog-tile__status", children: status })
36
+ ] })
37
+ ] }),
38
+ description === void 0 ? null : /* @__PURE__ */ jsx("p", { className: "crewlet-catalog-tile__description", children: description }),
39
+ foot ? /* @__PURE__ */ jsxs("div", { className: "crewlet-catalog-tile__foot", children: [
40
+ /* @__PURE__ */ jsx("span", { className: "crewlet-catalog-tile__meta", children: meta }),
41
+ action === void 0 ? null : /* @__PURE__ */ jsx("span", { className: "crewlet-catalog-tile__action", children: action })
42
+ ] }) : null
43
+ ]
44
+ }
45
+ );
46
+ }
47
+
48
+ export { CatalogTile };
@@ -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-QV4JP242.js').then(
12
+ loading ??= import('./Editor-IRDQ3JDZ.js').then(
13
13
  (module) => {
14
14
  engine = module.Editor;
15
15
  return engine;