@crewlethq/ui 0.12.0 → 0.14.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 +82 -5
  2. package/dist/AppShell/index.js +2 -1
  3. package/dist/Avatar/index.js +1 -1
  4. package/dist/{Avatar-QHYOFID3.css → Avatar-BPJ36QZR.css} +1 -1
  5. package/dist/AvatarPicker/index.js +5 -5
  6. package/dist/Breadcrumb/Breadcrumb.d.ts +68 -0
  7. package/dist/Breadcrumb/index.d.ts +3 -0
  8. package/dist/Breadcrumb/index.js +3 -0
  9. package/dist/Breadcrumb-YMWVM3SV.css +193 -0
  10. package/dist/ChoiceButtons/ChoiceButtons.d.ts +43 -0
  11. package/dist/ChoiceButtons/index.d.ts +3 -0
  12. package/dist/ChoiceButtons/index.js +3 -0
  13. package/dist/ChoiceButtons-DJ5EOGUA.css +127 -0
  14. package/dist/Combobox/index.js +2 -2
  15. package/dist/CommandPalette/CommandPalette.d.ts +48 -1
  16. package/dist/CommandPalette/index.js +3 -3
  17. package/dist/{CommandPalette-C5AMKGN2.css → CommandPalette-HBTNKHZQ.css} +55 -2
  18. package/dist/DataTable/index.js +4 -4
  19. package/dist/DataView/index.js +11 -11
  20. package/dist/DateTimePicker/index.js +2 -2
  21. package/dist/{DateTimePicker-4AZBTODT.css → DateTimePicker-NJ6XH2TE.css} +4 -3
  22. package/dist/Document/Document.d.ts +56 -0
  23. package/dist/Document/index.d.ts +3 -0
  24. package/dist/Document/index.js +2 -0
  25. package/dist/Document-PQGXJHB7.css +288 -0
  26. package/dist/EntityChip/index.js +1 -1
  27. package/dist/Highlight/Highlight.d.ts +45 -0
  28. package/dist/Highlight/index.d.ts +3 -0
  29. package/dist/Highlight/index.js +2 -0
  30. package/dist/Highlight-DXLV2R6L.css +29 -0
  31. package/dist/HuePicker/index.js +3 -3
  32. package/dist/ImageUpload/index.js +2 -2
  33. package/dist/{ImageUpload-L2GE4JUM.css → ImageUpload-NVGMN7DP.css} +9 -6
  34. package/dist/InboxList/InboxList.d.ts +116 -0
  35. package/dist/InboxList/index.d.ts +3 -0
  36. package/dist/InboxList/index.js +5 -0
  37. package/dist/InboxList-YMFWKGGS.css +252 -0
  38. package/dist/KeyChip/KeyChip.d.ts +21 -0
  39. package/dist/KeyChip/index.d.ts +3 -0
  40. package/dist/KeyChip/index.js +2 -0
  41. package/dist/KeyChip-4XJU4BBE.css +30 -0
  42. package/dist/Link/Link.d.ts +17 -2
  43. package/dist/Link/index.js +1 -1
  44. package/dist/{Link-6BEFNMN2.css → Link-WPMVLKLY.css} +36 -1
  45. package/dist/Listbox/index.d.ts +2 -0
  46. package/dist/Listbox/index.js +1 -1
  47. package/dist/Listbox/useHighlightRest.d.ts +35 -0
  48. package/dist/MarkdownEditor/MarkdownEditor.d.ts +93 -0
  49. package/dist/MarkdownEditor/format.d.ts +34 -0
  50. package/dist/MarkdownEditor/index.d.ts +5 -0
  51. package/dist/MarkdownEditor/index.js +12 -0
  52. package/dist/MarkdownEditor-ZLSHTOIZ.css +146 -0
  53. package/dist/Modal/Modal.d.ts +5 -1
  54. package/dist/Modal/index.js +1 -1
  55. package/dist/{Modal-BNT3TDV2.css → Modal-RQAYGG4L.css} +34 -1
  56. package/dist/OrgLabel/index.js +1 -1
  57. package/dist/OrgNode/index.js +1 -1
  58. package/dist/OrgTable/index.js +4 -4
  59. package/dist/Outline/Outline.d.ts +72 -0
  60. package/dist/Outline/index.d.ts +3 -0
  61. package/dist/Outline/index.js +2 -0
  62. package/dist/Outline-VCXKKU3E.css +78 -0
  63. package/dist/Popover/Popover.d.ts +21 -1
  64. package/dist/Popover/index.js +1 -1
  65. package/dist/ReadingPane/ReadingPane.d.ts +95 -0
  66. package/dist/ReadingPane/index.d.ts +3 -0
  67. package/dist/ReadingPane/index.js +4 -0
  68. package/dist/ReadingPane-5UOLPWY5.css +194 -0
  69. package/dist/SegmentedControl/SegmentedControl.d.ts +9 -1
  70. package/dist/SegmentedControl/index.js +3 -3
  71. package/dist/{SegmentedControl-76HODRBT.css → SegmentedControl-PKBLJVSA.css} +18 -0
  72. package/dist/Select/Select.d.ts +22 -0
  73. package/dist/Select/index.js +2 -2
  74. package/dist/{Select-4ANVLHUY.css → Select-2P7AWUE4.css} +56 -6
  75. package/dist/SidebarNav/index.js +2 -1
  76. package/dist/{SidebarNav-X5NLZNWA.css → SidebarNav-KF66MLOM.css} +4 -19
  77. package/dist/Switcher/Switcher.d.ts +151 -0
  78. package/dist/Switcher/index.d.ts +3 -0
  79. package/dist/Switcher/index.js +16 -0
  80. package/dist/Switcher-B44Q4WF4.css +346 -0
  81. package/dist/Tabs/Tabs.d.ts +7 -1
  82. package/dist/Tabs/index.js +1 -1
  83. package/dist/{Tabs-5I5Q5KKM.css → Tabs-ITJYJFMU.css} +49 -0
  84. package/dist/TagsInput/index.js +2 -2
  85. package/dist/ThemeGallery/ThemeGallery.d.ts +65 -0
  86. package/dist/ThemeGallery/index.d.ts +3 -0
  87. package/dist/ThemeGallery/index.js +6 -0
  88. package/dist/ThemeGallery-NITASULQ.css +93 -0
  89. package/dist/ThemeSwatch/ThemeSwatch.d.ts +71 -0
  90. package/dist/ThemeSwatch/index.d.ts +3 -0
  91. package/dist/ThemeSwatch/index.js +2 -0
  92. package/dist/ThemeSwatch-4DL457ZB.css +256 -0
  93. package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +5 -1
  94. package/dist/ThemeSwitcher/index.js +4 -4
  95. package/dist/ThemeToggle/ThemeToggle.d.ts +1 -1
  96. package/dist/ThemeToggle/index.js +1 -1
  97. package/dist/TimeWindowPicker/index.js +4 -4
  98. package/dist/{TimeWindowPicker-GBF4JDFI.css → TimeWindowPicker-BZ5HHATU.css} +5 -4
  99. package/dist/Toaster/index.js +1 -1
  100. package/dist/{Toaster-NVDCEIP5.css → Toaster-VZKISP2S.css} +81 -87
  101. package/dist/Tree/index.d.ts +1 -1
  102. package/dist/Tree/index.js +1 -1
  103. package/dist/Tree/useTreeState.d.ts +37 -7
  104. package/dist/TreeCanvas/index.js +2 -2
  105. package/dist/TreeGrid/TreeGrid.d.ts +22 -2
  106. package/dist/TreeGrid/index.js +2 -2
  107. package/dist/{TreeGrid-NSW7VMOX.css → TreeGrid-FBX3MSJA.css} +19 -0
  108. package/dist/{chunk-EBBAAQDY.js → chunk-26PEPONN.js} +3 -1
  109. package/dist/{chunk-GOUKOXJK.js → chunk-3VVKJ7AZ.js} +3 -3
  110. package/dist/{chunk-HV6IZFBK.js → chunk-4FFHJBEN.js} +2 -2
  111. package/dist/{chunk-JHQUT4WJ.js → chunk-4LDTQWS7.js} +1 -1
  112. package/dist/{chunk-GXYNEDNA.js → chunk-4Y7WKXAW.js} +1 -1
  113. package/dist/{chunk-IINFVK3W.js → chunk-5IXMLWGW.js} +6 -6
  114. package/dist/{chunk-MCPKHYMC.js → chunk-6LXMLQUM.js} +17 -4
  115. package/dist/{chunk-3UK4VFSK.js → chunk-6NIZCQUM.js} +1 -1
  116. package/dist/{chunk-ORNOOMVY.js → chunk-6TSZCBID.js} +2 -2
  117. package/dist/{chunk-ZMJHK7DR.js → chunk-75WOCYGC.js} +2 -2
  118. package/dist/chunk-77IEHFY4.js +299 -0
  119. package/dist/chunk-A5YKNRG6.js +94 -0
  120. package/dist/{chunk-JCNUQ3US.js → chunk-AXNQCAFC.js} +2 -2
  121. package/dist/{chunk-UG5ZMAXW.js → chunk-CBZSSKH3.js} +5 -5
  122. package/dist/{chunk-LAQK4V3Z.js → chunk-DJMLHCLD.js} +1 -1
  123. package/dist/{chunk-6MU7HNB4.js → chunk-F73MC7EZ.js} +47 -2
  124. package/dist/{chunk-ZPSOF6VL.js → chunk-FBSEJO2C.js} +1 -1
  125. package/dist/chunk-FYTIJM2T.js +40 -0
  126. package/dist/chunk-H6VKCIWV.js +41 -0
  127. package/dist/{chunk-HLBRPES3.js → chunk-IFM63LAG.js} +3 -3
  128. package/dist/chunk-IG75YMUN.js +22 -0
  129. package/dist/{chunk-SEFMO2EV.js → chunk-IXUU5DLZ.js} +55 -6
  130. package/dist/{chunk-ZHOM65MI.js → chunk-JCO3SIST.js} +1 -1
  131. package/dist/chunk-KLIEPFEZ.js +95 -0
  132. package/dist/{chunk-7LD6P32I.js → chunk-L3CTFFLZ.js} +2 -18
  133. package/dist/chunk-MNFU2RNT.js +74 -0
  134. package/dist/{chunk-S3BCVWTU.js → chunk-MY374UUD.js} +49 -31
  135. package/dist/{chunk-K5Q2DK3P.js → chunk-NXDEPUVG.js} +1 -1
  136. package/dist/{chunk-PDUZO35I.js → chunk-O2ZDZZS7.js} +15 -6
  137. package/dist/{chunk-5WEVLIB6.js → chunk-RZ7RGECB.js} +1 -1
  138. package/dist/{chunk-WEIINZPA.js → chunk-SBRE7IML.js} +6 -2
  139. package/dist/{chunk-TEEJSTFG.js → chunk-TFMJH2E6.js} +1 -1
  140. package/dist/{chunk-IVFJD7WY.js → chunk-UCCC7YVZ.js} +3 -2
  141. package/dist/chunk-VWNC2L6W.js +110 -0
  142. package/dist/chunk-VYY56AMX.js +2 -0
  143. package/dist/chunk-WI6K5M5X.js +24 -0
  144. package/dist/{chunk-XV65NTIT.js → chunk-WYQOHFML.js} +94 -41
  145. package/dist/chunk-XYCADWZN.js +100 -0
  146. package/dist/chunk-Y6NR7QJ3.js +336 -0
  147. package/dist/chunk-YSJC7AZC.js +62 -0
  148. package/dist/chunk-ZAJHGDAW.js +93 -0
  149. package/dist/generated/index.d.ts +12 -0
  150. package/dist/generated/index.js +64 -51
  151. package/dist/index.js +64 -51
  152. package/dist/styles.css +2711 -402
  153. package/dist/utils/highlight.d.ts +17 -0
  154. package/dist/utils/useMediaMatch.d.ts +12 -0
  155. package/package.json +3 -3
  156. package/dist/chunk-UAQIUSSK.js +0 -2
  157. /package/dist/{chunk-74OVQWA5.js → chunk-6AR2T5Y4.js} +0 -0
