@crewlethq/ui 0.23.0 → 0.25.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 +75 -3
- package/dist/ArrangeList/index.js +2 -2
- package/dist/ArtifactCard/ArtifactCard.d.ts +3 -2
- package/dist/ArtifactCard/index.js +1 -1
- package/dist/ArtifactCover/ArtifactCover.d.ts +37 -0
- package/dist/ArtifactCover/DashboardCover.d.ts +46 -0
- package/dist/ArtifactCover/index.d.ts +6 -0
- package/dist/ArtifactCover/index.js +14 -0
- package/dist/ArtifactCover-D4MBEJ5H.css +67 -0
- package/dist/ArtifactIcon/ArtifactIcon.d.ts +29 -0
- package/dist/ArtifactIcon/index.d.ts +2 -0
- package/dist/ArtifactIcon/index.js +13 -0
- package/dist/AvatarPicker/index.js +6 -6
- package/dist/Canvas/Canvas.d.ts +13 -2
- package/dist/Canvas/index.js +1 -1
- package/dist/CanvasBoard/CanvasBoard.d.ts +117 -0
- package/dist/CanvasBoard/budget.d.ts +38 -0
- package/dist/CanvasBoard/index.d.ts +5 -0
- package/dist/CanvasBoard/index.js +10 -0
- package/dist/CanvasBoard-ZLPDINSM.css +236 -0
- package/dist/CanvasSchematic/CanvasSchematic.d.ts +31 -0
- package/dist/CanvasSchematic/index.d.ts +3 -0
- package/dist/CanvasSchematic/index.js +2 -0
- package/dist/CanvasSchematic-PLB3N46J.css +36 -0
- package/dist/ChangeMark/index.js +3 -3
- package/dist/CharacterPicker/index.js +2 -2
- package/dist/Checkbox/Checkbox.d.ts +6 -0
- package/dist/Checkbox/index.js +1 -1
- package/dist/{Checkbox-KT7RS6QQ.css → Checkbox-5UORUG3F.css} +16 -0
- package/dist/CommentThread/index.js +2 -2
- package/dist/DashboardCover-RMINBODB.css +143 -0
- package/dist/DataTable/index.js +3 -3
- package/dist/DataView/index.js +5 -5
- package/dist/DatasetSource/DatasetSource.d.ts +83 -0
- package/dist/DatasetSource/index.d.ts +3 -0
- package/dist/DatasetSource/index.js +7 -0
- package/dist/DatasetSource-47LBDMPR.css +129 -0
- package/dist/DocTabsEditor/DocTabsEditor.d.ts +60 -0
- package/dist/DocTabsEditor/index.d.ts +3 -0
- package/dist/DocTabsEditor/index.js +9 -0
- package/dist/DocTabsEditor-RCOWHX5J.css +78 -0
- package/dist/DownloadButton/index.js +2 -2
- package/dist/HuePicker/index.js +4 -4
- package/dist/LinkInterstitial/index.js +2 -2
- package/dist/MarkdownEditor/index.js +5 -5
- package/dist/MergeConflicts/MergeConflicts.d.ts +51 -0
- package/dist/MergeConflicts/index.d.ts +3 -0
- package/dist/MergeConflicts/index.js +9 -0
- package/dist/MergeConflicts-O44ESH4T.css +77 -0
- package/dist/Meter/index.js +1 -1
- package/dist/{Meter-5VCSFMZW.css → Meter-ZZRFUEOH.css} +15 -0
- package/dist/ObjectHeader/ObjectHeader.d.ts +7 -1
- package/dist/ObjectHeader/index.js +1 -1
- package/dist/{ObjectHeader-UNVYM2KD.css → ObjectHeader-D7GU7QNI.css} +15 -0
- package/dist/PeopleRail/index.js +3 -3
- package/dist/PresenceModel/index.d.ts +1 -1
- package/dist/PresenceModel/index.js +1 -1
- package/dist/PresenceModel/presence.d.ts +10 -2
- package/dist/PresenceStack/index.js +3 -3
- package/dist/PresenterView/PresenterView.d.ts +52 -0
- package/dist/PresenterView/index.d.ts +3 -0
- package/dist/PresenterView/index.js +8 -0
- package/dist/PresenterView-T2C6ZZ3N.css +103 -0
- package/dist/Section/index.js +1 -1
- package/dist/{Section-QRUPRIQ2.css → Section-QR3ILQVK.css} +4 -1
- package/dist/SegmentedControl/SegmentedControl.d.ts +17 -0
- package/dist/SegmentedControl/index.js +4 -4
- package/dist/{SegmentedControl-PKBLJVSA.css → SegmentedControl-FLI45IOW.css} +13 -0
- package/dist/ShareDialog/index.js +3 -3
- package/dist/SheetGrid/SheetGrid.d.ts +24 -2
- package/dist/SheetGrid/index.js +11 -7
- package/dist/{SheetGrid-4HOXDVIB.css → SheetGrid-J3TKKXZL.css} +87 -17
- package/dist/SheetModel/edits.d.ts +7 -1
- package/dist/SheetModel/index.js +2 -2
- package/dist/SheetModel/labels.d.ts +9 -0
- package/dist/SheetModel/types.d.ts +6 -0
- package/dist/SlideCompare/SlideCompare.d.ts +52 -0
- package/dist/SlideCompare/index.d.ts +3 -0
- package/dist/SlideCompare/index.js +7 -0
- package/dist/SlideCompare-MGM3U2ME.css +80 -0
- package/dist/SlideFilmstrip/SlideFilmstrip.d.ts +50 -0
- package/dist/SlideFilmstrip/index.d.ts +3 -0
- package/dist/SlideFilmstrip/index.js +8 -0
- package/dist/SlideFilmstrip-BCLNAHFX.css +108 -0
- package/dist/SlideGrid/SlideGrid.d.ts +32 -0
- package/dist/SlideGrid/index.d.ts +3 -0
- package/dist/SlideGrid/index.js +5 -0
- package/dist/SlideGrid-RT6QEQEE.css +82 -0
- package/dist/SlideStage/SlideStage.d.ts +47 -0
- package/dist/SlideStage/index.d.ts +5 -0
- package/dist/SlideStage/index.js +4 -0
- package/dist/SlideStage/useSlideKeys.d.ts +21 -0
- package/dist/SlideStage-XIOTMMRU.css +32 -0
- package/dist/Switcher/index.js +2 -2
- package/dist/TableCells/index.js +2 -2
- package/dist/Tabs/index.js +2 -2
- package/dist/Tabs/roving.d.ts +1 -0
- package/dist/TagGroup/TagGroup.d.ts +16 -1
- package/dist/TagGroup/index.js +1 -1
- package/dist/{TagGroup-BCQZD7ZD.css → TagGroup-NAXTJHDS.css} +22 -0
- package/dist/ThemeGallery/index.js +2 -2
- package/dist/ThemeSwitcher/index.js +5 -5
- package/dist/TreeCanvas/index.js +2 -2
- package/dist/VersionCompare/VersionCompare.d.ts +8 -1
- package/dist/VersionCompare/index.js +5 -5
- package/dist/VersionTimeline/index.js +1 -1
- package/dist/{VersionTimeline-EBJ6MIPJ.css → VersionTimeline-6KRXEEOO.css} +7 -7
- package/dist/WidgetFrame/WidgetFrame.d.ts +73 -0
- package/dist/WidgetFrame/index.d.ts +3 -0
- package/dist/WidgetFrame/index.js +6 -0
- package/dist/WidgetFrame-4EFJOJMW.css +127 -0
- package/dist/chunk-3D7PSL2L.js +438 -0
- package/dist/{chunk-SJCKMSQK.js → chunk-5LUI3WQP.js} +1 -1
- package/dist/{chunk-TODND5AD.js → chunk-6J35F334.js} +7 -4
- package/dist/{chunk-IASV5UCP.js → chunk-7T42VQQT.js} +3 -1
- package/dist/{chunk-BJCFNRGH.js → chunk-BEHFTRMZ.js} +1 -1
- package/dist/chunk-BQYQWJPK.js +80 -0
- package/dist/{chunk-KLIEPFEZ.js → chunk-C2FRTWKO.js} +1 -1
- package/dist/{chunk-APS747CR.js → chunk-EHQTPVV4.js} +5 -3
- package/dist/{chunk-A2UXBCLO.js → chunk-FAQGGX2Z.js} +1 -1
- package/dist/chunk-FQCLKD7U.js +2 -0
- package/dist/{chunk-J4OKGJQ6.js → chunk-FVLCTCMV.js} +1 -1
- package/dist/{chunk-XJFOOXCF.js → chunk-HJEVSQN6.js} +1 -1
- package/dist/chunk-HONZQ4UR.js +107 -0
- package/dist/{chunk-5PSXBL73.js → chunk-HVIX5ECM.js} +1 -1
- package/dist/{chunk-36CWC2NH.js → chunk-INTEH4F3.js} +271 -143
- package/dist/{chunk-F6NZOVWL.js → chunk-IW55G7XG.js} +6 -2
- package/dist/chunk-KNLJL3VP.js +101 -0
- package/dist/chunk-KSSSFLE2.js +105 -0
- package/dist/{chunk-TXAFKH2A.js → chunk-KZOGQXSP.js} +6 -0
- package/dist/{chunk-CS65QSIJ.js → chunk-LZHLSQYK.js} +2 -2
- package/dist/chunk-MQEEQVG6.js +62 -0
- package/dist/chunk-NBWNLYWZ.js +62 -0
- package/dist/{chunk-YYZRLLLY.js → chunk-NHBP2XS5.js} +19 -3
- package/dist/chunk-O2EGEONV.js +90 -0
- package/dist/{chunk-YM3GJHGW.js → chunk-ODT5H4MN.js} +1 -1
- package/dist/{chunk-JCSXFAXG.js → chunk-OJRDEVHV.js} +1 -1
- package/dist/{chunk-U63Y5OCW.js → chunk-PRNX5AFE.js} +2 -2
- package/dist/chunk-Q4A5CGUB.js +43 -0
- package/dist/{chunk-7QL2OFP6.js → chunk-RCQXUT5K.js} +25 -9
- package/dist/{chunk-CBOICT64.js → chunk-RKKO7QHH.js} +2 -0
- package/dist/{chunk-TBIZSQHB.js → chunk-RSC7UJCR.js} +1 -1
- package/dist/chunk-RWA4H2TV.js +73 -0
- package/dist/{chunk-OQT7GSKJ.js → chunk-SGIQCI6Y.js} +1 -1
- package/dist/{chunk-35UKQ33X.js → chunk-SVW3VG72.js} +2 -2
- package/dist/{chunk-4PZ6FJKW.js → chunk-UGNUUVRI.js} +2 -2
- package/dist/chunk-UOR7TOAU.js +191 -0
- package/dist/{chunk-XMGB3ZAT.js → chunk-URUGEAFB.js} +3 -2
- package/dist/chunk-UZ7ZUSLH.js +179 -0
- package/dist/chunk-V2Z24W2Z.js +75 -0
- package/dist/{chunk-I7WXZOWA.js → chunk-VGE3G3T4.js} +3 -1
- package/dist/{chunk-UNZ7TVV5.js → chunk-W4XYY73O.js} +7 -9
- package/dist/{chunk-IPM2E6UI.js → chunk-WJDQ7XQA.js} +1 -1
- package/dist/{chunk-PPAQFGS2.js → chunk-YEKYVJQR.js} +1 -1
- package/dist/chunk-Z54BPRL6.js +74 -0
- package/dist/{chunk-S35G6PNC.js → chunk-Z7JYG5TF.js} +5 -4
- package/dist/chunk-ZZDY4XL7.js +112 -0
- package/dist/generated/index.d.ts +13 -0
- package/dist/generated/index.js +92 -79
- package/dist/index.js +92 -79
- package/dist/styles.css +1644 -153
- package/dist/utils/csv.d.ts +18 -0
- package/dist/utils/elementToPng.d.ts +49 -0
- package/dist/utils/index.d.ts +4 -1
- package/dist/utils/index.js +2 -2
- package/dist/utils/useDownload.d.ts +14 -4
- package/package.json +3 -3
- package/dist/chunk-E6UWRXNM.js +0 -52
- package/dist/chunk-M54K52ZU.js +0 -2
- package/dist/chunk-U5LQ2AS5.js +0 -1
- package/dist/{chunk-KG6XRG5Z.js → chunk-5OY4LJFH.js} +1 -1
- package/dist/{chunk-ZM7HLFOA.js → chunk-L2OQRPXJ.js} +1 -1
- package/dist/{chunk-MUGM7SEG.js → chunk-LFNUH4GY.js} +1 -1
- package/dist/{chunk-PBNP7H2C.js → chunk-M2VJGNCD.js} +1 -1
- /package/dist/{chunk-MSSZHDZI.js → chunk-SLRKS5PF.js} +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import { isComposing } from './chunk-R25RGPUB.js';
|
|
2
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
3
|
+
import './SlideStage-XIOTMMRU.css';
|
|
4
|
+
import { useRef, useState, useLayoutEffect, useEffect } from 'react';
|
|
5
|
+
import { jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var SLIDE_WIDTH = 1920;
|
|
8
|
+
var SLIDE_HEIGHT = 1080;
|
|
9
|
+
function SlideStage({
|
|
10
|
+
children,
|
|
11
|
+
label,
|
|
12
|
+
fit = "width",
|
|
13
|
+
scale,
|
|
14
|
+
width = SLIDE_WIDTH,
|
|
15
|
+
height = SLIDE_HEIGHT,
|
|
16
|
+
className
|
|
17
|
+
}) {
|
|
18
|
+
const box = useRef(null);
|
|
19
|
+
const [measured, setMeasured] = useState({
|
|
20
|
+
scale: 0,
|
|
21
|
+
left: 0,
|
|
22
|
+
top: 0
|
|
23
|
+
});
|
|
24
|
+
useLayoutEffect(() => {
|
|
25
|
+
const el = box.current;
|
|
26
|
+
if (!el || scale !== void 0) return void 0;
|
|
27
|
+
const read = () => {
|
|
28
|
+
const w = el.clientWidth;
|
|
29
|
+
const h = el.clientHeight;
|
|
30
|
+
if (fit === "contain") {
|
|
31
|
+
const s2 = Math.min(w / width, h / height);
|
|
32
|
+
setMeasured({ scale: s2, left: (w - width * s2) / 2, top: (h - height * s2) / 2 });
|
|
33
|
+
} else {
|
|
34
|
+
setMeasured({ scale: w / width, left: 0, top: 0 });
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
read();
|
|
38
|
+
if (typeof ResizeObserver === "undefined") return void 0;
|
|
39
|
+
const observer = new ResizeObserver(read);
|
|
40
|
+
observer.observe(el);
|
|
41
|
+
return () => observer.disconnect();
|
|
42
|
+
}, [fit, scale, width, height]);
|
|
43
|
+
const s = scale ?? measured.scale;
|
|
44
|
+
const boxStyle = fit === "width" || scale !== void 0 ? { aspectRatio: `${width} / ${height}`, ...scale !== void 0 ? { width: width * scale } : {} } : {};
|
|
45
|
+
const frameStyle = {
|
|
46
|
+
width,
|
|
47
|
+
height,
|
|
48
|
+
transform: `translate(${scale === void 0 ? measured.left : 0}px, ${scale === void 0 ? measured.top : 0}px) scale(${s})`,
|
|
49
|
+
// Hidden until measured, so a slide is never painted at full size for
|
|
50
|
+
// one frame inside a thumbnail.
|
|
51
|
+
visibility: s > 0 ? "visible" : "hidden"
|
|
52
|
+
};
|
|
53
|
+
return /* @__PURE__ */ jsx(
|
|
54
|
+
"div",
|
|
55
|
+
{
|
|
56
|
+
ref: box,
|
|
57
|
+
className: cx("crewlet-slide-stage", `crewlet-slide-stage--${fit}`, className),
|
|
58
|
+
style: boxStyle,
|
|
59
|
+
role: "group",
|
|
60
|
+
"aria-roledescription": "slide",
|
|
61
|
+
"aria-label": label,
|
|
62
|
+
children: /* @__PURE__ */ jsx("div", { className: "crewlet-slide-stage__frame", style: frameStyle, children })
|
|
63
|
+
}
|
|
64
|
+
);
|
|
65
|
+
}
|
|
66
|
+
function typing(target) {
|
|
67
|
+
if (!(target instanceof HTMLElement)) return false;
|
|
68
|
+
return target.isContentEditable || ["INPUT", "TEXTAREA", "SELECT"].includes(target.tagName);
|
|
69
|
+
}
|
|
70
|
+
function useSlideKeys({ onNext, onPrevious, onFirst, onLast, onExit, enabled = true }) {
|
|
71
|
+
useEffect(() => {
|
|
72
|
+
if (!enabled) return void 0;
|
|
73
|
+
const onKeyDown = (event) => {
|
|
74
|
+
if (event.defaultPrevented || isComposing(event) || typing(event.target)) return;
|
|
75
|
+
if (event.altKey || event.ctrlKey || event.metaKey) return;
|
|
76
|
+
const act = {
|
|
77
|
+
ArrowRight: onNext,
|
|
78
|
+
ArrowDown: onNext,
|
|
79
|
+
PageDown: onNext,
|
|
80
|
+
" ": onNext,
|
|
81
|
+
Enter: onNext,
|
|
82
|
+
ArrowLeft: onPrevious,
|
|
83
|
+
ArrowUp: onPrevious,
|
|
84
|
+
PageUp: onPrevious,
|
|
85
|
+
Backspace: onPrevious,
|
|
86
|
+
Home: onFirst,
|
|
87
|
+
End: onLast,
|
|
88
|
+
Escape: onExit
|
|
89
|
+
};
|
|
90
|
+
const fn = act[event.key];
|
|
91
|
+
if (!fn) return;
|
|
92
|
+
if ((event.key === "Enter" || event.key === " ") && event.target instanceof HTMLButtonElement) return;
|
|
93
|
+
event.preventDefault();
|
|
94
|
+
fn();
|
|
95
|
+
};
|
|
96
|
+
document.addEventListener("keydown", onKeyDown);
|
|
97
|
+
return () => document.removeEventListener("keydown", onKeyDown);
|
|
98
|
+
}, [enabled, onNext, onPrevious, onFirst, onLast, onExit]);
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
export { SLIDE_HEIGHT, SLIDE_WIDTH, SlideStage, useSlideKeys };
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { SlideStage } from './chunk-KNLJL3VP.js';
|
|
2
|
+
import { useReorder } from './chunk-XJ2QEBMM.js';
|
|
3
|
+
import { VisuallyHidden } from './chunk-BZFWDIV6.js';
|
|
4
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
5
|
+
import './SlideFilmstrip-BCLNAHFX.css';
|
|
6
|
+
import { useRef } from 'react';
|
|
7
|
+
import { EyeOffGlyph, GripVerticalGlyph } from '@crewlethq/icons/glyphs';
|
|
8
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
9
|
+
|
|
10
|
+
var LABELS = {
|
|
11
|
+
list: "Slides",
|
|
12
|
+
slide: (position, title) => `Slide ${position}, ${title}`,
|
|
13
|
+
hidden: "Hidden when presenting",
|
|
14
|
+
untitled: "Untitled"
|
|
15
|
+
};
|
|
16
|
+
function SlideFilmstrip({
|
|
17
|
+
slides,
|
|
18
|
+
selected,
|
|
19
|
+
onSelect,
|
|
20
|
+
renderSlide,
|
|
21
|
+
onReorder,
|
|
22
|
+
className,
|
|
23
|
+
labels
|
|
24
|
+
}) {
|
|
25
|
+
const text = { ...LABELS, ...labels };
|
|
26
|
+
const ids = slides.map((s) => s.id);
|
|
27
|
+
const byId = new Map(slides.map((s) => [s.id, s]));
|
|
28
|
+
const titleOf = (id) => byId.get(id)?.title || text.untitled;
|
|
29
|
+
const reorder = useReorder({
|
|
30
|
+
keys: ids,
|
|
31
|
+
onReorder: (next) => onReorder?.(next),
|
|
32
|
+
nameOf: (id) => text.slide(ids.indexOf(id) + 1, titleOf(id)),
|
|
33
|
+
axis: "vertical"
|
|
34
|
+
});
|
|
35
|
+
const order = onReorder ? reorder.order : ids;
|
|
36
|
+
const options = useRef(/* @__PURE__ */ new Map());
|
|
37
|
+
const go = (id) => {
|
|
38
|
+
if (!id) return;
|
|
39
|
+
onSelect(id);
|
|
40
|
+
options.current.get(id)?.focus();
|
|
41
|
+
};
|
|
42
|
+
const onKeyDown = (event) => {
|
|
43
|
+
const at = order.indexOf(selected);
|
|
44
|
+
const to = {
|
|
45
|
+
ArrowDown: order[at + 1],
|
|
46
|
+
ArrowUp: order[at - 1],
|
|
47
|
+
Home: order[0],
|
|
48
|
+
End: order[order.length - 1]
|
|
49
|
+
}[event.key];
|
|
50
|
+
if (to === void 0) return;
|
|
51
|
+
event.preventDefault();
|
|
52
|
+
go(to);
|
|
53
|
+
};
|
|
54
|
+
return /* @__PURE__ */ jsxs("div", { className: cx("crewlet-slide-filmstrip", className), children: [
|
|
55
|
+
onReorder ? /* @__PURE__ */ jsx(VisuallyHidden, { id: reorder.hintId, children: reorder.hint }) : null,
|
|
56
|
+
/* @__PURE__ */ jsx(
|
|
57
|
+
"ol",
|
|
58
|
+
{
|
|
59
|
+
className: "crewlet-slide-filmstrip__list",
|
|
60
|
+
"aria-label": text.list,
|
|
61
|
+
...onReorder ? reorder.containerProps : {},
|
|
62
|
+
children: order.map((id, i) => {
|
|
63
|
+
const slide = byId.get(id);
|
|
64
|
+
const isSelected = id === selected;
|
|
65
|
+
return /* @__PURE__ */ jsxs(
|
|
66
|
+
"li",
|
|
67
|
+
{
|
|
68
|
+
className: "crewlet-slide-filmstrip__item",
|
|
69
|
+
"data-selected": isSelected ? "true" : void 0,
|
|
70
|
+
"data-hidden": slide?.hidden ? "true" : void 0,
|
|
71
|
+
...onReorder ? reorder.itemProps(id) : {},
|
|
72
|
+
children: [
|
|
73
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-slide-filmstrip__number", "aria-hidden": "true", children: i + 1 }),
|
|
74
|
+
/* @__PURE__ */ jsxs(
|
|
75
|
+
"button",
|
|
76
|
+
{
|
|
77
|
+
type: "button",
|
|
78
|
+
ref: (node) => {
|
|
79
|
+
if (node) options.current.set(id, node);
|
|
80
|
+
else options.current.delete(id);
|
|
81
|
+
},
|
|
82
|
+
className: "crewlet-slide-filmstrip__thumb",
|
|
83
|
+
"aria-current": isSelected ? "true" : void 0,
|
|
84
|
+
"aria-label": text.slide(i + 1, titleOf(id)) + (slide?.hidden ? `, ${text.hidden}` : ""),
|
|
85
|
+
tabIndex: isSelected ? 0 : -1,
|
|
86
|
+
onClick: () => go(id),
|
|
87
|
+
onKeyDown,
|
|
88
|
+
children: [
|
|
89
|
+
/* @__PURE__ */ jsx(SlideStage, { label: text.slide(i + 1, titleOf(id)), children: renderSlide(id) }),
|
|
90
|
+
slide?.hidden ? /* @__PURE__ */ jsx("span", { className: "crewlet-slide-filmstrip__hidden", children: /* @__PURE__ */ jsx(EyeOffGlyph, { size: "sm" }) }) : null
|
|
91
|
+
]
|
|
92
|
+
}
|
|
93
|
+
),
|
|
94
|
+
onReorder ? /* @__PURE__ */ jsx("button", { type: "button", className: "crewlet-slide-filmstrip__handle", ...reorder.handleProps(id), children: /* @__PURE__ */ jsx(GripVerticalGlyph, { size: "sm" }) }) : null
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
id
|
|
98
|
+
);
|
|
99
|
+
})
|
|
100
|
+
}
|
|
101
|
+
)
|
|
102
|
+
] });
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
export { SlideFilmstrip };
|
|
@@ -168,6 +168,7 @@ function Canvas({
|
|
|
168
168
|
touch = true,
|
|
169
169
|
labels,
|
|
170
170
|
onReady,
|
|
171
|
+
onViewChange,
|
|
171
172
|
ref,
|
|
172
173
|
className
|
|
173
174
|
}) {
|
|
@@ -225,6 +226,11 @@ function Canvas({
|
|
|
225
226
|
useLayoutEffect(() => {
|
|
226
227
|
if (ready) apply(viewNow.current);
|
|
227
228
|
}, [ready, size, content, apply]);
|
|
229
|
+
const reportView = useRef(onViewChange);
|
|
230
|
+
reportView.current = onViewChange;
|
|
231
|
+
useLayoutEffect(() => {
|
|
232
|
+
if (ready) reportView.current?.(view, size);
|
|
233
|
+
}, [ready, view, size]);
|
|
228
234
|
useLayoutEffect(() => {
|
|
229
235
|
layer?.dispatchEvent(new CustomEvent(LAYER_REPOSITION_EVENT, { detail: view }));
|
|
230
236
|
}, [view, layer]);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Toolbar } from './chunk-PGRPNDWM.js';
|
|
2
|
-
import { SegmentedControl } from './chunk-
|
|
3
|
-
import { tabId } from './chunk-
|
|
2
|
+
import { SegmentedControl } from './chunk-RCQXUT5K.js';
|
|
3
|
+
import { tabId } from './chunk-HJEVSQN6.js';
|
|
4
4
|
import { IconButton } from './chunk-4FQT6ZAY.js';
|
|
5
5
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
6
6
|
import './MarkdownEditor-WOKV7CLK.css';
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Document } from './chunk-WI6K5M5X.js';
|
|
2
|
+
import { ArtifactKindGlyph } from './chunk-6J35F334.js';
|
|
3
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
4
|
+
import './ArtifactCover-D4MBEJ5H.css';
|
|
5
|
+
import './DashboardCover-RMINBODB.css';
|
|
6
|
+
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
7
|
+
|
|
8
|
+
function DocCover({ children, className }) {
|
|
9
|
+
return /* @__PURE__ */ jsx("span", { className: cx("crewlet-artifact-cover crewlet-doc-cover", className), children: /* @__PURE__ */ jsx(Document, { className: "crewlet-doc-cover__page", size: "sm", measure: "none", children }) });
|
|
10
|
+
}
|
|
11
|
+
var SHEET_COVER_COLUMNS = 4;
|
|
12
|
+
var SHEET_COVER_ROWS = 5;
|
|
13
|
+
function SheetCover({ columns, rows, className }) {
|
|
14
|
+
const shown = columns.slice(0, SHEET_COVER_COLUMNS);
|
|
15
|
+
return /* @__PURE__ */ jsxs("span", { className: cx("crewlet-artifact-cover crewlet-sheet-cover", className), style: { ["--crewlet-sheet-cover-columns"]: Math.max(shown.length, 1) }, children: [
|
|
16
|
+
shown.map((c, i) => /* @__PURE__ */ jsx("span", { className: "crewlet-sheet-cover__cell crewlet-sheet-cover__cell--head", children: c }, `h${i}`)),
|
|
17
|
+
rows.slice(0, SHEET_COVER_ROWS).map(
|
|
18
|
+
(row, r) => shown.map((_, i) => /* @__PURE__ */ jsx("span", { className: "crewlet-sheet-cover__cell", children: row[i] ?? "" }, `${r}-${i}`))
|
|
19
|
+
)
|
|
20
|
+
] });
|
|
21
|
+
}
|
|
22
|
+
var MAX_STATS = 3;
|
|
23
|
+
var MAX_SCHEMATIC = 8;
|
|
24
|
+
var GRID_COLUMNS = 12;
|
|
25
|
+
var COVER = "crewlet-artifact-cover crewlet-dashboard-cover";
|
|
26
|
+
function DashboardCover({ stats = [], layout = [], className, ...rest }) {
|
|
27
|
+
const shown = stats.slice(0, MAX_STATS);
|
|
28
|
+
if (shown.length > 0) {
|
|
29
|
+
return /* @__PURE__ */ jsx("div", { ...rest, className: cx(COVER, "crewlet-dashboard-cover--stats", className), children: shown.map((stat, index) => /* @__PURE__ */ jsxs("div", { className: "crewlet-dashboard-cover__stat", children: [
|
|
30
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__label", children: stat.label }),
|
|
31
|
+
stat.value !== void 0 && stat.value !== "" ? /* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__value", children: stat.value }) : stat.source ? /* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__source", children: stat.source }) : null
|
|
32
|
+
] }, `${index}:${stat.label}`)) });
|
|
33
|
+
}
|
|
34
|
+
const blocks = layout.slice(0, MAX_SCHEMATIC);
|
|
35
|
+
if (blocks.length > 0) {
|
|
36
|
+
return /* @__PURE__ */ jsx("div", { ...rest, className: cx(COVER, "crewlet-dashboard-cover--layout", className), children: blocks.map((block, index) => /* @__PURE__ */ jsx(
|
|
37
|
+
"span",
|
|
38
|
+
{
|
|
39
|
+
className: cx("crewlet-dashboard-cover__block", `crewlet-dashboard-cover__block--${block.kind}`),
|
|
40
|
+
style: { gridColumn: `span ${clampColumns(block.w)}` },
|
|
41
|
+
children: block.kind === "chart" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
42
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__bar" }),
|
|
43
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__bar" }),
|
|
44
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__bar" }),
|
|
45
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__bar" })
|
|
46
|
+
] }) : block.kind === "table" || block.kind === "note" ? /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
47
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__line" }),
|
|
48
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__line" }),
|
|
49
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__line" })
|
|
50
|
+
] }) : /* @__PURE__ */ jsx("span", { className: "crewlet-dashboard-cover__figure" })
|
|
51
|
+
},
|
|
52
|
+
index
|
|
53
|
+
)) });
|
|
54
|
+
}
|
|
55
|
+
return /* @__PURE__ */ jsx("div", { ...rest, className: cx(COVER, "crewlet-dashboard-cover--empty", className), children: /* @__PURE__ */ jsx(ArtifactKindGlyph, { kind: "dashboard", size: 32 }) });
|
|
56
|
+
}
|
|
57
|
+
function clampColumns(w) {
|
|
58
|
+
if (!Number.isFinite(w)) return GRID_COLUMNS;
|
|
59
|
+
return Math.min(GRID_COLUMNS, Math.max(1, Math.round(w)));
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { DashboardCover, DocCover, SHEET_COVER_COLUMNS, SHEET_COVER_ROWS, SheetCover };
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
2
|
+
import './CanvasSchematic-PLB3N46J.css';
|
|
3
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
4
|
+
|
|
5
|
+
var MARGIN = 0.06;
|
|
6
|
+
function CanvasSchematic({
|
|
7
|
+
label,
|
|
8
|
+
boards,
|
|
9
|
+
notes = [],
|
|
10
|
+
cover,
|
|
11
|
+
className,
|
|
12
|
+
...rest
|
|
13
|
+
}) {
|
|
14
|
+
const all = [...boards, ...notes];
|
|
15
|
+
const minX = Math.min(...all.map((r) => r.x));
|
|
16
|
+
const minY = Math.min(...all.map((r) => r.y));
|
|
17
|
+
const maxX = Math.max(...all.map((r) => r.x + r.w));
|
|
18
|
+
const maxY = Math.max(...all.map((r) => r.y + r.h));
|
|
19
|
+
const side = Math.max(maxX - minX, maxY - minY, 1);
|
|
20
|
+
const pad = side * MARGIN;
|
|
21
|
+
const viewBox = all.length === 0 ? "0 0 1 1" : `${minX - pad} ${minY - pad} ${maxX - minX + 2 * pad} ${maxY - minY + 2 * pad}`;
|
|
22
|
+
const coverBoard = boards.find((b) => b.id === cover);
|
|
23
|
+
return /* @__PURE__ */ jsx("div", { className: cx("crewlet-canvas-schematic", className), ...rest, children: /* @__PURE__ */ jsxs("svg", { viewBox, preserveAspectRatio: "xMidYMid meet", role: "img", "aria-label": label, children: [
|
|
24
|
+
notes.map((n, i) => /* @__PURE__ */ jsx(
|
|
25
|
+
"rect",
|
|
26
|
+
{
|
|
27
|
+
className: "crewlet-canvas-schematic__note",
|
|
28
|
+
x: n.x,
|
|
29
|
+
y: n.y,
|
|
30
|
+
width: n.w,
|
|
31
|
+
height: n.h
|
|
32
|
+
},
|
|
33
|
+
`note-${i}`
|
|
34
|
+
)),
|
|
35
|
+
boards.map((b) => /* @__PURE__ */ jsx(
|
|
36
|
+
"rect",
|
|
37
|
+
{
|
|
38
|
+
className: "crewlet-canvas-schematic__board",
|
|
39
|
+
"data-cover": b.id === cover || void 0,
|
|
40
|
+
x: b.x,
|
|
41
|
+
y: b.y,
|
|
42
|
+
width: b.w,
|
|
43
|
+
height: b.h,
|
|
44
|
+
vectorEffect: "non-scaling-stroke"
|
|
45
|
+
},
|
|
46
|
+
b.id
|
|
47
|
+
)),
|
|
48
|
+
coverBoard?.title && /* @__PURE__ */ jsx(
|
|
49
|
+
"text",
|
|
50
|
+
{
|
|
51
|
+
className: "crewlet-canvas-schematic__title",
|
|
52
|
+
x: coverBoard.x + coverBoard.w * 0.08,
|
|
53
|
+
y: coverBoard.y + coverBoard.h * 0.5,
|
|
54
|
+
fontSize: Math.min(coverBoard.h * 0.16, side * 0.06),
|
|
55
|
+
dominantBaseline: "middle",
|
|
56
|
+
children: coverBoard.title
|
|
57
|
+
}
|
|
58
|
+
)
|
|
59
|
+
] }) });
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
export { CanvasSchematic };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { PRESENCE_LABELS } from './chunk-
|
|
1
|
+
import { PRESENCE_LABELS } from './chunk-Z7JYG5TF.js';
|
|
2
2
|
import { isNodeHue } from './chunk-AYKXMIOR.js';
|
|
3
3
|
|
|
4
4
|
// src/SheetModel/types.ts
|
|
@@ -69,10 +69,16 @@ var SHEET_LABELS = {
|
|
|
69
69
|
return state.saving === 0 ? "Offline." : `Offline. ${changes(state.saving)} will sync when you reconnect.`;
|
|
70
70
|
}
|
|
71
71
|
if (state.failed !== void 0 && state.failed > 0) return "Could not save.";
|
|
72
|
+
if (state.refused !== void 0 && state.refused > 0) return `${changes(state.refused)} not saved`;
|
|
72
73
|
if (state.saving > 0) return `Saving ${changes(state.saving)}`;
|
|
73
74
|
return "Saved";
|
|
74
75
|
},
|
|
75
76
|
retry: "Retry",
|
|
77
|
+
dismiss: "Dismiss",
|
|
78
|
+
notSaved: (reason) => `Not saved: ${reason}`,
|
|
79
|
+
rowActions: (row) => `Row actions for row ${row}`,
|
|
80
|
+
deleteRow: "Delete row",
|
|
81
|
+
rowActionsHelp: "Shift and F10 opens the actions of the row.",
|
|
76
82
|
filter: "Filter options",
|
|
77
83
|
noOptions: "No matching options",
|
|
78
84
|
clear: "Clear",
|
|
@@ -693,9 +699,19 @@ var SheetPendingEdits = class {
|
|
|
693
699
|
for (const value of this.waiting.values()) count += value;
|
|
694
700
|
return count;
|
|
695
701
|
}
|
|
696
|
-
/**
|
|
702
|
+
/** Clears every refusal at once: the strip's Dismiss. */
|
|
703
|
+
dismissAll() {
|
|
704
|
+
if (this.refusals.size === 0) return;
|
|
705
|
+
this.refusals.clear();
|
|
706
|
+
this.emit();
|
|
707
|
+
}
|
|
708
|
+
/**
|
|
709
|
+
* The sync strip's state. A refusal is not a failure to retry (the engine
|
|
710
|
+
* decided it), but it is counted, so the strip holds "not saved" until the
|
|
711
|
+
* reader dismisses it rather than going back to "Saved".
|
|
712
|
+
*/
|
|
697
713
|
sync(offline = false) {
|
|
698
|
-
return { saving: this.saving, offline };
|
|
714
|
+
return { saving: this.saving, offline, refused: this.refusals.size };
|
|
699
715
|
}
|
|
700
716
|
/** Every refusal since the last `resetFailures`, for a host that reports them. */
|
|
701
717
|
get failures() {
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { useAnnouncer } from './chunk-RSAQOKH3.js';
|
|
2
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
3
|
+
import './TagGroup-NAXTJHDS.css';
|
|
4
|
+
import { useState, useRef, Children, useLayoutEffect } from 'react';
|
|
5
|
+
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
function TagGroup({
|
|
8
|
+
label,
|
|
9
|
+
max = 6,
|
|
10
|
+
overflow = "expand",
|
|
11
|
+
moreLabel = (hidden) => `+${hidden} more`,
|
|
12
|
+
countLabel = (hidden) => `+${hidden}`,
|
|
13
|
+
expandedMessage = (total) => `Showing all ${total}.`,
|
|
14
|
+
className,
|
|
15
|
+
children
|
|
16
|
+
}) {
|
|
17
|
+
const [open, setOpen] = useState(false);
|
|
18
|
+
const announce = useAnnouncer();
|
|
19
|
+
const list = useRef(null);
|
|
20
|
+
const all = Children.toArray(children);
|
|
21
|
+
const fit = overflow === "fit";
|
|
22
|
+
const fitted = useFitted(list, fit, all.length);
|
|
23
|
+
const shown = fit ? all.slice(0, fitted) : open ? all : all.slice(0, max);
|
|
24
|
+
const hidden = all.length - shown.length;
|
|
25
|
+
return /* @__PURE__ */ jsxs(
|
|
26
|
+
"ul",
|
|
27
|
+
{
|
|
28
|
+
ref: list,
|
|
29
|
+
tabIndex: -1,
|
|
30
|
+
className: cx("crewlet-tag-group", fit && "crewlet-tag-group--fit", className),
|
|
31
|
+
"aria-label": `${label}, ${all.length}`,
|
|
32
|
+
children: [
|
|
33
|
+
shown.map((tag, index) => (
|
|
34
|
+
// Keyed by position: the list only ever grows at the end, as the tail
|
|
35
|
+
// is revealed, so no item ever changes the index it sits at.
|
|
36
|
+
/* @__PURE__ */ jsx("li", { className: "crewlet-tag-group__item", children: tag }, index)
|
|
37
|
+
)),
|
|
38
|
+
hidden > 0 && fit ? /* @__PURE__ */ jsx("li", { className: "crewlet-tag-group__item", "data-count": "", children: /* @__PURE__ */ jsx("span", { className: "crewlet-tag-group__count", children: countLabel(hidden) }) }) : hidden > 0 ? /* @__PURE__ */ jsx("li", { className: "crewlet-tag-group__item", children: /* @__PURE__ */ jsx(
|
|
39
|
+
"button",
|
|
40
|
+
{
|
|
41
|
+
type: "button",
|
|
42
|
+
className: "crewlet-tag-group__more",
|
|
43
|
+
onClick: () => {
|
|
44
|
+
setOpen(true);
|
|
45
|
+
list.current?.focus();
|
|
46
|
+
announce(expandedMessage(all.length));
|
|
47
|
+
},
|
|
48
|
+
children: moreLabel(hidden)
|
|
49
|
+
}
|
|
50
|
+
) }) : null
|
|
51
|
+
]
|
|
52
|
+
}
|
|
53
|
+
);
|
|
54
|
+
}
|
|
55
|
+
function useFitted(list, active, total) {
|
|
56
|
+
const [fitted, setFitted] = useState(total);
|
|
57
|
+
const width = useRef(null);
|
|
58
|
+
useLayoutEffect(() => {
|
|
59
|
+
if (!active) return;
|
|
60
|
+
setFitted(total);
|
|
61
|
+
}, [active, total]);
|
|
62
|
+
useLayoutEffect(() => {
|
|
63
|
+
const box = list.current;
|
|
64
|
+
if (!active || !box) return;
|
|
65
|
+
const items = [...box.children];
|
|
66
|
+
const first = items[0];
|
|
67
|
+
if (!first) return;
|
|
68
|
+
const top = first.offsetTop;
|
|
69
|
+
const tags = items.filter((item) => !item.hasAttribute("data-count"));
|
|
70
|
+
const count = items.find((item) => item.hasAttribute("data-count"));
|
|
71
|
+
const onLine = tags.filter((item) => item.offsetTop === top).length;
|
|
72
|
+
const room = count && count.offsetTop !== top ? onLine - 1 : onLine;
|
|
73
|
+
const next = Math.max(1, Math.min(room, tags.length));
|
|
74
|
+
if (next < tags.length) setFitted(next);
|
|
75
|
+
}, [list, active, fitted, total]);
|
|
76
|
+
useLayoutEffect(() => {
|
|
77
|
+
const box = list.current;
|
|
78
|
+
if (!active || !box || typeof ResizeObserver !== "function") return void 0;
|
|
79
|
+
const observer = new ResizeObserver(([entry]) => {
|
|
80
|
+
const now = entry?.contentRect.width ?? 0;
|
|
81
|
+
if (width.current !== null && width.current !== now) setFitted(total);
|
|
82
|
+
width.current = now;
|
|
83
|
+
});
|
|
84
|
+
observer.observe(box);
|
|
85
|
+
return () => observer.disconnect();
|
|
86
|
+
}, [list, active, total]);
|
|
87
|
+
return active ? fitted : total;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
export { TagGroup };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { presenceHueClass } from './chunk-I6POAB4V.js';
|
|
2
|
-
import { presenceLabels, presenceOrder } from './chunk-
|
|
2
|
+
import { presenceLabels, presenceOrder } from './chunk-Z7JYG5TF.js';
|
|
3
3
|
import { AVATAR_SIZES, Avatar } from './chunk-5OM447RW.js';
|
|
4
4
|
import { VisuallyHidden } from './chunk-BZFWDIV6.js';
|
|
5
5
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { PageHeader } from './chunk-HOXGBLEY.js';
|
|
2
2
|
import { Toolbar } from './chunk-PGRPNDWM.js';
|
|
3
|
-
import { DataTable } from './chunk-
|
|
3
|
+
import { DataTable } from './chunk-SVW3VG72.js';
|
|
4
4
|
import { DateTimePicker } from './chunk-WG5WUFBX.js';
|
|
5
5
|
import { useListbox, useOptionKeys } from './chunk-F73MC7EZ.js';
|
|
6
6
|
import { Kbd } from './chunk-SMBKXWML.js';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { HuePicker } from './chunk-
|
|
1
|
+
import { HuePicker } from './chunk-SGIQCI6Y.js';
|
|
2
2
|
import { Popover } from './chunk-BWRGFKJP.js';
|
|
3
3
|
import { NODE_HUE_NAMES } from './chunk-AYKXMIOR.js';
|
|
4
|
-
import { CharacterPicker } from './chunk-
|
|
4
|
+
import { CharacterPicker } from './chunk-HVIX5ECM.js';
|
|
5
5
|
import { Avatar } from './chunk-5OM447RW.js';
|
|
6
6
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
7
7
|
import './AvatarPicker-PREY36MG.css';
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { SlideStage } from './chunk-KNLJL3VP.js';
|
|
2
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
3
|
+
import './SlideGrid-RT6QEQEE.css';
|
|
4
|
+
import { EyeOffGlyph } from '@crewlethq/icons/glyphs';
|
|
5
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
|
+
|
|
7
|
+
var LABELS = {
|
|
8
|
+
slide: (position, title) => `Slide ${position}, ${title}`,
|
|
9
|
+
hidden: "Hidden when presenting",
|
|
10
|
+
untitled: "Untitled"
|
|
11
|
+
};
|
|
12
|
+
function SlideGrid({ sections, renderSlide, onOpen, current, className, labels }) {
|
|
13
|
+
const text = { ...LABELS, ...labels };
|
|
14
|
+
let n = 0;
|
|
15
|
+
return /* @__PURE__ */ jsx("div", { className: cx("crewlet-slide-grid", className), children: sections.map((section, s) => /* @__PURE__ */ jsxs("section", { className: "crewlet-slide-grid__section", children: [
|
|
16
|
+
section.title ? /* @__PURE__ */ jsx("h3", { className: "crewlet-slide-grid__heading", children: section.title }) : null,
|
|
17
|
+
/* @__PURE__ */ jsx("ol", { className: "crewlet-slide-grid__list", children: section.slides.map((slide) => {
|
|
18
|
+
n += 1;
|
|
19
|
+
const name = text.slide(n, slide.title || text.untitled);
|
|
20
|
+
return /* @__PURE__ */ jsx("li", { className: "crewlet-slide-grid__item", children: /* @__PURE__ */ jsxs(
|
|
21
|
+
"button",
|
|
22
|
+
{
|
|
23
|
+
type: "button",
|
|
24
|
+
className: "crewlet-slide-grid__card",
|
|
25
|
+
"aria-label": slide.hidden ? `${name}, ${text.hidden}` : name,
|
|
26
|
+
"aria-current": slide.id === current ? "true" : void 0,
|
|
27
|
+
"data-hidden": slide.hidden ? "true" : void 0,
|
|
28
|
+
onClick: () => onOpen(slide.id),
|
|
29
|
+
children: [
|
|
30
|
+
/* @__PURE__ */ jsx(SlideStage, { label: name, children: renderSlide(slide.id) }),
|
|
31
|
+
/* @__PURE__ */ jsxs("span", { className: "crewlet-slide-grid__caption", children: [
|
|
32
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-slide-grid__number", children: n }),
|
|
33
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-slide-grid__title", children: slide.title || text.untitled }),
|
|
34
|
+
slide.hidden ? /* @__PURE__ */ jsx(EyeOffGlyph, { size: "sm" }) : null
|
|
35
|
+
] })
|
|
36
|
+
]
|
|
37
|
+
}
|
|
38
|
+
) }, slide.id);
|
|
39
|
+
}) })
|
|
40
|
+
] }, `${s}:${section.title}`)) });
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export { SlideGrid };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { tabId } from './chunk-
|
|
2
|
-
import { useRoving, tabStop } from './chunk-
|
|
1
|
+
import { tabId } from './chunk-HJEVSQN6.js';
|
|
2
|
+
import { useRoving, tabStop } from './chunk-RKKO7QHH.js';
|
|
3
3
|
import { Count } from './chunk-BHHIIK3M.js';
|
|
4
4
|
import { VisuallyHidden } from './chunk-BZFWDIV6.js';
|
|
5
5
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
6
|
-
import { useId } from 'react';
|
|
6
|
+
import { useState, useId } from 'react';
|
|
7
7
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
8
8
|
|
|
9
9
|
var ACTIVATE_HINT = "Press Enter or Space to choose the option you land on.";
|
|
@@ -25,16 +25,27 @@ function SegmentedControl({
|
|
|
25
25
|
const radio = semantics === "radio";
|
|
26
26
|
const manual = radio && activate === "manual";
|
|
27
27
|
const cards = options.some((option) => option.description !== void 0);
|
|
28
|
-
const { buttons, onKeyDown, onFocusAt, focused } = useRoving(
|
|
28
|
+
const { buttons, onKeyDown, onFocusAt, reset, focused } = useRoving(
|
|
29
29
|
options.length,
|
|
30
|
-
radio && !manual ? (index) =>
|
|
30
|
+
radio && !manual ? (index) => {
|
|
31
|
+
const option = options[index];
|
|
32
|
+
if (!option.disabled) onValueChange(option.value);
|
|
33
|
+
} : null,
|
|
31
34
|
{ followFocus: manual }
|
|
32
35
|
);
|
|
36
|
+
const [seen, setSeen] = useState(value);
|
|
37
|
+
if (seen !== value) {
|
|
38
|
+
setSeen(value);
|
|
39
|
+
reset();
|
|
40
|
+
}
|
|
33
41
|
const chosenIndex = Math.max(
|
|
34
42
|
0,
|
|
35
43
|
options.findIndex((option) => option.value === value)
|
|
36
44
|
);
|
|
37
|
-
const stop = tabStop(
|
|
45
|
+
const stop = tabStop(
|
|
46
|
+
options.map((option) => ({ disabled: option.disabled === true && option.describedBy === void 0 })),
|
|
47
|
+
focused ?? chosenIndex
|
|
48
|
+
);
|
|
38
49
|
const hintId = useId();
|
|
39
50
|
const hint = manual ? activateHint === void 0 ? ACTIVATE_HINT : activateHint : null;
|
|
40
51
|
return /* @__PURE__ */ jsxs(
|
|
@@ -66,6 +77,7 @@ function SegmentedControl({
|
|
|
66
77
|
options.map((option, index) => {
|
|
67
78
|
const chosen = option.value === value;
|
|
68
79
|
const named = option.srLabel ?? (option.label ? void 0 : option.title);
|
|
80
|
+
const explained = option.disabled === true && option.describedBy !== void 0;
|
|
69
81
|
return /* @__PURE__ */ jsxs(
|
|
70
82
|
"button",
|
|
71
83
|
{
|
|
@@ -81,14 +93,18 @@ function SegmentedControl({
|
|
|
81
93
|
"aria-label": named,
|
|
82
94
|
tabIndex: index === stop ? 0 : -1,
|
|
83
95
|
title: option.title,
|
|
84
|
-
disabled: option.disabled,
|
|
96
|
+
disabled: option.disabled && !explained,
|
|
97
|
+
"aria-disabled": explained || void 0,
|
|
98
|
+
"aria-describedby": option.describedBy,
|
|
85
99
|
className: cx(
|
|
86
100
|
"crewlet-tabs__tab",
|
|
87
101
|
"crewlet-segmented__option",
|
|
88
102
|
chosen && "is-active",
|
|
89
103
|
option.disabled && "is-disabled"
|
|
90
104
|
),
|
|
91
|
-
onClick: () =>
|
|
105
|
+
onClick: () => {
|
|
106
|
+
if (!option.disabled) onValueChange(option.value);
|
|
107
|
+
},
|
|
92
108
|
onFocus: () => onFocusAt(index),
|
|
93
109
|
onKeyDown: (event) => onKeyDown(event, radio),
|
|
94
110
|
children: [
|
|
@@ -97,7 +113,7 @@ function SegmentedControl({
|
|
|
97
113
|
/* @__PURE__ */ jsx("span", { className: "crewlet-tabs__label", children: option.label }),
|
|
98
114
|
option.description ? /* @__PURE__ */ jsx("span", { className: "crewlet-segmented__description", children: option.description }) : null
|
|
99
115
|
] }) : null,
|
|
100
|
-
option.count != null ? /* @__PURE__ */ jsx(Count, { value: option.count }) : null
|
|
116
|
+
option.count != null ? /* @__PURE__ */ jsx(Count, { value: option.capped ? `${option.count.toLocaleString()}+` : option.count }) : null
|
|
101
117
|
]
|
|
102
118
|
},
|
|
103
119
|
option.value
|
|
@@ -57,10 +57,12 @@ function useRoving(count, select, { followFocus = false, columns } = {}) {
|
|
|
57
57
|
onFocusAt(next);
|
|
58
58
|
select?.(next);
|
|
59
59
|
};
|
|
60
|
+
const reset = () => setLanded(null);
|
|
60
61
|
return {
|
|
61
62
|
buttons,
|
|
62
63
|
onKeyDown,
|
|
63
64
|
onFocusAt,
|
|
65
|
+
reset,
|
|
64
66
|
/*
|
|
65
67
|
* Where the stop belongs, or null for "on the caller's selection, as
|
|
66
68
|
* ever". Bounded by the CURRENT count, because a row whose options
|