@crewlethq/ui 0.83.0 → 0.84.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 +34 -0
- package/dist/ActionCard/ActionCard.d.ts +7 -7
- package/dist/ActionCard/index.js +1 -1
- package/dist/ActionCard-YZKL3CKR.css +130 -0
- package/dist/AppShell/AppShell.d.ts +14 -11
- package/dist/AppShell/index.js +1 -1
- package/dist/{AppShell-U7D2MUUF.css → AppShell-NX5HCD4O.css} +84 -44
- package/dist/ArtifactBar/index.js +1 -1
- package/dist/ArtifactCard/index.js +2 -2
- package/dist/ArtifactKindIllustration/index.js +1 -1
- package/dist/{ArtifactKinds-3EH4KR3F.css → ArtifactKinds-27TE3KJL.css} +7 -7
- package/dist/ArtifactMakeRow/index.js +1 -1
- package/dist/ArtifactNameCell/index.js +1 -1
- package/dist/BriefCard/index.js +2 -1
- package/dist/CatalogTile/CatalogTile.d.ts +23 -5
- package/dist/CatalogTile/index.d.ts +1 -1
- package/dist/CatalogTile/index.js +2 -1
- package/dist/{CatalogTile-6VF36JWA.css → CatalogTile-TMOSGSV3.css} +4 -3
- package/dist/CompactNav/CompactNav.d.ts +10 -6
- package/dist/CompactNav/index.js +1 -1
- package/dist/DataView/index.js +1 -1
- package/dist/DirectoryList/index.js +1 -1
- package/dist/{DirectoryList-XZOWYOA3.css → DirectoryList-IXQIMNFS.css} +8 -1
- package/dist/InboxList/InboxList.d.ts +28 -2
- package/dist/InboxList/index.d.ts +1 -1
- package/dist/InboxList/index.js +6 -1
- package/dist/{InboxList-OFGSX5IH.css → InboxList-X5Q5WWAI.css} +63 -2
- package/dist/ListDetail/ListDetail.d.ts +6 -0
- package/dist/ListDetail/index.js +1 -1
- package/dist/{ListDetail-N3L7PB46.css → ListDetail-JGESKTR7.css} +38 -0
- package/dist/ReadingPane/ReadingPane.d.ts +17 -1
- package/dist/ReadingPane/index.d.ts +1 -1
- package/dist/ReadingPane/index.js +2 -1
- package/dist/{ReadingPane-VLYOWMCM.css → ReadingPane-VFTRDPC5.css} +19 -0
- package/dist/RichEditor/index.js +1 -1
- package/dist/SectionFrame/index.js +2 -2
- package/dist/ShareDialog/index.js +1 -1
- package/dist/SidebarNav/SidebarNav.d.ts +18 -2
- package/dist/SidebarNav/index.d.ts +1 -1
- package/dist/SidebarNav/index.js +1 -1
- package/dist/{SidebarNav-E7PZGGA6.css → SidebarNav-IKBKGXW4.css} +20 -0
- package/dist/{chunk-AUSFKGKL.js → chunk-3AMWXJQX.js} +1 -1
- package/dist/{chunk-Q7N2ATMC.js → chunk-64JNKLLP.js} +57 -9
- package/dist/chunk-6C7GQOBV.js +10 -0
- package/dist/{chunk-YRNNUCQP.js → chunk-7BDBO2NP.js} +1 -1
- package/dist/{chunk-25JQNHTC.js → chunk-BRK3HXGZ.js} +8 -2
- package/dist/{chunk-QM3432PH.js → chunk-C4JTX25K.js} +2 -2
- package/dist/{chunk-QE4OIE3Q.js → chunk-DJIWCW5Z.js} +6 -4
- package/dist/{chunk-QPHD4UUG.js → chunk-F6ZUM66S.js} +160 -25
- package/dist/{chunk-MVMVMHYI.js → chunk-HDEKHP65.js} +1 -1
- package/dist/{chunk-BXGBGYKH.js → chunk-HKUZ2GYX.js} +1 -1
- package/dist/{chunk-ZB3E2Z4Y.js → chunk-J5T5TDM2.js} +1 -1
- package/dist/{chunk-C46DDVTK.js → chunk-LTD7KLOU.js} +1 -1
- package/dist/{chunk-YBC2CYPD.js → chunk-O4VTQMEF.js} +1 -1
- package/dist/{chunk-HTBTAIH6.js → chunk-OM2LABPS.js} +2 -2
- package/dist/{chunk-PGBKZSSQ.js → chunk-ORONAXSF.js} +10 -7
- package/dist/{chunk-ICE3D63E.js → chunk-QWRAWKB2.js} +50 -9
- package/dist/{chunk-SRDNGGZE.js → chunk-RKIJAXQA.js} +1 -1
- package/dist/{chunk-CF4M6N6A.js → chunk-XYSSFI5C.js} +1 -7
- package/dist/generated/index.js +31 -30
- package/dist/index.js +31 -30
- package/dist/styles.css +294 -88
- package/dist/utils/developing.d.ts +10 -0
- package/package.json +3 -3
- package/dist/ActionCard-47WSZ2O5.css +0 -110
- package/dist/{Editor-5D5Z3LBQ.js → Editor-VGNB35NJ.js} +1 -1
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { Eyebrow } from './chunk-RK4XPHVG.js';
|
|
2
|
+
import { returnFocus } from './chunk-4ITETIGZ.js';
|
|
2
3
|
import { useHeadingLevel, HeadingLevelProvider, nextHeadingLevel, headingTag } from './chunk-PQADV6P6.js';
|
|
3
4
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
4
|
-
import './ReadingPane-
|
|
5
|
-
import { createContext, useId, useContext } from 'react';
|
|
5
|
+
import './ReadingPane-VFTRDPC5.css';
|
|
6
|
+
import { createContext, useId, useRef, useState, useEffect, useLayoutEffect, createElement, useContext } from 'react';
|
|
6
7
|
import { ClockGlyph, CheckGlyph } from '@crewlethq/icons/glyphs';
|
|
7
8
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
8
9
|
|
|
@@ -12,19 +13,62 @@ function usePane(part) {
|
|
|
12
13
|
if (pane === null) throw new Error(`${part} must be drawn inside a ReadingPane.`);
|
|
13
14
|
return pane;
|
|
14
15
|
}
|
|
15
|
-
|
|
16
|
+
var READING_PANE_ENTER = { animations: ["crewlet-reading-pane-enter"] };
|
|
17
|
+
function ReadingPane({ headingLevel, contentKey, focusTarget, className, children, ...rest }) {
|
|
16
18
|
const titleId = useId();
|
|
17
19
|
const outer = useHeadingLevel();
|
|
18
20
|
const level = headingLevel ?? outer;
|
|
19
21
|
const named = rest["aria-label"] !== void 0 || rest["aria-labelledby"] !== void 0;
|
|
20
|
-
|
|
22
|
+
const pane = useRef(null);
|
|
23
|
+
const column = useRef(null);
|
|
24
|
+
const [drawnKey, setDrawnKey] = useState(contentKey);
|
|
25
|
+
const [moved, setMoved] = useState(false);
|
|
26
|
+
if (drawnKey !== contentKey) {
|
|
27
|
+
setDrawnKey(contentKey);
|
|
28
|
+
setMoved(true);
|
|
29
|
+
}
|
|
30
|
+
const owned = useRef(false);
|
|
31
|
+
useEffect(() => {
|
|
32
|
+
const root = pane.current;
|
|
33
|
+
if (!root) return void 0;
|
|
34
|
+
const doc = root.ownerDocument;
|
|
35
|
+
const inside = (node) => node instanceof Node && root.contains(node);
|
|
36
|
+
const focusIn = () => {
|
|
37
|
+
owned.current = true;
|
|
38
|
+
};
|
|
39
|
+
const focusOut = (event) => {
|
|
40
|
+
if (event.relatedTarget !== null && !inside(event.relatedTarget)) owned.current = false;
|
|
41
|
+
};
|
|
42
|
+
const press = (event) => {
|
|
43
|
+
owned.current = inside(event.target);
|
|
44
|
+
};
|
|
45
|
+
root.addEventListener("focusin", focusIn);
|
|
46
|
+
root.addEventListener("focusout", focusOut);
|
|
47
|
+
doc.addEventListener("pointerdown", press, true);
|
|
48
|
+
return () => {
|
|
49
|
+
root.removeEventListener("focusin", focusIn);
|
|
50
|
+
root.removeEventListener("focusout", focusOut);
|
|
51
|
+
doc.removeEventListener("pointerdown", press, true);
|
|
52
|
+
};
|
|
53
|
+
}, []);
|
|
54
|
+
const settled = useRef(contentKey);
|
|
55
|
+
useLayoutEffect(() => {
|
|
56
|
+
if (contentKey === settled.current) return;
|
|
57
|
+
settled.current = contentKey;
|
|
58
|
+
if (!owned.current) return;
|
|
59
|
+
const target = focusTarget?.() ?? column.current?.querySelector(".crewlet-reading-pane__title");
|
|
60
|
+
returnFocus(target, { preventScroll: true });
|
|
61
|
+
}, [contentKey, focusTarget]);
|
|
62
|
+
return /* @__PURE__ */ jsx("div", { ref: pane, className: "crewlet-reading-pane", children: /* @__PURE__ */ createElement(
|
|
21
63
|
"article",
|
|
22
64
|
{
|
|
23
65
|
...rest,
|
|
66
|
+
key: contentKey,
|
|
67
|
+
ref: column,
|
|
24
68
|
"aria-labelledby": named ? rest["aria-labelledby"] : titleId,
|
|
25
|
-
className: cx("crewlet-reading-pane__column", className)
|
|
26
|
-
|
|
27
|
-
}
|
|
69
|
+
className: cx("crewlet-reading-pane__column", moved && "crewlet-reading-pane__column--entering", className)
|
|
70
|
+
},
|
|
71
|
+
/* @__PURE__ */ jsx(ReadingPaneContext.Provider, { value: { titleId, level }, children: /* @__PURE__ */ jsx(HeadingLevelProvider, { level: nextHeadingLevel(level), children }) })
|
|
28
72
|
) });
|
|
29
73
|
}
|
|
30
74
|
function ReadingPaneByline({ start, leading, note, className, children, ...rest }) {
|
|
@@ -46,7 +90,11 @@ function ReadingPaneByline({ start, leading, note, className, children, ...rest
|
|
|
46
90
|
function ReadingPaneTitle({ className, children, ...rest }) {
|
|
47
91
|
const { titleId, level } = usePane("ReadingPane.Title");
|
|
48
92
|
const Heading = headingTag(level);
|
|
49
|
-
return
|
|
93
|
+
return (
|
|
94
|
+
// Focusable from code alone, for the pane to hand focus to when its item
|
|
95
|
+
// changes; never a tab stop.
|
|
96
|
+
/* @__PURE__ */ jsx(Heading, { id: titleId, tabIndex: -1, ...rest, className: cx("crewlet-reading-pane__title", className), children })
|
|
97
|
+
);
|
|
50
98
|
}
|
|
51
99
|
function ReadingPaneLead({ className, children, ...rest }) {
|
|
52
100
|
return /* @__PURE__ */ jsx("div", { ...rest, className: cx("crewlet-reading-pane__lead", className), children });
|
|
@@ -109,4 +157,4 @@ ReadingPane.Reasoning = ReadingPaneReasoning;
|
|
|
109
157
|
ReadingPane.Outcome = ReadingPaneOutcome;
|
|
110
158
|
ReadingPane.Section = ReadingPaneSection;
|
|
111
159
|
|
|
112
|
-
export { ReadingPane, ReadingPaneByline, ReadingPaneLead, ReadingPaneOutcome, ReadingPaneQuote, ReadingPaneReasoning, ReadingPaneSection, ReadingPaneTitle };
|
|
160
|
+
export { READING_PANE_ENTER, ReadingPane, ReadingPaneByline, ReadingPaneLead, ReadingPaneOutcome, ReadingPaneQuote, ReadingPaneReasoning, ReadingPaneSection, ReadingPaneTitle };
|
|
@@ -4,7 +4,7 @@ import { HIT_AREA_CLASS } from './chunk-2YTOOH3A.js';
|
|
|
4
4
|
import { VisuallyHidden } from './chunk-UT6CW3C7.js';
|
|
5
5
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
6
6
|
import './HitArea-QUOS6ZDJ.css';
|
|
7
|
-
import './SidebarNav-
|
|
7
|
+
import './SidebarNav-IKBKGXW4.css';
|
|
8
8
|
import { createContext, useId, useState, useContext } from 'react';
|
|
9
9
|
import { ChevronDownGlyph } from '@crewlethq/icons/glyphs';
|
|
10
10
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -136,7 +136,13 @@ function NavItem({
|
|
|
136
136
|
count || badge || state ? /* @__PURE__ */ jsx(VisuallyHidden, { children: `${spoken([count, badge])}${state}` }) : null
|
|
137
137
|
] }),
|
|
138
138
|
count ? /* @__PURE__ */ jsx(Figure, { figure: count, mark: count.mark, className: "crewlet-nav-item__count" }) : null,
|
|
139
|
-
badge ? /* @__PURE__ */ jsx(
|
|
139
|
+
badge ? /* @__PURE__ */ jsx(
|
|
140
|
+
Figure,
|
|
141
|
+
{
|
|
142
|
+
figure: badge,
|
|
143
|
+
className: cx("crewlet-nav-item__badge", badge.tone === "quiet" && "crewlet-nav-item__badge--quiet")
|
|
144
|
+
}
|
|
145
|
+
) : null
|
|
140
146
|
] });
|
|
141
147
|
const rowClass = cx("crewlet-nav-item__row", HIT_AREA_CLASS);
|
|
142
148
|
let row;
|
|
@@ -3,13 +3,13 @@ import { PrincipalAvatar } from './chunk-HF5L56YQ.js';
|
|
|
3
3
|
import { RelativeTime } from './chunk-EJNJMHQG.js';
|
|
4
4
|
import { Card } from './chunk-U2IQNDDR.js';
|
|
5
5
|
import { AvatarStack } from './chunk-IRONPJB4.js';
|
|
6
|
-
import { ArtifactKindGround } from './chunk-
|
|
6
|
+
import { ArtifactKindGround } from './chunk-J5T5TDM2.js';
|
|
7
7
|
import { Checkbox } from './chunk-YQ7Q52XU.js';
|
|
8
8
|
import { ArtifactAccessGlyph } from './chunk-DOY3KC6I.js';
|
|
9
9
|
import { ArtifactKindGlyph } from './chunk-RSKW25Y5.js';
|
|
10
10
|
import { VisuallyHidden } from './chunk-UT6CW3C7.js';
|
|
11
11
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
12
|
-
import './ArtifactKinds-
|
|
12
|
+
import './ArtifactKinds-27TE3KJL.css';
|
|
13
13
|
import './ArtifactCard-B2QE5CVL.css';
|
|
14
14
|
import { useId } from 'react';
|
|
15
15
|
import { PinGlyph } from '@crewlethq/icons/glyphs';
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
+
import { StatusDot } from './chunk-CYQBDZ6M.js';
|
|
1
2
|
import { useHeadingLevel, headingTag } from './chunk-PQADV6P6.js';
|
|
2
3
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
3
|
-
import './CatalogTile-
|
|
4
|
+
import './CatalogTile-TMOSGSV3.css';
|
|
4
5
|
import { useId } from 'react';
|
|
5
|
-
import {
|
|
6
|
+
import { jsx, jsxs } from 'react/jsx-runtime';
|
|
6
7
|
|
|
7
8
|
function CatalogTile({
|
|
8
9
|
as: Element = "article",
|
|
@@ -22,6 +23,7 @@ function CatalogTile({
|
|
|
22
23
|
const Heading = headingTag(headingLevel ?? level);
|
|
23
24
|
const titleId = useId();
|
|
24
25
|
const foot = meta !== void 0 || action !== void 0;
|
|
26
|
+
const state = status ? /* @__PURE__ */ jsx("span", { className: "crewlet-catalog-tile__status", children: /* @__PURE__ */ jsx(StatusDot, { tone: status.tone, children: status.label }) }) : null;
|
|
25
27
|
if (density === "compact") {
|
|
26
28
|
return /* @__PURE__ */ jsxs(
|
|
27
29
|
Element,
|
|
@@ -39,7 +41,7 @@ function CatalogTile({
|
|
|
39
41
|
/* @__PURE__ */ jsx("span", { className: "crewlet-catalog-tile__mark", "aria-hidden": "true", children: mark }),
|
|
40
42
|
/* @__PURE__ */ jsxs("span", { className: "crewlet-catalog-tile__title", children: [
|
|
41
43
|
/* @__PURE__ */ jsx(Heading, { id: titleId, className: "crewlet-catalog-tile__name", children: title }),
|
|
42
|
-
|
|
44
|
+
state,
|
|
43
45
|
meta === void 0 || meta === null ? null : /* @__PURE__ */ jsx("span", { className: "crewlet-catalog-tile__meta", children: meta })
|
|
44
46
|
] }),
|
|
45
47
|
action === void 0 ? null : /* @__PURE__ */ jsx("span", { className: "crewlet-catalog-tile__action", children: action })
|
|
@@ -67,7 +69,7 @@ function CatalogTile({
|
|
|
67
69
|
/* @__PURE__ */ jsx("span", { className: "crewlet-catalog-tile__mark", "aria-hidden": "true", children: mark }),
|
|
68
70
|
/* @__PURE__ */ jsxs("span", { className: "crewlet-catalog-tile__title", children: [
|
|
69
71
|
/* @__PURE__ */ jsx(Heading, { id: titleId, className: "crewlet-catalog-tile__name", children: title }),
|
|
70
|
-
|
|
72
|
+
state
|
|
71
73
|
] })
|
|
72
74
|
] }),
|
|
73
75
|
description === void 0 ? null : /* @__PURE__ */ jsx("p", { className: "crewlet-catalog-tile__description", children: description }),
|
|
@@ -1,15 +1,108 @@
|
|
|
1
1
|
import { Eyebrow } from './chunk-RK4XPHVG.js';
|
|
2
|
+
import { developing } from './chunk-6C7GQOBV.js';
|
|
3
|
+
import { usePresence, releaseFocus } from './chunk-PCAT2EFB.js';
|
|
2
4
|
import { useHeadingLevel, headingTag } from './chunk-PQADV6P6.js';
|
|
3
5
|
import { VisuallyHidden } from './chunk-UT6CW3C7.js';
|
|
4
6
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
5
|
-
import './InboxList-
|
|
6
|
-
import { useId, useState } from 'react';
|
|
7
|
+
import './InboxList-X5Q5WWAI.css';
|
|
8
|
+
import { useId, useState, useRef, useLayoutEffect, useEffect, useCallback, cloneElement, Children, isValidElement } from 'react';
|
|
7
9
|
import { ChevronDownGlyph } from '@crewlethq/icons/glyphs';
|
|
8
10
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
9
11
|
|
|
10
12
|
function InboxList({ label, className, children, ...rest }) {
|
|
11
13
|
return /* @__PURE__ */ jsx("nav", { ...rest, "aria-label": label, className: cx("crewlet-inbox-list", className), children });
|
|
12
14
|
}
|
|
15
|
+
var INBOX_ROW_LEAVE = { transitions: ["grid-template-rows"] };
|
|
16
|
+
function rowsOf(children) {
|
|
17
|
+
const given = [];
|
|
18
|
+
Children.forEach(children, (child) => {
|
|
19
|
+
if (isValidElement(child)) given.push(child.key !== null);
|
|
20
|
+
});
|
|
21
|
+
return Children.toArray(children).filter((child) => isValidElement(child)).map((element, index) => ({
|
|
22
|
+
key: String(element.key),
|
|
23
|
+
element,
|
|
24
|
+
keyed: given[index] === true,
|
|
25
|
+
component: typeof element.type !== "string"
|
|
26
|
+
}));
|
|
27
|
+
}
|
|
28
|
+
function sameKeys(a, b) {
|
|
29
|
+
return a.length === b.length && a.every((key, index) => key === b[index]);
|
|
30
|
+
}
|
|
31
|
+
function keepPlaces(previous, next, kept) {
|
|
32
|
+
const placed = new Set(next);
|
|
33
|
+
const order = [...next];
|
|
34
|
+
previous.forEach((key, index) => {
|
|
35
|
+
if (placed.has(key) || !kept.has(key)) return;
|
|
36
|
+
let at = 0;
|
|
37
|
+
for (let back = index - 1; back >= 0; back -= 1) {
|
|
38
|
+
if (placed.has(previous[back])) {
|
|
39
|
+
at = order.indexOf(previous[back]) + 1;
|
|
40
|
+
break;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
order.splice(at, 0, key);
|
|
44
|
+
placed.add(key);
|
|
45
|
+
});
|
|
46
|
+
return order;
|
|
47
|
+
}
|
|
48
|
+
function useLeavingRows(children) {
|
|
49
|
+
const rows = rowsOf(children);
|
|
50
|
+
const keys = rows.map((row) => row.key);
|
|
51
|
+
const [shown, setRows] = useState(() => ({
|
|
52
|
+
keys,
|
|
53
|
+
order: keys,
|
|
54
|
+
leaving: /* @__PURE__ */ new Map()
|
|
55
|
+
}));
|
|
56
|
+
const drawn = useRef(/* @__PURE__ */ new Map());
|
|
57
|
+
useLayoutEffect(() => {
|
|
58
|
+
drawn.current = new Map(rows.map((row) => [row.key, row]));
|
|
59
|
+
});
|
|
60
|
+
let now = shown;
|
|
61
|
+
if (!sameKeys(shown.keys, keys)) {
|
|
62
|
+
const present = new Set(keys);
|
|
63
|
+
const leaving = new Map([...shown.leaving].filter(([key]) => !present.has(key)));
|
|
64
|
+
for (const key of shown.keys) {
|
|
65
|
+
if (present.has(key)) continue;
|
|
66
|
+
const last = drawn.current.get(key);
|
|
67
|
+
if (last?.keyed && last.component) leaving.set(key, last.element);
|
|
68
|
+
}
|
|
69
|
+
now = { keys, order: keepPlaces(shown.order, keys, new Set(leaving.keys())), leaving };
|
|
70
|
+
setRows(now);
|
|
71
|
+
}
|
|
72
|
+
const warned = useRef(false);
|
|
73
|
+
useEffect(() => {
|
|
74
|
+
if (warned.current || !developing()) return;
|
|
75
|
+
if (rows.some((row) => row.component && !row.keyed)) {
|
|
76
|
+
warned.current = true;
|
|
77
|
+
console.warn(
|
|
78
|
+
"[crewlet] InboxGroup was handed a row without a key of its own. Give each row a stable key, such as its id: a row without one is told apart by its position, and is not kept while it leaves."
|
|
79
|
+
);
|
|
80
|
+
}
|
|
81
|
+
});
|
|
82
|
+
const drop = useCallback((key) => {
|
|
83
|
+
setRows((was) => {
|
|
84
|
+
if (!was.leaving.has(key)) return was;
|
|
85
|
+
const leaving = new Map(was.leaving);
|
|
86
|
+
leaving.delete(key);
|
|
87
|
+
return { ...was, leaving, order: was.order.filter((each) => each !== key) };
|
|
88
|
+
});
|
|
89
|
+
}, []);
|
|
90
|
+
if (now.leaving.size === 0) return rows.map((row) => row.element);
|
|
91
|
+
const live = new Map(rows.map((row) => [row.key, row.element]));
|
|
92
|
+
return now.order.map((key) => {
|
|
93
|
+
const row = live.get(key);
|
|
94
|
+
if (row) return row;
|
|
95
|
+
const last = now.leaving.get(key);
|
|
96
|
+
if (!last) return null;
|
|
97
|
+
return cloneElement(last, {
|
|
98
|
+
leaving: true,
|
|
99
|
+
onLeft: () => {
|
|
100
|
+
last.props.onLeft?.();
|
|
101
|
+
drop(key);
|
|
102
|
+
}
|
|
103
|
+
});
|
|
104
|
+
});
|
|
105
|
+
}
|
|
13
106
|
function InboxGroup({
|
|
14
107
|
label,
|
|
15
108
|
hideLabel = false,
|
|
@@ -19,10 +112,12 @@ function InboxGroup({
|
|
|
19
112
|
open: controlledOpen,
|
|
20
113
|
defaultOpen = false,
|
|
21
114
|
onOpenChange,
|
|
115
|
+
arrived,
|
|
22
116
|
className,
|
|
23
117
|
children,
|
|
24
118
|
...rest
|
|
25
119
|
}) {
|
|
120
|
+
const rows = useLeavingRows(children);
|
|
26
121
|
const level = useHeadingLevel();
|
|
27
122
|
const Heading = headingTag(headingLevel ?? level);
|
|
28
123
|
const labelId = useId();
|
|
@@ -40,6 +135,7 @@ function InboxGroup({
|
|
|
40
135
|
" ",
|
|
41
136
|
/* @__PURE__ */ jsx("span", { className: "crewlet-inbox-list__count", children: count })
|
|
42
137
|
] });
|
|
138
|
+
const arrival = arrived === void 0 ? null : /* @__PURE__ */ jsx("span", { "aria-hidden": "true", className: "crewlet-inbox-list__arrival" }, arrived);
|
|
43
139
|
return /* @__PURE__ */ jsxs(
|
|
44
140
|
"section",
|
|
45
141
|
{
|
|
@@ -54,27 +150,31 @@ function InboxGroup({
|
|
|
54
150
|
// A DISCLOSURE INSIDE THE HEADING, never a heading inside a button: a
|
|
55
151
|
// reader moving by heading still lands on the group, and the button
|
|
56
152
|
// in it says whether the rows are shown.
|
|
57
|
-
/* @__PURE__ */
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
153
|
+
/* @__PURE__ */ jsxs(Heading, { className: "crewlet-inbox-list__label", children: [
|
|
154
|
+
/* @__PURE__ */ jsxs(
|
|
155
|
+
"button",
|
|
156
|
+
{
|
|
157
|
+
type: "button",
|
|
158
|
+
id: labelId,
|
|
159
|
+
className: "crewlet-inbox-list__disclosure",
|
|
160
|
+
"aria-expanded": open,
|
|
161
|
+
"aria-controls": rowsId,
|
|
162
|
+
onClick: toggle,
|
|
163
|
+
children: [
|
|
164
|
+
/* @__PURE__ */ jsx(ChevronDownGlyph, { "aria-hidden": true, size: "sm", className: "crewlet-inbox-list__chevron" }),
|
|
165
|
+
/* @__PURE__ */ jsx(Eyebrow, { children: label }),
|
|
166
|
+
counted
|
|
167
|
+
]
|
|
168
|
+
}
|
|
169
|
+
),
|
|
170
|
+
arrival
|
|
171
|
+
] })
|
|
73
172
|
) : /* @__PURE__ */ jsxs(Heading, { id: labelId, className: "crewlet-inbox-list__label", children: [
|
|
74
173
|
/* @__PURE__ */ jsx(Eyebrow, { children: label }),
|
|
75
|
-
counted
|
|
174
|
+
counted,
|
|
175
|
+
arrival
|
|
76
176
|
] }),
|
|
77
|
-
/* @__PURE__ */ jsx("ul", { id: rowsId, className: "crewlet-inbox-list__rows", hidden: !open, children })
|
|
177
|
+
/* @__PURE__ */ jsx("ul", { id: rowsId, className: "crewlet-inbox-list__rows", hidden: !open, children: rows })
|
|
78
178
|
]
|
|
79
179
|
}
|
|
80
180
|
);
|
|
@@ -99,10 +199,29 @@ function InboxRow({
|
|
|
99
199
|
outcomeTone = "neutral",
|
|
100
200
|
href,
|
|
101
201
|
onClick,
|
|
202
|
+
leaving = false,
|
|
203
|
+
onLeft,
|
|
204
|
+
arrived = false,
|
|
102
205
|
className,
|
|
103
206
|
children,
|
|
104
207
|
...rest
|
|
105
208
|
}) {
|
|
209
|
+
const self = useRef(null);
|
|
210
|
+
const presence = usePresence(!leaving, self, INBOX_ROW_LEAVE);
|
|
211
|
+
const gone = !presence.present;
|
|
212
|
+
useLayoutEffect(() => {
|
|
213
|
+
if (presence.leaving) releaseFocus(self.current);
|
|
214
|
+
}, [presence.leaving]);
|
|
215
|
+
const told = useRef(false);
|
|
216
|
+
useEffect(() => {
|
|
217
|
+
if (!gone) {
|
|
218
|
+
told.current = false;
|
|
219
|
+
return;
|
|
220
|
+
}
|
|
221
|
+
if (told.current) return;
|
|
222
|
+
told.current = true;
|
|
223
|
+
onLeft?.();
|
|
224
|
+
}, [gone, onLeft]);
|
|
106
225
|
const contents = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
107
226
|
leading === void 0 ? null : /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
108
227
|
/* @__PURE__ */ jsx("span", { className: "crewlet-inbox-row__leading", children: leading }),
|
|
@@ -157,10 +276,26 @@ function InboxRow({
|
|
|
157
276
|
);
|
|
158
277
|
const current = selected ? "true" : void 0;
|
|
159
278
|
const control = href !== void 0 ? /* @__PURE__ */ jsx("a", { className: controlClass, href, "aria-current": current, onClick, children: contents }) : /* @__PURE__ */ jsx("button", { type: "button", className: controlClass, "aria-current": current, onClick, children: contents });
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
279
|
+
if (gone) return null;
|
|
280
|
+
return /* @__PURE__ */ jsx(
|
|
281
|
+
"li",
|
|
282
|
+
{
|
|
283
|
+
...rest,
|
|
284
|
+
ref: self,
|
|
285
|
+
inert: presence.leaving,
|
|
286
|
+
className: cx(
|
|
287
|
+
"crewlet-inbox-row",
|
|
288
|
+
selected && "crewlet-inbox-row--selected",
|
|
289
|
+
arrived && "crewlet-inbox-row--arrived",
|
|
290
|
+
presence.leaving && "crewlet-inbox-row--leaving",
|
|
291
|
+
className
|
|
292
|
+
),
|
|
293
|
+
children: /* @__PURE__ */ jsxs("div", { className: "crewlet-inbox-row__body", children: [
|
|
294
|
+
control,
|
|
295
|
+
aside === void 0 || aside === null || aside === false ? null : /* @__PURE__ */ jsx("div", { className: "crewlet-inbox-row__aside", children: aside })
|
|
296
|
+
] })
|
|
297
|
+
}
|
|
298
|
+
);
|
|
164
299
|
}
|
|
165
300
|
function InboxMore({ className, children, ...rest }) {
|
|
166
301
|
return /* @__PURE__ */ jsx("div", { ...rest, className: cx("crewlet-inbox-list__more", className), children });
|
|
@@ -173,4 +308,4 @@ InboxList.Row = InboxRow;
|
|
|
173
308
|
InboxList.More = InboxMore;
|
|
174
309
|
InboxList.Toggle = InboxToggle;
|
|
175
310
|
|
|
176
|
-
export { InboxGroup, InboxList, InboxMore, InboxRow, InboxToggle };
|
|
311
|
+
export { INBOX_ROW_LEAVE, InboxGroup, InboxList, InboxMore, InboxRow, InboxToggle };
|
|
@@ -3,7 +3,7 @@ import { HIT_AREA_CLASS } from './chunk-2YTOOH3A.js';
|
|
|
3
3
|
import { VisuallyHidden } from './chunk-UT6CW3C7.js';
|
|
4
4
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
5
5
|
import './HitArea-QUOS6ZDJ.css';
|
|
6
|
-
import './ArtifactKinds-
|
|
6
|
+
import './ArtifactKinds-27TE3KJL.css';
|
|
7
7
|
import './ArtifactMakeRow-6UX2LTF7.css';
|
|
8
8
|
import { useId } from 'react';
|
|
9
9
|
import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
|
|
@@ -7,7 +7,7 @@ import { Button } from './chunk-DGXZ635L.js';
|
|
|
7
7
|
import { returnFocus } from './chunk-4ITETIGZ.js';
|
|
8
8
|
import { IconButton } from './chunk-UAUP6XGK.js';
|
|
9
9
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
10
|
-
import './ArtifactKinds-
|
|
10
|
+
import './ArtifactKinds-27TE3KJL.css';
|
|
11
11
|
import './ArtifactBar-X46WJNW7.css';
|
|
12
12
|
import { useId, useState, useRef, useEffect } from 'react';
|
|
13
13
|
import { ChevronLeftGlyph, EllipsisGlyph, ChevronDownGlyph } from '@crewlethq/icons/glyphs';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { VisuallyHidden } from './chunk-UT6CW3C7.js';
|
|
2
2
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
3
|
-
import './ArtifactKinds-
|
|
3
|
+
import './ArtifactKinds-27TE3KJL.css';
|
|
4
4
|
import './ArtifactKindIllustration-D2J3HJMJ.css';
|
|
5
5
|
import { useId } from 'react';
|
|
6
6
|
import { CheckGlyph } from '@crewlethq/icons/glyphs';
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { ArtifactKindGlyph } from './chunk-RSKW25Y5.js';
|
|
2
2
|
import { VisuallyHidden } from './chunk-UT6CW3C7.js';
|
|
3
3
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
4
|
-
import './ArtifactKinds-
|
|
4
|
+
import './ArtifactKinds-27TE3KJL.css';
|
|
5
5
|
import './ArtifactNameCell-3AHLUSE5.css';
|
|
6
6
|
import { FolderGlyph, PinGlyph } from '@crewlethq/icons/glyphs';
|
|
7
7
|
import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
2
|
-
import './ArtifactKinds-
|
|
3
|
-
import './ActionCard-
|
|
2
|
+
import './ArtifactKinds-27TE3KJL.css';
|
|
3
|
+
import './ActionCard-YZKL3CKR.css';
|
|
4
4
|
import { jsxs, jsx } from 'react/jsx-runtime';
|
|
5
5
|
|
|
6
6
|
var ACTION_CARD_GROUND = {
|
|
@@ -12,11 +12,11 @@ import { IconButton } from './chunk-UAUP6XGK.js';
|
|
|
12
12
|
import { VisuallyHidden } from './chunk-UT6CW3C7.js';
|
|
13
13
|
import { cx } from './chunk-ODEQTPFM.js';
|
|
14
14
|
import './HitArea-QUOS6ZDJ.css';
|
|
15
|
-
import './AppShell-
|
|
15
|
+
import './AppShell-NX5HCD4O.css';
|
|
16
16
|
import './ResizeHandle-2UNSZ4ZQ.css';
|
|
17
17
|
import { createContext, forwardRef, useContext, useSyncExternalStore, useCallback, useId, useState, useRef, useEffect, useLayoutEffect } from 'react';
|
|
18
18
|
import { breakpoint } from '@crewlethq/tokens';
|
|
19
|
-
import { ChevronUpGlyph, ChevronsUpDownGlyph, ChevronRightGlyph,
|
|
19
|
+
import { ChevronUpGlyph, ChevronsUpDownGlyph, ChevronRightGlyph, ChevronsRightGlyph, ChevronsLeftGlyph, MenuGlyph } from '@crewlethq/icons/glyphs';
|
|
20
20
|
import { jsxs, Fragment, jsx } from 'react/jsx-runtime';
|
|
21
21
|
|
|
22
22
|
function AccountRow({
|
|
@@ -246,6 +246,7 @@ function AppShell({
|
|
|
246
246
|
const narrow = useMediaMatch(NARROW);
|
|
247
247
|
const [drawerOpen, setDrawerOpen] = useState(false);
|
|
248
248
|
const [scroller, setScroller] = useState(null);
|
|
249
|
+
const [gauge, setGauge] = useState(null);
|
|
249
250
|
const [drawerZ, setDrawerZ] = useState(null);
|
|
250
251
|
const rail = useRef(null);
|
|
251
252
|
const closeDrawer = useCallback(() => setDrawerOpen(false), []);
|
|
@@ -274,18 +275,19 @@ function AppShell({
|
|
|
274
275
|
);
|
|
275
276
|
const [gutter, setGutter] = useState(0);
|
|
276
277
|
useLayoutEffect(() => {
|
|
277
|
-
|
|
278
|
-
|
|
278
|
+
const ruler = gauge ?? scroller;
|
|
279
|
+
if (!ruler) return void 0;
|
|
280
|
+
const measure = () => setGutter(Math.max(0, ruler.offsetWidth - ruler.clientWidth));
|
|
279
281
|
measure();
|
|
280
282
|
if (typeof ResizeObserver === "undefined") return void 0;
|
|
281
283
|
const observer = new ResizeObserver(unlessRailMoving(measure));
|
|
282
|
-
observer.observe(
|
|
284
|
+
observer.observe(ruler);
|
|
283
285
|
const held = heldMeasures.current;
|
|
284
286
|
return () => {
|
|
285
287
|
observer.disconnect();
|
|
286
288
|
held.delete(measure);
|
|
287
289
|
};
|
|
288
|
-
}, [scroller, unlessRailMoving]);
|
|
290
|
+
}, [gauge, scroller, unlessRailMoving]);
|
|
289
291
|
const root = useRef(null);
|
|
290
292
|
const sheet = useRef(null);
|
|
291
293
|
const asideColumn = hasAside && asideShape === "column";
|
|
@@ -433,6 +435,7 @@ function AppShell({
|
|
|
433
435
|
/* @__PURE__ */ jsxs("div", { ref: sheet, className: "crewlet-app-shell__sheet", children: [
|
|
434
436
|
topbar,
|
|
435
437
|
banner ? /* @__PURE__ */ jsx("div", { className: "crewlet-app-shell__banner", children: banner }) : null,
|
|
438
|
+
fill === true ? /* @__PURE__ */ jsx("div", { className: "crewlet-app-shell__gauge", "aria-hidden": "true", children: /* @__PURE__ */ jsx("div", { ref: setGauge, className: "crewlet-app-shell__gauge-ruler" }) }) : null,
|
|
436
439
|
/* @__PURE__ */ jsxs("div", { className: "crewlet-app-shell__body", children: [
|
|
437
440
|
/* @__PURE__ */ jsx("main", { id: main, ref: setMain, className: "crewlet-app-shell__main", tabIndex: -1, children: /* @__PURE__ */ jsx("div", { ref: content, className: "crewlet-app-shell__content", children: /* @__PURE__ */ jsx(ScreenWidthContext.Provider, { value: screenWidth, children }) }) }),
|
|
438
441
|
hasPeek ? /* @__PURE__ */ jsx(PeekContext.Provider, { value: { shape: peekShape }, children: peek }) : null
|
|
@@ -619,7 +622,7 @@ function RailFold({
|
|
|
619
622
|
label,
|
|
620
623
|
size: "sm",
|
|
621
624
|
variant: "ghost",
|
|
622
|
-
icon: compact ? /* @__PURE__ */ jsx(
|
|
625
|
+
icon: compact ? /* @__PURE__ */ jsx(ChevronsRightGlyph, { size: "sm" }) : /* @__PURE__ */ jsx(ChevronsLeftGlyph, { size: "sm" }),
|
|
623
626
|
"aria-controls": railId,
|
|
624
627
|
"aria-expanded": !compact,
|
|
625
628
|
"aria-keyshortcuts": keys ? ariaKeyshortcuts(keys, apple) : void 0,
|