@@ -0,0 +1,110 @@
1
+ import { KeyChip } from './chunk-FYTIJM2T.js';
2
+ import { cx } from './chunk-ODEQTPFM.js';
3
+ import './Breadcrumb-YMWVM3SV.css';
4
+ import { useRef, useState, useLayoutEffect } from 'react';
5
+ import { ChevronRightGlyph } from '@crewlethq/icons/glyphs';
6
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
7
+
8
+ function Breadcrumb({ crumbs, current, label = "Breadcrumb", className, style, ...rest }) {
9
+ const trail = useRef(null);
10
+ const signature = crumbs.map((crumb) => [crumb.label, crumb.keyChip ?? "", crumb.mono ? "m" : "", crumb.href ? "l" : ""].join("\0")).join("");
11
+ const overflows = useOverflows(trail, signature);
12
+ const floor = useFloor(trail, signature);
13
+ return /* @__PURE__ */ jsx(
14
+ "nav",
15
+ {
16
+ ...rest,
17
+ ref: trail,
18
+ className: cx("crewlet-breadcrumb", className),
19
+ "aria-label": label,
20
+ tabIndex: overflows ? 0 : void 0,
21
+ style: floor > 0 ? { ...style, "--crewlet-breadcrumb-floor": `${floor}px` } : style,
22
+ children: crumbs.map((crumb, i) => {
23
+ const last = i === crumbs.length - 1;
24
+ const words = /* @__PURE__ */ jsxs(Fragment, { children: [
25
+ crumb.icon !== void 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-breadcrumb__icon", "aria-hidden": "true", children: crumb.icon }) : null,
26
+ crumb.keyChip ? /* @__PURE__ */ jsxs(Fragment, { children: [
27
+ /* @__PURE__ */ jsx(KeyChip, { className: "crewlet-breadcrumb__key", children: crumb.keyChip }),
28
+ " "
29
+ ] }) : null,
30
+ crumb.badge !== void 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-breadcrumb__badge", "aria-hidden": "true", children: crumb.badge }) : null,
31
+ /* @__PURE__ */ jsx("span", { className: "crewlet-breadcrumb__text", children: crumb.label })
32
+ ] });
33
+ const face = crumb.mono ? "is-mono" : void 0;
34
+ return (
35
+ // KEYED BY DEPTH, not by words: the crumb at a depth is the same place
36
+ // in the trail whatever it is called, so a heading whose subject is
37
+ // switched keeps its element, and the control in it keeps focus.
38
+ /* @__PURE__ */ jsxs("span", { className: "crewlet-breadcrumb__part", children: [
39
+ i > 0 ? /* @__PURE__ */ jsx(ChevronRightGlyph, { size: "xs", className: "crewlet-breadcrumb__separator", "aria-hidden": "true" }) : null,
40
+ last ? /* @__PURE__ */ jsx(
41
+ "h1",
42
+ {
43
+ className: cx("crewlet-breadcrumb__here", current !== void 0 && "crewlet-breadcrumb__here--control", face),
44
+ "aria-current": "page",
45
+ children: current !== void 0 ? current : words
46
+ }
47
+ ) : crumb.href ? /* @__PURE__ */ jsx("a", { className: cx("crewlet-breadcrumb__crumb", face), href: crumb.href, children: words }) : (
48
+ // AN ANCESTOR WITH NO PAGE OF ITS OWN, or one the reader is
49
+ // already on ("Work" on Work's landing): its words in the
50
+ // ancestors' quiet ink, with nothing to press.
51
+ /* @__PURE__ */ jsx("span", { className: cx("crewlet-breadcrumb__crumb", face), children: words })
52
+ )
53
+ ] }, i)
54
+ );
55
+ })
56
+ }
57
+ );
58
+ }
59
+ function useFloor(el, content) {
60
+ const [floor, setFloor] = useState(0);
61
+ useLayoutEffect(() => {
62
+ const node = el.current;
63
+ if (!node) return;
64
+ const bar = node.parentElement;
65
+ const measure = () => {
66
+ const last = node.querySelector(".crewlet-breadcrumb__part:last-child > .crewlet-breadcrumb__here");
67
+ if (!last) return setFloor(0);
68
+ const start = node.getBoundingClientRect().left - node.scrollLeft;
69
+ const offset = last.getBoundingClientRect().left - start;
70
+ const stub = parseFloat(getComputedStyle(last).minWidth) || 0;
71
+ const wanted = Math.max(0, Math.ceil(offset + stub));
72
+ setFloor(bar ? Math.min(wanted, roomBeside(bar, node)) : wanted);
73
+ };
74
+ measure();
75
+ if (typeof ResizeObserver !== "function") return;
76
+ const watch = new ResizeObserver(measure);
77
+ for (const part of node.querySelectorAll(".crewlet-breadcrumb__part")) watch.observe(part);
78
+ if (bar) watch.observe(bar);
79
+ return () => watch.disconnect();
80
+ }, [el, content]);
81
+ return floor;
82
+ }
83
+ function roomBeside(bar, item) {
84
+ const style = getComputedStyle(bar);
85
+ const content = bar.clientWidth - (parseFloat(style.paddingLeft) || 0) - (parseFloat(style.paddingRight) || 0);
86
+ if (content <= 0) return Infinity;
87
+ const gap = parseFloat(style.columnGap) || 0;
88
+ let before = 0;
89
+ for (let sib = item.previousElementSibling; sib; sib = sib.previousElementSibling) {
90
+ const width = sib.getBoundingClientRect().width;
91
+ if (width > 0) before += width + gap;
92
+ }
93
+ return Math.max(0, Math.floor(content - before));
94
+ }
95
+ function useOverflows(el, content) {
96
+ const [overflows, setOverflows] = useState(false);
97
+ useLayoutEffect(() => {
98
+ const node = el.current;
99
+ if (!node) return;
100
+ const measure = () => setOverflows(node.scrollWidth > node.clientWidth);
101
+ measure();
102
+ if (typeof ResizeObserver !== "function") return;
103
+ const watch = new ResizeObserver(measure);
104
+ watch.observe(node);
105
+ return () => watch.disconnect();
106
+ }, [el, content]);
107
+ return overflows;
108
+ }
109
+
110
+ export { Breadcrumb };
@@ -0,0 +1,2 @@
1
+ import './Tabs-ITJYJFMU.css';
2
+ import './SegmentedControl-PKBLJVSA.css';
@@ -0,0 +1,24 @@
1
+ import { cx } from './chunk-ODEQTPFM.js';
2
+ import './Document-PQGXJHB7.css';
3
+ import { jsx } from 'react/jsx-runtime';
4
+
5
+ function Document({ as: Tag = "div", size = "md", measure = "normal", className, children, ...rest }) {
6
+ return /* @__PURE__ */ jsx(
7
+ Tag,
8
+ {
9
+ ...rest,
10
+ className: cx(
11
+ "crewlet-document",
12
+ `crewlet-document--${size}`,
13
+ measure === "normal" && "crewlet-document--measure",
14
+ className
15
+ ),
16
+ children
17
+ }
18
+ );
19
+ }
20
+ function DocumentTitle({ as: Tag = "h1", className, children, ...rest }) {
21
+ return /* @__PURE__ */ jsx(Tag, { ...rest, className: cx("crewlet-document-title", className), children });
22
+ }
23
+
24
+ export { Document, DocumentTitle };
@@ -1,14 +1,14 @@
1
- import { useListbox } from './chunk-6MU7HNB4.js';
1
+ import { Modal } from './chunk-TFMJH2E6.js';
2
+ import { useListbox, useHighlightRest } from './chunk-F73MC7EZ.js';
2
3
  import { Kbd } from './chunk-SMBKXWML.js';
