@astralform/ui 0.0.0-stage → 0.3.7-next.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/DESIGN.md +243 -0
- package/LICENSE +21 -0
- package/README.md +128 -2
- package/dist/components/Alert.d.ts +7 -0
- package/dist/components/Alert.js +40 -0
- package/dist/components/Alert.js.map +1 -0
- package/dist/components/AvatarEditor.d.ts +13 -0
- package/dist/components/AvatarEditor.js +44 -0
- package/dist/components/AvatarEditor.js.map +1 -0
- package/dist/components/Badge.d.ts +16 -0
- package/dist/components/Badge.js +38 -0
- package/dist/components/Badge.js.map +1 -0
- package/dist/components/Button.d.ts +8 -0
- package/dist/components/Button.js +21 -0
- package/dist/components/Button.js.map +1 -0
- package/dist/components/Card.d.ts +10 -0
- package/dist/components/Card.js +22 -0
- package/dist/components/Card.js.map +1 -0
- package/dist/components/CompactResourceRow.d.ts +34 -0
- package/dist/components/CompactResourceRow.js +11 -0
- package/dist/components/CompactResourceRow.js.map +1 -0
- package/dist/components/ConfirmDialog.d.ts +12 -0
- package/dist/components/ConfirmDialog.js +7 -0
- package/dist/components/ConfirmDialog.js.map +1 -0
- package/dist/components/CookieConsent.d.ts +1 -0
- package/dist/components/CookieConsent.js +42 -0
- package/dist/components/CookieConsent.js.map +1 -0
- package/dist/components/DataTable.d.ts +53 -0
- package/dist/components/DataTable.js +79 -0
- package/dist/components/DataTable.js.map +1 -0
- package/dist/components/DevTools.d.ts +6 -0
- package/dist/components/DevTools.js +59 -0
- package/dist/components/DevTools.js.map +1 -0
- package/dist/components/EmptyState.d.ts +11 -0
- package/dist/components/EmptyState.js +6 -0
- package/dist/components/EmptyState.js.map +1 -0
- package/dist/components/ImageCropModal.d.ts +18 -0
- package/dist/components/ImageCropModal.js +67 -0
- package/dist/components/ImageCropModal.js.map +1 -0
- package/dist/components/InlineBanner.d.ts +20 -0
- package/dist/components/InlineBanner.js +53 -0
- package/dist/components/InlineBanner.js.map +1 -0
- package/dist/components/Input.d.ts +8 -0
- package/dist/components/Input.js +10 -0
- package/dist/components/Input.js.map +1 -0
- package/dist/components/InventoryCard.d.ts +20 -0
- package/dist/components/InventoryCard.js +22 -0
- package/dist/components/InventoryCard.js.map +1 -0
- package/dist/components/LoadingSpinner.d.ts +26 -0
- package/dist/components/LoadingSpinner.js +32 -0
- package/dist/components/LoadingSpinner.js.map +1 -0
- package/dist/components/Modal.d.ts +10 -0
- package/dist/components/Modal.js +38 -0
- package/dist/components/Modal.js.map +1 -0
- package/dist/components/PageHeader.d.ts +11 -0
- package/dist/components/PageHeader.js +5 -0
- package/dist/components/PageHeader.js.map +1 -0
- package/dist/components/PreviewModal.d.ts +24 -0
- package/dist/components/PreviewModal.js +69 -0
- package/dist/components/PreviewModal.js.map +1 -0
- package/dist/components/ProgressBar.d.ts +8 -0
- package/dist/components/ProgressBar.js +12 -0
- package/dist/components/ProgressBar.js.map +1 -0
- package/dist/components/ProviderIcon.d.ts +7 -0
- package/dist/components/ProviderIcon.js +34 -0
- package/dist/components/ProviderIcon.js.map +1 -0
- package/dist/components/ResizeHandle.d.ts +56 -0
- package/dist/components/ResizeHandle.js +166 -0
- package/dist/components/ResizeHandle.js.map +1 -0
- package/dist/components/SegmentedProgressBar.d.ts +9 -0
- package/dist/components/SegmentedProgressBar.js +23 -0
- package/dist/components/SegmentedProgressBar.js.map +1 -0
- package/dist/components/Select.d.ts +13 -0
- package/dist/components/Select.js +14 -0
- package/dist/components/Select.js.map +1 -0
- package/dist/components/SpotlightButton.d.ts +10 -0
- package/dist/components/SpotlightButton.js +51 -0
- package/dist/components/SpotlightButton.js.map +1 -0
- package/dist/components/StatCard.d.ts +9 -0
- package/dist/components/StatCard.js +8 -0
- package/dist/components/StatCard.js.map +1 -0
- package/dist/components/StatusBadge.d.ts +4 -0
- package/dist/components/StatusBadge.js +10 -0
- package/dist/components/StatusBadge.js.map +1 -0
- package/dist/components/TabNav.d.ts +39 -0
- package/dist/components/TabNav.js +25 -0
- package/dist/components/TabNav.js.map +1 -0
- package/dist/components/TableShell.d.ts +21 -0
- package/dist/components/TableShell.js +19 -0
- package/dist/components/TableShell.js.map +1 -0
- package/dist/components/Textarea.d.ts +7 -0
- package/dist/components/Textarea.js +10 -0
- package/dist/components/Textarea.js.map +1 -0
- package/dist/components/Toggle.d.ts +16 -0
- package/dist/components/Toggle.js +25 -0
- package/dist/components/Toggle.js.map +1 -0
- package/dist/components/Toolbar.d.ts +34 -0
- package/dist/components/Toolbar.js +30 -0
- package/dist/components/Toolbar.js.map +1 -0
- package/dist/components/TypeToConfirmModal.d.ts +15 -0
- package/dist/components/TypeToConfirmModal.js +14 -0
- package/dist/components/TypeToConfirmModal.js.map +1 -0
- package/dist/components/UnsavedChangesModal.d.ts +7 -0
- package/dist/components/UnsavedChangesModal.js +7 -0
- package/dist/components/UnsavedChangesModal.js.map +1 -0
- package/dist/components/UsageCard.d.ts +11 -0
- package/dist/components/UsageCard.js +9 -0
- package/dist/components/UsageCard.js.map +1 -0
- package/dist/components/avatar.d.ts +79 -0
- package/dist/components/avatar.js +88 -0
- package/dist/components/avatar.js.map +1 -0
- package/dist/components/badge-config.d.ts +16 -0
- package/dist/components/badge-config.js +48 -0
- package/dist/components/badge-config.js.map +1 -0
- package/dist/components/glowing-effect.d.ts +14 -0
- package/dist/components/glowing-effect.js +108 -0
- package/dist/components/glowing-effect.js.map +1 -0
- package/dist/index.d.ts +39 -0
- package/dist/index.js +42 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/cookies.d.ts +36 -0
- package/dist/lib/cookies.js +78 -0
- package/dist/lib/cookies.js.map +1 -0
- package/dist/lib/environment.d.ts +24 -0
- package/dist/lib/environment.js +52 -0
- package/dist/lib/environment.js.map +1 -0
- package/dist/lib/utils.d.ts +4 -0
- package/dist/lib/utils.js +8 -0
- package/dist/lib/utils.js.map +1 -0
- package/dist/types.d.ts +12 -0
- package/dist/types.js +12 -0
- package/dist/types.js.map +1 -0
- package/package.json +89 -4
- package/src/styles/base.css +779 -0
- package/src/styles/fonts.css +25 -0
- package/src/styles/theme-default.css +164 -0
- package/src/styles/theme-default.generated.css +79 -0
- package/src/styles/tokens/_foundations.css +28 -0
- package/src/styles/tokens/_semantics.css +72 -0
- package/themes/chat.DESIGN.md +197 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { Icon } from "@phosphor-icons/react";
|
|
3
|
+
interface InventoryCardProps {
|
|
4
|
+
/** URL for icon image */
|
|
5
|
+
iconUrl?: string | null;
|
|
6
|
+
/** Phosphor fallback when no URL is set */
|
|
7
|
+
fallbackIcon: Icon;
|
|
8
|
+
/** Primary label */
|
|
9
|
+
title: string;
|
|
10
|
+
/** Secondary text — single line, truncated */
|
|
11
|
+
description?: string;
|
|
12
|
+
/** Badge compositions after title */
|
|
13
|
+
badges?: ReactNode;
|
|
14
|
+
/** Click handler — navigates to edit/detail page or opens preview */
|
|
15
|
+
onClick?: () => void;
|
|
16
|
+
/** Show a + indicator on the right (for recommended items) */
|
|
17
|
+
showPlus?: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function InventoryCard({ iconUrl, fallbackIcon: FallbackIcon, title, description, badges, onClick, showPlus, }: InventoryCardProps): import("react").JSX.Element;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import {} from "react";
|
|
3
|
+
import { cn } from "../lib/utils";
|
|
4
|
+
import { PlusIcon } from "@phosphor-icons/react";
|
|
5
|
+
import { Avatar, iconFallback } from "./avatar";
|
|
6
|
+
export function InventoryCard({ iconUrl, fallbackIcon: FallbackIcon, title, description, badges, onClick, showPlus, }) {
|
|
7
|
+
const interactiveProps = onClick
|
|
8
|
+
? {
|
|
9
|
+
role: "button",
|
|
10
|
+
tabIndex: 0,
|
|
11
|
+
onClick,
|
|
12
|
+
onKeyDown: (e) => {
|
|
13
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
14
|
+
e.preventDefault();
|
|
15
|
+
onClick();
|
|
16
|
+
}
|
|
17
|
+
},
|
|
18
|
+
}
|
|
19
|
+
: {};
|
|
20
|
+
return (_jsxs("div", { ...interactiveProps, className: cn("@container/card rounded-3xl border border-border-primary flex items-center transition-colors", "gap-3 px-3 py-2.5 @[22rem]/card:gap-4 @[22rem]/card:px-5 @[22rem]/card:py-4", onClick && "cursor-pointer hover:bg-surface-secondary"), children: [_jsx(Avatar, { src: iconUrl, size: "lg", rounded: "rounded-xl", fallback: iconFallback(FallbackIcon) }), _jsxs("div", { className: "min-w-0 flex-1", children: [_jsxs("div", { className: "flex items-center gap-1.5", children: [_jsx("span", { className: "text-sm font-medium text-text-primary truncate", children: title }), badges && (_jsx("div", { className: "flex items-center gap-1.5 shrink-0", children: badges }))] }), _jsx("div", { className: "hidden @[22rem]/card:block", children: description && (_jsx("p", { className: "text-sm text-text-muted mt-0.5 line-clamp-1", children: description })) })] }), showPlus && (_jsx("div", { className: "flex-shrink-0", children: _jsx(PlusIcon, { size: 20, className: "text-text-muted" }) }))] }));
|
|
21
|
+
}
|
|
22
|
+
//# sourceMappingURL=InventoryCard.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"InventoryCard.js","sourceRoot":"","sources":["../../src/components/InventoryCard.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAkB,MAAM,OAAO,CAAC;AACvC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,QAAQ,EAAE,MAAM,uBAAuB,CAAC;AAEjD,OAAO,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAmBhD,MAAM,UAAU,aAAa,CAAC,EAC5B,OAAO,EACP,YAAY,EAAE,YAAY,EAC1B,KAAK,EACL,WAAW,EACX,MAAM,EACN,OAAO,EACP,QAAQ,GACW;IACnB,MAAM,gBAAgB,GAAG,OAAO;QAC9B,CAAC,CAAC;YACE,IAAI,EAAE,QAAiB;YACvB,QAAQ,EAAE,CAAC;YACX,OAAO;YACP,SAAS,EAAE,CAAC,CAAsB,EAAE,EAAE;gBACpC,IAAI,CAAC,CAAC,GAAG,KAAK,OAAO,IAAI,CAAC,CAAC,GAAG,KAAK,GAAG,EAAE,CAAC;oBACvC,CAAC,CAAC,cAAc,EAAE,CAAC;oBACnB,OAAO,EAAE,CAAC;gBACZ,CAAC;YACH,CAAC;SACF;QACH,CAAC,CAAC,EAAE,CAAC;IAEP,OAAO,CACL,kBACM,gBAAgB,EACpB,SAAS,EAAE,EAAE,CACX,8FAA8F,EAC9F,6EAA6E,EAC7E,OAAO,IAAI,2CAA2C,CACvD,aAED,KAAC,MAAM,IACL,GAAG,EAAE,OAAO,EACZ,IAAI,EAAC,IAAI,EACT,OAAO,EAAC,YAAY,EACpB,QAAQ,EAAE,YAAY,CAAC,YAAY,CAAC,GACpC,EAGF,eAAK,SAAS,EAAC,gBAAgB,aAC7B,eAAK,SAAS,EAAC,2BAA2B,aACxC,eAAM,SAAS,EAAC,gDAAgD,YAC7D,KAAK,GACD,EACN,MAAM,IAAI,CACT,cAAK,SAAS,EAAC,oCAAoC,YAAE,MAAM,GAAO,CACnE,IACG,EACN,cAAK,SAAS,EAAC,4BAA4B,YACxC,WAAW,IAAI,CACd,YAAG,SAAS,EAAC,6CAA6C,YACvD,WAAW,GACV,CACL,GACG,IACF,EAGL,QAAQ,IAAI,CACX,cAAK,SAAS,EAAC,eAAe,YAC5B,KAAC,QAAQ,IAAC,IAAI,EAAE,EAAE,EAAE,SAAS,EAAC,iBAAiB,GAAG,GAC9C,CACP,IACG,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
interface LoadingSpinnerProps {
|
|
2
|
+
size?: "sm" | "md" | "lg";
|
|
3
|
+
className?: string;
|
|
4
|
+
}
|
|
5
|
+
/** Section-level spinner — centered rotating arc with vertical breathing room. */
|
|
6
|
+
export declare function LoadingSpinner({ size, className, }: LoadingSpinnerProps): import("react").JSX.Element;
|
|
7
|
+
interface InlineSpinnerProps {
|
|
8
|
+
/** Pixel size of the glyph. */
|
|
9
|
+
size?: number;
|
|
10
|
+
className?: string;
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Inline loading spinner — solid center dot with a spinning ring.
|
|
14
|
+
* For per-action loading states inside rows, buttons, and blocks.
|
|
15
|
+
*/
|
|
16
|
+
export declare const InlineSpinner: import("react").NamedExoticComponent<InlineSpinnerProps>;
|
|
17
|
+
interface PageSpinnerProps {
|
|
18
|
+
size?: "sm" | "md" | "lg";
|
|
19
|
+
className?: string;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Page-level spinner — minimal rotating arc; the caller owns the height
|
|
23
|
+
* (no forced padding), for full-view loading states.
|
|
24
|
+
*/
|
|
25
|
+
export declare const PageSpinner: import("react").NamedExoticComponent<PageSpinnerProps>;
|
|
26
|
+
export {};
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { memo } from "react";
|
|
3
|
+
import { cn } from "../lib/utils";
|
|
4
|
+
const sizeClasses = {
|
|
5
|
+
sm: "h-5 w-5",
|
|
6
|
+
md: "h-8 w-8",
|
|
7
|
+
lg: "h-12 w-12",
|
|
8
|
+
};
|
|
9
|
+
/** Section-level spinner — centered rotating arc with vertical breathing room. */
|
|
10
|
+
export function LoadingSpinner({ size = "md", className, }) {
|
|
11
|
+
return (_jsx("div", { className: cn("flex items-center justify-center py-12", className), children: _jsx("div", { className: cn("animate-spin rounded-full border-b-2 border-text-tertiary", sizeClasses[size]) }) }));
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Inline loading spinner — solid center dot with a spinning ring.
|
|
15
|
+
* For per-action loading states inside rows, buttons, and blocks.
|
|
16
|
+
*/
|
|
17
|
+
export const InlineSpinner = memo(function InlineSpinner({ size = 14, className = "text-text-secondary", }) {
|
|
18
|
+
return (_jsxs("svg", { width: size, height: size, viewBox: "0 0 16 16", fill: "none", className: className, children: [_jsx("circle", { cx: "8", cy: "8", r: "2.5", fill: "currentColor" }), _jsx("circle", { cx: "8", cy: "8", r: "6", stroke: "currentColor", strokeWidth: "1.5", strokeDasharray: "28 10", opacity: "0.5", className: "animate-spin origin-center" })] }));
|
|
19
|
+
});
|
|
20
|
+
const pageSpinnerSize = {
|
|
21
|
+
sm: "h-5 w-5",
|
|
22
|
+
md: "h-8 w-8",
|
|
23
|
+
lg: "h-12 w-12",
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Page-level spinner — minimal rotating arc; the caller owns the height
|
|
27
|
+
* (no forced padding), for full-view loading states.
|
|
28
|
+
*/
|
|
29
|
+
export const PageSpinner = memo(function PageSpinner({ size = "sm", className, }) {
|
|
30
|
+
return (_jsx("div", { className: cn("flex items-center justify-center", className), children: _jsx("div", { className: cn("animate-spin rounded-full border-b-2 border-text-tertiary", pageSpinnerSize[size]) }) }));
|
|
31
|
+
});
|
|
32
|
+
//# sourceMappingURL=LoadingSpinner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LoadingSpinner.js","sourceRoot":"","sources":["../../src/components/LoadingSpinner.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAOlC,MAAM,WAAW,GAAG;IAClB,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,WAAW;CAChB,CAAC;AAEF,kFAAkF;AAClF,MAAM,UAAU,cAAc,CAAC,EAC7B,IAAI,GAAG,IAAI,EACX,SAAS,GACW;IACpB,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,wCAAwC,EAAE,SAAS,CAAC,YACrE,cACE,SAAS,EAAE,EAAE,CACX,2DAA2D,EAC3D,WAAW,CAAC,IAAI,CAAC,CAClB,GACD,GACE,CACP,CAAC;AACJ,CAAC;AAQD;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,aAAa,CAAC,EACvD,IAAI,GAAG,EAAE,EACT,SAAS,GAAG,qBAAqB,GACd;IACnB,OAAO,CACL,eACE,KAAK,EAAE,IAAI,EACX,MAAM,EAAE,IAAI,EACZ,OAAO,EAAC,WAAW,EACnB,IAAI,EAAC,MAAM,EACX,SAAS,EAAE,SAAS,aAEpB,iBAAQ,EAAE,EAAC,GAAG,EAAC,EAAE,EAAC,GAAG,EAAC,CAAC,EAAC,KAAK,EAAC,IAAI,EAAC,cAAc,GAAG,EACpD,iBACE,EAAE,EAAC,GAAG,EACN,EAAE,EAAC,GAAG,EACN,CAAC,EAAC,GAAG,EACL,MAAM,EAAC,cAAc,EACrB,WAAW,EAAC,KAAK,EACjB,eAAe,EAAC,OAAO,EACvB,OAAO,EAAC,KAAK,EACb,SAAS,EAAC,4BAA4B,GACtC,IACE,CACP,CAAC;AACJ,CAAC,CAAC,CAAC;AAOH,MAAM,eAAe,GAA0D;IAC7E,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,SAAS;IACb,EAAE,EAAE,WAAW;CAChB,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,IAAI,CAAC,SAAS,WAAW,CAAC,EACnD,IAAI,GAAG,IAAI,EACX,SAAS,GACQ;IACjB,OAAO,CACL,cAAK,SAAS,EAAE,EAAE,CAAC,kCAAkC,EAAE,SAAS,CAAC,YAC/D,cACE,SAAS,EAAE,EAAE,CACX,2DAA2D,EAC3D,eAAe,CAAC,IAAI,CAAC,CACtB,GACD,GACE,CACP,CAAC;AACJ,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
interface ModalProps {
|
|
3
|
+
isOpen: boolean;
|
|
4
|
+
onClose: () => void;
|
|
5
|
+
title?: string;
|
|
6
|
+
children: ReactNode;
|
|
7
|
+
size?: "sm" | "md" | "lg" | "xl";
|
|
8
|
+
}
|
|
9
|
+
export declare function Modal({ isOpen, onClose, title, children, size, }: ModalProps): import("react").JSX.Element;
|
|
10
|
+
export {};
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
import { Fragment, useState } from "react";
|
|
3
|
+
import { Dialog, DialogPanel, DialogTitle, Transition, TransitionChild, } from "@headlessui/react";
|
|
4
|
+
import { XIcon } from "@phosphor-icons/react";
|
|
5
|
+
import { cn } from "../lib/utils";
|
|
6
|
+
export function Modal({ isOpen, onClose, title, children, size = "md", }) {
|
|
7
|
+
const sizes = {
|
|
8
|
+
sm: "max-w-sm",
|
|
9
|
+
md: "max-w-md",
|
|
10
|
+
lg: "max-w-lg",
|
|
11
|
+
xl: "max-w-xl",
|
|
12
|
+
};
|
|
13
|
+
// The panel stays on screen through its leave transition after `isOpen` turns
|
|
14
|
+
// false, but callers reset what the title and body read in the same update
|
|
15
|
+
// that closes the modal (an edit target back to null, a form unmounted behind
|
|
16
|
+
// `isOpen &&`). Rendering those props would flash a different title over an
|
|
17
|
+
// empty panel while it fades, so a closing modal keeps showing what it last
|
|
18
|
+
// showed open, and is inert so that frozen content can't be acted on. The
|
|
19
|
+
// frozen copy is dropped once the leave ends.
|
|
20
|
+
const [frozen, setFrozen] = useState(null);
|
|
21
|
+
if (isOpen && (frozen?.title !== title || frozen?.children !== children)) {
|
|
22
|
+
setFrozen({ title, children });
|
|
23
|
+
}
|
|
24
|
+
const content = isOpen || !frozen ? { title, children } : frozen;
|
|
25
|
+
// Each open that follows a rendered close gets a fresh body; without the key,
|
|
26
|
+
// a reopen during the fade would reconcile against the frozen body and keep
|
|
27
|
+
// the state it was closed with. (A close and reopen in one batch never renders
|
|
28
|
+
// closed, so it keeps its body, as it always did.)
|
|
29
|
+
const [openCount, setOpenCount] = useState(0);
|
|
30
|
+
const [wasOpen, setWasOpen] = useState(false);
|
|
31
|
+
if (isOpen !== wasOpen) {
|
|
32
|
+
setWasOpen(isOpen);
|
|
33
|
+
if (isOpen)
|
|
34
|
+
setOpenCount(openCount + 1);
|
|
35
|
+
}
|
|
36
|
+
return (_jsx(Transition, { show: isOpen, as: Fragment, afterLeave: () => setFrozen(null), children: _jsxs(Dialog, { as: "div", className: "relative z-50", onClose: onClose, children: [_jsx(TransitionChild, { as: Fragment, enter: "ease-out duration-[var(--duration-enter)]", enterFrom: "opacity-0", enterTo: "opacity-100", leave: "ease-in duration-[var(--duration-hover)]", leaveFrom: "opacity-100", leaveTo: "opacity-0", children: _jsx("div", { className: "fixed inset-0 bg-surface-overlay backdrop-blur-sm transition-opacity" }) }), _jsx("div", { className: "fixed inset-0 z-10 overflow-y-auto", children: _jsx("div", { className: "flex min-h-full items-end justify-center p-4 text-center sm:items-center sm:p-0", children: _jsx(TransitionChild, { as: Fragment, enter: "ease-out duration-[var(--duration-enter)]", enterFrom: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95", enterTo: "opacity-100 translate-y-0 sm:scale-100", leave: "ease-in duration-[var(--duration-hover)]", leaveFrom: "opacity-100 translate-y-0 sm:scale-100", leaveTo: "opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95", children: _jsxs(DialogPanel, { inert: !isOpen, className: cn("relative transform overflow-hidden rounded-modal bg-surface-secondary text-left shadow-[var(--shadow-modal)] transition-all sm:my-8 w-full border border-border-primary", sizes[size]), children: [content.title && (_jsxs("div", { className: "flex items-center justify-between px-6 py-4 border-b border-border-primary", children: [_jsx(DialogTitle, { as: "h3", className: "text-lg font-semibold text-text-primary", children: content.title }), _jsxs("button", { type: "button", className: "rounded-md text-text-tertiary hover:text-text-secondary focus:outline-none focus:ring-2 focus:ring-white/30", onClick: onClose, children: [_jsx("span", { className: "sr-only", children: "Close" }), _jsx(XIcon, { size: 24, "aria-hidden": "true" })] })] })), _jsx("div", { className: "px-6 py-4", children: content.children }, openCount)] }) }) }) })] }) }));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=Modal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Modal.js","sourceRoot":"","sources":["../../src/components/Modal.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
interface PageHeaderProps {
|
|
3
|
+
/** Short description beneath the breadcrumb title */
|
|
4
|
+
description?: string;
|
|
5
|
+
/** Right-aligned slot for buttons/search */
|
|
6
|
+
actions?: ReactNode;
|
|
7
|
+
/** Page content */
|
|
8
|
+
children?: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
export declare function PageHeader({ description, actions, children, }: PageHeaderProps): import("react").JSX.Element;
|
|
11
|
+
export {};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function PageHeader({ description, actions, children, }) {
|
|
3
|
+
return (_jsxs("div", { className: "space-y-6", children: [(description || actions) && (_jsxs("div", { className: "flex items-center justify-between gap-4", children: [description ? (_jsx("p", { className: "text-sm text-text-tertiary", children: description })) : (_jsx("div", {})), actions && _jsx("div", { className: "flex-shrink-0", children: actions })] })), children] }));
|
|
4
|
+
}
|
|
5
|
+
//# sourceMappingURL=PageHeader.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PageHeader.js","sourceRoot":"","sources":["../../src/components/PageHeader.tsx"],"names":[],"mappings":";AAWA,MAAM,UAAU,UAAU,CAAC,EACzB,WAAW,EACX,OAAO,EACP,QAAQ,GACQ;IAChB,OAAO,CACL,eAAK,SAAS,EAAC,WAAW,aACvB,CAAC,WAAW,IAAI,OAAO,CAAC,IAAI,CAC3B,eAAK,SAAS,EAAC,yCAAyC,aACrD,WAAW,CAAC,CAAC,CAAC,CACb,YAAG,SAAS,EAAC,4BAA4B,YAAE,WAAW,GAAK,CAC5D,CAAC,CAAC,CAAC,CACF,eAAO,CACR,EACA,OAAO,IAAI,cAAK,SAAS,EAAC,eAAe,YAAE,OAAO,GAAO,IACtD,CACP,EACA,QAAQ,IACL,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import type { Icon } from "@phosphor-icons/react";
|
|
3
|
+
interface PreviewModalProps {
|
|
4
|
+
isOpen: boolean;
|
|
5
|
+
onClose: () => void;
|
|
6
|
+
onInstall: () => void;
|
|
7
|
+
isInstalling?: boolean;
|
|
8
|
+
/** URL for icon image */
|
|
9
|
+
iconUrl?: string | null;
|
|
10
|
+
/** Phosphor fallback */
|
|
11
|
+
fallbackIcon: Icon;
|
|
12
|
+
/** Item title */
|
|
13
|
+
title: string;
|
|
14
|
+
/** Item description */
|
|
15
|
+
subtitle?: string;
|
|
16
|
+
/** Content body — rendered inside a bordered scrollable area */
|
|
17
|
+
children: ReactNode;
|
|
18
|
+
}
|
|
19
|
+
export declare function PreviewModal({ isOpen, onClose, onInstall, isInstalling, iconUrl, fallbackIcon: FallbackIcon, title, subtitle, children, }: PreviewModalProps): import("react").JSX.Element;
|
|
20
|
+
/** Renders skill/preset markdown content with basic formatting */
|
|
21
|
+
export declare function MarkdownContent({ content }: {
|
|
22
|
+
content: string;
|
|
23
|
+
}): import("react").JSX.Element;
|
|
24
|
+
export {};
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import {} from "react";
|
|
3
|
+
import { PlusIcon, XIcon } from "@phosphor-icons/react";
|
|
4
|
+
import { Button } from "./Button";
|
|
5
|
+
import { Modal } from "./Modal";
|
|
6
|
+
import { Avatar, iconFallback } from "./avatar";
|
|
7
|
+
export function PreviewModal({ isOpen, onClose, onInstall, isInstalling, iconUrl, fallbackIcon: FallbackIcon, title, subtitle, children, }) {
|
|
8
|
+
return (_jsxs(Modal, { isOpen: isOpen, onClose: onClose, size: "lg", children: [_jsxs("button", { type: "button", className: "absolute top-4 right-4 rounded-md text-text-tertiary hover:text-text-secondary focus:outline-none focus:ring-2 focus:ring-white/30 cursor-pointer", onClick: onClose, children: [_jsx("span", { className: "sr-only", children: "Close" }), _jsx(XIcon, { size: 20, "aria-hidden": "true" })] }), _jsx(Avatar, { src: iconUrl, size: "lg", rounded: "rounded-2xl", className: "h-14 w-14 mb-4", fallback: iconFallback(FallbackIcon) }), _jsx("h2", { className: "text-lg font-semibold text-text-primary", children: title }), subtitle && (_jsx("p", { className: "mt-1 text-sm text-text-tertiary", children: subtitle })), _jsx("div", { className: "mt-4", children: _jsx("div", { className: "rounded-lg border border-border-primary bg-surface-primary/50 max-h-80 overflow-y-auto p-4", children: children }) }), _jsx("div", { className: "mt-4 flex justify-end", children: _jsx(Button, { onClick: onInstall, isLoading: isInstalling, children: isInstalling ? ("Installing...") : (_jsxs(_Fragment, { children: [_jsx(PlusIcon, { size: 16, className: "mr-1.5" }), "Install"] })) }) })] }));
|
|
9
|
+
}
|
|
10
|
+
/** Renders skill/preset markdown content with basic formatting */
|
|
11
|
+
export function MarkdownContent({ content }) {
|
|
12
|
+
// Strip YAML frontmatter
|
|
13
|
+
const stripped = content.replace(/^---[\s\S]*?---\s*/, "");
|
|
14
|
+
return (_jsx("div", { className: "space-y-1.5 text-sm text-text-secondary", children: stripped.split("\n").map((line, i) => {
|
|
15
|
+
const lineKey = `${line.slice(0, 40)}-${i}`;
|
|
16
|
+
if (line.startsWith("# ")) {
|
|
17
|
+
return (_jsx("h2", { className: "text-base font-semibold text-text-primary mt-3 first:mt-0", children: formatInline(line.slice(2)) }, lineKey));
|
|
18
|
+
}
|
|
19
|
+
if (line.startsWith("## ")) {
|
|
20
|
+
return (_jsx("h3", { className: "font-semibold text-text-primary mt-3", children: formatInline(line.slice(3)) }, lineKey));
|
|
21
|
+
}
|
|
22
|
+
if (line.startsWith("### ")) {
|
|
23
|
+
return (_jsx("h4", { className: "font-medium text-text-primary mt-2", children: formatInline(line.slice(4)) }, lineKey));
|
|
24
|
+
}
|
|
25
|
+
if (/^\d+\.\s/.test(line)) {
|
|
26
|
+
return (_jsxs("div", { className: "flex gap-2 ml-2", children: [_jsxs("span", { className: "text-text-muted flex-shrink-0", children: [line.match(/^\d+/)?.[0], "."] }), _jsx("span", { children: formatInline(line.replace(/^\d+\.\s*/, "")) })] }, lineKey));
|
|
27
|
+
}
|
|
28
|
+
if (line.startsWith("- ")) {
|
|
29
|
+
return (_jsxs("div", { className: "flex gap-2 ml-2", children: [_jsx("span", { className: "text-text-muted flex-shrink-0", children: "\u2022" }), _jsx("span", { children: formatInline(line.slice(2)) })] }, lineKey));
|
|
30
|
+
}
|
|
31
|
+
if (line.trim() === "") {
|
|
32
|
+
return _jsx("div", { className: "h-1" }, lineKey);
|
|
33
|
+
}
|
|
34
|
+
return _jsx("p", { children: formatInline(line) }, lineKey);
|
|
35
|
+
}) }));
|
|
36
|
+
}
|
|
37
|
+
/** Formats inline markdown: **bold** and `code` */
|
|
38
|
+
function formatInline(text) {
|
|
39
|
+
const parts = [];
|
|
40
|
+
let remaining = text;
|
|
41
|
+
let key = 0;
|
|
42
|
+
while (remaining.length > 0) {
|
|
43
|
+
// Match **bold**
|
|
44
|
+
const boldMatch = remaining.match(/\*\*(.+?)\*\*/);
|
|
45
|
+
// Match `code`
|
|
46
|
+
const codeMatch = remaining.match(/`(.+?)`/);
|
|
47
|
+
// Find the earliest match
|
|
48
|
+
const boldIdx = boldMatch?.index ?? Infinity;
|
|
49
|
+
const codeIdx = codeMatch?.index ?? Infinity;
|
|
50
|
+
if (boldIdx === Infinity && codeIdx === Infinity) {
|
|
51
|
+
parts.push(remaining);
|
|
52
|
+
break;
|
|
53
|
+
}
|
|
54
|
+
if (boldIdx <= codeIdx && boldMatch) {
|
|
55
|
+
if (boldIdx > 0)
|
|
56
|
+
parts.push(remaining.slice(0, boldIdx));
|
|
57
|
+
parts.push(_jsx("strong", { className: "font-semibold text-text-primary", children: boldMatch[1] }, key++));
|
|
58
|
+
remaining = remaining.slice(boldIdx + boldMatch[0].length);
|
|
59
|
+
}
|
|
60
|
+
else if (codeMatch) {
|
|
61
|
+
if (codeIdx > 0)
|
|
62
|
+
parts.push(remaining.slice(0, codeIdx));
|
|
63
|
+
parts.push(_jsx("code", { className: "bg-surface-tertiary text-text-secondary px-1 py-0.5 rounded text-xs font-mono", children: codeMatch[1] }, key++));
|
|
64
|
+
remaining = remaining.slice(codeIdx + codeMatch[0].length);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return parts.length === 1 && typeof parts[0] === "string" ? parts[0] : parts;
|
|
68
|
+
}
|
|
69
|
+
//# sourceMappingURL=PreviewModal.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"PreviewModal.js","sourceRoot":"","sources":["../../src/components/PreviewModal.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
export function ProgressBar({ value, max, label, size = "md", }) {
|
|
3
|
+
const percentage = max > 0 ? Math.min((value / max) * 100, 100) : 0;
|
|
4
|
+
const colorClass = percentage >= 90
|
|
5
|
+
? "bg-danger"
|
|
6
|
+
: percentage >= 70
|
|
7
|
+
? "bg-warning"
|
|
8
|
+
: "bg-success-muted";
|
|
9
|
+
const height = size === "sm" ? "h-1.5" : "h-2.5";
|
|
10
|
+
return (_jsxs("div", { children: [label && (_jsxs("div", { className: "flex items-center justify-between text-sm mb-1", children: [_jsx("span", { className: "text-text-tertiary", children: label }), _jsxs("span", { className: "font-medium text-text-primary", children: [value.toLocaleString(), " / ", max.toLocaleString()] })] })), _jsx("div", { className: `${height} bg-surface-tertiary rounded-full overflow-hidden`, children: _jsx("div", { className: `h-full ${colorClass} rounded-full transition-all duration-300`, style: { width: `${percentage}%` } }) })] }));
|
|
11
|
+
}
|
|
12
|
+
//# sourceMappingURL=ProgressBar.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProgressBar.js","sourceRoot":"","sources":["../../src/components/ProgressBar.tsx"],"names":[],"mappings":";AAOA,MAAM,UAAU,WAAW,CAAC,EAC1B,KAAK,EACL,GAAG,EACH,KAAK,EACL,IAAI,GAAG,IAAI,GACM;IACjB,MAAM,UAAU,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,KAAK,GAAG,GAAG,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IAEpE,MAAM,UAAU,GACd,UAAU,IAAI,EAAE;QACd,CAAC,CAAC,WAAW;QACb,CAAC,CAAC,UAAU,IAAI,EAAE;YAChB,CAAC,CAAC,YAAY;YACd,CAAC,CAAC,kBAAkB,CAAC;IAE3B,MAAM,MAAM,GAAG,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC;IAEjD,OAAO,CACL,0BACG,KAAK,IAAI,CACR,eAAK,SAAS,EAAC,gDAAgD,aAC7D,eAAM,SAAS,EAAC,oBAAoB,YAAE,KAAK,GAAQ,EACnD,gBAAM,SAAS,EAAC,+BAA+B,aAC5C,KAAK,CAAC,cAAc,EAAE,SAAK,GAAG,CAAC,cAAc,EAAE,IAC3C,IACH,CACP,EACD,cACE,SAAS,EAAE,GAAG,MAAM,mDAAmD,YAEvE,cACE,SAAS,EAAE,UAAU,UAAU,2CAA2C,EAC1E,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,UAAU,GAAG,EAAE,GAClC,GACE,IACF,CACP,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
|
|
2
|
+
const SLUG_MAP = {
|
|
3
|
+
xai: "grok",
|
|
4
|
+
azure_openai: "azure",
|
|
5
|
+
z_ai: "zai",
|
|
6
|
+
z_ai_coding: "zai",
|
|
7
|
+
moonshot_coding: "moonshot",
|
|
8
|
+
};
|
|
9
|
+
function WrenchFallback({ size }) {
|
|
10
|
+
return (_jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", children: [_jsx("rect", { width: "24", height: "24", rx: "6", fill: "#27272a" }), _jsx("path", { d: "M14.7 6.3a1 1 0 00-1.4 0l-6 6a1 1 0 000 1.4l2 2a1 1 0 001.4 0l6-6a1 1 0 000-1.4l-2-2zM7 17h10", stroke: "#71717a", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round" })] }));
|
|
11
|
+
}
|
|
12
|
+
export function ProviderIcon({ provider, size = 24, className, }) {
|
|
13
|
+
const slug = SLUG_MAP[provider] ?? provider;
|
|
14
|
+
if (slug === "custom") {
|
|
15
|
+
return (_jsx("span", { className: className, children: _jsx(WrenchFallback, { size: size }) }));
|
|
16
|
+
}
|
|
17
|
+
// Padding inside the rounded square for the icon
|
|
18
|
+
const padding = Math.round(size * 0.15);
|
|
19
|
+
const iconSize = size - padding * 2;
|
|
20
|
+
return (_jsx("span", { className: className, style: {
|
|
21
|
+
display: "inline-flex",
|
|
22
|
+
alignItems: "center",
|
|
23
|
+
justifyContent: "center",
|
|
24
|
+
width: size,
|
|
25
|
+
height: size,
|
|
26
|
+
borderRadius: size * 0.25,
|
|
27
|
+
backgroundColor: "#f4f4f5",
|
|
28
|
+
flexShrink: 0,
|
|
29
|
+
}, children: _jsx("img", { src: `/icons/providers/${slug}.svg`, alt: provider, width: iconSize, height: iconSize, onError: (e) => {
|
|
30
|
+
const el = e.target;
|
|
31
|
+
el.style.display = "none";
|
|
32
|
+
} }) }));
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=ProviderIcon.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ProviderIcon.js","sourceRoot":"","sources":["../../src/components/ProviderIcon.tsx"],"names":[],"mappings":";AAMA,MAAM,QAAQ,GAA2B;IACvC,GAAG,EAAE,MAAM;IACX,YAAY,EAAE,OAAO;IACrB,IAAI,EAAE,KAAK;IACX,WAAW,EAAE,KAAK;IAClB,eAAe,EAAE,UAAU;CAC5B,CAAC;AAEF,SAAS,cAAc,CAAC,EAAE,IAAI,EAAoB;IAChD,OAAO,CACL,eAAK,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,EAAC,WAAW,EAAC,IAAI,EAAC,MAAM,aAC7D,eAAM,KAAK,EAAC,IAAI,EAAC,MAAM,EAAC,IAAI,EAAC,EAAE,EAAC,GAAG,EAAC,IAAI,EAAC,SAAS,GAAG,EACrD,eACE,CAAC,EAAC,+FAA+F,EACjG,MAAM,EAAC,SAAS,EAChB,WAAW,EAAC,KAAK,EACjB,aAAa,EAAC,OAAO,EACrB,cAAc,EAAC,OAAO,GACtB,IACE,CACP,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,EAC3B,QAAQ,EACR,IAAI,GAAG,EAAE,EACT,SAAS,GACS;IAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC;IAE5C,IAAI,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtB,OAAO,CACL,eAAM,SAAS,EAAE,SAAS,YACxB,KAAC,cAAc,IAAC,IAAI,EAAE,IAAI,GAAI,GACzB,CACR,CAAC;IACJ,CAAC;IAED,iDAAiD;IACjD,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACxC,MAAM,QAAQ,GAAG,IAAI,GAAG,OAAO,GAAG,CAAC,CAAC;IAEpC,OAAO,CACL,eACE,SAAS,EAAE,SAAS,EACpB,KAAK,EAAE;YACL,OAAO,EAAE,aAAa;YACtB,UAAU,EAAE,QAAQ;YACpB,cAAc,EAAE,QAAQ;YACxB,KAAK,EAAE,IAAI;YACX,MAAM,EAAE,IAAI;YACZ,YAAY,EAAE,IAAI,GAAG,IAAI;YACzB,eAAe,EAAE,SAAS;YAC1B,UAAU,EAAE,CAAC;SACd,YAED,cACE,GAAG,EAAE,oBAAoB,IAAI,MAAM,EACnC,GAAG,EAAE,QAAQ,EACb,KAAK,EAAE,QAAQ,EACf,MAAM,EAAE,QAAQ,EAChB,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;gBACb,MAAM,EAAE,GAAG,CAAC,CAAC,MAA0B,CAAC;gBACxC,EAAE,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;YAC5B,CAAC,GACD,GACG,CACR,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ResizeHandle — the draggable divider between two layout panes.
|
|
3
|
+
*
|
|
4
|
+
* Renders a ZERO-WIDTH anchor plus a wider grab strip centred on it, so the
|
|
5
|
+
* handle costs no layout space and the parent can place it either as a
|
|
6
|
+
* zero-basis flex item (a chat ↔ console divider) or absolutely at a CSS
|
|
7
|
+
* variable (a sidebar ↔ card divider) with the same markup.
|
|
8
|
+
*
|
|
9
|
+
* The drag itself never goes through React: the parent mirrors each pointer
|
|
10
|
+
* position straight onto a CSS custom property and commits the final value to
|
|
11
|
+
* the (persisted) store on release. Pointer capture keeps the gesture alive
|
|
12
|
+
* over the panes and past the window edge.
|
|
13
|
+
*
|
|
14
|
+
* Keyboard: it is an ARIA window splitter — focusable, with arrow keys
|
|
15
|
+
* nudging by ``NUDGE_STEP`` and Home/End driving the splitter to its
|
|
16
|
+
* left/right extreme. Both are axis-relative like the arrows, so on a
|
|
17
|
+
* right-hand pane Home maximises and End minimises.
|
|
18
|
+
* Double-click (or Enter) restores the default.
|
|
19
|
+
*/
|
|
20
|
+
/** Arrow-key increment, in px. */
|
|
21
|
+
export declare const NUDGE_STEP = 16;
|
|
22
|
+
export interface ResizeHandleProps {
|
|
23
|
+
/** Positions the zero-width anchor. The grab strip centres on it. */
|
|
24
|
+
className?: string;
|
|
25
|
+
/** Accessible name, e.g. "Resize sidebar". */
|
|
26
|
+
label: string;
|
|
27
|
+
/** Pane the separator resizes — observed to report its width to AT. */
|
|
28
|
+
target: React.RefObject<HTMLElement | null>;
|
|
29
|
+
/** Which side of the divider contains the target pane. Keyboard deltas use the pane's width direction so `aria-valuenow` and the on-screen motion agree. */
|
|
30
|
+
side?: "left" | "right";
|
|
31
|
+
min: number;
|
|
32
|
+
max: number;
|
|
33
|
+
/** Pointer went down at `clientX`. */
|
|
34
|
+
onResizeStart: (clientX: number) => void;
|
|
35
|
+
/** Pointer moved to `clientX`. */
|
|
36
|
+
onResize: (clientX: number) => void;
|
|
37
|
+
/** Pointer released (or the gesture was cancelled). */
|
|
38
|
+
onResizeEnd: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* Arrow key pressed: `dx` px along the x axis, signed like the arrow —
|
|
41
|
+
* always the divider's physical direction, never the pane's width.
|
|
42
|
+
* The parent maps it to a width (subtracting it for a right-hand pane)
|
|
43
|
+
* and clamps the result to `[min, max]`; `Home`/`End` send a full-range
|
|
44
|
+
* delta and rely on that clamp to land on the bound.
|
|
45
|
+
*/
|
|
46
|
+
onNudge: (dx: number) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Restore the pane's default width. On a double-press this is fired
|
|
49
|
+
* after `onResizeEnd`, so the reset follows a zero-length resize
|
|
50
|
+
* cycle; the `Enter` shortcut fires it on its own.
|
|
51
|
+
*/
|
|
52
|
+
onReset: () => void;
|
|
53
|
+
/** Optional localized tooltip. */
|
|
54
|
+
title?: string;
|
|
55
|
+
}
|
|
56
|
+
export declare function ResizeHandle({ className, label, target, min, max, onResizeStart, onResize, onResizeEnd, onNudge, onReset, side, title, }: ResizeHandleProps): import("react").JSX.Element;
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import { jsx as _jsx } from "react/jsx-runtime";
|
|
2
|
+
/**
|
|
3
|
+
* ResizeHandle — the draggable divider between two layout panes.
|
|
4
|
+
*
|
|
5
|
+
* Renders a ZERO-WIDTH anchor plus a wider grab strip centred on it, so the
|
|
6
|
+
* handle costs no layout space and the parent can place it either as a
|
|
7
|
+
* zero-basis flex item (a chat ↔ console divider) or absolutely at a CSS
|
|
8
|
+
* variable (a sidebar ↔ card divider) with the same markup.
|
|
9
|
+
*
|
|
10
|
+
* The drag itself never goes through React: the parent mirrors each pointer
|
|
11
|
+
* position straight onto a CSS custom property and commits the final value to
|
|
12
|
+
* the (persisted) store on release. Pointer capture keeps the gesture alive
|
|
13
|
+
* over the panes and past the window edge.
|
|
14
|
+
*
|
|
15
|
+
* Keyboard: it is an ARIA window splitter — focusable, with arrow keys
|
|
16
|
+
* nudging by ``NUDGE_STEP`` and Home/End driving the splitter to its
|
|
17
|
+
* left/right extreme. Both are axis-relative like the arrows, so on a
|
|
18
|
+
* right-hand pane Home maximises and End minimises.
|
|
19
|
+
* Double-click (or Enter) restores the default.
|
|
20
|
+
*/
|
|
21
|
+
import { useEffect, useRef, useState } from "react";
|
|
22
|
+
import { cn } from "../lib/utils";
|
|
23
|
+
/** Arrow-key increment, in px. */
|
|
24
|
+
export const NUDGE_STEP = 16;
|
|
25
|
+
/**
|
|
26
|
+
* Window within which a second press counts as a double-press, in ms.
|
|
27
|
+
*
|
|
28
|
+
* Reset cannot use `onDoubleClick`: the handle calls `preventDefault()` on
|
|
29
|
+
* pointerdown (so a drag never turns into a text selection), and that also
|
|
30
|
+
* suppresses the compatibility mouse events a `dblclick` is synthesised from.
|
|
31
|
+
* So the pair is timed here instead. Matches the platform default.
|
|
32
|
+
*/
|
|
33
|
+
const DOUBLE_PRESS_MS = 400;
|
|
34
|
+
/** Movement past this (px) makes a press a drag, so it can't pair as a double-press. */
|
|
35
|
+
const DRAG_SLOP_PX = 4;
|
|
36
|
+
export function ResizeHandle({ className, label, target, min, max, onResizeStart, onResize, onResizeEnd, onNudge, onReset, side = "left", title = "Drag to resize · double-click to reset", }) {
|
|
37
|
+
const dragging = useRef(false);
|
|
38
|
+
const dragged = useRef(false);
|
|
39
|
+
const pressOrigin = useRef(null);
|
|
40
|
+
const lastPressX = useRef(null);
|
|
41
|
+
const pendingReset = useRef(false);
|
|
42
|
+
const activePointerId = useRef(null);
|
|
43
|
+
const lastPressAt = useRef(null);
|
|
44
|
+
// Reported as aria-valuenow. Measured rather than passed down because the
|
|
45
|
+
// pane's real width is a CSS clamp() the browser re-evaluates on every
|
|
46
|
+
// window resize — the store's number is only the user's *request*.
|
|
47
|
+
const [width, setWidth] = useState(null);
|
|
48
|
+
useEffect(() => {
|
|
49
|
+
const el = target.current;
|
|
50
|
+
if (!el || typeof ResizeObserver === "undefined")
|
|
51
|
+
return;
|
|
52
|
+
const observer = new ResizeObserver(() => {
|
|
53
|
+
const next = Math.round(el.getBoundingClientRect().width);
|
|
54
|
+
setWidth((prev) => (prev === next ? prev : next));
|
|
55
|
+
});
|
|
56
|
+
observer.observe(el);
|
|
57
|
+
return () => observer.disconnect();
|
|
58
|
+
}, [target]);
|
|
59
|
+
const endDrag = () => {
|
|
60
|
+
if (!dragging.current)
|
|
61
|
+
return;
|
|
62
|
+
dragging.current = false;
|
|
63
|
+
activePointerId.current = null;
|
|
64
|
+
const wasReset = pendingReset.current;
|
|
65
|
+
pendingReset.current = false;
|
|
66
|
+
onResizeEnd();
|
|
67
|
+
// Defer the reset until the second press of a double-press actually
|
|
68
|
+
// releases within the drag slop — otherwise starting a drag inside the
|
|
69
|
+
// 400 ms window jumps the pane to its default instead of running the
|
|
70
|
+
// intended gesture.
|
|
71
|
+
if (wasReset && !dragged.current)
|
|
72
|
+
onReset();
|
|
73
|
+
};
|
|
74
|
+
const cancelPress = () => {
|
|
75
|
+
lastPressAt.current = null;
|
|
76
|
+
dragged.current = false;
|
|
77
|
+
pressOrigin.current = null;
|
|
78
|
+
lastPressX.current = null;
|
|
79
|
+
pendingReset.current = false;
|
|
80
|
+
};
|
|
81
|
+
// A pane can vanish mid-gesture — Esc closes the console, ⌘B collapses the
|
|
82
|
+
// sidebar — and it takes this handle, and the pointerup that would have
|
|
83
|
+
// ended the drag, with it. Without this the shell would stay "resizing"
|
|
84
|
+
// forever: layout transitions off, drag override never dropped. Kept in a
|
|
85
|
+
// ref so the unmount cleanup doesn't also fire whenever the prop changes.
|
|
86
|
+
const endDragRef = useRef(endDrag);
|
|
87
|
+
useEffect(() => {
|
|
88
|
+
endDragRef.current = endDrag;
|
|
89
|
+
});
|
|
90
|
+
useEffect(() => () => {
|
|
91
|
+
// cancelPress is safe to close over: it touches only refs. If it ever
|
|
92
|
+
// reads a prop, mirror it the way endDrag is mirrored above.
|
|
93
|
+
cancelPress();
|
|
94
|
+
endDragRef.current();
|
|
95
|
+
}, []);
|
|
96
|
+
return (_jsx("div", { className: cn("relative", className), children: _jsx("div", { role: "separator", "aria-orientation": "vertical", "aria-label": label, "aria-valuenow": width ?? undefined, "aria-valuemin": min, "aria-valuemax": max, tabIndex: 0, title: title, onPointerDown: (e) => {
|
|
97
|
+
// Secondary buttons open context menus; let them through.
|
|
98
|
+
if (e.button !== 0)
|
|
99
|
+
return;
|
|
100
|
+
if (dragging.current)
|
|
101
|
+
return;
|
|
102
|
+
e.preventDefault();
|
|
103
|
+
// preventDefault also swallows the focus a click would give, and
|
|
104
|
+
// the keyboard resize is only reachable once this has focus.
|
|
105
|
+
e.currentTarget.focus();
|
|
106
|
+
const previous = lastPressAt.current;
|
|
107
|
+
const previousDragged = dragged.current;
|
|
108
|
+
lastPressAt.current = e.timeStamp;
|
|
109
|
+
pressOrigin.current = e.clientX;
|
|
110
|
+
dragged.current = false;
|
|
111
|
+
const isDoublePress = previous !== null &&
|
|
112
|
+
lastPressX.current !== null &&
|
|
113
|
+
Math.abs(e.clientX - lastPressX.current) <= DRAG_SLOP_PX &&
|
|
114
|
+
!previousDragged &&
|
|
115
|
+
e.timeStamp - previous < DOUBLE_PRESS_MS;
|
|
116
|
+
pendingReset.current = isDoublePress;
|
|
117
|
+
lastPressX.current = e.clientX;
|
|
118
|
+
if (isDoublePress) {
|
|
119
|
+
lastPressAt.current = null;
|
|
120
|
+
}
|
|
121
|
+
e.currentTarget.setPointerCapture(e.pointerId);
|
|
122
|
+
activePointerId.current = e.pointerId;
|
|
123
|
+
dragging.current = true;
|
|
124
|
+
onResizeStart(e.clientX);
|
|
125
|
+
}, onPointerMove: (e) => {
|
|
126
|
+
if (dragging.current && e.pointerId === activePointerId.current) {
|
|
127
|
+
if (pressOrigin.current !== null &&
|
|
128
|
+
Math.abs(e.clientX - pressOrigin.current) > DRAG_SLOP_PX) {
|
|
129
|
+
dragged.current = true;
|
|
130
|
+
pendingReset.current = false;
|
|
131
|
+
}
|
|
132
|
+
onResize(e.clientX);
|
|
133
|
+
}
|
|
134
|
+
}, onPointerUp: (e) => {
|
|
135
|
+
if (e.pointerId === activePointerId.current)
|
|
136
|
+
endDrag();
|
|
137
|
+
}, onPointerCancel: (e) => {
|
|
138
|
+
if (e.pointerId === activePointerId.current) {
|
|
139
|
+
cancelPress();
|
|
140
|
+
endDrag();
|
|
141
|
+
}
|
|
142
|
+
}, onLostPointerCapture: (e) => {
|
|
143
|
+
if (e.pointerId === activePointerId.current) {
|
|
144
|
+
cancelPress();
|
|
145
|
+
endDrag();
|
|
146
|
+
}
|
|
147
|
+
}, onKeyDown: (e) => {
|
|
148
|
+
if (e.key === "ArrowLeft")
|
|
149
|
+
onNudge(-NUDGE_STEP);
|
|
150
|
+
else if (e.key === "ArrowRight")
|
|
151
|
+
onNudge(NUDGE_STEP);
|
|
152
|
+
else if (e.key === "Home")
|
|
153
|
+
onNudge(side === "left" ? -(max - min) : max - min);
|
|
154
|
+
else if (e.key === "End")
|
|
155
|
+
onNudge(side === "left" ? max - min : -(max - min));
|
|
156
|
+
else if (e.key === "Enter")
|
|
157
|
+
onReset();
|
|
158
|
+
else
|
|
159
|
+
return;
|
|
160
|
+
e.preventDefault();
|
|
161
|
+
}, className: cn("group absolute inset-y-0 left-1/2 z-20 w-2.5 -translate-x-1/2",
|
|
162
|
+
// touch-none: the browser must not claim the gesture as a scroll
|
|
163
|
+
// before the pointermove handlers see it.
|
|
164
|
+
"cursor-col-resize touch-none focus:outline-none"), children: _jsx("span", { "aria-hidden": true, className: "pointer-events-none absolute inset-y-0 left-1/2 w-0.5 -translate-x-1/2 rounded-full bg-accent opacity-0 transition-opacity duration-150 group-hover:opacity-60 group-focus-visible:opacity-100 group-active:opacity-100" }) }) }));
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=ResizeHandle.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ResizeHandle.js","sourceRoot":"","sources":["../../src/components/ResizeHandle.tsx"],"names":[],"mappings":"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"}
|