@astralform/ui 0.0.0-stage → 0.3.6

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.
Files changed (139) hide show
  1. package/DESIGN.md +243 -0
  2. package/LICENSE +21 -0
  3. package/README.md +128 -2
  4. package/dist/components/Alert.d.ts +7 -0
  5. package/dist/components/Alert.js +40 -0
  6. package/dist/components/Alert.js.map +1 -0
  7. package/dist/components/AvatarEditor.d.ts +13 -0
  8. package/dist/components/AvatarEditor.js +44 -0
  9. package/dist/components/AvatarEditor.js.map +1 -0
  10. package/dist/components/Badge.d.ts +16 -0
  11. package/dist/components/Badge.js +38 -0
  12. package/dist/components/Badge.js.map +1 -0
  13. package/dist/components/Button.d.ts +8 -0
  14. package/dist/components/Button.js +21 -0
  15. package/dist/components/Button.js.map +1 -0
  16. package/dist/components/Card.d.ts +10 -0
  17. package/dist/components/Card.js +22 -0
  18. package/dist/components/Card.js.map +1 -0
  19. package/dist/components/CompactResourceRow.d.ts +34 -0
  20. package/dist/components/CompactResourceRow.js +11 -0
  21. package/dist/components/CompactResourceRow.js.map +1 -0
  22. package/dist/components/ConfirmDialog.d.ts +12 -0
  23. package/dist/components/ConfirmDialog.js +7 -0
  24. package/dist/components/ConfirmDialog.js.map +1 -0
  25. package/dist/components/CookieConsent.d.ts +1 -0
  26. package/dist/components/CookieConsent.js +42 -0
  27. package/dist/components/CookieConsent.js.map +1 -0
  28. package/dist/components/DataTable.d.ts +53 -0
  29. package/dist/components/DataTable.js +79 -0
  30. package/dist/components/DataTable.js.map +1 -0
  31. package/dist/components/DevTools.d.ts +6 -0
  32. package/dist/components/DevTools.js +59 -0
  33. package/dist/components/DevTools.js.map +1 -0
  34. package/dist/components/EmptyState.d.ts +11 -0
  35. package/dist/components/EmptyState.js +6 -0
  36. package/dist/components/EmptyState.js.map +1 -0
  37. package/dist/components/ImageCropModal.d.ts +18 -0
  38. package/dist/components/ImageCropModal.js +67 -0
  39. package/dist/components/ImageCropModal.js.map +1 -0
  40. package/dist/components/InlineBanner.d.ts +20 -0
  41. package/dist/components/InlineBanner.js +53 -0
  42. package/dist/components/InlineBanner.js.map +1 -0
  43. package/dist/components/Input.d.ts +8 -0
  44. package/dist/components/Input.js +10 -0
  45. package/dist/components/Input.js.map +1 -0
  46. package/dist/components/InventoryCard.d.ts +20 -0
  47. package/dist/components/InventoryCard.js +22 -0
  48. package/dist/components/InventoryCard.js.map +1 -0
  49. package/dist/components/LoadingSpinner.d.ts +26 -0
  50. package/dist/components/LoadingSpinner.js +32 -0
  51. package/dist/components/LoadingSpinner.js.map +1 -0
  52. package/dist/components/Modal.d.ts +10 -0
  53. package/dist/components/Modal.js +38 -0
  54. package/dist/components/Modal.js.map +1 -0
  55. package/dist/components/PageHeader.d.ts +11 -0
  56. package/dist/components/PageHeader.js +5 -0
  57. package/dist/components/PageHeader.js.map +1 -0
  58. package/dist/components/PreviewModal.d.ts +24 -0
  59. package/dist/components/PreviewModal.js +69 -0
  60. package/dist/components/PreviewModal.js.map +1 -0
  61. package/dist/components/ProgressBar.d.ts +8 -0
  62. package/dist/components/ProgressBar.js +12 -0
  63. package/dist/components/ProgressBar.js.map +1 -0
  64. package/dist/components/ProviderIcon.d.ts +7 -0
  65. package/dist/components/ProviderIcon.js +34 -0
  66. package/dist/components/ProviderIcon.js.map +1 -0
  67. package/dist/components/ResizeHandle.d.ts +56 -0
  68. package/dist/components/ResizeHandle.js +166 -0
  69. package/dist/components/ResizeHandle.js.map +1 -0
  70. package/dist/components/SegmentedProgressBar.d.ts +9 -0
  71. package/dist/components/SegmentedProgressBar.js +23 -0
  72. package/dist/components/SegmentedProgressBar.js.map +1 -0
  73. package/dist/components/Select.d.ts +13 -0
  74. package/dist/components/Select.js +14 -0
  75. package/dist/components/Select.js.map +1 -0
  76. package/dist/components/SpotlightButton.d.ts +10 -0
  77. package/dist/components/SpotlightButton.js +51 -0
  78. package/dist/components/SpotlightButton.js.map +1 -0
  79. package/dist/components/StatCard.d.ts +9 -0
  80. package/dist/components/StatCard.js +8 -0
  81. package/dist/components/StatCard.js.map +1 -0
  82. package/dist/components/StatusBadge.d.ts +4 -0
  83. package/dist/components/StatusBadge.js +10 -0
  84. package/dist/components/StatusBadge.js.map +1 -0
  85. package/dist/components/TabNav.d.ts +39 -0
  86. package/dist/components/TabNav.js +25 -0
  87. package/dist/components/TabNav.js.map +1 -0
  88. package/dist/components/TableShell.d.ts +21 -0
  89. package/dist/components/TableShell.js +19 -0
  90. package/dist/components/TableShell.js.map +1 -0
  91. package/dist/components/Textarea.d.ts +7 -0
  92. package/dist/components/Textarea.js +10 -0
  93. package/dist/components/Textarea.js.map +1 -0
  94. package/dist/components/Toggle.d.ts +16 -0
  95. package/dist/components/Toggle.js +25 -0
  96. package/dist/components/Toggle.js.map +1 -0
  97. package/dist/components/Toolbar.d.ts +34 -0
  98. package/dist/components/Toolbar.js +30 -0
  99. package/dist/components/Toolbar.js.map +1 -0
  100. package/dist/components/TypeToConfirmModal.d.ts +15 -0
  101. package/dist/components/TypeToConfirmModal.js +14 -0
  102. package/dist/components/TypeToConfirmModal.js.map +1 -0
  103. package/dist/components/UnsavedChangesModal.d.ts +7 -0
  104. package/dist/components/UnsavedChangesModal.js +7 -0
  105. package/dist/components/UnsavedChangesModal.js.map +1 -0
  106. package/dist/components/UsageCard.d.ts +11 -0
  107. package/dist/components/UsageCard.js +9 -0
  108. package/dist/components/UsageCard.js.map +1 -0
  109. package/dist/components/avatar.d.ts +79 -0
  110. package/dist/components/avatar.js +88 -0
  111. package/dist/components/avatar.js.map +1 -0
  112. package/dist/components/badge-config.d.ts +16 -0
  113. package/dist/components/badge-config.js +48 -0
  114. package/dist/components/badge-config.js.map +1 -0
  115. package/dist/components/glowing-effect.d.ts +14 -0
  116. package/dist/components/glowing-effect.js +108 -0
  117. package/dist/components/glowing-effect.js.map +1 -0
  118. package/dist/index.d.ts +39 -0
  119. package/dist/index.js +42 -0
  120. package/dist/index.js.map +1 -0
  121. package/dist/lib/cookies.d.ts +36 -0
  122. package/dist/lib/cookies.js +78 -0
  123. package/dist/lib/cookies.js.map +1 -0
  124. package/dist/lib/environment.d.ts +24 -0
  125. package/dist/lib/environment.js +52 -0
  126. package/dist/lib/environment.js.map +1 -0
  127. package/dist/lib/utils.d.ts +4 -0
  128. package/dist/lib/utils.js +8 -0
  129. package/dist/lib/utils.js.map +1 -0
  130. package/dist/types.d.ts +12 -0
  131. package/dist/types.js +12 -0
  132. package/dist/types.js.map +1 -0
  133. package/package.json +89 -4
  134. package/src/styles/base.css +779 -0
  135. package/src/styles/fonts.css +25 -0
  136. package/src/styles/theme-default.css +164 -0
  137. package/src/styles/tokens/_foundations.css +28 -0
  138. package/src/styles/tokens/_semantics.css +72 -0
  139. 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,8 @@
1
+ interface ProgressBarProps {
2
+ value: number;
3
+ max: number;
4
+ label?: string;
5
+ size?: "sm" | "md";
6
+ }
7
+ export declare function ProgressBar({ value, max, label, size, }: ProgressBarProps): import("react").JSX.Element;
8
+ export {};
@@ -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,7 @@
1
+ interface ProviderIconProps {
2
+ provider: string;
3
+ size?: number;
4
+ className?: string;
5
+ }
6
+ export declare function ProviderIcon({ provider, size, className, }: ProviderIconProps): import("react").JSX.Element;
7
+ export {};
@@ -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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"}