3
4
  import { Input } from './chunk-FTEJPHBI.js';
4
- import { Modal } from './chunk-TEEJSTFG.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';
8
8
  import { cx } from './chunk-ODEQTPFM.js';
9
- import './CommandPalette-C5AMKGN2.css';
10
- import { useId, useMemo } from 'react';
11
- import { SearchGlyph } from '@crewlethq/icons/glyphs';
9
+ import './CommandPalette-HBTNKHZQ.css';
10
+ import { useId, useMemo, useRef, useEffect, useState } from 'react';
11
+ import { ChevronLeftGlyph, SearchGlyph } from '@crewlethq/icons/glyphs';
12
12
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
13
13
 
14
14
  function CommandPalette(props) {
@@ -33,6 +33,8 @@ function Palette({
33
33
  onScopeChange,
34
34
  groupsScope,
35
35
  scopesLabel = "Search in",
36
+ step,
37
+ onHighlight,
36
38
  className,
37
39
  ...rest
38
40
  }) {
@@ -48,11 +50,33 @@ function Palette({
48
50
  onCommit: (at) => {
49
51
  const item = flat[at];
50
52
  if (!item) return;
51
- item.onSelect();
52
- onClose();
53
+ if (item.onSelect() !== false) onClose();
53
54
  },
54
55
  onClose
55
56
  });
57
+ const offeredNow = useRef(flat);
58
+ offeredNow.current = flat;
59
+ const highlight = useHighlightRest(
60
+ onHighlight ? (key) => onHighlight(key === null ? null : offeredNow.current.find((item) => item.id === key) ?? null) : void 0
61
+ );
62
+ const byPointer = useRef(false);
63
+ const restingKey = flat[listbox.active]?.id ?? null;
64
+ useEffect(() => {
65
+ const pointer = byPointer.current;
66
+ byPointer.current = false;
67
+ if (restingKey === null) highlight.now(null);
68
+ else if (pointer) highlight.rest(restingKey);
69
+ else highlight.now(restingKey);
70
+ }, [restingKey, highlight]);
71
+ const stepKey = step?.label ?? null;
72
+ const [shownStep, setShownStep] = useState(stepKey);
73
+ const [before, setBefore] = useState(0);
74
+ if (stepKey !== shownStep) {
75
+ setShownStep(stepKey);
76
+ if (shownStep === null) setBefore(listbox.active);
77
+ const start = step?.startAt === void 0 ? -1 : flat.findIndex((item) => item.id === step.startAt);
78
+ listbox.setActive(stepKey === null ? before : Math.max(start, 0));
79
+ }
56
80
  const tabId = (scopeId) => `${id}-scope-${scopeId}`;
57
81
  const panelId = `${id}-panel`;
58
82
  const current = scopes?.find((candidate) => candidate.id === scope);
@@ -62,17 +86,24 @@ function Palette({
62
86
  listbox.setActive(0);
63
87
  }
64
88
  function onKeyDown(event) {
89
+ if (step && !isComposing(event) && !event.altKey && !event.ctrlKey && !event.metaKey) {
90
+ if (event.key === "Escape" || event.key === "Backspace" && query === "") {
91
+ event.preventDefault();
92
+ step.onBack();
93
+ return;
94
+ }
95
+ }
65
96
  if (listbox.onKeyDown(event)) return;
66
97
  if (!scopes || scopes.length === 0 || isComposing(event)) return;
67
98
  if (event.altKey || event.ctrlKey || event.metaKey) return;
68
- let step = 0;
69
- if (event.key === "Tab") step = event.shiftKey ? -1 : 1;
70
- else if (query === "" && !event.shiftKey && event.key === "ArrowRight") step = 1;
71
- else if (query === "" && !event.shiftKey && event.key === "ArrowLeft") step = -1;
72
- if (step === 0) return;
99
+ let by = 0;
100
+ if (event.key === "Tab") by = event.shiftKey ? -1 : 1;
101
+ else if (query === "" && !event.shiftKey && event.key === "ArrowRight") by = 1;
102
+ else if (query === "" && !event.shiftKey && event.key === "ArrowLeft") by = -1;
103
+ if (by === 0) return;
73
104
  event.preventDefault();
74
105
  const at = scopes.findIndex((candidate) => candidate.id === scope);
75
- const next = scopes[(at + step + scopes.length) % scopes.length];
106
+ const next = scopes[(at + by + scopes.length) % scopes.length];
76
107
  if (next) choose(next.id);
77
108
  }
78
109
  const active = listbox.active;
@@ -91,31 +122,49 @@ function Palette({
91
122
  className: cx("crewlet-palette", className),
92
123
  footerStart: footer,
93
124
  children: [
94
- /* @__PURE__ */ jsx(
95
- Input,
96
- {
97
- appearance: "command",
98
- containerClassName: "crewlet-palette__field",
99
- leading: /* @__PURE__ */ jsx(SearchGlyph, { size: "sm" }),
100
- trailing: escapeHint ? /* @__PURE__ */ jsx(Kbd, { subtle: true, "aria-hidden": true, className: "crewlet-palette__escape", children: "Esc" }) : void 0,
101
- value: query,
102
- onChange: (event) => {
103
- onQueryChange(event.target.value);
104
- listbox.setActive(0);
105
- },
106
- onKeyDown,
107
- placeholder,
108
- role: "combobox",
109
- "aria-label": label,
110
- "aria-expanded": true,
111
- "aria-controls": listbox.listId,
112
- "aria-autocomplete": "list",
113
- "aria-activedescendant": active >= 0 ? listbox.optionId(active) : void 0,
114
- "aria-describedby": current ? tabId(current.id) : void 0,
115
- autoComplete: "off",
116
- spellCheck: false
117
- }
118
- ),
125
+ /* @__PURE__ */ jsxs("div", { className: cx("crewlet-palette__bar", step && "is-step"), children: [
126
+ step ? /* @__PURE__ */ jsxs(
127
+ "button",
128
+ {
129
+ type: "button",
130
+ className: "crewlet-palette__step",
131
+ tabIndex: -1,
132
+ onMouseDown: (event) => event.preventDefault(),
133
+ onClick: step.onBack,
134
+ children: [
135
+ /* @__PURE__ */ jsx(ChevronLeftGlyph, { size: "sm" }),
136
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: "Back from" }),
137
+ " ",
138
+ step.label
139
+ ]
140
+ }
141
+ ) : null,
142
+ /* @__PURE__ */ jsx(
143
+ Input,
144
+ {
145
+ appearance: "command",
146
+ containerClassName: "crewlet-palette__field",
147
+ leading: step ? void 0 : /* @__PURE__ */ jsx(SearchGlyph, { size: "sm" }),
148
+ trailing: escapeHint ? /* @__PURE__ */ jsx(Kbd, { subtle: true, "aria-hidden": true, className: "crewlet-palette__escape", children: "Esc" }) : void 0,
149
+ value: query,
150
+ onChange: (event) => {
151
+ onQueryChange(event.target.value);
152
+ listbox.setActive(0);
153
+ },
154
+ onKeyDown,
155
+ placeholder,
156
+ role: "combobox",
157
+ "aria-label": step ? step.label : label,
158
+ "aria-expanded": true,
159
+ "aria-controls": listbox.listId,
160
+ "aria-autocomplete": "list",
161
+ "aria-activedescendant": active >= 0 ? listbox.optionId(active) : void 0,
162
+ "aria-describedby": current ? tabId(current.id) : void 0,
163
+ autoComplete: "off",
164
+ spellCheck: false
165
+ }
166
+ )
167
+ ] }),
119
168
  scopes ? /* @__PURE__ */ jsx("div", { className: "crewlet-palette__scopes", role: "tablist", "aria-label": scopesLabel, children: scopes.map((candidate) => {
120
169
  const selected = candidate.id === scope;
121
170
  return /* @__PURE__ */ jsxs(
@@ -143,6 +192,7 @@ function Palette({
143
192
  {
144
193
  className: "crewlet-palette__results",
145
194
  ref: listbox.listRef,
195
+ onMouseLeave: () => highlight.now(null),
146
196
  ...scopes ? { id: panelId, role: "tabpanel", "aria-labelledby": current ? tabId(current.id) : void 0 } : {},
147
197
  children: [
148
198
  /* @__PURE__ */ jsx("div", { className: "crewlet-palette__lead", "aria-live": "polite", children: lead }),
@@ -187,11 +237,14 @@ function Palette({
187
237
  className: "crewlet-listbox__option crewlet-palette__row",
188
238
  role: "option",
189
239
  "aria-selected": mine === active,
190
- onMouseEnter: listbox.optionHandlers(mine).onMouseEnter,
240
+ onMouseEnter: () => {
241
+ if (mine === active) highlight.rest(item.id);
242
+ else byPointer.current = true;
243
+ listbox.optionHandlers(mine).onMouseEnter();
244
+ },
191
245
  onMouseDown: (event) => event.preventDefault(),
192
246
  onClick: () => {
193
- item.onSelect();
194
- onClose();
247
+ if (item.onSelect() !== false) onClose();
195
248
  },
196
249
  children: [
197
250
  item.icon !== void 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-palette__icon", "aria-hidden": "true", children: item.icon }) : null,
@@ -0,0 +1,100 @@
1
+ import { Eyebrow } from './chunk-RK4XPHVG.js';
2
+ import { useHeadingLevel, headingTag } from './chunk-PQADV6P6.js';
3
+ import { VisuallyHidden } from './chunk-BZFWDIV6.js';
4
+ import { cx } from './chunk-ODEQTPFM.js';
5
+ import './InboxList-YMFWKGGS.css';
6
+ import { useId } from 'react';
7
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
8
+
9
+ function InboxList({ label, className, children, ...rest }) {
10
+ return /* @__PURE__ */ jsx("nav", { ...rest, "aria-label": label, className: cx("crewlet-inbox-list", className), children });
11
+ }
12
+ function InboxGroup({ label, hideLabel = false, headingLevel, className, children, ...rest }) {
13
+ const level = useHeadingLevel();
14
+ const Heading = headingTag(headingLevel ?? level);
15
+ const labelId = useId();
16
+ return /* @__PURE__ */ jsxs("section", { ...rest, "aria-labelledby": labelId, className: cx("crewlet-inbox-list__group", className), children: [
17
+ hideLabel ? /* @__PURE__ */ jsx(VisuallyHidden, { as: Heading, id: labelId, children: label }) : /* @__PURE__ */ jsx(Heading, { id: labelId, className: "crewlet-inbox-list__label", children: /* @__PURE__ */ jsx(Eyebrow, { children: label }) }),
18
+ /* @__PURE__ */ jsx("ul", { className: "crewlet-inbox-list__rows", children })
19
+ ] });
20
+ }
21
+ function InboxRow({
22
+ title,
23
+ qualifier,
24
+ qualifierTone = "default",
25
+ meta,
26
+ leading,
27
+ excerpt,
28
+ aside,
29
+ selected = false,
30
+ unread = false,
31
+ unreadLabel = "Unread",
32
+ actionable = false,
33
+ done = false,
34
+ doneLabel = "Done",
35
+ href,
36
+ onClick,
37
+ className,
38
+ children,
39
+ ...rest
40
+ }) {
41
+ const contents = /* @__PURE__ */ jsxs(Fragment, { children: [
42
+ leading === void 0 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
43
+ /* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__leading", children: leading }),
44
+ " "
45
+ ] }),
46
+ /* @__PURE__ */ jsxs("span", { className: "crewlet-inbox-row__main", children: [
47
+ /* @__PURE__ */ jsxs("span", { className: "crewlet-inbox-row__head", children: [
48
+ /* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__title", children: title }),
49
+ qualifier === void 0 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
50
+ " ",
51
+ /* @__PURE__ */ jsx("span", { className: cx("crewlet-inbox-row__qualifier", qualifierTone === "danger" && "crewlet-inbox-row__qualifier--danger"), children: qualifier })
52
+ ] }),
53
+ meta === void 0 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
54
+ " ",
55
+ /* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__meta", children: meta })
56
+ ] })
57
+ ] }),
58
+ " ",
59
+ /* @__PURE__ */ jsxs("span", { className: "crewlet-inbox-row__text", children: [
60
+ children,
61
+ excerpt === void 0 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
62
+ " ",
63
+ /* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__excerpt", children: excerpt })
64
+ ] })
65
+ ] }),
66
+ unread ? /* @__PURE__ */ jsxs(Fragment, { children: [
67
+ " ",
68
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: unreadLabel })
69
+ ] }) : null,
70
+ done ? /* @__PURE__ */ jsxs(Fragment, { children: [
71
+ " ",
72
+ /* @__PURE__ */ jsx(VisuallyHidden, { children: doneLabel })
73
+ ] }) : null
74
+ ] })
75
+ ] });
76
+ const controlClass = cx(
77
+ "crewlet-inbox-row__control",
78
+ unread && "crewlet-inbox-row__control--unread",
79
+ actionable && "crewlet-inbox-row__control--actionable",
80
+ done && "crewlet-inbox-row__control--done"
81
+ );
82
+ const current = selected ? "true" : void 0;
83
+ 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 });
84
+ return /* @__PURE__ */ jsxs("li", { ...rest, className: cx("crewlet-inbox-row", selected && "crewlet-inbox-row--selected", className), children: [
85
+ control,
86
+ aside === void 0 || aside === null || aside === false ? null : /* @__PURE__ */ jsx("div", { className: "crewlet-inbox-row__aside", children: aside })
87
+ ] });
88
+ }
89
+ function InboxMore({ className, children, ...rest }) {
90
+ return /* @__PURE__ */ jsx("div", { ...rest, className: cx("crewlet-inbox-list__more", className), children });
91
+ }
92
+ function InboxToggle({ expanded, className, children, ...rest }) {
93
+ return /* @__PURE__ */ jsx("button", { ...rest, type: "button", "aria-expanded": expanded, className: cx("crewlet-inbox-list__toggle", className), children });
94
+ }
95
+ InboxList.Group = InboxGroup;
96
+ InboxList.Row = InboxRow;
97
+ InboxList.More = InboxMore;
98
+ InboxList.Toggle = InboxToggle;
99
+
100
+ export { InboxGroup, InboxList, InboxMore, InboxRow, InboxToggle };