@crewlethq/ui 0.38.0 → 0.40.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +79 -3
- package/dist/AgentHandoffPanel/index.js +3 -3
- package/dist/AppShell/AppShell.d.ts +13 -2
- package/dist/AppShell/index.js +1 -1
- package/dist/{AppShell-NDU4XMGF.css → AppShell-NPSWZ3XW.css} +45 -4
- package/dist/ArtifactBar/index.js +6 -5
- package/dist/{ArtifactBar-FWPBBKQ5.css → ArtifactBar-6PGWGKN2.css} +13 -1
- package/dist/ArtifactCard/index.js +2 -2
- package/dist/AuthLayout/index.js +2 -2
- package/dist/AvatarPicker/index.js +10 -6
- package/dist/Card/Card.d.ts +14 -2
- package/dist/Card/index.js +1 -1
- package/dist/{Card-G2ZGT5Z6.css → Card-JR2UPQH7.css} +20 -0
- package/dist/CatalogTile/CatalogTile.d.ts +47 -0
- package/dist/CatalogTile/index.d.ts +3 -0
- package/dist/CatalogTile/index.js +3 -0
- package/dist/CatalogTile-XL4XLFUH.css +135 -0
- package/dist/CharacterPicker/index.js +2 -2
- package/dist/Charts/Histogram.d.ts +71 -0
- package/dist/Charts/index.d.ts +2 -0
- package/dist/Charts/index.js +1 -1
- package/dist/{Charts-MBJG72BS.css → Charts-TZ744HT6.css} +118 -0
- package/dist/CodeBlock/index.js +1 -1
- package/dist/{CodeBlock-GYNJ2HI6.css → CodeBlock-N5ETJF24.css} +13 -0
- package/dist/CommandPalette/index.js +3 -3
- package/dist/CommentThread/index.js +3 -3
- package/dist/Composer/index.js +2 -2
- package/dist/DataGrid/DataGrid.d.ts +267 -0
- package/dist/DataGrid/index.d.ts +3 -0
- package/dist/DataGrid/index.js +7 -0
- package/dist/DataGrid-AQKPJD7W.css +482 -0
- package/dist/DataTable/index.js +2 -2
- package/dist/DataView/index.js +4 -4
- package/dist/DatasetSource/DatasetSource.d.ts +7 -1
- package/dist/DatasetSource/index.js +1 -1
- package/dist/HuePicker/index.js +11 -4
- package/dist/LayersList/index.js +2 -2
- package/dist/LinkInterstitial/index.js +2 -2
- package/dist/List/List.d.ts +8 -0
- package/dist/List/index.js +1 -1
- package/dist/{List-MYJIV6MP.css → List-YHLIZFK4.css} +46 -0
- package/dist/ListInput/ListInput.d.ts +9 -1
- package/dist/ListInput/index.js +2 -2
- package/dist/LockedLabel/LockedLabel.d.ts +34 -0
- package/dist/LockedLabel/index.d.ts +3 -0
- package/dist/LockedLabel/index.js +3 -0
- package/dist/LockedLabel-VQEGEB7G.css +16 -0
- package/dist/MarkdownEditor/index.js +8 -5
- package/dist/MergeConflicts/index.js +11 -5
- package/dist/Modal/index.js +1 -1
- package/dist/{Modal-7MWRCWAI.css → Modal-TOEWHDCQ.css} +5 -0
- package/dist/ObjectHeader/index.js +1 -1
- package/dist/{ObjectHeader-D7GU7QNI.css → ObjectHeader-ZOS22FKX.css} +7 -8
- package/dist/PageNote/PageNote.d.ts +14 -0
- package/dist/PageNote/index.d.ts +3 -0
- package/dist/PageNote/index.js +2 -0
- package/dist/PageNote-RHLXH3ML.css +12 -0
- package/dist/PropertyList/PropertyList.d.ts +88 -0
- package/dist/PropertyList/index.d.ts +3 -0
- package/dist/PropertyList/index.js +7 -0
- package/dist/PropertyList-SCYM66LL.css +96 -0
- package/dist/RelatedRow/RelatedRow.d.ts +27 -0
- package/dist/RelatedRow/index.d.ts +3 -0
- package/dist/RelatedRow/index.js +9 -0
- package/dist/RelatedRow-2FVS6QQA.css +6 -0
- package/dist/RichEditor/index.js +1 -1
- package/dist/SectionFrame/SectionFrame.d.ts +76 -0
- package/dist/SectionFrame/index.d.ts +3 -0
- package/dist/SectionFrame/index.js +7 -0
- package/dist/SectionFrame-M62UUVFQ.css +164 -0
- package/dist/SegmentedControl/index.js +11 -4
- package/dist/SettingsTable/SettingsTable.d.ts +66 -0
- package/dist/SettingsTable/index.d.ts +3 -0
- package/dist/SettingsTable/index.js +3 -0
- package/dist/SettingsTable-6DUFAFXG.css +160 -0
- package/dist/ShareDialog/index.js +2 -2
- package/dist/SheetColumnEditor/index.js +7 -6
- package/dist/SheetGrid/index.js +3 -3
- package/dist/SidebarNav/SidebarNav.d.ts +35 -2
- package/dist/SidebarNav/index.js +2 -1
- package/dist/{SidebarNav-7SGUZYKK.css → SidebarNav-YI74SPDC.css} +10 -0
- package/dist/StatCard/index.js +1 -1
- package/dist/{StatCard-4T7TMWMN.css → StatCard-HAA3F5GX.css} +8 -3
- package/dist/StatGroup/index.js +1 -1
- package/dist/{StatGroup-DOFHX5QJ.css → StatGroup-ZMW7VQWP.css} +27 -0
- package/dist/Switcher/index.js +2 -2
- package/dist/Tabs/Tabs.d.ts +55 -1
- package/dist/Tabs/fold.d.ts +54 -0
- package/dist/Tabs/index.d.ts +1 -1
- package/dist/Tabs/index.js +9 -2
- package/dist/Tabs/roving.d.ts +3 -3
- package/dist/{Tabs-WIF7457H.css → Tabs-S7F4RWAN.css} +77 -0
- package/dist/TagsInput/index.js +1 -1
- package/dist/ThemeGallery/index.js +2 -2
- package/dist/ThemeSwitcher/index.js +12 -5
- package/dist/TileGrid/TileGrid.d.ts +33 -0
- package/dist/TileGrid/index.d.ts +3 -0
- package/dist/TileGrid/index.js +2 -0
- package/dist/TileGrid-I6LNYD2H.css +52 -0
- package/dist/VersionCompare/index.js +12 -5
- package/dist/{chunk-B5J23C73.js → chunk-2PEXZ7L4.js} +1 -1
- package/dist/{chunk-S27UBCVX.js → chunk-2VOHUGUA.js} +2 -2
- package/dist/{chunk-XBURIXHO.js → chunk-3TXY3PJZ.js} +1 -1
- package/dist/{chunk-2QZ2VPHR.js → chunk-4OK4DX3V.js} +2 -2
- package/dist/chunk-4RKTZSEW.js +64 -0
- package/dist/{chunk-ECGGQX2H.js → chunk-A44YHLCQ.js} +2 -2
- package/dist/{chunk-F4LPQA4E.js → chunk-BA32AVKS.js} +1 -1
- package/dist/chunk-CV4NES3P.js +9 -0
- package/dist/{chunk-PPHTIKZO.js → chunk-E4BOVKNJ.js} +1 -1
- package/dist/{chunk-W7PAIVAP.js → chunk-E7QLG3PG.js} +30 -9
- package/dist/{chunk-RKKO7QHH.js → chunk-EGMQURBR.js} +5 -4
- package/dist/{chunk-GMW4ZHST.js → chunk-EX22Q5SH.js} +2 -2
- package/dist/{chunk-A23KDROH.js → chunk-FXBGEANQ.js} +1 -1
- package/dist/{chunk-4L2BWSHR.js → chunk-GFYQKMQZ.js} +2 -2
- package/dist/{chunk-HG5VF3TZ.js → chunk-HMVQQEHW.js} +91 -2
- package/dist/{chunk-IPWU6ERC.js → chunk-HQJ24WPM.js} +4 -2
- package/dist/{chunk-SVGARBDY.js → chunk-IAGYPTEJ.js} +2 -2
- package/dist/{chunk-ZK3VYY7L.js → chunk-INHXF2CL.js} +24 -11
- package/dist/chunk-INVSUFJK.js +71 -0
- package/dist/{chunk-6NNY5WBF.js → chunk-JKAGN4V4.js} +1 -1
- package/dist/{chunk-4LRAJXHL.js → chunk-JSWOXRRE.js} +1 -1
- package/dist/{chunk-DYB66CNM.js → chunk-KKNHMXTE.js} +6 -3
- package/dist/{chunk-UWRBD2YO.js → chunk-KNHUBHFX.js} +1 -1
- package/dist/{chunk-ZMDYQ2HH.js → chunk-KWWP3D7M.js} +1 -1
- package/dist/{chunk-46RL3E54.js → chunk-M6NQ4XGK.js} +1 -1
- package/dist/{chunk-PT6WKXKW.js → chunk-MMPKN7WV.js} +1 -1
- package/dist/{chunk-NRBAXRWE.js → chunk-N3TFYBN3.js} +1 -1
- package/dist/chunk-NNTO3TNC.js +9 -0
- package/dist/{chunk-DS2C73RJ.js → chunk-NZWX27J7.js} +2 -2
- package/dist/{chunk-VGE3G3T4.js → chunk-ODOJJGXH.js} +1 -1
- package/dist/chunk-OHGH7O6T.js +19 -0
- package/dist/{chunk-4ISUIS6F.js → chunk-OOC7Q67K.js} +1 -1
- package/dist/{chunk-BT5H2THK.js → chunk-OUD75UB2.js} +1 -1
- package/dist/chunk-PCT47E7O.js +48 -0
- package/dist/{chunk-X3UYTAOG.js → chunk-PFZOFAQ6.js} +1 -1
- package/dist/{chunk-YQG4PZGC.js → chunk-QRKT4XTT.js} +2 -2
- package/dist/{chunk-BJI3RFXG.js → chunk-S4DREXGM.js} +1 -1
- package/dist/{chunk-GDDE4UM7.js → chunk-SEC2GR2V.js} +1 -1
- package/dist/{chunk-YEVG2X5R.js → chunk-SNQRGH4A.js} +1 -1
- package/dist/chunk-T6MXORP5.js +116 -0
- package/dist/{chunk-OTCXRJ7D.js → chunk-U2XAJONO.js} +1 -1
- package/dist/{chunk-3ZUINC7C.js → chunk-WYYCPV46.js} +6 -1
- package/dist/chunk-X4IXXLWM.js +306 -0
- package/dist/{chunk-PAQXOP2M.js → chunk-XGBUUQDU.js} +2 -2
- package/dist/chunk-XIDD7PJO.js +416 -0
- package/dist/{chunk-XO7PUL4F.js → chunk-YPTTSJPM.js} +1 -1
- package/dist/chunk-ZUTUI27P.js +21 -0
- package/dist/generated/index.d.ts +9 -0
- package/dist/generated/index.js +83 -74
- package/dist/index.js +83 -74
- package/dist/styles.css +1627 -104
- package/package.json +3 -3
- package/dist/chunk-7SDUKCNW.js +0 -141
- package/dist/{Editor-QV4JP242.js → Editor-IRDQ3JDZ.js} +1 -1
- package/dist/{chunk-JZPK4IXR.js → chunk-3PR65I3H.js} +2 -2
- package/dist/{chunk-ETVEGR2Y.js → chunk-ISA2O2BK.js} +1 -1
- /package/dist/{chunk-4QQ3MND5.js → chunk-S3QTFUJX.js} +0 -0
|
@@ -0,0 +1,416 @@
|
|
|
1
|
+
import { EmptyState } from './chunk-RA2ULG6H.js';
|
|
2
|
+
import { useMediaMatch } from './chunk-RTPQDNW3.js';
|
|
3
|
+
import { Button } from './chunk-OG6CL3EB.js';
|
|
4
|
+
import { VisuallyHidden } from './chunk-BZFWDIV6.js';
|
|
5
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
6
|
+
import './DataGrid-AQKPJD7W.css';
|
|
7
|
+
import { useId, useRef, useState, useMemo, useCallback, useLayoutEffect, useImperativeHandle } from 'react';
|
|
8
|
+
import { breakpoint } from '@crewlethq/tokens';
|
|
9
|
+
import { ChevronDownGlyph, ChevronUpGlyph } from '@crewlethq/icons/glyphs';
|
|
10
|
+
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
11
|
+
|
|
12
|
+
function columnChoicesOf(columns) {
|
|
13
|
+
return columns.map((column) => ({
|
|
14
|
+
key: column.key,
|
|
15
|
+
label: headerWord(column) || column.label || column.key,
|
|
16
|
+
optional: column.optional
|
|
17
|
+
}));
|
|
18
|
+
}
|
|
19
|
+
function ChooserList({ label, items, onToggle }) {
|
|
20
|
+
const headingId = useId();
|
|
21
|
+
if (items.length === 0) return null;
|
|
22
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
23
|
+
/* @__PURE__ */ jsx("div", { className: "crewlet-column-chooser__label", id: headingId, children: label }),
|
|
24
|
+
/* @__PURE__ */ jsx("div", { className: "crewlet-column-chooser__choices", role: "group", "aria-labelledby": headingId, children: items.map((item) => /* @__PURE__ */ jsxs("label", { className: "crewlet-column-chooser__choice", children: [
|
|
25
|
+
/* @__PURE__ */ jsx("input", { type: "checkbox", checked: item.checked, onChange: () => onToggle(item.key) }),
|
|
26
|
+
/* @__PURE__ */ jsx("span", { children: item.label })
|
|
27
|
+
] }, item.key)) })
|
|
28
|
+
] });
|
|
29
|
+
}
|
|
30
|
+
function ColumnChooser({ choices, value, onChange, label = "Columns" }) {
|
|
31
|
+
const chosen = new Set(value ? value.split(",").filter(Boolean) : []);
|
|
32
|
+
const isOn = (choice) => chosen.size === 0 ? !choice.optional : chosen.has(choice.key);
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
ChooserList,
|
|
35
|
+
{
|
|
36
|
+
label,
|
|
37
|
+
items: choices.map((choice) => ({ key: choice.key, label: choice.label, checked: isOn(choice) })),
|
|
38
|
+
onToggle: (key) => {
|
|
39
|
+
const next = new Set(choices.filter(isOn).map((c) => c.key));
|
|
40
|
+
if (next.has(key)) next.delete(key);
|
|
41
|
+
else next.add(key);
|
|
42
|
+
onChange(
|
|
43
|
+
choices.filter((c) => next.has(c.key)).map((c) => c.key).join(",")
|
|
44
|
+
);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
var LABELS = {
|
|
50
|
+
hiddenToFit: (names) => `Hidden to fit: ${names}`,
|
|
51
|
+
loadMore: "Load more",
|
|
52
|
+
showEveryColumn: "Show every column",
|
|
53
|
+
and: "and"
|
|
54
|
+
};
|
|
55
|
+
function parseGridSort(raw) {
|
|
56
|
+
if (!raw) return null;
|
|
57
|
+
return raw.startsWith("-") ? { key: raw.slice(1), desc: true } : { key: raw, desc: false };
|
|
58
|
+
}
|
|
59
|
+
function headerWord(column) {
|
|
60
|
+
return typeof column.header === "string" ? column.header : "";
|
|
61
|
+
}
|
|
62
|
+
function bandRows(band) {
|
|
63
|
+
return band.bands ? band.bands.flatMap(bandRows) : band.rows;
|
|
64
|
+
}
|
|
65
|
+
function compare(a, b) {
|
|
66
|
+
if (typeof a === "number" && typeof b === "number") {
|
|
67
|
+
if (Number.isNaN(a)) return Number.isNaN(b) ? 0 : 1;
|
|
68
|
+
if (Number.isNaN(b)) return -1;
|
|
69
|
+
return a < b ? -1 : a > b ? 1 : 0;
|
|
70
|
+
}
|
|
71
|
+
return String(a).localeCompare(String(b), void 0, { numeric: true, sensitivity: "base" });
|
|
72
|
+
}
|
|
73
|
+
var SHRINK_CAP = "20%";
|
|
74
|
+
var SHRINK_SHARE = 0.2;
|
|
75
|
+
var SQUEEZE_SAMPLE_ROWS = 12;
|
|
76
|
+
var NO_DROPS = [];
|
|
77
|
+
var NO_FIT = { set: "", width: 0, dropped: NO_DROPS };
|
|
78
|
+
function fitGridColumns({
|
|
79
|
+
fit,
|
|
80
|
+
width,
|
|
81
|
+
overflows,
|
|
82
|
+
visible
|
|
83
|
+
}) {
|
|
84
|
+
if (fit.dropped.length > 0 && width > fit.width) {
|
|
85
|
+
return { set: fit.set, width, dropped: NO_DROPS };
|
|
86
|
+
}
|
|
87
|
+
if (overflows) {
|
|
88
|
+
let next;
|
|
89
|
+
for (const c of visible) {
|
|
90
|
+
if (c.drop === void 0) continue;
|
|
91
|
+
if (!next || c.drop < next.drop) next = c;
|
|
92
|
+
}
|
|
93
|
+
if (next) return { set: fit.set, width, dropped: [...fit.dropped, next.key] };
|
|
94
|
+
}
|
|
95
|
+
if (width !== fit.width && (fit.dropped.length > 0 || fit.width === 0)) {
|
|
96
|
+
return { ...fit, width };
|
|
97
|
+
}
|
|
98
|
+
return null;
|
|
99
|
+
}
|
|
100
|
+
function overflowing(wrap) {
|
|
101
|
+
const last = wrap.querySelector(":scope > .crewlet-data-grid__head")?.lastElementChild;
|
|
102
|
+
if (!last) return false;
|
|
103
|
+
const inner = wrap.getBoundingClientRect().left + wrap.clientLeft + wrap.clientWidth;
|
|
104
|
+
return last.getBoundingClientRect().right > inner + 0.5;
|
|
105
|
+
}
|
|
106
|
+
function squeezed(wrap, visible) {
|
|
107
|
+
const heads = wrap.querySelector(":scope > .crewlet-data-grid__head")?.children;
|
|
108
|
+
if (!heads) return false;
|
|
109
|
+
const cap = wrap.clientWidth * SHRINK_SHARE - 1;
|
|
110
|
+
const rows = [...wrap.querySelectorAll(":scope > .crewlet-data-grid__body .crewlet-data-grid__row")].slice(
|
|
111
|
+
0,
|
|
112
|
+
SQUEEZE_SAMPLE_ROWS
|
|
113
|
+
);
|
|
114
|
+
for (let i = 0; i < visible.length; i++) {
|
|
115
|
+
const column = visible[i];
|
|
116
|
+
if (!column.shrink || column.width) continue;
|
|
117
|
+
const head = heads[i];
|
|
118
|
+
if (!head || head.getBoundingClientRect().width >= cap) continue;
|
|
119
|
+
for (const row of rows) {
|
|
120
|
+
const cell = row.querySelectorAll(":scope > .crewlet-data-grid__cell")[i];
|
|
121
|
+
if (cell && cutShort(cell)) return true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
function cutShort(el) {
|
|
127
|
+
for (const node of [el, ...el.querySelectorAll("*")]) {
|
|
128
|
+
const box = node;
|
|
129
|
+
if (box.clientWidth > 1 && box.scrollWidth > box.clientWidth + 1) return true;
|
|
130
|
+
}
|
|
131
|
+
return false;
|
|
132
|
+
}
|
|
133
|
+
function droppedNames(columns, dropped, and) {
|
|
134
|
+
const names = dropped.map((key) => {
|
|
135
|
+
const c = columns.find((col) => col.key === key);
|
|
136
|
+
return c && (headerWord(c) || c.label) || key;
|
|
137
|
+
});
|
|
138
|
+
return names.length <= 1 ? names[0] ?? "" : `${names.slice(0, -1).join(", ")} ${and} ${names[names.length - 1]}`;
|
|
139
|
+
}
|
|
140
|
+
function DataGrid({
|
|
141
|
+
rows,
|
|
142
|
+
bands,
|
|
143
|
+
columns,
|
|
144
|
+
rowKey,
|
|
145
|
+
onRowActivate,
|
|
146
|
+
rowHref,
|
|
147
|
+
isSelected,
|
|
148
|
+
isFailed,
|
|
149
|
+
sort: sortRaw = "",
|
|
150
|
+
onSortChange,
|
|
151
|
+
serverSorted = false,
|
|
152
|
+
cols: colsRaw = "",
|
|
153
|
+
onColsChange,
|
|
154
|
+
empty,
|
|
155
|
+
footer,
|
|
156
|
+
onLoadMore,
|
|
157
|
+
loadedNote,
|
|
158
|
+
phoneRows = "labelled",
|
|
159
|
+
flush = false,
|
|
160
|
+
handleRef,
|
|
161
|
+
onPointerDown,
|
|
162
|
+
labels,
|
|
163
|
+
"aria-label": ariaLabel,
|
|
164
|
+
"aria-labelledby": ariaLabelledby,
|
|
165
|
+
className
|
|
166
|
+
}) {
|
|
167
|
+
const text = { ...LABELS, ...labels };
|
|
168
|
+
const sort = parseGridSort(sortRaw);
|
|
169
|
+
const body = useRef(null);
|
|
170
|
+
const [cursor, setCursor] = useState(-1);
|
|
171
|
+
const gridId = useId();
|
|
172
|
+
const shownColumns = useMemo(() => {
|
|
173
|
+
const asked = colsRaw.split(",").map((c) => c.trim()).filter(Boolean);
|
|
174
|
+
if (asked.length === 0) return columns.filter((c) => !c.optional);
|
|
175
|
+
const byKey = new Map(columns.map((c) => [c.key, c]));
|
|
176
|
+
const picked = asked.map((key) => byKey.get(key)).filter((c) => !!c);
|
|
177
|
+
return picked.length > 0 ? picked : columns.filter((c) => !c.optional);
|
|
178
|
+
}, [columns, colsRaw]);
|
|
179
|
+
const [wrap, setWrap] = useState(null);
|
|
180
|
+
const phone = useMediaMatch(`(width < ${breakpoint.phone})`);
|
|
181
|
+
const shownKeys = shownColumns.map((c) => c.key).join(",");
|
|
182
|
+
const [fit, setFit] = useState(NO_FIT);
|
|
183
|
+
const dropped = !phone && fit.set === shownKeys ? fit.dropped : NO_DROPS;
|
|
184
|
+
const visibleColumns = useMemo(
|
|
185
|
+
() => dropped.length === 0 ? shownColumns : shownColumns.filter((c) => !dropped.includes(c.key)),
|
|
186
|
+
[shownColumns, dropped]
|
|
187
|
+
);
|
|
188
|
+
const sortRows = useCallback(
|
|
189
|
+
(input) => {
|
|
190
|
+
if (!sort || serverSorted) return input;
|
|
191
|
+
const column = columns.find((c) => c.key === sort.key);
|
|
192
|
+
if (!column?.sortValue) return input;
|
|
193
|
+
const get = column.sortValue;
|
|
194
|
+
return [...input].sort((a, b) => {
|
|
195
|
+
const av = get(a);
|
|
196
|
+
const bv = get(b);
|
|
197
|
+
if (av == null && bv == null) return 0;
|
|
198
|
+
if (av == null) return 1;
|
|
199
|
+
if (bv == null) return -1;
|
|
200
|
+
const cmp = compare(av, bv);
|
|
201
|
+
return sort.desc ? -cmp : cmp;
|
|
202
|
+
});
|
|
203
|
+
},
|
|
204
|
+
[columns, sort, serverSorted]
|
|
205
|
+
);
|
|
206
|
+
const flat = useMemo(() => {
|
|
207
|
+
const walk = (band) => band.bands ? band.bands.flatMap(walk) : sortRows(band.rows);
|
|
208
|
+
if (bands) return bands.flatMap(walk);
|
|
209
|
+
return sortRows(rows ?? []);
|
|
210
|
+
}, [bands, rows, sortRows]);
|
|
211
|
+
const [boxWidth, setBoxWidth] = useState(0);
|
|
212
|
+
useLayoutEffect(() => {
|
|
213
|
+
if (!wrap || typeof ResizeObserver !== "function") return;
|
|
214
|
+
const watch = new ResizeObserver(() => setBoxWidth(wrap.clientWidth));
|
|
215
|
+
watch.observe(wrap);
|
|
216
|
+
return () => watch.disconnect();
|
|
217
|
+
}, [wrap]);
|
|
218
|
+
useLayoutEffect(() => {
|
|
219
|
+
const el = wrap;
|
|
220
|
+
if (!el || phone) return;
|
|
221
|
+
const next = fitGridColumns({
|
|
222
|
+
fit: fit.set === shownKeys ? fit : { ...NO_FIT, set: shownKeys },
|
|
223
|
+
width: el.clientWidth,
|
|
224
|
+
overflows: overflowing(el) || squeezed(el, visibleColumns),
|
|
225
|
+
visible: visibleColumns
|
|
226
|
+
});
|
|
227
|
+
if (next !== null) setFit(next);
|
|
228
|
+
}, [wrap, phone, fit, shownKeys, visibleColumns, flat, boxWidth]);
|
|
229
|
+
useImperativeHandle(
|
|
230
|
+
handleRef,
|
|
231
|
+
() => ({
|
|
232
|
+
step: (by) => setCursor((at) => {
|
|
233
|
+
const next = Math.max(0, Math.min(flat.length - 1, at + by));
|
|
234
|
+
body.current?.querySelector(`[data-row-index="${next}"]`)?.scrollIntoView({ block: "nearest" });
|
|
235
|
+
return next;
|
|
236
|
+
}),
|
|
237
|
+
activate: (event) => {
|
|
238
|
+
const row = flat[cursor];
|
|
239
|
+
if (row === void 0 || !onRowActivate) return false;
|
|
240
|
+
onRowActivate(row, event);
|
|
241
|
+
return true;
|
|
242
|
+
},
|
|
243
|
+
rowCount: () => flat.length
|
|
244
|
+
}),
|
|
245
|
+
[flat, cursor, onRowActivate]
|
|
246
|
+
);
|
|
247
|
+
function headerClick(column) {
|
|
248
|
+
if (!column.sortValue || !onSortChange) return;
|
|
249
|
+
if (sort?.key === column.key && !sort.desc) onSortChange(`-${column.key}`);
|
|
250
|
+
else if (sort?.key === column.key && sort.desc) onSortChange("");
|
|
251
|
+
else onSortChange(column.key);
|
|
252
|
+
}
|
|
253
|
+
const template = visibleColumns.map((c) => c.width ?? (c.shrink ? `fit-content(${SHRINK_CAP})` : `minmax(${c.floor ?? 0}, 1fr)`)).join(" ");
|
|
254
|
+
if (flat.length === 0 && !bands?.length && empty) {
|
|
255
|
+
return /* @__PURE__ */ jsx("div", { className: cx("crewlet-data-grid", className), "data-flush": flush || void 0, children: /* @__PURE__ */ jsx(
|
|
256
|
+
EmptyState,
|
|
257
|
+
{
|
|
258
|
+
size: "compact",
|
|
259
|
+
icon: empty.icon,
|
|
260
|
+
title: empty.title,
|
|
261
|
+
description: empty.hint,
|
|
262
|
+
action: empty.action
|
|
263
|
+
}
|
|
264
|
+
) });
|
|
265
|
+
}
|
|
266
|
+
let index = -1;
|
|
267
|
+
function renderRow(row) {
|
|
268
|
+
index += 1;
|
|
269
|
+
const at = index;
|
|
270
|
+
const link = rowHref?.(row);
|
|
271
|
+
const marked = Boolean(isSelected?.(row));
|
|
272
|
+
const rowId = `${gridId}-row-${at}`;
|
|
273
|
+
const overlay = link !== void 0 ? (
|
|
274
|
+
// eslint-disable-next-line jsx-a11y/anchor-has-content
|
|
275
|
+
/* @__PURE__ */ jsx(
|
|
276
|
+
"a",
|
|
277
|
+
{
|
|
278
|
+
className: "crewlet-data-grid__row-link",
|
|
279
|
+
href: link,
|
|
280
|
+
"aria-labelledby": rowId,
|
|
281
|
+
"aria-current": marked ? "true" : void 0,
|
|
282
|
+
onClick: (e) => onRowActivate?.(row, e)
|
|
283
|
+
}
|
|
284
|
+
)
|
|
285
|
+
) : onRowActivate ? /* @__PURE__ */ jsx(
|
|
286
|
+
"button",
|
|
287
|
+
{
|
|
288
|
+
type: "button",
|
|
289
|
+
className: "crewlet-data-grid__row-link",
|
|
290
|
+
"aria-labelledby": rowId,
|
|
291
|
+
"aria-current": marked ? "true" : void 0,
|
|
292
|
+
onClick: (e) => onRowActivate(row, e)
|
|
293
|
+
}
|
|
294
|
+
) : null;
|
|
295
|
+
const inner = visibleColumns.map((column, i) => /* @__PURE__ */ jsxs(
|
|
296
|
+
"span",
|
|
297
|
+
{
|
|
298
|
+
role: "cell",
|
|
299
|
+
className: cx(
|
|
300
|
+
"crewlet-data-grid__cell",
|
|
301
|
+
column.align === "right" && "crewlet-data-grid__cell--right",
|
|
302
|
+
column.shrink && "crewlet-data-grid__cell--shrink"
|
|
303
|
+
),
|
|
304
|
+
"data-lead": column.phoneLead || void 0,
|
|
305
|
+
"data-phone-omit": column.phoneOmit || void 0,
|
|
306
|
+
"data-label": column.action ? void 0 : headerWord(column) || column.label || void 0,
|
|
307
|
+
children: [
|
|
308
|
+
i === 0 ? overlay : null,
|
|
309
|
+
column.cell(row)
|
|
310
|
+
]
|
|
311
|
+
},
|
|
312
|
+
column.key
|
|
313
|
+
));
|
|
314
|
+
return /* @__PURE__ */ jsx(
|
|
315
|
+
"div",
|
|
316
|
+
{
|
|
317
|
+
id: rowId,
|
|
318
|
+
role: "row",
|
|
319
|
+
className: cx(
|
|
320
|
+
"crewlet-data-grid__row",
|
|
321
|
+
marked && "crewlet-data-grid__row--selected",
|
|
322
|
+
isFailed?.(row) && "crewlet-data-grid__row--failed",
|
|
323
|
+
cursor === at && "crewlet-data-grid__row--cursor"
|
|
324
|
+
),
|
|
325
|
+
"data-row-index": at,
|
|
326
|
+
"aria-current": overlay === null && marked ? "true" : void 0,
|
|
327
|
+
children: inner
|
|
328
|
+
},
|
|
329
|
+
rowKey(row)
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
function renderBand(band) {
|
|
333
|
+
const loaded = bandRows(band).length;
|
|
334
|
+
return (
|
|
335
|
+
// A BAND IS ROWS OF THE TABLE: its head and its foot are rows of one
|
|
336
|
+
// cell each across every column, and its own box is layout alone.
|
|
337
|
+
/* @__PURE__ */ jsxs("div", { className: "crewlet-data-grid__band", role: "none", children: [
|
|
338
|
+
/* @__PURE__ */ jsx("div", { className: "crewlet-data-grid__band-head", role: "row", children: /* @__PURE__ */ jsxs("span", { className: "crewlet-data-grid__band-cell", role: "rowheader", "aria-colspan": visibleColumns.length, children: [
|
|
339
|
+
band.mark,
|
|
340
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-data-grid__truncate", children: band.label }),
|
|
341
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-data-grid__band-count", children: band.total != null && band.total !== loaded ? `${loaded} of ${band.total}` : loaded })
|
|
342
|
+
] }) }),
|
|
343
|
+
band.bands ? band.bands.map((sub) => renderBand(sub)) : sortRows(band.rows).map(renderRow),
|
|
344
|
+
band.footer && /* @__PURE__ */ jsx("div", { className: "crewlet-data-grid__band-foot", role: "row", children: /* @__PURE__ */ jsx("span", { className: "crewlet-data-grid__band-cell", role: "cell", "aria-colspan": visibleColumns.length, children: band.footer }) })
|
|
345
|
+
] }, band.key)
|
|
346
|
+
);
|
|
347
|
+
}
|
|
348
|
+
return /* @__PURE__ */ jsxs(
|
|
349
|
+
"div",
|
|
350
|
+
{
|
|
351
|
+
ref: setWrap,
|
|
352
|
+
role: "table",
|
|
353
|
+
"aria-label": ariaLabel,
|
|
354
|
+
"aria-labelledby": ariaLabelledby,
|
|
355
|
+
className: cx("crewlet-data-grid", className),
|
|
356
|
+
"data-phone-rows": phoneRows === "compact" ? "compact" : void 0,
|
|
357
|
+
"data-flush": flush || void 0,
|
|
358
|
+
style: { gridTemplateColumns: template },
|
|
359
|
+
onPointerDown,
|
|
360
|
+
children: [
|
|
361
|
+
/* @__PURE__ */ jsx("div", { className: "crewlet-data-grid__head", role: "row", children: visibleColumns.map((column) => {
|
|
362
|
+
const sorted = sort?.key === column.key;
|
|
363
|
+
const sortable = Boolean(column.sortValue && onSortChange);
|
|
364
|
+
const headClass = cx(
|
|
365
|
+
"crewlet-data-grid__th",
|
|
366
|
+
column.align === "right" && "crewlet-data-grid__th--right",
|
|
367
|
+
column.shrink && "crewlet-data-grid__th--shrink",
|
|
368
|
+
sorted && "crewlet-data-grid__th--sorted",
|
|
369
|
+
!sortable && "crewlet-data-grid__th--plain"
|
|
370
|
+
);
|
|
371
|
+
const content = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
372
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-data-grid__truncate", children: column.header }),
|
|
373
|
+
sorted && (sort?.desc ? /* @__PURE__ */ jsx(ChevronDownGlyph, { size: "xs" }) : /* @__PURE__ */ jsx(ChevronUpGlyph, { size: "xs" }))
|
|
374
|
+
] });
|
|
375
|
+
if (!sortable) {
|
|
376
|
+
const named = !headerWord(column) && !column.action ? column.label : void 0;
|
|
377
|
+
return /* @__PURE__ */ jsxs("div", { className: headClass, role: "columnheader", title: named, children: [
|
|
378
|
+
content,
|
|
379
|
+
named && /* @__PURE__ */ jsx(VisuallyHidden, { children: named })
|
|
380
|
+
] }, column.key);
|
|
381
|
+
}
|
|
382
|
+
return /* @__PURE__ */ jsx(
|
|
383
|
+
"div",
|
|
384
|
+
{
|
|
385
|
+
className: headClass,
|
|
386
|
+
role: "columnheader",
|
|
387
|
+
"aria-sort": sorted ? sort?.desc ? "descending" : "ascending" : void 0,
|
|
388
|
+
children: /* @__PURE__ */ jsx(
|
|
389
|
+
"button",
|
|
390
|
+
{
|
|
391
|
+
type: "button",
|
|
392
|
+
className: "crewlet-data-grid__sort",
|
|
393
|
+
onClick: () => headerClick(column),
|
|
394
|
+
"aria-label": headerWord(column) ? void 0 : column.label,
|
|
395
|
+
children: content
|
|
396
|
+
}
|
|
397
|
+
)
|
|
398
|
+
},
|
|
399
|
+
column.key
|
|
400
|
+
);
|
|
401
|
+
}) }),
|
|
402
|
+
/* @__PURE__ */ jsx("div", { className: "crewlet-data-grid__body", role: "rowgroup", ref: body, children: bands ? bands.map((band) => renderBand(band)) : sortRows(rows ?? []).map(renderRow) }),
|
|
403
|
+
(footer || onLoadMore || loadedNote || dropped.length > 0) && /* @__PURE__ */ jsxs("div", { className: "crewlet-data-grid__foot", children: [
|
|
404
|
+
footer,
|
|
405
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-data-grid__foot-spacer", "aria-hidden": "true" }),
|
|
406
|
+
dropped.length > 0 && /* @__PURE__ */ jsx("span", { className: "crewlet-data-grid__note", children: text.hiddenToFit(droppedNames(shownColumns, dropped, text.and)) }),
|
|
407
|
+
loadedNote && /* @__PURE__ */ jsx("span", { className: "crewlet-data-grid__note", children: loadedNote }),
|
|
408
|
+
onLoadMore && /* @__PURE__ */ jsx(Button, { size: "small", variant: "secondary", onClick: onLoadMore, children: text.loadMore })
|
|
409
|
+
] }),
|
|
410
|
+
colsRaw && onColsChange && /* @__PURE__ */ jsx("button", { type: "button", className: "crewlet-data-grid__cols-reset", onClick: () => onColsChange(""), children: text.showEveryColumn })
|
|
411
|
+
]
|
|
412
|
+
}
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
export { ChooserList, ColumnChooser, DataGrid, columnChoicesOf, fitGridColumns, parseGridSort };
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Text } from './chunk-IKBK4A5O.js';
|
|
2
|
+
import { Inline, Stack, Spacer } from './chunk-ZAC7SKUN.js';
|
|
3
|
+
import { Card } from './chunk-INHXF2CL.js';
|
|
4
|
+
import { cx } from './chunk-ODEQTPFM.js';
|
|
5
|
+
import './RelatedRow-2FVS6QQA.css';
|
|
6
|
+
import { ChevronRightGlyph } from '@crewlethq/icons/glyphs';
|
|
7
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
8
|
+
|
|
9
|
+
function RelatedRow({ href, icon, title, description, label = "Related", className }) {
|
|
10
|
+
return /* @__PURE__ */ jsx("nav", { "aria-label": label, className: cx("crewlet-related-row", className), children: /* @__PURE__ */ jsx(Card, { href, interactive: true, padding: "sm", children: /* @__PURE__ */ jsxs(Inline, { gap: 3, children: [
|
|
11
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-related-row__glyph", "aria-hidden": "true", children: icon }),
|
|
12
|
+
/* @__PURE__ */ jsxs(Stack, { gap: 1, children: [
|
|
13
|
+
/* @__PURE__ */ jsx(Text, { variant: "cell", children: title }),
|
|
14
|
+
/* @__PURE__ */ jsx(Text, { variant: "caption", children: description })
|
|
15
|
+
] }),
|
|
16
|
+
/* @__PURE__ */ jsx(Spacer, {}),
|
|
17
|
+
/* @__PURE__ */ jsx("span", { className: "crewlet-related-row__glyph", "aria-hidden": "true", children: /* @__PURE__ */ jsx(ChevronRightGlyph, { size: "sm" }) })
|
|
18
|
+
] }) }) });
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export { RelatedRow };
|
|
@@ -32,6 +32,7 @@ export * from '../CanvasBoard/index.js';
|
|
|
32
32
|
export * from '../CanvasSchematic/index.js';
|
|
33
33
|
export * from '../CanvasToolbar/index.js';
|
|
34
34
|
export * from '../Card/index.js';
|
|
35
|
+
export * from '../CatalogTile/index.js';
|
|
35
36
|
export * from '../ChangeMark/index.js';
|
|
36
37
|
export * from '../CharacterPicker/index.js';
|
|
37
38
|
export * from '../Charts/index.js';
|
|
@@ -49,6 +50,7 @@ export * from '../Container/index.js';
|
|
|
49
50
|
export * from '../Copyable/index.js';
|
|
50
51
|
export * from '../Count/index.js';
|
|
51
52
|
export * from '../CursorFlag/index.js';
|
|
53
|
+
export * from '../DataGrid/index.js';
|
|
52
54
|
export * from '../DataTable/index.js';
|
|
53
55
|
export * from '../DataView/index.js';
|
|
54
56
|
export * from '../DatasetSource/index.js';
|
|
@@ -95,6 +97,7 @@ export * from '../ListInput/index.js';
|
|
|
95
97
|
export * from '../Listbox/index.js';
|
|
96
98
|
export * from '../LiveCursor/index.js';
|
|
97
99
|
export * from '../LivePreview/index.js';
|
|
100
|
+
export * from '../LockedLabel/index.js';
|
|
98
101
|
export * from '../Markdown/index.js';
|
|
99
102
|
export * from '../MarkdownEditor/index.js';
|
|
100
103
|
export * from '../MediaMatch/index.js';
|
|
@@ -110,6 +113,7 @@ export * from '../OrgNode/index.js';
|
|
|
110
113
|
export * from '../OrgTable/index.js';
|
|
111
114
|
export * from '../Outline/index.js';
|
|
112
115
|
export * from '../PageHeader/index.js';
|
|
116
|
+
export * from '../PageNote/index.js';
|
|
113
117
|
export * from '../PeopleRail/index.js';
|
|
114
118
|
export * from '../PinTile/index.js';
|
|
115
119
|
export * from '../Popover/index.js';
|
|
@@ -120,9 +124,11 @@ export * from '../PresenterView/index.js';
|
|
|
120
124
|
export * from '../PricingCard/index.js';
|
|
121
125
|
export * from '../Principal/index.js';
|
|
122
126
|
export * from '../PrincipalPicker/index.js';
|
|
127
|
+
export * from '../PropertyList/index.js';
|
|
123
128
|
export * from '../Prose/index.js';
|
|
124
129
|
export * from '../QrCode/index.js';
|
|
125
130
|
export * from '../ReadingPane/index.js';
|
|
131
|
+
export * from '../RelatedRow/index.js';
|
|
126
132
|
export * from '../RelativeTime/index.js';
|
|
127
133
|
export * from '../Reorder/index.js';
|
|
128
134
|
export * from '../RichEditor/index.js';
|
|
@@ -130,9 +136,11 @@ export * from '../RichEditorMarkdown/index.js';
|
|
|
130
136
|
export * from '../SandboxedFrame/index.js';
|
|
131
137
|
export * from '../SearchTrigger/index.js';
|
|
132
138
|
export * from '../Section/index.js';
|
|
139
|
+
export * from '../SectionFrame/index.js';
|
|
133
140
|
export * from '../SegmentedControl/index.js';
|
|
134
141
|
export * from '../SegmentedMeter/index.js';
|
|
135
142
|
export * from '../Select/index.js';
|
|
143
|
+
export * from '../SettingsTable/index.js';
|
|
136
144
|
export * from '../ShareDialog/index.js';
|
|
137
145
|
export * from '../SheetColumnEditor/index.js';
|
|
138
146
|
export * from '../SheetGrid/index.js';
|
|
@@ -163,6 +171,7 @@ export * from '../ThemeGallery/index.js';
|
|
|
163
171
|
export * from '../ThemeSwatch/index.js';
|
|
164
172
|
export * from '../ThemeSwitcher/index.js';
|
|
165
173
|
export * from '../ThemeToggle/index.js';
|
|
174
|
+
export * from '../TileGrid/index.js';
|
|
166
175
|
export * from '../TimeWindowPicker/index.js';
|
|
167
176
|
export * from '../Timeline/index.js';
|
|
168
177
|
export * from '../Toaster/index.js';
|