@crewlethq/ui 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +76 -5
- package/dist/AppShell/index.js +2 -1
- package/dist/Avatar/index.js +1 -1
- package/dist/{Avatar-QHYOFID3.css → Avatar-BPJ36QZR.css} +1 -1
- package/dist/AvatarPicker/index.js +6 -6
- package/dist/Breadcrumb/Breadcrumb.d.ts +68 -0
- package/dist/Breadcrumb/index.d.ts +3 -0
- package/dist/Breadcrumb/index.js +3 -0
- package/dist/Breadcrumb-YMWVM3SV.css +193 -0
- package/dist/ChoiceButtons/ChoiceButtons.d.ts +43 -0
- package/dist/ChoiceButtons/index.d.ts +3 -0
- package/dist/ChoiceButtons/index.js +3 -0
- package/dist/ChoiceButtons-DJ5EOGUA.css +127 -0
- package/dist/ChoiceList/ChoiceList.d.ts +45 -0
- package/dist/ChoiceList/index.d.ts +3 -0
- package/dist/ChoiceList/index.js +2 -0
- package/dist/ChoiceList-2PQJS4DX.css +109 -0
- package/dist/Combobox/index.js +2 -2
- package/dist/CommandPalette/CommandPalette.d.ts +48 -1
- package/dist/CommandPalette/index.js +3 -3
- package/dist/{CommandPalette-C5AMKGN2.css → CommandPalette-HBTNKHZQ.css} +55 -2
- package/dist/Composer/Composer.d.ts +27 -0
- package/dist/Composer/index.d.ts +3 -0
- package/dist/Composer/index.js +7 -0
- package/dist/Composer-ABGJIAIR.css +88 -0
- package/dist/DataTable/index.js +3 -3
- package/dist/DataView/index.js +11 -11
- package/dist/DateTimePicker/index.js +2 -2
- package/dist/Document/Document.d.ts +56 -0
- package/dist/Document/index.d.ts +3 -0
- package/dist/Document/index.js +2 -0
- package/dist/Document-PQGXJHB7.css +288 -0
- package/dist/EntityChip/index.js +1 -1
- package/dist/Highlight/Highlight.d.ts +45 -0
- package/dist/Highlight/index.d.ts +3 -0
- package/dist/Highlight/index.js +2 -0
- package/dist/Highlight-DXLV2R6L.css +29 -0
- package/dist/HuePicker/index.js +3 -3
- package/dist/ImageUpload/index.js +2 -2
- package/dist/{ImageUpload-L2GE4JUM.css → ImageUpload-NVGMN7DP.css} +9 -6
- package/dist/InboxList/InboxList.d.ts +116 -0
- package/dist/InboxList/index.d.ts +3 -0
- package/dist/InboxList/index.js +5 -0
- package/dist/InboxList-YMFWKGGS.css +252 -0
- package/dist/KeyChip/KeyChip.d.ts +21 -0
- package/dist/KeyChip/index.d.ts +3 -0
- package/dist/KeyChip/index.js +2 -0
- package/dist/KeyChip-4XJU4BBE.css +30 -0
- package/dist/Link/Link.d.ts +17 -2
- package/dist/Link/index.js +1 -1
- package/dist/{Link-6BEFNMN2.css → Link-WPMVLKLY.css} +36 -1
- package/dist/Listbox/index.d.ts +2 -0
- package/dist/Listbox/index.js +1 -1
- package/dist/Listbox/useHighlightRest.d.ts +35 -0
- package/dist/MarkdownEditor/MarkdownEditor.d.ts +93 -0
- package/dist/MarkdownEditor/format.d.ts +34 -0
- package/dist/MarkdownEditor/index.d.ts +5 -0
- package/dist/MarkdownEditor/index.js +12 -0
- package/dist/MarkdownEditor-ZLSHTOIZ.css +146 -0
- package/dist/Modal/Modal.d.ts +5 -1
- package/dist/Modal/index.js +1 -1
- package/dist/{Modal-BNT3TDV2.css → Modal-3YJ2GG2T.css} +33 -0
- package/dist/OrgLabel/index.js +1 -1
- package/dist/OrgNode/index.js +1 -1
- package/dist/OrgTable/index.js +5 -5
- package/dist/Outline/Outline.d.ts +72 -0
- package/dist/Outline/index.d.ts +3 -0
- package/dist/Outline/index.js +2 -0
- package/dist/Outline-VCXKKU3E.css +78 -0
- package/dist/Popover/Popover.d.ts +21 -1
- package/dist/Popover/index.js +1 -1
- package/dist/ReadingPane/ReadingPane.d.ts +95 -0
- package/dist/ReadingPane/index.d.ts +3 -0
- package/dist/ReadingPane/index.js +4 -0
- package/dist/ReadingPane-5UOLPWY5.css +194 -0
- package/dist/SegmentedControl/SegmentedControl.d.ts +9 -1
- package/dist/SegmentedControl/index.js +3 -3
- package/dist/{SegmentedControl-76HODRBT.css → SegmentedControl-PKBLJVSA.css} +18 -0
- package/dist/Select/Select.d.ts +22 -0
- package/dist/Select/index.js +2 -2
- package/dist/{Select-4ANVLHUY.css → Select-XMZ44RWY.css} +24 -0
- package/dist/SidebarNav/index.js +2 -1
- package/dist/{SidebarNav-X5NLZNWA.css → SidebarNav-KF66MLOM.css} +4 -19
- package/dist/Switcher/Switcher.d.ts +151 -0
- package/dist/Switcher/index.d.ts +3 -0
- package/dist/Switcher/index.js +16 -0
- package/dist/Switcher-B44Q4WF4.css +346 -0
- package/dist/Tabs/Tabs.d.ts +7 -1
- package/dist/Tabs/index.js +1 -1
- package/dist/{Tabs-5I5Q5KKM.css → Tabs-ITJYJFMU.css} +49 -0
- package/dist/TagsInput/index.js +2 -2
- package/dist/ThemeGallery/ThemeGallery.d.ts +65 -0
- package/dist/ThemeGallery/index.d.ts +3 -0
- package/dist/ThemeGallery/index.js +6 -0
- package/dist/ThemeGallery-NITASULQ.css +93 -0
- package/dist/ThemeSwatch/ThemeSwatch.d.ts +71 -0
- package/dist/ThemeSwatch/index.d.ts +3 -0
- package/dist/ThemeSwatch/index.js +2 -0
- package/dist/ThemeSwatch-4DL457ZB.css +256 -0
- package/dist/ThemeSwitcher/ThemeSwitcher.d.ts +5 -1
- package/dist/ThemeSwitcher/index.js +4 -4
- package/dist/ThemeToggle/ThemeToggle.d.ts +1 -1
- package/dist/ThemeToggle/index.js +1 -1
- package/dist/TimeWindowPicker/index.js +4 -4
- package/dist/Toaster/index.js +1 -1
- package/dist/{Toaster-NVDCEIP5.css → Toaster-KZ7YE2HA.css} +1 -0
- package/dist/Tree/index.d.ts +1 -1
- package/dist/Tree/index.js +1 -1
- package/dist/Tree/useTreeState.d.ts +37 -7
- package/dist/TreeCanvas/index.js +2 -2
- package/dist/TreeGrid/TreeGrid.d.ts +22 -2
- package/dist/TreeGrid/index.js +2 -2
- package/dist/{TreeGrid-NSW7VMOX.css → TreeGrid-FBX3MSJA.css} +19 -0
- package/dist/{chunk-EBBAAQDY.js → chunk-26PEPONN.js} +3 -1
- package/dist/{chunk-HV6IZFBK.js → chunk-4FFHJBEN.js} +2 -2
- package/dist/{chunk-JHQUT4WJ.js → chunk-4LDTQWS7.js} +1 -1
- package/dist/{chunk-ELZKOVEC.js → chunk-4Y7WKXAW.js} +1 -1
- package/dist/{chunk-MCPKHYMC.js → chunk-6LXMLQUM.js} +17 -4
- package/dist/{chunk-3UK4VFSK.js → chunk-6NIZCQUM.js} +1 -1
- package/dist/{chunk-ORNOOMVY.js → chunk-6TSZCBID.js} +2 -2
- package/dist/{chunk-ZMJHK7DR.js → chunk-75WOCYGC.js} +2 -2
- package/dist/chunk-77IEHFY4.js +299 -0
- package/dist/chunk-A5YKNRG6.js +94 -0
- package/dist/{chunk-HLBRPES3.js → chunk-B2CITO6R.js} +2 -2
- package/dist/{chunk-TEEJSTFG.js → chunk-CF6DTETT.js} +1 -1
- package/dist/{chunk-LAQK4V3Z.js → chunk-DJMLHCLD.js} +1 -1
- package/dist/{chunk-6MU7HNB4.js → chunk-F73MC7EZ.js} +47 -2
- package/dist/{chunk-ZPSOF6VL.js → chunk-FBSEJO2C.js} +1 -1
- package/dist/chunk-FYTIJM2T.js +40 -0
- package/dist/{chunk-7JGWSOLM.js → chunk-GG2QEZO2.js} +1 -1
- package/dist/chunk-H6VKCIWV.js +41 -0
- package/dist/{chunk-6SDGRKQ7.js → chunk-HKGS67VG.js} +94 -41
- package/dist/chunk-IG75YMUN.js +22 -0
- package/dist/{chunk-JCNUQ3US.js → chunk-JDPAA2JU.js} +1 -1
- package/dist/chunk-KLIEPFEZ.js +95 -0
- package/dist/{chunk-7LD6P32I.js → chunk-L3CTFFLZ.js} +2 -18
- package/dist/{chunk-UG5ZMAXW.js → chunk-LELD5KPA.js} +1 -1
- package/dist/chunk-MNFU2RNT.js +74 -0
- package/dist/{chunk-S3BCVWTU.js → chunk-MY374UUD.js} +49 -31
- package/dist/{chunk-K5Q2DK3P.js → chunk-NXDEPUVG.js} +1 -1
- package/dist/{chunk-PDUZO35I.js → chunk-O2ZDZZS7.js} +15 -6
- package/dist/chunk-QBXZLGK2.js +40 -0
- package/dist/chunk-QSLIN64M.js +47 -0
- package/dist/{chunk-5WEVLIB6.js → chunk-RZ7RGECB.js} +1 -1
- package/dist/chunk-S3IENQ3E.js +336 -0
- package/dist/{chunk-WEIINZPA.js → chunk-SBRE7IML.js} +6 -2
- package/dist/{chunk-IVFJD7WY.js → chunk-UCCC7YVZ.js} +3 -2
- package/dist/{chunk-CIOKUMVC.js → chunk-UZPHPW3Z.js} +7 -7
- package/dist/chunk-VWNC2L6W.js +110 -0
- package/dist/chunk-VYY56AMX.js +2 -0
- package/dist/chunk-WI6K5M5X.js +24 -0
- package/dist/{chunk-R4ZJB5YX.js → chunk-WY2NLRZN.js} +2 -2
- package/dist/{chunk-SEFMO2EV.js → chunk-XFE5W2I4.js} +44 -5
- package/dist/chunk-XYCADWZN.js +100 -0
- package/dist/chunk-YSJC7AZC.js +62 -0
- package/dist/chunk-ZAJHGDAW.js +93 -0
- package/dist/generated/index.d.ts +14 -0
- package/dist/generated/index.js +65 -50
- package/dist/index.js +65 -50
- package/dist/styles.css +4456 -1965
- package/dist/utils/highlight.d.ts +17 -0
- package/dist/utils/useMediaMatch.d.ts +12 -0
- package/package.json +3 -3
- package/dist/chunk-UAQIUSSK.js +0 -2
- /package/dist/{chunk-PQLMLG5K.js → chunk-6AR2T5Y4.js} +0 -0
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
2
|
+
import './ChoiceList-2PQJS4DX.css';
|
|
3
|
+
import { useId } from 'react';
|
|
4
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
|
+
|
|
6
|
+
function ChoiceList({ options, value, onChange, label, footer, disabled, className }) {
|
|
7
|
+
const name = useId();
|
|
8
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("crewlet-choice-list", disabled && "is-disabled", className), children: [
|
|
9
|
+
/* @__PURE__ */ jsx("div", { role: "radiogroup", "aria-label": label, className: "crewlet-choice-list__group", children: options.map((option) => {
|
|
10
|
+
const id = `${name}-${option.value}`;
|
|
11
|
+
const checked = option.value === value;
|
|
12
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("crewlet-choice-list__item", option.separated && "is-separated"), children: [
|
|
13
|
+
/* @__PURE__ */ jsxs("label", { className: cx("crewlet-choice-list__row", checked && "is-checked"), htmlFor: id, children: [
|
|
14
|
+
/* @__PURE__ */ jsx(
|
|
15
|
+
"input",
|
|
16
|
+
{
|
|
17
|
+
id,
|
|
18
|
+
type: "radio",
|
|
19
|
+
name,
|
|
20
|
+
value: option.value,
|
|
21
|
+
checked,
|
|
22
|
+
disabled,
|
|
23
|
+
onChange: () => onChange(option.value),
|
|
24
|
+
className: "crewlet-choice-list__radio"
|
|
25
|
+
}
|
|
26
|
+
),
|
|
27
|
+
/* @__PURE__ */ jsxs("span", { className: "crewlet-choice-list__text", children: [
|
|
28
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-choice-list__label", children: option.label }),
|
|
29
|
+
option.detail ? /* @__PURE__ */ jsx("span", { className: "crewlet-choice-list__detail", children: option.detail }) : null
|
|
30
|
+
] }),
|
|
31
|
+
option.tag ? /* @__PURE__ */ jsx("span", { className: "crewlet-choice-list__tag", children: option.tag }) : null
|
|
32
|
+
] }),
|
|
33
|
+
checked && option.panel ? /* @__PURE__ */ jsx("div", { className: "crewlet-choice-list__panel", children: option.panel }) : null
|
|
34
|
+
] }, option.value);
|
|
35
|
+
}) }),
|
|
36
|
+
footer ? /* @__PURE__ */ jsx("div", { className: "crewlet-choice-list__footer", children: footer }) : null
|
|
37
|
+
] });
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export { ChoiceList };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { Kbd } from './chunk-SMBKXWML.js';
|
|
2
|
+
import { Textarea } from './chunk-FTEJPHBI.js';
|
|
3
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
4
|
+
import './Composer-ABGJIAIR.css';
|
|
5
|
+
import { forwardRef } from 'react';
|
|
6
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
var COMPOSER_COUNTER_AT = 0.8;
|
|
9
|
+
var Composer = forwardRef(function Composer2({ value, onChange, onSubmit, label, actions, maxLength, className, rows = 3, onKeyDown, ...rest }, ref) {
|
|
10
|
+
const near = maxLength !== void 0 && value.length >= maxLength * COMPOSER_COUNTER_AT;
|
|
11
|
+
const keyDown = (event) => {
|
|
12
|
+
onKeyDown?.(event);
|
|
13
|
+
if (event.defaultPrevented || !onSubmit) return;
|
|
14
|
+
if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
|
|
15
|
+
event.preventDefault();
|
|
16
|
+
onSubmit();
|
|
17
|
+
}
|
|
18
|
+
};
|
|
19
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("crewlet-composer", className), children: [
|
|
20
|
+
/* @__PURE__ */ jsx(
|
|
21
|
+
Textarea,
|
|
22
|
+
{
|
|
23
|
+
ref,
|
|
24
|
+
className: "crewlet-composer__field",
|
|
25
|
+
"aria-label": label,
|
|
26
|
+
value,
|
|
27
|
+
onChange: (event) => onChange(event.target.value),
|
|
28
|
+
onKeyDown: keyDown,
|
|
29
|
+
maxLength,
|
|
30
|
+
rows,
|
|
31
|
+
autoResize: true,
|
|
32
|
+
...rest
|
|
33
|
+
}
|
|
34
|
+
),
|
|
35
|
+
/* @__PURE__ */ jsxs("div", { className: "crewlet-composer__footer", children: [
|
|
36
|
+
onSubmit ? /* @__PURE__ */ jsxs("span", { className: "crewlet-composer__hint", children: [
|
|
37
|
+
/* @__PURE__ */ jsx(Kbd, { keys: ["Mod", "Enter"], subtle: true }),
|
|
38
|
+
" to send"
|
|
39
|
+
] }) : null,
|
|
40
|
+
near ? /* @__PURE__ */ jsx("span", { className: "crewlet-composer__counter", "aria-live": "polite", children: `${value.length.toLocaleString()} / ${maxLength.toLocaleString()}` }) : null,
|
|
41
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-composer__spacer" }),
|
|
42
|
+
actions
|
|
43
|
+
] })
|
|
44
|
+
] });
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
export { COMPOSER_COUNTER_AT, Composer };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useTreeState, useMeasuredSizes, layoutForest, treeAncestors, useLayoutAnchor, treeExpandable, layoutConnectors, treeItemAction, treeStep, treePosInSet, treeSetSize, treeLevel, placeGroups } from './chunk-
|
|
1
|
+
import { useTreeState, useMeasuredSizes, layoutForest, treeAncestors, useLayoutAnchor, treeExpandable, layoutConnectors, treeItemAction, treeStep, treePosInSet, treeSetSize, treeLevel, placeGroups } from './chunk-MY374UUD.js';
|
|
2
2
|
import { CANVAS_COMPOSE_CONTEXT, CANVAS_FIT_MAX_ZOOM, Canvas } from './chunk-2PZBIHRV.js';
|
|
3
3
|
import { focusables } from './chunk-R25RGPUB.js';
|
|
4
4
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import { Skeleton } from './chunk-W5J7R5EB.js';
|
|
2
|
+
import { Modal } from './chunk-CF6DTETT.js';
|
|
3
|
+
import { useListbox, useOptionKeys } from './chunk-F73MC7EZ.js';
|
|
4
|
+
import { Input } from './chunk-FTEJPHBI.js';
|
|
5
|
+
import { KeyChip, highlightMatch } from './chunk-FYTIJM2T.js';
|
|
6
|
+
import { useMediaMatch } from './chunk-IG75YMUN.js';
|
|
7
|
+
import { announce } from './chunk-RSAQOKH3.js';
|
|
8
|
+
import { Popover } from './chunk-O2ZDZZS7.js';
|
|
9
|
+
import { focusables, isComposing } from './chunk-R25RGPUB.js';
|
|
10
|
+
import { VisuallyHidden } from './chunk-BZFWDIV6.js';
|
|
11
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
12
|
+
import './Switcher-B44Q4WF4.css';
|
|
13
|
+
import { forwardRef, useId, useRef, useCallback, useMemo, useEffect } from 'react';
|
|
14
|
+
import { ChevronDownGlyph, SearchGlyph } from '@crewlethq/icons/glyphs';
|
|
15
|
+
import { breakpoint } from '@crewlethq/tokens';
|
|
16
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
17
|
+
|
|
18
|
+
var PHONE = `(width < ${breakpoint.phone})`;
|
|
19
|
+
var TOUCH = "(pointer: coarse)";
|
|
20
|
+
var DROP = 6;
|
|
21
|
+
var SKELETON_NAMES = [72, 128, 96, 150, 110, 84];
|
|
22
|
+
function Switcher({ label, open, onOpenChange, trigger, className, ...panel }) {
|
|
23
|
+
const phone = useMediaMatch(PHONE);
|
|
24
|
+
const touch = useMediaMatch(TOUCH);
|
|
25
|
+
const triggerId = useId();
|
|
26
|
+
const body = useRef(null);
|
|
27
|
+
const shift = useRef(0);
|
|
28
|
+
const place = phone ? "sheet" : trigger ? "anchored" : "centered";
|
|
29
|
+
const close = useCallback(() => onOpenChange(false), [onOpenChange]);
|
|
30
|
+
const initialFocus = useCallback(() => touch ? body.current : null, [touch]);
|
|
31
|
+
const alignUnder = useCallback((surface, anchor) => {
|
|
32
|
+
const mark = anchor.querySelector(".crewlet-key-chip, .crewlet-switcher-trigger__label");
|
|
33
|
+
const lead = surface.querySelector(".crewlet-switcher__lead");
|
|
34
|
+
if (mark && lead) {
|
|
35
|
+
const from = mark.getBoundingClientRect().left - anchor.getBoundingClientRect().left;
|
|
36
|
+
const to = lead.getBoundingClientRect().left - surface.getBoundingClientRect().left;
|
|
37
|
+
shift.current = from - to;
|
|
38
|
+
}
|
|
39
|
+
return shift.current;
|
|
40
|
+
}, []);
|
|
41
|
+
function done() {
|
|
42
|
+
close();
|
|
43
|
+
if (place === "anchored") document.getElementById(triggerId)?.focus();
|
|
44
|
+
}
|
|
45
|
+
function leave(back) {
|
|
46
|
+
const button = document.getElementById(triggerId);
|
|
47
|
+
close();
|
|
48
|
+
if (!button) return;
|
|
49
|
+
const surface = body.current;
|
|
50
|
+
const next = back ? void 0 : focusables(document.body).find(
|
|
51
|
+
(el) => (button.compareDocumentPosition(el) & Node.DOCUMENT_POSITION_FOLLOWING) !== 0 && !button.contains(el) && !surface?.contains(el)
|
|
52
|
+
);
|
|
53
|
+
(next ?? button).focus();
|
|
54
|
+
}
|
|
55
|
+
const content = /* @__PURE__ */ jsx(
|
|
56
|
+
SwitcherPanel,
|
|
57
|
+
{
|
|
58
|
+
...panel,
|
|
59
|
+
panelRef: body,
|
|
60
|
+
onDone: done,
|
|
61
|
+
onLeave: place === "anchored" ? leave : void 0
|
|
62
|
+
}
|
|
63
|
+
);
|
|
64
|
+
if (place === "anchored" && trigger) {
|
|
65
|
+
return /* @__PURE__ */ jsx(
|
|
66
|
+
Popover,
|
|
67
|
+
{
|
|
68
|
+
label,
|
|
69
|
+
open,
|
|
70
|
+
onOpenChange: (next) => onOpenChange(next),
|
|
71
|
+
alignOffset: alignUnder,
|
|
72
|
+
sideOffset: DROP,
|
|
73
|
+
initialFocus,
|
|
74
|
+
className: cx("crewlet-switcher", "crewlet-switcher--anchored", className),
|
|
75
|
+
trigger: (isOpen, toggle) => /* @__PURE__ */ jsx(SwitcherButton, { ...trigger, id: triggerId, expanded: isOpen, onToggle: toggle, onOpen: () => onOpenChange(true) }),
|
|
76
|
+
children: content
|
|
77
|
+
}
|
|
78
|
+
);
|
|
79
|
+
}
|
|
80
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
81
|
+
trigger ? /* @__PURE__ */ jsx(
|
|
82
|
+
SwitcherButton,
|
|
83
|
+
{
|
|
84
|
+
...trigger,
|
|
85
|
+
id: triggerId,
|
|
86
|
+
expanded: open,
|
|
87
|
+
onToggle: () => onOpenChange(!open),
|
|
88
|
+
onOpen: () => onOpenChange(true)
|
|
89
|
+
}
|
|
90
|
+
) : null,
|
|
91
|
+
/* @__PURE__ */ jsx(
|
|
92
|
+
Modal,
|
|
93
|
+
{
|
|
94
|
+
open,
|
|
95
|
+
onClose: close,
|
|
96
|
+
placement: place === "sheet" ? "bottom" : "top",
|
|
97
|
+
title: place === "sheet" ? label : void 0,
|
|
98
|
+
ariaLabel: label,
|
|
99
|
+
showCloseButton: place === "sheet",
|
|
100
|
+
flush: true,
|
|
101
|
+
initialFocus,
|
|
102
|
+
className: cx("crewlet-switcher", `crewlet-switcher--${place}`, className),
|
|
103
|
+
children: content
|
|
104
|
+
}
|
|
105
|
+
)
|
|
106
|
+
] });
|
|
107
|
+
}
|
|
108
|
+
var SwitcherButton = forwardRef(function SwitcherButton2({ label, keyChip, tag, mono, title, id, expanded, onToggle, onOpen, ...rest }, ref) {
|
|
109
|
+
return /* @__PURE__ */ jsxs(
|
|
110
|
+
"button",
|
|
111
|
+
{
|
|
112
|
+
type: "button",
|
|
113
|
+
"aria-haspopup": "dialog",
|
|
114
|
+
"aria-expanded": expanded,
|
|
115
|
+
...rest,
|
|
116
|
+
ref,
|
|
117
|
+
id,
|
|
118
|
+
title,
|
|
119
|
+
className: cx("crewlet-switcher-trigger", mono && "is-mono"),
|
|
120
|
+
onClick: onToggle,
|
|
121
|
+
onKeyDown: (event) => {
|
|
122
|
+
if (event.key !== "ArrowDown" || expanded || event.altKey || event.ctrlKey || event.metaKey) return;
|
|
123
|
+
event.preventDefault();
|
|
124
|
+
onOpen();
|
|
125
|
+
},
|
|
126
|
+
children: [
|
|
127
|
+
keyChip ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
128
|
+
/* @__PURE__ */ jsx(KeyChip, { children: keyChip }),
|
|
129
|
+
" "
|
|
130
|
+
] }) : null,
|
|
131
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-switcher-trigger__label", children: label }),
|
|
132
|
+
tag !== void 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
133
|
+
" ",
|
|
134
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-switcher-trigger__tag", children: tag })
|
|
135
|
+
] }) : null,
|
|
136
|
+
/* @__PURE__ */ jsx(ChevronDownGlyph, { size: "sm", className: "crewlet-switcher-trigger__chevron", "aria-hidden": "true" })
|
|
137
|
+
]
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
function SwitcherPanel({
|
|
142
|
+
query,
|
|
143
|
+
onQueryChange,
|
|
144
|
+
placeholder = "Search",
|
|
145
|
+
listLabel,
|
|
146
|
+
pinned,
|
|
147
|
+
note,
|
|
148
|
+
message,
|
|
149
|
+
groups = [],
|
|
150
|
+
footer = [],
|
|
151
|
+
loading = false,
|
|
152
|
+
loadingLabel = "Loading",
|
|
153
|
+
announcement,
|
|
154
|
+
panelRef,
|
|
155
|
+
onDone,
|
|
156
|
+
onLeave
|
|
157
|
+
}) {
|
|
158
|
+
const id = useId();
|
|
159
|
+
const footerId = `${id}-footer`;
|
|
160
|
+
const noteId = `${id}-note`;
|
|
161
|
+
const titleId = `${id}-message`;
|
|
162
|
+
const bodyId = `${id}-message-body`;
|
|
163
|
+
const flat = useMemo(
|
|
164
|
+
() => [...pinned ? [pinned] : [], ...message?.actions ?? [], ...groups.flatMap((group) => group.options), ...footer],
|
|
165
|
+
[pinned, message, groups, footer]
|
|
166
|
+
);
|
|
167
|
+
const held = useCallback((index2) => Boolean(flat[index2]?.held), [flat]);
|
|
168
|
+
const listbox = useListbox({
|
|
169
|
+
id,
|
|
170
|
+
open: true,
|
|
171
|
+
count: flat.length,
|
|
172
|
+
// The surface around the list owns Escape and a press outside it.
|
|
173
|
+
popup: false,
|
|
174
|
+
// ENTER TAKES A ROW THE WAY A PRESS DOES: through the row's own click, so
|
|
175
|
+
// a link with nothing else to do is followed as a link.
|
|
176
|
+
onCommit: (index2) => document.getElementById(listbox.optionId(index2))?.click(),
|
|
177
|
+
onClose: onDone
|
|
178
|
+
});
|
|
179
|
+
const keys = useOptionKeys({ listbox, count: flat.length, disabled: held, ends: false });
|
|
180
|
+
const { active, setActive } = listbox;
|
|
181
|
+
const { step } = keys;
|
|
182
|
+
useEffect(() => {
|
|
183
|
+
if (active >= 0 && held(active)) setActive(step(active, 1));
|
|
184
|
+
}, [active, held, setActive, step]);
|
|
185
|
+
useEffect(() => setActive(loading ? -1 : 0), [loading, setActive]);
|
|
186
|
+
useEffect(() => {
|
|
187
|
+
if (announcement) announce(announcement);
|
|
188
|
+
}, [announcement]);
|
|
189
|
+
function onKeyDown(event) {
|
|
190
|
+
if (isComposing(event)) return;
|
|
191
|
+
if (keys.onKeyDown(event)) return;
|
|
192
|
+
if (event.key === "Enter" && (event.metaKey || event.ctrlKey) && !event.altKey && !event.shiftKey) {
|
|
193
|
+
const option = flat[active];
|
|
194
|
+
if (option?.href && !option.held) {
|
|
195
|
+
event.preventDefault();
|
|
196
|
+
window.open(option.href, "_blank", "noopener");
|
|
197
|
+
}
|
|
198
|
+
return;
|
|
199
|
+
}
|
|
200
|
+
if (listbox.onKeyDown(event)) return;
|
|
201
|
+
if (event.key === "Tab" && onLeave && !event.altKey && !event.ctrlKey && !event.metaKey) {
|
|
202
|
+
event.preventDefault();
|
|
203
|
+
onLeave(event.shiftKey);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
function onRowClick(event, option) {
|
|
207
|
+
if (option.held) {
|
|
208
|
+
event.preventDefault();
|
|
209
|
+
return;
|
|
210
|
+
}
|
|
211
|
+
if (option.href && (event.metaKey || event.ctrlKey || event.shiftKey || event.altKey)) return;
|
|
212
|
+
if (option.onSelect) event.preventDefault();
|
|
213
|
+
if (!option.keepsOpen) onDone();
|
|
214
|
+
option.onSelect?.();
|
|
215
|
+
}
|
|
216
|
+
let index = -1;
|
|
217
|
+
function row(option, highlight) {
|
|
218
|
+
index += 1;
|
|
219
|
+
const mine = index;
|
|
220
|
+
const name = option.accessibleLabel && option.held ? `${option.accessibleLabel}, ${option.held}` : option.accessibleLabel;
|
|
221
|
+
const props = {
|
|
222
|
+
id: listbox.optionId(mine),
|
|
223
|
+
role: "option",
|
|
224
|
+
className: cx("crewlet-listbox__option", "crewlet-switcher__option", option.current && "is-current"),
|
|
225
|
+
"aria-selected": mine === active,
|
|
226
|
+
"aria-current": option.current ? "page" : void 0,
|
|
227
|
+
"aria-disabled": option.held ? true : void 0,
|
|
228
|
+
"aria-label": name,
|
|
229
|
+
// The press is prevented so focus stays in the field; a middle press is
|
|
230
|
+
// left alone, because it is what opens a link in a new tab.
|
|
231
|
+
onMouseDown: (event) => {
|
|
232
|
+
if (event.button === 0) event.preventDefault();
|
|
233
|
+
},
|
|
234
|
+
onMouseEnter: () => {
|
|
235
|
+
if (!option.held) setActive(mine);
|
|
236
|
+
},
|
|
237
|
+
onClick: (event) => onRowClick(event, option)
|
|
238
|
+
};
|
|
239
|
+
const words = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
240
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-switcher__lead", "aria-hidden": option.keyChip ? void 0 : true, children: option.keyChip ? /* @__PURE__ */ jsx(KeyChip, { highlight: highlight ? query : void 0, children: option.keyChip }) : option.icon }),
|
|
241
|
+
" ",
|
|
242
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-switcher__label", children: highlight ? highlightMatch(option.label, query, "word", "crewlet-switcher__match") : option.label }),
|
|
243
|
+
option.meta !== void 0 || option.held ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
244
|
+
" ",
|
|
245
|
+
/* @__PURE__ */ jsxs("span", { className: "crewlet-switcher__meta", children: [
|
|
246
|
+
option.meta,
|
|
247
|
+
option.held
|
|
248
|
+
] })
|
|
249
|
+
] }) : null
|
|
250
|
+
] });
|
|
251
|
+
return option.href && !option.held ? /* @__PURE__ */ jsx("a", { ...props, href: option.href, tabIndex: -1, children: words }, option.id) : /* @__PURE__ */ jsx("div", { ...props, children: words }, option.id);
|
|
252
|
+
}
|
|
253
|
+
const follows = Boolean(note || message || groups.length > 0 || loading);
|
|
254
|
+
const describedBy = [note ? noteId : "", message ? titleId : "", message?.body ? bodyId : ""].filter(Boolean).join(" ");
|
|
255
|
+
return /* @__PURE__ */ jsxs("div", { ref: panelRef, className: "crewlet-switcher__panel", tabIndex: -1, children: [
|
|
256
|
+
/* @__PURE__ */ jsx(
|
|
257
|
+
Input,
|
|
258
|
+
{
|
|
259
|
+
appearance: "command",
|
|
260
|
+
containerClassName: "crewlet-switcher__search",
|
|
261
|
+
leading: /* @__PURE__ */ jsx(SearchGlyph, { size: "sm" }),
|
|
262
|
+
value: query,
|
|
263
|
+
onChange: (event) => {
|
|
264
|
+
onQueryChange(event.target.value);
|
|
265
|
+
setActive(0);
|
|
266
|
+
},
|
|
267
|
+
onClear: () => {
|
|
268
|
+
onQueryChange("");
|
|
269
|
+
setActive(0);
|
|
270
|
+
},
|
|
271
|
+
clearLabel: "Clear the search",
|
|
272
|
+
onKeyDown,
|
|
273
|
+
placeholder,
|
|
274
|
+
role: "combobox",
|
|
275
|
+
"aria-label": placeholder,
|
|
276
|
+
"aria-expanded": true,
|
|
277
|
+
"aria-controls": listbox.listId,
|
|
278
|
+
"aria-autocomplete": "list",
|
|
279
|
+
"aria-activedescendant": active >= 0 ? listbox.optionId(active) : void 0,
|
|
280
|
+
"aria-describedby": describedBy || void 0,
|
|
281
|
+
autoComplete: "off",
|
|
282
|
+
spellCheck: false
|
|
283
|
+
}
|
|
284
|
+
),
|
|
285
|
+
/* @__PURE__ */ jsxs("div", { className: "crewlet-switcher__scroller", ref: listbox.listRef, children: [
|
|
286
|
+
/* @__PURE__ */ jsxs(
|
|
287
|
+
"div",
|
|
288
|
+
{
|
|
289
|
+
id: listbox.listId,
|
|
290
|
+
role: "listbox",
|
|
291
|
+
"aria-label": listLabel,
|
|
292
|
+
"aria-owns": footer.length > 0 ? footerId : void 0,
|
|
293
|
+
"aria-busy": loading || void 0,
|
|
294
|
+
className: "crewlet-switcher__list",
|
|
295
|
+
children: [
|
|
296
|
+
pinned ? row(pinned, false) : null,
|
|
297
|
+
pinned && follows ? /* @__PURE__ */ jsx("div", { className: "crewlet-listbox__separator", "aria-hidden": "true" }) : null,
|
|
298
|
+
note ? /* @__PURE__ */ jsx("div", { role: "presentation", id: noteId, className: "crewlet-switcher__note", children: note }) : null,
|
|
299
|
+
message ? (
|
|
300
|
+
// A MESSAGE NAMES WHAT CAN BE DONE ABOUT IT: its actions are a group
|
|
301
|
+
// labelled by it, so a row reached by the arrows is heard with it.
|
|
302
|
+
/* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": titleId, "aria-describedby": message.body ? bodyId : void 0, children: [
|
|
303
|
+
/* @__PURE__ */ jsxs("div", { role: "presentation", className: "crewlet-switcher__message", children: [
|
|
304
|
+
/* @__PURE__ */ jsx("span", { id: titleId, className: "crewlet-switcher__message-title", children: message.title }),
|
|
305
|
+
message.body ? /* @__PURE__ */ jsx("span", { id: bodyId, className: "crewlet-switcher__message-body", children: message.body }) : null
|
|
306
|
+
] }),
|
|
307
|
+
(message.actions ?? []).map((option) => row(option, false))
|
|
308
|
+
] })
|
|
309
|
+
) : null,
|
|
310
|
+
groups.map((group) => (
|
|
311
|
+
// Named by its heading's own words, not the figure beside them.
|
|
312
|
+
/* @__PURE__ */ jsxs("div", { role: "group", "aria-labelledby": `${id}-group-${group.id}`, children: [
|
|
313
|
+
/* @__PURE__ */ jsxs("div", { role: "presentation", className: "crewlet-listbox__heading crewlet-switcher__heading", children: [
|
|
314
|
+
/* @__PURE__ */ jsx("span", { id: `${id}-group-${group.id}`, children: group.label }),
|
|
315
|
+
group.count !== void 0 ? /* @__PURE__ */ jsx("span", { className: "crewlet-switcher__count", children: group.count }) : null
|
|
316
|
+
] }),
|
|
317
|
+
group.options.map((option) => row(option, true))
|
|
318
|
+
] }, group.id)
|
|
319
|
+
))
|
|
320
|
+
]
|
|
321
|
+
}
|
|
322
|
+
),
|
|
323
|
+
loading ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
324
|
+
/* @__PURE__ */ jsx("div", { className: "crewlet-switcher__skeleton", "aria-hidden": "true", children: SKELETON_NAMES.map((width) => /* @__PURE__ */ jsxs("div", { className: "crewlet-switcher__skeleton-row", children: [
|
|
325
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-switcher__lead", children: /* @__PURE__ */ jsx(Skeleton, { variant: "box", width: 34, height: 10, borderRadius: 4 }) }),
|
|
326
|
+
/* @__PURE__ */ jsx(Skeleton, { variant: "box", width, height: 10, borderRadius: 4 }),
|
|
327
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-switcher__meta", children: /* @__PURE__ */ jsx(Skeleton, { variant: "box", width: 14, height: 10, borderRadius: 4 }) })
|
|
328
|
+
] }, width)) }),
|
|
329
|
+
/* @__PURE__ */ jsx(VisuallyHidden, { children: /* @__PURE__ */ jsx("span", { role: "status", children: loadingLabel }) })
|
|
330
|
+
] }) : null
|
|
331
|
+
] }),
|
|
332
|
+
footer.length > 0 ? /* @__PURE__ */ jsx("div", { id: footerId, role: "group", className: "crewlet-switcher__footer", children: footer.map((option) => row(option, false)) }) : null
|
|
333
|
+
] });
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
export { Switcher };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useThemePreference, useDensityPreference } from './chunk-K3OWD7BJ.js';
|
|
2
|
-
import { SegmentedControl } from './chunk-
|
|
2
|
+
import { SegmentedControl } from './chunk-26PEPONN.js';
|
|
3
3
|
import { SunGlyph, MonitorGlyph, MoonGlyph } from '@crewlethq/icons/glyphs';
|
|
4
4
|
import { jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
@@ -32,11 +32,12 @@ function StoredThemeSwitcher({
|
|
|
32
32
|
function ThemeRow({
|
|
33
33
|
value,
|
|
34
34
|
onChange,
|
|
35
|
-
label = "
|
|
35
|
+
label = "Mode",
|
|
36
36
|
lightLabel = "Light",
|
|
37
37
|
systemLabel = "Follow the system",
|
|
38
38
|
darkLabel = "Dark",
|
|
39
39
|
size = "sm",
|
|
40
|
+
fill,
|
|
40
41
|
className
|
|
41
42
|
}) {
|
|
42
43
|
return /* @__PURE__ */ jsx(
|
|
@@ -45,6 +46,7 @@ function ThemeRow({
|
|
|
45
46
|
label,
|
|
46
47
|
semantics: "radio",
|
|
47
48
|
size,
|
|
49
|
+
fill,
|
|
48
50
|
className,
|
|
49
51
|
value,
|
|
50
52
|
onValueChange: onChange,
|
|
@@ -93,6 +95,7 @@ function DensityRow({
|
|
|
93
95
|
normalMark = "M",
|
|
94
96
|
comfortableMark = "L",
|
|
95
97
|
size = "sm",
|
|
98
|
+
fill,
|
|
96
99
|
className
|
|
97
100
|
}) {
|
|
98
101
|
return /* @__PURE__ */ jsx(
|
|
@@ -101,6 +104,7 @@ function DensityRow({
|
|
|
101
104
|
label,
|
|
102
105
|
semantics: "radio",
|
|
103
106
|
size,
|
|
107
|
+
fill,
|
|
104
108
|
className,
|
|
105
109
|
value,
|
|
106
110
|
onValueChange: onChange,
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
+
import { KeyChip } from './chunk-FYTIJM2T.js';
|
|
1
2
|
import { VisuallyHidden } from './chunk-BZFWDIV6.js';
|
|
2
3
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
3
|
-
import './SidebarNav-
|
|
4
|
+
import './SidebarNav-KF66MLOM.css';
|
|
4
5
|
import { useId, useState } from 'react';
|
|
5
6
|
import { ChevronDownGlyph } from '@crewlethq/icons/glyphs';
|
|
6
7
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -66,7 +67,7 @@ function NavItem({
|
|
|
66
67
|
}
|
|
67
68
|
const inside = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
68
69
|
icon ? /* @__PURE__ */ jsx("span", { className: "crewlet-nav-item__icon", "aria-hidden": true, children: icon }) : null,
|
|
69
|
-
lead ? /* @__PURE__ */ jsx(
|
|
70
|
+
lead ? /* @__PURE__ */ jsx(KeyChip, { className: "crewlet-nav-item__lead", children: lead }) : null,
|
|
70
71
|
lead ? " " : null,
|
|
71
72
|
/* @__PURE__ */ jsxs("span", { className: "crewlet-nav-item__label", children: [
|
|
72
73
|
label,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { Toolbar } from './chunk-PGRPNDWM.js';
|
|
2
|
-
import { RelativeTime } from './chunk-3CZ7XAVY.js';
|
|
3
1
|
import { PageHeader } from './chunk-HOXGBLEY.js';
|
|
4
|
-
import {
|
|
2
|
+
import { RelativeTime } from './chunk-3CZ7XAVY.js';
|
|
3
|
+
import { Toolbar } from './chunk-PGRPNDWM.js';
|
|
4
|
+
import { DataTable } from './chunk-WY2NLRZN.js';
|
|
5
|
+
import { Menu } from './chunk-TFH6SYWB.js';
|
|
6
|
+
import { DateTimePicker } from './chunk-JDPAA2JU.js';
|
|
7
|
+
import { useListbox, useOptionKeys } from './chunk-F73MC7EZ.js';
|
|
5
8
|
import { Kbd } from './chunk-SMBKXWML.js';
|
|
6
9
|
import { Input } from './chunk-FTEJPHBI.js';
|
|
7
|
-
import { useListbox, useOptionKeys } from './chunk-6MU7HNB4.js';
|
|
8
|
-
import { DataTable } from './chunk-R4ZJB5YX.js';
|
|
9
|
-
import { Menu } from './chunk-TFH6SYWB.js';
|
|
10
10
|
import { Button } from './chunk-OG6CL3EB.js';
|
|
11
11
|
import { IconButton } from './chunk-4FQT6ZAY.js';
|
|
12
|
-
import { Popover } from './chunk-
|
|
12
|
+
import { Popover } from './chunk-O2ZDZZS7.js';
|
|
13
13
|
import { Count } from './chunk-BHHIIK3M.js';
|
|
14
14
|
import { VisuallyHidden } from './chunk-BZFWDIV6.js';
|
|
15
15
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
@@ -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,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,10 +1,10 @@
|
|
|
1
1
|
import { Menu } from './chunk-TFH6SYWB.js';
|
|
2
2
|
import { EmptyValue } from './chunk-EUCC37WY.js';
|
|
3
|
-
import {
|
|
3
|
+
import { Checkbox } from './chunk-YCTMKKRA.js';
|
|
4
4
|
import { useClipboard } from './chunk-5VNUYO76.js';
|
|
5
|
+
import { Modal } from './chunk-CF6DTETT.js';
|
|
5
6
|
import { Button } from './chunk-OG6CL3EB.js';
|
|
6
7
|
import { useCardHeaderSlot } from './chunk-AV2DXAEL.js';
|
|
7
|
-
import { Checkbox } from './chunk-YCTMKKRA.js';
|
|
8
8
|
import { IconButton } from './chunk-4FQT6ZAY.js';
|
|
9
9
|
import { VisuallyHidden } from './chunk-BZFWDIV6.js';
|
|
10
10
|
import { cx } from './chunk-ODEQTPFM.js';
|