@agimon-ai/doompi-web-components 0.0.1-alpha.44 → 0.0.1-alpha.45
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/dist/src/components/Breadcrumb.cjs +1 -1
- package/dist/src/components/Breadcrumb.cjs.map +1 -1
- package/dist/src/components/Breadcrumb.d.mts +1 -1
- package/dist/src/components/Breadcrumb.d.mts.map +1 -1
- package/dist/src/components/Breadcrumb.mjs +1 -1
- package/dist/src/components/Breadcrumb.mjs.map +1 -1
- package/dist/src/components/Button.cjs +1 -1
- package/dist/src/components/Button.cjs.map +1 -1
- package/dist/src/components/Button.mjs +1 -1
- package/dist/src/components/Button.mjs.map +1 -1
- package/dist/src/components/EmptyState.cjs +1 -1
- package/dist/src/components/EmptyState.cjs.map +1 -1
- package/dist/src/components/EmptyState.mjs +1 -1
- package/dist/src/components/EmptyState.mjs.map +1 -1
- package/dist/src/components/Input.cjs +1 -1
- package/dist/src/components/Input.cjs.map +1 -1
- package/dist/src/components/Input.mjs +1 -1
- package/dist/src/components/Input.mjs.map +1 -1
- package/dist/src/components/MessageItem.cjs +1 -1
- package/dist/src/components/MessageItem.cjs.map +1 -1
- package/dist/src/components/MessageItem.mjs +1 -1
- package/dist/src/components/MessageItem.mjs.map +1 -1
- package/dist/src/components/Sheet.cjs +1 -1
- package/dist/src/components/Sheet.cjs.map +1 -1
- package/dist/src/components/Sheet.d.mts.map +1 -1
- package/dist/src/components/Sheet.mjs +1 -1
- package/dist/src/components/Sheet.mjs.map +1 -1
- package/dist/src/components/Tabs.cjs +1 -1
- package/dist/src/components/Tabs.cjs.map +1 -1
- package/dist/src/components/Tabs.mjs +1 -1
- package/dist/src/components/Tabs.mjs.map +1 -1
- package/dist/src/components/TerminalView.cjs +1 -1
- package/dist/src/components/TerminalView.cjs.map +1 -1
- package/dist/src/components/TerminalView.mjs +1 -1
- package/dist/src/components/TerminalView.mjs.map +1 -1
- package/dist/src/components/Toast.cjs +1 -1
- package/dist/src/components/Toast.cjs.map +1 -1
- package/dist/src/components/Toast.mjs +1 -1
- package/dist/src/components/Toast.mjs.map +1 -1
- package/dist/src/components/ToolPathLink.cjs +1 -1
- package/dist/src/components/ToolPathLink.cjs.map +1 -1
- package/dist/src/components/ToolPathLink.mjs +1 -1
- package/dist/src/components/ToolPathLink.mjs.map +1 -1
- package/dist/themes/doom-nord-dark.cjs +1 -1
- package/dist/themes/doom-nord-dark.mjs +1 -1
- package/dist/themes/doom-one-dark.cjs +1 -1
- package/dist/themes/doom-one-dark.mjs +1 -1
- package/dist/themes/doom-one-light.cjs +1 -1
- package/dist/themes/doom-one-light.mjs +1 -1
- package/package.json +3 -3
- package/styles/tokens.css +1 -1
- package/themes/doom-nord-dark.json +1 -1
- package/themes/doom-one-dark.json +1 -1
- package/themes/doom-one-light.json +2 -2
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../lib/cn.cjs"),t=require("./Tooltip.cjs");let n=require("react/jsx-runtime");function r(e,t=4){let n=e.split(`/`).filter(e=>e!==``);
|
|
1
|
+
const e=require("../lib/cn.cjs"),t=require("./Tooltip.cjs");let n=require("react/jsx-runtime");function r(e,t=4){let n=e.split(`/`).filter(e=>e!==``);if(n.length===0)return[e];let r=Math.max(3,t);return n.length<=r?n:[n[0]??``,`…`,...n.slice(n.length-(r-2))]}function i({path:i,keep:a,className:o,"data-testid":s}){let c=r(i,a),l=c.length-1;return/* @__PURE__ */ (0,n.jsx)(t.TooltipProvider,{children:/* @__PURE__ */ (0,n.jsxs)(t.Tooltip,{children:[/* @__PURE__ */ (0,n.jsx)(t.TooltipTrigger,{asChild:!0,children:/* @__PURE__ */ (0,n.jsx)(`span`,{"data-slot":`breadcrumb`,"data-testid":s,title:void 0,className:e.cn(`flex min-w-0 items-baseline gap-1 truncate font-mono text-sm`,o),children:c.map((e,t)=>/* @__PURE__ */ (0,n.jsxs)(`span`,{className:`flex min-w-0 items-baseline gap-1`,children:[t>0?/* @__PURE__ */ (0,n.jsx)(`span`,{className:`shrink-0 text-doom-faint`,children:`/`}):null,/* @__PURE__ */ (0,n.jsx)(`span`,{className:t===l?`truncate font-bold text-doom-hi`:`min-w-0 truncate text-doom-faint`,children:e})]},`${e}-${String(t)}`))})}),/* @__PURE__ */ (0,n.jsx)(t.TooltipContent,{className:`max-w-[32rem] break-all whitespace-normal`,children:i})]})})}exports.BREADCRUMB_ELLIPSIS=`…`,exports.Breadcrumb=i,exports.breadcrumbSegments=r;
|
|
2
2
|
//# sourceMappingURL=Breadcrumb.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumb.cjs","names":["TooltipProvider","Tooltip","TooltipTrigger","cn","TooltipContent"],"sources":["../../../src/components/Breadcrumb.tsx"],"sourcesContent":["import { cn } from '../lib/cn';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './Tooltip';\n\n/** The marker a collapsed run of segments is shown as. */\nexport const BREADCRUMB_ELLIPSIS = '…';\n\n/**\n * A path as breadcrumb segments, with the middle collapsed when it is deeper\n * than `keep` allows.\n *\n * The first segment and the last few are what place a leaf; the ones between\n * are what a reader skims past, so those are the ones that go. The leaf is\n * always the final segment and is never collapsed.\n */\nexport function breadcrumbSegments(path: string, keep = 4): string[] {\n const segments = path.split('/').filter((segment) => segment !== '');\n if (segments.length === 0) return [path];\n if (segments.length <=
|
|
1
|
+
{"version":3,"file":"Breadcrumb.cjs","names":["TooltipProvider","Tooltip","TooltipTrigger","cn","TooltipContent"],"sources":["../../../src/components/Breadcrumb.tsx"],"sourcesContent":["import { cn } from '../lib/cn';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './Tooltip';\n\n/** The marker a collapsed run of segments is shown as. */\nexport const BREADCRUMB_ELLIPSIS = '…';\n\n/**\n * A path as breadcrumb segments, with the middle collapsed when it is deeper\n * than `keep` allows.\n *\n * The first segment and the last few are what place a leaf; the ones between\n * are what a reader skims past, so those are the ones that go. The leaf is\n * always the final segment and is never collapsed.\n */\nexport function breadcrumbSegments(path: string, keep = 4): string[] {\n const segments = path.split('/').filter((segment) => segment !== '');\n if (segments.length === 0) return [path];\n const limit = Math.max(3, keep);\n if (segments.length <= limit) return segments;\n // Keep room for the first segment, the collapse marker, and the leaf.\n return [segments[0] ?? '', BREADCRUMB_ELLIPSIS, ...segments.slice(segments.length - (limit - 2))];\n}\n\nexport interface BreadcrumbProps {\n /** The path to show, separated by forward slashes. */\n path: string;\n /** How many segments survive, with a minimum of three to retain the leaf. */\n keep?: number;\n /** Marks the trail so a test can find it. */\n 'data-testid'?: string;\n className?: string;\n}\n\n/**\n * A slash-separated path, shortened to fit and readable in full on hover.\n *\n * Two things shorten it, because they solve different problems. Collapsing the\n * middle keeps a deep path legible at any width, and truncation handles what is\n * left when the container is narrower than even that. Either one hides\n * something, so the whole path is always one hover away, wrapped rather than\n * clipped: a tooltip that truncates too would defeat the point of having one.\n *\n * The leaf carries the emphasis. A reader scanning a header is looking for the\n * file, and the directories are context for it.\n */\nexport function Breadcrumb({ path, keep, className, 'data-testid': testId }: BreadcrumbProps) {\n const segments = breadcrumbSegments(path, keep);\n const lastIndex = segments.length - 1;\n\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span\n data-slot=\"breadcrumb\"\n data-testid={testId}\n title={undefined}\n className={cn('flex min-w-0 items-baseline gap-1 truncate font-mono text-sm', className)}\n >\n {segments.map((segment, index) => (\n // Segments repeat in a path (src/app/src), so the index is what\n // keeps two of the same name apart.\n <span key={`${segment}-${String(index)}`} className=\"flex min-w-0 items-baseline gap-1\">\n {index > 0 ? <span className=\"shrink-0 text-doom-faint\">/</span> : null}\n <span\n className={\n index === lastIndex ? 'truncate font-bold text-doom-hi' : 'min-w-0 truncate text-doom-faint'\n }\n >\n {segment}\n </span>\n </span>\n ))}\n </span>\n </TooltipTrigger>\n <TooltipContent className=\"max-w-[32rem] break-all whitespace-normal\">{path}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n"],"mappings":"+FAcA,SAAgB,EAAmB,EAAc,EAAO,EAAa,CACnE,IAAM,EAAW,EAAK,MAAM,GAAG,CAAC,CAAC,OAAQ,GAAY,IAAY,EAAE,EACnE,GAAI,EAAS,SAAW,EAAG,MAAO,CAAC,CAAI,EACvC,IAAM,EAAQ,KAAK,IAAI,EAAG,CAAI,EAG9B,OAFI,EAAS,QAAU,EAAc,EAE9B,CAAC,EAAS,IAAM,OAAyB,GAAG,EAAS,MAAM,EAAS,QAAU,EAAQ,EAAE,CAAC,CAClG,CAwBA,SAAgB,EAAW,CAAE,OAAM,OAAM,YAAW,cAAe,GAA2B,CAC5F,IAAM,EAAW,EAAmB,EAAM,CAAI,EACxC,EAAY,EAAS,OAAS,EAEpC,MACE,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,gBAAD,CAAA,SACE,iBAAA,EAAA,EAAA,KAAA,CAACC,EAAAA,QAAD,CAAA,SAAA,CACE,iBAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,QAAA,GACd,SAAA,iBAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,YAAU,aACV,cAAa,EACb,MAAO,IAAA,GACP,UAAWC,EAAAA,GAAG,+DAAgE,CAAS,EAEtF,SAAA,EAAS,KAAK,EAAS,IAGtB,iBAAA,EAAA,EAAA,KAAA,CAAC,OAAD,CAA0C,UAAU,oCAApD,SAAA,CACG,EAAQ,EAAI,iBAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,2BAA2B,SAAA,GAAO,CAAA,EAAI,KACnE,iBAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,UACE,IAAU,EAAY,kCAAoC,mCAG3D,SAAA,CACG,CAAA,CACF,CATK,EAAA,GAAG,EAAQ,GAAG,OAAO,CAAK,GAS/B,CACP,CACG,CAAA,CACQ,CAAA,EAChB,iBAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,eAAD,CAAgB,UAAU,4CAA6C,SAAA,CAAqB,CAAA,CACrF,CAAA,CAAA,CACM,CAAA,CAErB"}
|
|
@@ -13,7 +13,7 @@ export declare function breadcrumbSegments(path: string, keep?: number): string[
|
|
|
13
13
|
export interface BreadcrumbProps {
|
|
14
14
|
/** The path to show, separated by forward slashes. */
|
|
15
15
|
path: string;
|
|
16
|
-
/** How many segments survive
|
|
16
|
+
/** How many segments survive, with a minimum of three to retain the leaf. */
|
|
17
17
|
keep?: number;
|
|
18
18
|
/** Marks the trail so a test can find it. */
|
|
19
19
|
'data-testid'?: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumb.d.mts","names":[],"sources":["../../../src/components/Breadcrumb.tsx"],"mappings":";;qBAIa;;;;;;;;;wBAUG,mBAAmB,cAAc;
|
|
1
|
+
{"version":3,"file":"Breadcrumb.d.mts","names":[],"sources":["../../../src/components/Breadcrumb.tsx"],"mappings":";;qBAIa;;;;;;;;;wBAUG,mBAAmB,cAAc;iBAShC;;EAEf;;EAEA;;EAEA;EACA;;;;;;;;;;;;;;wBAec,aAAa,MAAM,MAAM,0BAA0B,UAAU,kCAAe,IAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cn as e}from"../lib/cn.mjs";import{Tooltip as t,TooltipContent as n,TooltipProvider as r,TooltipTrigger as i}from"./Tooltip.mjs";import{jsx as a,jsxs as o}from"react/jsx-runtime";const s=`…`;function c(e,t=4){let n=e.split(`/`).filter(e=>e!==``);
|
|
1
|
+
import{cn as e}from"../lib/cn.mjs";import{Tooltip as t,TooltipContent as n,TooltipProvider as r,TooltipTrigger as i}from"./Tooltip.mjs";import{jsx as a,jsxs as o}from"react/jsx-runtime";const s=`…`;function c(e,t=4){let n=e.split(`/`).filter(e=>e!==``);if(n.length===0)return[e];let r=Math.max(3,t);return n.length<=r?n:[n[0]??``,`…`,...n.slice(n.length-(r-2))]}function l({path:s,keep:l,className:u,"data-testid":d}){let f=c(s,l),p=f.length-1;return/* @__PURE__ */ a(r,{children:/* @__PURE__ */ o(t,{children:[/* @__PURE__ */ a(i,{asChild:!0,children:/* @__PURE__ */ a(`span`,{"data-slot":`breadcrumb`,"data-testid":d,title:void 0,className:e(`flex min-w-0 items-baseline gap-1 truncate font-mono text-sm`,u),children:f.map((e,t)=>/* @__PURE__ */ o(`span`,{className:`flex min-w-0 items-baseline gap-1`,children:[t>0?/* @__PURE__ */ a(`span`,{className:`shrink-0 text-doom-faint`,children:`/`}):null,/* @__PURE__ */ a(`span`,{className:t===p?`truncate font-bold text-doom-hi`:`min-w-0 truncate text-doom-faint`,children:e})]},`${e}-${String(t)}`))})}),/* @__PURE__ */ a(n,{className:`max-w-[32rem] break-all whitespace-normal`,children:s})]})})}export{s as BREADCRUMB_ELLIPSIS,l as Breadcrumb,c as breadcrumbSegments};
|
|
2
2
|
//# sourceMappingURL=Breadcrumb.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Breadcrumb.mjs","names":[],"sources":["../../../src/components/Breadcrumb.tsx"],"sourcesContent":["import { cn } from '../lib/cn';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './Tooltip';\n\n/** The marker a collapsed run of segments is shown as. */\nexport const BREADCRUMB_ELLIPSIS = '…';\n\n/**\n * A path as breadcrumb segments, with the middle collapsed when it is deeper\n * than `keep` allows.\n *\n * The first segment and the last few are what place a leaf; the ones between\n * are what a reader skims past, so those are the ones that go. The leaf is\n * always the final segment and is never collapsed.\n */\nexport function breadcrumbSegments(path: string, keep = 4): string[] {\n const segments = path.split('/').filter((segment) => segment !== '');\n if (segments.length === 0) return [path];\n if (segments.length <=
|
|
1
|
+
{"version":3,"file":"Breadcrumb.mjs","names":[],"sources":["../../../src/components/Breadcrumb.tsx"],"sourcesContent":["import { cn } from '../lib/cn';\nimport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from './Tooltip';\n\n/** The marker a collapsed run of segments is shown as. */\nexport const BREADCRUMB_ELLIPSIS = '…';\n\n/**\n * A path as breadcrumb segments, with the middle collapsed when it is deeper\n * than `keep` allows.\n *\n * The first segment and the last few are what place a leaf; the ones between\n * are what a reader skims past, so those are the ones that go. The leaf is\n * always the final segment and is never collapsed.\n */\nexport function breadcrumbSegments(path: string, keep = 4): string[] {\n const segments = path.split('/').filter((segment) => segment !== '');\n if (segments.length === 0) return [path];\n const limit = Math.max(3, keep);\n if (segments.length <= limit) return segments;\n // Keep room for the first segment, the collapse marker, and the leaf.\n return [segments[0] ?? '', BREADCRUMB_ELLIPSIS, ...segments.slice(segments.length - (limit - 2))];\n}\n\nexport interface BreadcrumbProps {\n /** The path to show, separated by forward slashes. */\n path: string;\n /** How many segments survive, with a minimum of three to retain the leaf. */\n keep?: number;\n /** Marks the trail so a test can find it. */\n 'data-testid'?: string;\n className?: string;\n}\n\n/**\n * A slash-separated path, shortened to fit and readable in full on hover.\n *\n * Two things shorten it, because they solve different problems. Collapsing the\n * middle keeps a deep path legible at any width, and truncation handles what is\n * left when the container is narrower than even that. Either one hides\n * something, so the whole path is always one hover away, wrapped rather than\n * clipped: a tooltip that truncates too would defeat the point of having one.\n *\n * The leaf carries the emphasis. A reader scanning a header is looking for the\n * file, and the directories are context for it.\n */\nexport function Breadcrumb({ path, keep, className, 'data-testid': testId }: BreadcrumbProps) {\n const segments = breadcrumbSegments(path, keep);\n const lastIndex = segments.length - 1;\n\n return (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger asChild>\n <span\n data-slot=\"breadcrumb\"\n data-testid={testId}\n title={undefined}\n className={cn('flex min-w-0 items-baseline gap-1 truncate font-mono text-sm', className)}\n >\n {segments.map((segment, index) => (\n // Segments repeat in a path (src/app/src), so the index is what\n // keeps two of the same name apart.\n <span key={`${segment}-${String(index)}`} className=\"flex min-w-0 items-baseline gap-1\">\n {index > 0 ? <span className=\"shrink-0 text-doom-faint\">/</span> : null}\n <span\n className={\n index === lastIndex ? 'truncate font-bold text-doom-hi' : 'min-w-0 truncate text-doom-faint'\n }\n >\n {segment}\n </span>\n </span>\n ))}\n </span>\n </TooltipTrigger>\n <TooltipContent className=\"max-w-[32rem] break-all whitespace-normal\">{path}</TooltipContent>\n </Tooltip>\n </TooltipProvider>\n );\n}\n"],"mappings":"0LAIA,MAAa,EAAsB,IAUnC,SAAgB,EAAmB,EAAc,EAAO,EAAa,CACnE,IAAM,EAAW,EAAK,MAAM,GAAG,CAAC,CAAC,OAAQ,GAAY,IAAY,EAAE,EACnE,GAAI,EAAS,SAAW,EAAG,MAAO,CAAC,CAAI,EACvC,IAAM,EAAQ,KAAK,IAAI,EAAG,CAAI,EAG9B,OAFI,EAAS,QAAU,EAAc,EAE9B,CAAC,EAAS,IAAM,OAAyB,GAAG,EAAS,MAAM,EAAS,QAAU,EAAQ,EAAE,CAAC,CAClG,CAwBA,SAAgB,EAAW,CAAE,OAAM,OAAM,YAAW,cAAe,GAA2B,CAC5F,IAAM,EAAW,EAAmB,EAAM,CAAI,EACxC,EAAY,EAAS,OAAS,EAEpC,MACE,kBAAC,EAAD,CAAA,SACE,kBAAC,EAAD,CAAA,SAAA,CACE,kBAAC,EAAD,CAAgB,QAAA,GACd,SAAA,kBAAC,OAAD,CACE,YAAU,aACV,cAAa,EACb,MAAO,IAAA,GACP,UAAW,EAAG,+DAAgE,CAAS,EAEtF,SAAA,EAAS,KAAK,EAAS,IAGtB,kBAAC,OAAD,CAA0C,UAAU,oCAApD,SAAA,CACG,EAAQ,EAAI,kBAAC,OAAD,CAAM,UAAU,2BAA2B,SAAA,GAAO,CAAA,EAAI,KACnE,kBAAC,OAAD,CACE,UACE,IAAU,EAAY,kCAAoC,mCAG3D,SAAA,CACG,CAAA,CACF,CATK,EAAA,GAAG,EAAQ,GAAG,OAAO,CAAK,GAS/B,CACP,CACG,CAAA,CACQ,CAAA,EAChB,kBAAC,EAAD,CAAgB,UAAU,4CAA6C,SAAA,CAAqB,CAAA,CACrF,CAAA,CAAA,CACM,CAAA,CAErB"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../lib/cn.cjs"),t=require("./Spinner.cjs");let n=require("radix-ui"),r=require("react/jsx-runtime");const i=(0,require("class-variance-authority").cva)(`inline-flex shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-mono transition-[color,background-color,border-color,filter] outline-none focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 [&_svg]:pointer-events-none [&_svg]:shrink-0`,{variants:{variant:{primary:`bg-doom-blue font-bold text-doom-rail hover:brightness-110`,outline:`border border-doom-border text-doom-dim hover:border-doom-blue/50 hover:text-doom-hi`,ghost:`text-doom-dim hover:bg-doom-panel hover:text-doom-hi`,subtle:`bg-doom-panel text-doom-dim hover:bg-doom-deep hover:text-doom-hi`,danger:`bg-doom-red font-bold text-doom-rail hover:brightness-110`,"danger-outline":`border border-doom-edge-red bg-doom-tint-red font-bold text-doom-red hover:brightness-110`,success:`bg-doom-green font-bold text-doom-rail hover:brightness-110`,link:`text-doom-blue hover:underline`},size:{xs:`h-
|
|
1
|
+
const e=require("../lib/cn.cjs"),t=require("./Spinner.cjs");let n=require("radix-ui"),r=require("react/jsx-runtime");const i=(0,require("class-variance-authority").cva)(`inline-flex min-h-6 min-w-6 shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-mono transition-[color,background-color,border-color,filter] outline-none focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 [&_svg]:pointer-events-none [&_svg]:shrink-0`,{variants:{variant:{primary:`bg-doom-blue font-bold text-doom-rail hover:brightness-110`,outline:`border border-doom-border text-doom-dim hover:border-doom-blue/50 hover:text-doom-hi`,ghost:`text-doom-dim hover:bg-doom-panel hover:text-doom-hi`,subtle:`bg-doom-panel text-doom-dim hover:bg-doom-deep hover:text-doom-hi`,danger:`bg-doom-red font-bold text-doom-rail hover:brightness-110`,"danger-outline":`border border-doom-edge-red bg-doom-tint-red font-bold text-doom-red hover:brightness-110`,success:`bg-doom-green font-bold text-doom-rail hover:brightness-110`,link:`text-doom-blue hover:underline`},size:{xs:`h-6 rounded px-1.5 text-2xs`,sm:`h-7 px-2.5 text-xs`,md:`h-8 px-3 text-sm`,lg:`h-9 px-3.5 text-base`,icon:`h-6 w-6 rounded p-0`,"icon-md":`h-8 w-8 p-0`,card:`h-auto w-full flex-col items-stretch justify-start gap-1 px-[11px] py-2.5 text-left whitespace-normal`}},defaultVariants:{variant:`outline`,size:`md`}});function a({className:a,variant:o,size:s,asChild:c=!1,loading:l=!1,loadingLabel:u,disabled:d,type:f,children:p,...m}){let h=c?n.Slot.Root:`button`,g=!c&&l;return/* @__PURE__ */ (0,r.jsx)(h,{"data-slot":`button`,type:c?void 0:f??`button`,"aria-busy":g?!0:void 0,disabled:c?void 0:d??g,className:e.cn(i({variant:o,size:s}),a),...m,children:c?p:/* @__PURE__ */ (0,r.jsxs)(r.Fragment,{children:[g?/* @__PURE__ */ (0,r.jsx)(t.Spinner,{label:u}):null,p]})})}exports.Button=a,exports.buttonVariants=i;
|
|
2
2
|
//# sourceMappingURL=Button.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.cjs","names":["cva","Slot","cn","Spinner"],"sources":["../../../src/components/Button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { Spinner } from './Spinner';\n\nexport const buttonVariants = cva(\n 'inline-flex shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-mono transition-[color,background-color,border-color,filter] outline-none focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 [&_svg]:pointer-events-none [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n primary: 'bg-doom-blue font-bold text-doom-rail hover:brightness-110',\n outline: 'border border-doom-border text-doom-dim hover:border-doom-blue/50 hover:text-doom-hi',\n ghost: 'text-doom-dim hover:bg-doom-panel hover:text-doom-hi',\n subtle: 'bg-doom-panel text-doom-dim hover:bg-doom-deep hover:text-doom-hi',\n danger: 'bg-doom-red font-bold text-doom-rail hover:brightness-110',\n 'danger-outline': 'border border-doom-edge-red bg-doom-tint-red font-bold text-doom-red hover:brightness-110',\n success: 'bg-doom-green font-bold text-doom-rail hover:brightness-110',\n link: 'text-doom-blue hover:underline',\n },\n size: {\n xs: 'h-
|
|
1
|
+
{"version":3,"file":"Button.cjs","names":["cva","Slot","cn","Spinner"],"sources":["../../../src/components/Button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { Spinner } from './Spinner';\n\nexport const buttonVariants = cva(\n 'inline-flex min-h-6 min-w-6 shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-mono transition-[color,background-color,border-color,filter] outline-none focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 [&_svg]:pointer-events-none [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n primary: 'bg-doom-blue font-bold text-doom-rail hover:brightness-110',\n outline: 'border border-doom-border text-doom-dim hover:border-doom-blue/50 hover:text-doom-hi',\n ghost: 'text-doom-dim hover:bg-doom-panel hover:text-doom-hi',\n subtle: 'bg-doom-panel text-doom-dim hover:bg-doom-deep hover:text-doom-hi',\n danger: 'bg-doom-red font-bold text-doom-rail hover:brightness-110',\n 'danger-outline': 'border border-doom-edge-red bg-doom-tint-red font-bold text-doom-red hover:brightness-110',\n success: 'bg-doom-green font-bold text-doom-rail hover:brightness-110',\n link: 'text-doom-blue hover:underline',\n },\n size: {\n xs: 'h-6 rounded px-1.5 text-2xs',\n sm: 'h-7 px-2.5 text-xs',\n md: 'h-8 px-3 text-sm',\n lg: 'h-9 px-3.5 text-base',\n icon: 'h-6 w-6 rounded p-0',\n 'icon-md': 'h-8 w-8 p-0',\n /**\n * A whole card that is one click target: a session in the rail, a run\n * in a panel. It keeps the button's focus ring and cursor and gives up\n * the button's single-line box, which is what a card-shaped <button>\n * would otherwise have to restate.\n */\n card: 'h-auto w-full flex-col items-stretch justify-start gap-1 px-[11px] py-2.5 text-left whitespace-normal',\n },\n },\n defaultVariants: { variant: 'outline', size: 'md' },\n },\n);\n\nexport type ButtonVariant = NonNullable<VariantProps<typeof buttonVariants>['variant']>;\nexport type ButtonSize = NonNullable<VariantProps<typeof buttonVariants>['size']>;\n\nexport interface ButtonProps extends ComponentProps<'button'>, VariantProps<typeof buttonVariants> {\n /** Render the child element instead of a <button>, passing the classes down (shadcn's asChild). */\n asChild?: boolean;\n /**\n * Work is in flight: the button shows a spinner and stops accepting clicks.\n * Ignored under asChild, where the child owns its own content.\n */\n loading?: boolean;\n /** What the spinner announces while loading; omit it and the wait is silent. */\n loadingLabel?: string;\n}\n\n/** The one button: every variant is a theme token, so it recolours with the theme. */\nexport function Button({\n className,\n variant,\n size,\n asChild = false,\n loading = false,\n loadingLabel,\n disabled,\n type,\n children,\n ...props\n}: ButtonProps) {\n const Component = asChild ? Slot.Root : 'button';\n const busy = !asChild && loading;\n return (\n <Component\n data-slot=\"button\"\n type={asChild ? undefined : (type ?? 'button')}\n aria-busy={busy ? true : undefined}\n disabled={asChild ? undefined : (disabled ?? busy)}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n >\n {/* Slot takes exactly one child, so asChild hands its element straight through. */}\n {asChild ? (\n children\n ) : (\n <>\n {busy ? <Spinner label={loadingLabel} /> : null}\n {children}\n </>\n )}\n </Component>\n );\n}\n"],"mappings":"qHAOA,MAAa,GAAA,oCAAiBA,CAAAA,CAAAA,IAAAA,CAC5B,yVACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,6DACT,QAAS,uFACT,MAAO,uDACP,OAAQ,oEACR,OAAQ,4DACR,iBAAkB,4FAClB,QAAS,8DACT,KAAM,gCACR,EACA,KAAM,CACJ,GAAI,8BACJ,GAAI,qBACJ,GAAI,mBACJ,GAAI,uBACJ,KAAM,sBACN,UAAW,cAOX,KAAM,uGACR,CACF,EACA,gBAAiB,CAAE,QAAS,UAAW,KAAM,IAAK,CACpD,CACF,EAkBA,SAAgB,EAAO,CACrB,YACA,UACA,OACA,UAAU,GACV,UAAU,GACV,eACA,WACA,OACA,WACA,GAAG,GACW,CACd,IAAM,EAAY,EAAUC,EAAAA,KAAK,KAAO,SAClC,EAAO,CAAC,GAAW,EACzB,MACE,iBAAA,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,YAAU,SACV,KAAM,EAAU,IAAA,GAAa,GAAQ,SACrC,YAAW,EAAO,GAAO,IAAA,GACzB,SAAU,EAAU,IAAA,GAAa,GAAY,EAC7C,UAAWC,EAAAA,GAAG,EAAe,CAAE,UAAS,MAAK,CAAC,EAAG,CAAS,EAC1D,GAAI,EAGH,SAAA,EACC,EAEA,iBAAA,EAAA,EAAA,KAAA,CAAA,EAAA,SAAA,CAAA,SAAA,CACG,EAAO,iBAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,QAAD,CAAS,MAAO,CAAe,CAAA,EAAI,KAC1C,CACD,CAAA,CAAA,CAEK,CAAA,CAEf"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cn as e}from"../lib/cn.mjs";import{Spinner as t}from"./Spinner.mjs";import{Slot as n}from"radix-ui";import{Fragment as r,jsx as i,jsxs as a}from"react/jsx-runtime";import{cva as o}from"class-variance-authority";const s=o(`inline-flex shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-mono transition-[color,background-color,border-color,filter] outline-none focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 [&_svg]:pointer-events-none [&_svg]:shrink-0`,{variants:{variant:{primary:`bg-doom-blue font-bold text-doom-rail hover:brightness-110`,outline:`border border-doom-border text-doom-dim hover:border-doom-blue/50 hover:text-doom-hi`,ghost:`text-doom-dim hover:bg-doom-panel hover:text-doom-hi`,subtle:`bg-doom-panel text-doom-dim hover:bg-doom-deep hover:text-doom-hi`,danger:`bg-doom-red font-bold text-doom-rail hover:brightness-110`,"danger-outline":`border border-doom-edge-red bg-doom-tint-red font-bold text-doom-red hover:brightness-110`,success:`bg-doom-green font-bold text-doom-rail hover:brightness-110`,link:`text-doom-blue hover:underline`},size:{xs:`h-
|
|
1
|
+
import{cn as e}from"../lib/cn.mjs";import{Spinner as t}from"./Spinner.mjs";import{Slot as n}from"radix-ui";import{Fragment as r,jsx as i,jsxs as a}from"react/jsx-runtime";import{cva as o}from"class-variance-authority";const s=o(`inline-flex min-h-6 min-w-6 shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-mono transition-[color,background-color,border-color,filter] outline-none focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 [&_svg]:pointer-events-none [&_svg]:shrink-0`,{variants:{variant:{primary:`bg-doom-blue font-bold text-doom-rail hover:brightness-110`,outline:`border border-doom-border text-doom-dim hover:border-doom-blue/50 hover:text-doom-hi`,ghost:`text-doom-dim hover:bg-doom-panel hover:text-doom-hi`,subtle:`bg-doom-panel text-doom-dim hover:bg-doom-deep hover:text-doom-hi`,danger:`bg-doom-red font-bold text-doom-rail hover:brightness-110`,"danger-outline":`border border-doom-edge-red bg-doom-tint-red font-bold text-doom-red hover:brightness-110`,success:`bg-doom-green font-bold text-doom-rail hover:brightness-110`,link:`text-doom-blue hover:underline`},size:{xs:`h-6 rounded px-1.5 text-2xs`,sm:`h-7 px-2.5 text-xs`,md:`h-8 px-3 text-sm`,lg:`h-9 px-3.5 text-base`,icon:`h-6 w-6 rounded p-0`,"icon-md":`h-8 w-8 p-0`,card:`h-auto w-full flex-col items-stretch justify-start gap-1 px-[11px] py-2.5 text-left whitespace-normal`}},defaultVariants:{variant:`outline`,size:`md`}});function c({className:o,variant:c,size:l,asChild:u=!1,loading:d=!1,loadingLabel:f,disabled:p,type:m,children:h,...g}){let _=u?n.Root:`button`,v=!u&&d;return/* @__PURE__ */ i(_,{"data-slot":`button`,type:u?void 0:m??`button`,"aria-busy":v?!0:void 0,disabled:u?void 0:p??v,className:e(s({variant:c,size:l}),o),...g,children:u?h:/* @__PURE__ */ a(r,{children:[v?/* @__PURE__ */ i(t,{label:f}):null,h]})})}export{c as Button,s as buttonVariants};
|
|
2
2
|
//# sourceMappingURL=Button.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Button.mjs","names":[],"sources":["../../../src/components/Button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { Spinner } from './Spinner';\n\nexport const buttonVariants = cva(\n 'inline-flex shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-mono transition-[color,background-color,border-color,filter] outline-none focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 [&_svg]:pointer-events-none [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n primary: 'bg-doom-blue font-bold text-doom-rail hover:brightness-110',\n outline: 'border border-doom-border text-doom-dim hover:border-doom-blue/50 hover:text-doom-hi',\n ghost: 'text-doom-dim hover:bg-doom-panel hover:text-doom-hi',\n subtle: 'bg-doom-panel text-doom-dim hover:bg-doom-deep hover:text-doom-hi',\n danger: 'bg-doom-red font-bold text-doom-rail hover:brightness-110',\n 'danger-outline': 'border border-doom-edge-red bg-doom-tint-red font-bold text-doom-red hover:brightness-110',\n success: 'bg-doom-green font-bold text-doom-rail hover:brightness-110',\n link: 'text-doom-blue hover:underline',\n },\n size: {\n xs: 'h-
|
|
1
|
+
{"version":3,"file":"Button.mjs","names":[],"sources":["../../../src/components/Button.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { Spinner } from './Spinner';\n\nexport const buttonVariants = cva(\n 'inline-flex min-h-6 min-w-6 shrink-0 cursor-pointer items-center justify-center gap-1.5 whitespace-nowrap rounded-md font-mono transition-[color,background-color,border-color,filter] outline-none focus-visible:ring-2 focus-visible:ring-doom-blue/50 disabled:pointer-events-none disabled:opacity-40 [&_svg]:pointer-events-none [&_svg]:shrink-0',\n {\n variants: {\n variant: {\n primary: 'bg-doom-blue font-bold text-doom-rail hover:brightness-110',\n outline: 'border border-doom-border text-doom-dim hover:border-doom-blue/50 hover:text-doom-hi',\n ghost: 'text-doom-dim hover:bg-doom-panel hover:text-doom-hi',\n subtle: 'bg-doom-panel text-doom-dim hover:bg-doom-deep hover:text-doom-hi',\n danger: 'bg-doom-red font-bold text-doom-rail hover:brightness-110',\n 'danger-outline': 'border border-doom-edge-red bg-doom-tint-red font-bold text-doom-red hover:brightness-110',\n success: 'bg-doom-green font-bold text-doom-rail hover:brightness-110',\n link: 'text-doom-blue hover:underline',\n },\n size: {\n xs: 'h-6 rounded px-1.5 text-2xs',\n sm: 'h-7 px-2.5 text-xs',\n md: 'h-8 px-3 text-sm',\n lg: 'h-9 px-3.5 text-base',\n icon: 'h-6 w-6 rounded p-0',\n 'icon-md': 'h-8 w-8 p-0',\n /**\n * A whole card that is one click target: a session in the rail, a run\n * in a panel. It keeps the button's focus ring and cursor and gives up\n * the button's single-line box, which is what a card-shaped <button>\n * would otherwise have to restate.\n */\n card: 'h-auto w-full flex-col items-stretch justify-start gap-1 px-[11px] py-2.5 text-left whitespace-normal',\n },\n },\n defaultVariants: { variant: 'outline', size: 'md' },\n },\n);\n\nexport type ButtonVariant = NonNullable<VariantProps<typeof buttonVariants>['variant']>;\nexport type ButtonSize = NonNullable<VariantProps<typeof buttonVariants>['size']>;\n\nexport interface ButtonProps extends ComponentProps<'button'>, VariantProps<typeof buttonVariants> {\n /** Render the child element instead of a <button>, passing the classes down (shadcn's asChild). */\n asChild?: boolean;\n /**\n * Work is in flight: the button shows a spinner and stops accepting clicks.\n * Ignored under asChild, where the child owns its own content.\n */\n loading?: boolean;\n /** What the spinner announces while loading; omit it and the wait is silent. */\n loadingLabel?: string;\n}\n\n/** The one button: every variant is a theme token, so it recolours with the theme. */\nexport function Button({\n className,\n variant,\n size,\n asChild = false,\n loading = false,\n loadingLabel,\n disabled,\n type,\n children,\n ...props\n}: ButtonProps) {\n const Component = asChild ? Slot.Root : 'button';\n const busy = !asChild && loading;\n return (\n <Component\n data-slot=\"button\"\n type={asChild ? undefined : (type ?? 'button')}\n aria-busy={busy ? true : undefined}\n disabled={asChild ? undefined : (disabled ?? busy)}\n className={cn(buttonVariants({ variant, size }), className)}\n {...props}\n >\n {/* Slot takes exactly one child, so asChild hands its element straight through. */}\n {asChild ? (\n children\n ) : (\n <>\n {busy ? <Spinner label={loadingLabel} /> : null}\n {children}\n </>\n )}\n </Component>\n );\n}\n"],"mappings":"0NAOA,MAAa,EAAiB,EAC5B,yVACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,6DACT,QAAS,uFACT,MAAO,uDACP,OAAQ,oEACR,OAAQ,4DACR,iBAAkB,4FAClB,QAAS,8DACT,KAAM,gCACR,EACA,KAAM,CACJ,GAAI,8BACJ,GAAI,qBACJ,GAAI,mBACJ,GAAI,uBACJ,KAAM,sBACN,UAAW,cAOX,KAAM,uGACR,CACF,EACA,gBAAiB,CAAE,QAAS,UAAW,KAAM,IAAK,CACpD,CACF,EAkBA,SAAgB,EAAO,CACrB,YACA,UACA,OACA,UAAU,GACV,UAAU,GACV,eACA,WACA,OACA,WACA,GAAG,GACW,CACd,IAAM,EAAY,EAAU,EAAK,KAAO,SAClC,EAAO,CAAC,GAAW,EACzB,MACE,kBAAC,EAAD,CACE,YAAU,SACV,KAAM,EAAU,IAAA,GAAa,GAAQ,SACrC,YAAW,EAAO,GAAO,IAAA,GACzB,SAAU,EAAU,IAAA,GAAa,GAAY,EAC7C,UAAW,EAAG,EAAe,CAAE,UAAS,MAAK,CAAC,EAAG,CAAS,EAC1D,GAAI,EAGH,SAAA,EACC,EAEA,kBAAA,EAAA,CAAA,SAAA,CACG,EAAO,kBAAC,EAAD,CAAS,MAAO,CAAe,CAAA,EAAI,KAC1C,CACD,CAAA,CAAA,CAEK,CAAA,CAEf"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../lib/cn.cjs");let t=require("radix-ui"),n=require("react/jsx-runtime");function r({title:r,description:i,children:a,className:o,asChild:s=!1,...c}){let l=s?t.Slot.Root:`div`;return/* @__PURE__ */ (0,n.jsx)(l,{"data-slot":`empty-state`,className:e.cn(`flex flex-1 items-center justify-center px-3 py-4 sm:px-4`,o),...c,children:/* @__PURE__ */ (0,n.jsxs)(`div`,{className:`flex w-
|
|
1
|
+
const e=require("../lib/cn.cjs");let t=require("radix-ui"),n=require("react/jsx-runtime");function r({title:r,description:i,children:a,className:o,asChild:s=!1,...c}){let l=s?t.Slot.Root:`div`;return/* @__PURE__ */ (0,n.jsx)(l,{"data-slot":`empty-state`,className:e.cn(`flex min-w-0 flex-1 items-center justify-center px-3 py-4 sm:px-4`,o),...c,children:/* @__PURE__ */ (0,n.jsxs)(`div`,{className:`flex min-w-0 w-full max-w-[520px] flex-col items-center gap-3 text-center`,children:[/* @__PURE__ */ (0,n.jsx)(`span`,{className:`text-base font-bold text-doom-hi`,children:r}),i?/* @__PURE__ */ (0,n.jsx)(`span`,{className:`text-sm leading-relaxed text-doom-dim`,children:i}):null,a]})})}exports.EmptyState=r;
|
|
2
2
|
//# sourceMappingURL=EmptyState.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState.cjs","names":["Slot","cn"],"sources":["../../../src/components/EmptyState.tsx"],"sourcesContent":["import { Slot } from 'radix-ui';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../lib/cn';\n\nexport interface EmptyStateProps extends Omit<ComponentProps<'div'>, 'title'> {\n title: ReactNode;\n description?: ReactNode;\n /** Optional calls to action under the copy. */\n children?: ReactNode;\n /**\n * Render the child element instead of a <div>, so an empty row inside a\n * list stays an <li> and the list keeps its semantics.\n */\n asChild?: boolean;\n}\n\n/** The centred \"nothing here yet\" card every empty panel shares. */\nexport function EmptyState({ title, description, children, className, asChild = false, ...props }: EmptyStateProps) {\n const Component = asChild ? Slot.Root : 'div';\n return (\n <Component\n data-slot=\"empty-state\"\n className={cn('flex flex-1 items-center justify-center px-3 py-4 sm:px-4', className)}\n {...props}\n >\n <div className=\"flex w-
|
|
1
|
+
{"version":3,"file":"EmptyState.cjs","names":["Slot","cn"],"sources":["../../../src/components/EmptyState.tsx"],"sourcesContent":["import { Slot } from 'radix-ui';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../lib/cn';\n\nexport interface EmptyStateProps extends Omit<ComponentProps<'div'>, 'title'> {\n title: ReactNode;\n description?: ReactNode;\n /** Optional calls to action under the copy. */\n children?: ReactNode;\n /**\n * Render the child element instead of a <div>, so an empty row inside a\n * list stays an <li> and the list keeps its semantics.\n */\n asChild?: boolean;\n}\n\n/** The centred \"nothing here yet\" card every empty panel shares. */\nexport function EmptyState({ title, description, children, className, asChild = false, ...props }: EmptyStateProps) {\n const Component = asChild ? Slot.Root : 'div';\n return (\n <Component\n data-slot=\"empty-state\"\n className={cn('flex min-w-0 flex-1 items-center justify-center px-3 py-4 sm:px-4', className)}\n {...props}\n >\n <div className=\"flex min-w-0 w-full max-w-[520px] flex-col items-center gap-3 text-center\">\n <span className=\"text-base font-bold text-doom-hi\">{title}</span>\n {description ? <span className=\"text-sm leading-relaxed text-doom-dim\">{description}</span> : null}\n {children}\n </div>\n </Component>\n );\n}\n"],"mappings":"0FAkBA,SAAgB,EAAW,CAAE,QAAO,cAAa,WAAU,YAAW,UAAU,GAAO,GAAG,GAA0B,CAClH,IAAM,EAAY,EAAUA,EAAAA,KAAK,KAAO,MACxC,MACE,iBAAA,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,YAAU,cACV,UAAWC,EAAAA,GAAG,oEAAqE,CAAS,EAC5F,GAAI,EAEJ,SAAA,iBAAA,EAAA,EAAA,KAAA,CAAC,MAAD,CAAK,UAAU,4EAAf,SAAA,CACE,iBAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,mCAAoC,SAAA,CAAY,CAAA,EAC/D,EAAc,iBAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,UAAU,wCAAyC,SAAA,CAAkB,CAAA,EAAI,KAC7F,CACE,GACI,CAAA,CAEf"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cn as e}from"../lib/cn.mjs";import{Slot as t}from"radix-ui";import{jsx as n,jsxs as r}from"react/jsx-runtime";function i({title:i,description:a,children:o,className:s,asChild:c=!1,...l}){let u=c?t.Root:`div`;return/* @__PURE__ */ n(u,{"data-slot":`empty-state`,className:e(`flex flex-1 items-center justify-center px-3 py-4 sm:px-4`,s),...l,children:/* @__PURE__ */ r(`div`,{className:`flex w-
|
|
1
|
+
import{cn as e}from"../lib/cn.mjs";import{Slot as t}from"radix-ui";import{jsx as n,jsxs as r}from"react/jsx-runtime";function i({title:i,description:a,children:o,className:s,asChild:c=!1,...l}){let u=c?t.Root:`div`;return/* @__PURE__ */ n(u,{"data-slot":`empty-state`,className:e(`flex min-w-0 flex-1 items-center justify-center px-3 py-4 sm:px-4`,s),...l,children:/* @__PURE__ */ r(`div`,{className:`flex min-w-0 w-full max-w-[520px] flex-col items-center gap-3 text-center`,children:[/* @__PURE__ */ n(`span`,{className:`text-base font-bold text-doom-hi`,children:i}),a?/* @__PURE__ */ n(`span`,{className:`text-sm leading-relaxed text-doom-dim`,children:a}):null,o]})})}export{i as EmptyState};
|
|
2
2
|
//# sourceMappingURL=EmptyState.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"EmptyState.mjs","names":[],"sources":["../../../src/components/EmptyState.tsx"],"sourcesContent":["import { Slot } from 'radix-ui';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../lib/cn';\n\nexport interface EmptyStateProps extends Omit<ComponentProps<'div'>, 'title'> {\n title: ReactNode;\n description?: ReactNode;\n /** Optional calls to action under the copy. */\n children?: ReactNode;\n /**\n * Render the child element instead of a <div>, so an empty row inside a\n * list stays an <li> and the list keeps its semantics.\n */\n asChild?: boolean;\n}\n\n/** The centred \"nothing here yet\" card every empty panel shares. */\nexport function EmptyState({ title, description, children, className, asChild = false, ...props }: EmptyStateProps) {\n const Component = asChild ? Slot.Root : 'div';\n return (\n <Component\n data-slot=\"empty-state\"\n className={cn('flex flex-1 items-center justify-center px-3 py-4 sm:px-4', className)}\n {...props}\n >\n <div className=\"flex w-
|
|
1
|
+
{"version":3,"file":"EmptyState.mjs","names":[],"sources":["../../../src/components/EmptyState.tsx"],"sourcesContent":["import { Slot } from 'radix-ui';\nimport type { ComponentProps, ReactNode } from 'react';\n\nimport { cn } from '../lib/cn';\n\nexport interface EmptyStateProps extends Omit<ComponentProps<'div'>, 'title'> {\n title: ReactNode;\n description?: ReactNode;\n /** Optional calls to action under the copy. */\n children?: ReactNode;\n /**\n * Render the child element instead of a <div>, so an empty row inside a\n * list stays an <li> and the list keeps its semantics.\n */\n asChild?: boolean;\n}\n\n/** The centred \"nothing here yet\" card every empty panel shares. */\nexport function EmptyState({ title, description, children, className, asChild = false, ...props }: EmptyStateProps) {\n const Component = asChild ? Slot.Root : 'div';\n return (\n <Component\n data-slot=\"empty-state\"\n className={cn('flex min-w-0 flex-1 items-center justify-center px-3 py-4 sm:px-4', className)}\n {...props}\n >\n <div className=\"flex min-w-0 w-full max-w-[520px] flex-col items-center gap-3 text-center\">\n <span className=\"text-base font-bold text-doom-hi\">{title}</span>\n {description ? <span className=\"text-sm leading-relaxed text-doom-dim\">{description}</span> : null}\n {children}\n </div>\n </Component>\n );\n}\n"],"mappings":"qHAkBA,SAAgB,EAAW,CAAE,QAAO,cAAa,WAAU,YAAW,UAAU,GAAO,GAAG,GAA0B,CAClH,IAAM,EAAY,EAAU,EAAK,KAAO,MACxC,MACE,kBAAC,EAAD,CACE,YAAU,cACV,UAAW,EAAG,oEAAqE,CAAS,EAC5F,GAAI,EAEJ,SAAA,kBAAC,MAAD,CAAK,UAAU,4EAAf,SAAA,CACE,kBAAC,OAAD,CAAM,UAAU,mCAAoC,SAAA,CAAY,CAAA,EAC/D,EAAc,kBAAC,OAAD,CAAM,UAAU,wCAAyC,SAAA,CAAkB,CAAA,EAAI,KAC7F,CACE,GACI,CAAA,CAEf"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../lib/cn.cjs");let t=require("react/jsx-runtime");const n=(0,require("class-variance-authority").cva)(`min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red`,{variants:{variant:{default:`rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60`,bare:`border-0 bg-transparent`},size:{xs:`px-1.5 py-0.5 text-2xs`,sm:`px-2 py-1 text-xs`,md:`px-2.5 py-1.5 text-sm`,lg:`px-3 py-
|
|
1
|
+
const e=require("../lib/cn.cjs");let t=require("react/jsx-runtime");const n=(0,require("class-variance-authority").cva)(`min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red`,{variants:{variant:{default:`rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60`,bare:`border-0 bg-transparent`},size:{xs:`min-h-6 px-1.5 py-0.5 text-2xs`,sm:`min-h-7 px-2 py-1 text-xs`,md:`min-h-8 px-2.5 py-1.5 text-sm`,lg:`min-h-9 px-3 py-1.5 text-base`}},compoundVariants:[{variant:`bare`,class:`min-h-0 p-0`}],defaultVariants:{variant:`default`,size:`md`}});function r({className:r,type:i,variant:a,size:o,...s}){return/* @__PURE__ */ (0,t.jsx)(`input`,{type:i??`text`,"data-slot":`input`,spellCheck:!1,className:e.cn(n({variant:a,size:o}),r),...s})}exports.Input=r,exports.fieldVariants=n;
|
|
2
2
|
//# sourceMappingURL=Input.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.cjs","names":["cva","cn"],"sources":["../../../src/components/Input.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The shape both fields wear, so a single-line and a multi-line field in the\n * same form agree on their well, their type ramp, and their invalid state.\n * Textarea builds on it rather than restating it.\n */\nexport const fieldVariants = cva(\n 'min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red',\n {\n variants: {\n variant: {\n default: 'rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60',\n /** No well: a composer or a palette search that draws its own surface. */\n bare: 'border-0 bg-transparent',\n },\n /** The same rungs Button names, so a field and the button beside it line up. */\n size: {\n xs: 'px-1.5 py-0.5 text-2xs',\n sm: 'px-2 py-1 text-xs',\n md: 'px-2.5 py-1.5 text-sm',\n lg: 'px-3 py-
|
|
1
|
+
{"version":3,"file":"Input.cjs","names":["cva","cn"],"sources":["../../../src/components/Input.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The shape both fields wear, so a single-line and a multi-line field in the\n * same form agree on their well, their type ramp, and their invalid state.\n * Textarea builds on it rather than restating it.\n */\nexport const fieldVariants = cva(\n 'min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red',\n {\n variants: {\n variant: {\n default: 'rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60',\n /** No well: a composer or a palette search that draws its own surface. */\n bare: 'border-0 bg-transparent',\n },\n /** The same rungs Button names, so a field and the button beside it line up. */\n size: {\n xs: 'min-h-6 px-1.5 py-0.5 text-2xs',\n sm: 'min-h-7 px-2 py-1 text-xs',\n md: 'min-h-8 px-2.5 py-1.5 text-sm',\n lg: 'min-h-9 px-3 py-1.5 text-base',\n },\n },\n compoundVariants: [\n // A bare field sits inside a surface that already has its own padding,\n // so it keeps the size's type ramp and gives up the size's box.\n { variant: 'bare', class: 'min-h-0 p-0' },\n ],\n defaultVariants: { variant: 'default', size: 'md' },\n },\n);\n\nexport type FieldVariant = NonNullable<VariantProps<typeof fieldVariants>['variant']>;\nexport type FieldSize = NonNullable<VariantProps<typeof fieldVariants>['size']>;\n\nexport interface InputProps extends Omit<ComponentProps<'input'>, 'size'>, VariantProps<typeof fieldVariants> {}\n\n/** The one text field: deep well, quiet border, accent border on focus, red edge when invalid. */\nexport function Input({ className, type, variant, size, ...props }: InputProps) {\n return (\n <input\n type={type ?? 'text'}\n data-slot=\"input\"\n spellCheck={false}\n className={cn(fieldVariants({ variant, size }), className)}\n {...props}\n />\n );\n}\n"],"mappings":"oEAUA,MAAa,GAAA,oCAAgBA,CAAAA,CAAAA,IAAAA,CAC3B,2JACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,6FAET,KAAM,yBACR,EAEA,KAAM,CACJ,GAAI,iCACJ,GAAI,4BACJ,GAAI,gCACJ,GAAI,+BACN,CACF,EACA,iBAAkB,CAGhB,CAAE,QAAS,OAAQ,MAAO,aAAc,CAC1C,EACA,gBAAiB,CAAE,QAAS,UAAW,KAAM,IAAK,CACpD,CACF,EAQA,SAAgB,EAAM,CAAE,YAAW,OAAM,UAAS,OAAM,GAAG,GAAqB,CAC9E,MACE,iBAAA,EAAA,EAAA,IAAA,CAAC,QAAD,CACE,KAAM,GAAQ,OACd,YAAU,QACV,WAAY,GACZ,UAAWC,EAAAA,GAAG,EAAc,CAAE,UAAS,MAAK,CAAC,EAAG,CAAS,EACzD,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cn as e}from"../lib/cn.mjs";import{jsx as t}from"react/jsx-runtime";import{cva as n}from"class-variance-authority";const r=n(`min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red`,{variants:{variant:{default:`rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60`,bare:`border-0 bg-transparent`},size:{xs:`px-1.5 py-0.5 text-2xs`,sm:`px-2 py-1 text-xs`,md:`px-2.5 py-1.5 text-sm`,lg:`px-3 py-
|
|
1
|
+
import{cn as e}from"../lib/cn.mjs";import{jsx as t}from"react/jsx-runtime";import{cva as n}from"class-variance-authority";const r=n(`min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red`,{variants:{variant:{default:`rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60`,bare:`border-0 bg-transparent`},size:{xs:`min-h-6 px-1.5 py-0.5 text-2xs`,sm:`min-h-7 px-2 py-1 text-xs`,md:`min-h-8 px-2.5 py-1.5 text-sm`,lg:`min-h-9 px-3 py-1.5 text-base`}},compoundVariants:[{variant:`bare`,class:`min-h-0 p-0`}],defaultVariants:{variant:`default`,size:`md`}});function i({className:n,type:i,variant:a,size:o,...s}){return/* @__PURE__ */ t(`input`,{type:i??`text`,"data-slot":`input`,spellCheck:!1,className:e(r({variant:a,size:o}),n),...s})}export{i as Input,r as fieldVariants};
|
|
2
2
|
//# sourceMappingURL=Input.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Input.mjs","names":[],"sources":["../../../src/components/Input.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The shape both fields wear, so a single-line and a multi-line field in the\n * same form agree on their well, their type ramp, and their invalid state.\n * Textarea builds on it rather than restating it.\n */\nexport const fieldVariants = cva(\n 'min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red',\n {\n variants: {\n variant: {\n default: 'rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60',\n /** No well: a composer or a palette search that draws its own surface. */\n bare: 'border-0 bg-transparent',\n },\n /** The same rungs Button names, so a field and the button beside it line up. */\n size: {\n xs: 'px-1.5 py-0.5 text-2xs',\n sm: 'px-2 py-1 text-xs',\n md: 'px-2.5 py-1.5 text-sm',\n lg: 'px-3 py-
|
|
1
|
+
{"version":3,"file":"Input.mjs","names":[],"sources":["../../../src/components/Input.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The shape both fields wear, so a single-line and a multi-line field in the\n * same form agree on their well, their type ramp, and their invalid state.\n * Textarea builds on it rather than restating it.\n */\nexport const fieldVariants = cva(\n 'min-w-0 font-mono text-doom-hi outline-none placeholder:text-doom-faint disabled:opacity-50 aria-invalid:border-doom-edge-red aria-invalid:text-doom-red',\n {\n variants: {\n variant: {\n default: 'rounded border border-doom-border bg-doom-deep transition-colors focus:border-doom-blue/60',\n /** No well: a composer or a palette search that draws its own surface. */\n bare: 'border-0 bg-transparent',\n },\n /** The same rungs Button names, so a field and the button beside it line up. */\n size: {\n xs: 'min-h-6 px-1.5 py-0.5 text-2xs',\n sm: 'min-h-7 px-2 py-1 text-xs',\n md: 'min-h-8 px-2.5 py-1.5 text-sm',\n lg: 'min-h-9 px-3 py-1.5 text-base',\n },\n },\n compoundVariants: [\n // A bare field sits inside a surface that already has its own padding,\n // so it keeps the size's type ramp and gives up the size's box.\n { variant: 'bare', class: 'min-h-0 p-0' },\n ],\n defaultVariants: { variant: 'default', size: 'md' },\n },\n);\n\nexport type FieldVariant = NonNullable<VariantProps<typeof fieldVariants>['variant']>;\nexport type FieldSize = NonNullable<VariantProps<typeof fieldVariants>['size']>;\n\nexport interface InputProps extends Omit<ComponentProps<'input'>, 'size'>, VariantProps<typeof fieldVariants> {}\n\n/** The one text field: deep well, quiet border, accent border on focus, red edge when invalid. */\nexport function Input({ className, type, variant, size, ...props }: InputProps) {\n return (\n <input\n type={type ?? 'text'}\n data-slot=\"input\"\n spellCheck={false}\n className={cn(fieldVariants({ variant, size }), className)}\n {...props}\n />\n );\n}\n"],"mappings":"0HAUA,MAAa,EAAgB,EAC3B,2JACA,CACE,SAAU,CACR,QAAS,CACP,QAAS,6FAET,KAAM,yBACR,EAEA,KAAM,CACJ,GAAI,iCACJ,GAAI,4BACJ,GAAI,gCACJ,GAAI,+BACN,CACF,EACA,iBAAkB,CAGhB,CAAE,QAAS,OAAQ,MAAO,aAAc,CAC1C,EACA,gBAAiB,CAAE,QAAS,UAAW,KAAM,IAAK,CACpD,CACF,EAQA,SAAgB,EAAM,CAAE,YAAW,OAAM,UAAS,OAAM,GAAG,GAAqB,CAC9E,MACE,kBAAC,QAAD,CACE,KAAM,GAAQ,OACd,YAAU,QACV,WAAY,GACZ,UAAW,EAAG,EAAc,CAAE,UAAS,MAAK,CAAC,EAAG,CAAS,EACzD,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../icons/icons.cjs");const e=require("../lib/cn.cjs"),t=require("./Button.cjs"),n=require("./StatusBadge.cjs");let r=require("react/jsx-runtime"),i=require("react"),a=require("class-variance-authority"),o=require("lucide-react");const s=(0,i.createContext)({tone:`neutral`,expandable:!1,expanded:!1,toggle:()=>void 0});function c(){return(0,i.useContext)(s)}const l=(0,i.createContext)(null),u=(0,a.cva)(`overflow-hidden rounded-md border bg-doom-panel transition-colors`,{variants:{tone:n.STATUS_EDGE},defaultVariants:{tone:`neutral`}}),d=(0,a.cva)(`overflow-hidden border-l-2 transition-colors`,{variants:{tone:n.STATUS_EDGE},defaultVariants:{tone:`neutral`}});function f({className:t,tone:n,expandable:a=!1,defaultExpanded:o=!1,expanded:c,onExpandedChange:f,children:p,...m}){let[h,g]=(0,i.useState)(o),_=(0,i.useContext)(l)!==null,v=c??h,y={tone:n??`neutral`,expandable:a,expanded:v,toggle:()=>{let e=!v;c===void 0&&g(e),f?.(e)}};return/* @__PURE__ */ (0,r.jsx)(s.Provider,{value:y,children:/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`message-item`,"data-expanded":v,"data-grouped":_,className:e.cn(_?d({tone:n}):u({tone:n}),t),...m,children:typeof p==`function`?p(y):p})})}function p({className:t,tone:i,title:a,summary:o,badge:s,children:c,...d}){let f=s===void 0?h[i??`neutral`]:s;return/* @__PURE__ */ (0,r.jsx)(l.Provider,{value:{tone:i??`neutral`},children:/* @__PURE__ */ (0,r.jsxs)(`div`,{"data-slot":`message-item-group`,className:e.cn(u({tone:i}),t),...d,children:[/* @__PURE__ */ (0,r.jsxs)(`div`,{className:`flex min-h-8 items-center gap-2 border-doom-border-soft border-b px-[11px] text-sm text-doom-dim`,children:[/* @__PURE__ */ (0,r.jsx)(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:a}),/* @__PURE__ */ (0,r.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-doom-faint`,children:o}),f!==null&&f!==``?/* @__PURE__ */ (0,r.jsx)(n.StatusBadge,{tone:i??`neutral`,children:f}):null]}),/* @__PURE__ */ (0,r.jsx)(`div`,{className:`flex flex-col divide-y divide-doom-border-soft`,children:c})]})})}function m(e){return e.running?`running`:e.isError?`error`:`ok`}const h={neutral:``,running:`RUNNING`,ok:`OK`,error:`ERROR`,info:`INFO`,accent:`NOTE`},g=/* @__PURE__ */ new Set([`ok`,`neutral`]);function _({className:a,title:s,badge:u,children:d,...f}){let{tone:p,expandable:m,expanded:_,toggle:v}=c(),y=(0,i.useContext)(l),b=y!==null&&g.has(p)?null:h[p],x=u===void 0?b:u;return/* @__PURE__ */ (0,r.jsxs)(`div`,{"data-slot":`message-item-header`,className:e.cn(`flex min-h-8 items-center gap-2 px-[11px] text-sm text-doom-dim`,a),...f,children:[y===null?/* @__PURE__ */ (0,r.jsx)(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:s}):null,/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`message-item-summary`,className:`flex min-w-0 flex-1 items-center gap-2`,children:d}),x!==null&&x!==``?/* @__PURE__ */ (0,r.jsx)(n.StatusBadge,{tone:p,"data-testid":`tool-status`,children:x}):null,m?/* @__PURE__ */ (0,r.jsx)(t.Button,{variant:`ghost`,size:`icon`,"data-testid":`tool-expand`,"aria-expanded":_,"aria-label":_?`collapse`:`expand`,onClick:v,className:`text-doom-faint hover:text-doom-blue`,children:_?/* @__PURE__ */ (0,r.jsx)(o.ChevronUp,{className:`h-3 w-3`}):/* @__PURE__ */ (0,r.jsx)(o.ChevronDown,{className:`h-3 w-3`})}):null]})}function v({className:t,...n}){return/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`message-item-body`,className:e.cn(`border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim`,t),...n})}const y={neutral:`…`,running:`◐`,ok:`✓`,error:`✗`,info:`●`,accent:`●`},b=(0,a.cva)(`shrink-0`,{variants:{tone:{neutral:`text-doom-faint`,running:`text-doom-yellow`,ok:`text-doom-green`,error:`text-doom-red`,info:`text-doom-blue`,accent:`text-doom-magenta`}},defaultVariants:{tone:`neutral`}});function x({className:t,tone:n,glyph:i,expands:a=!1,children:o,...s}){let{toggle:l}=c(),u=/* @__PURE__ */ (0,r.jsxs)(r.Fragment,{children:[/* @__PURE__ */ (0,r.jsx)(`span`,{className:b({tone:n}),children:i??y[n??`neutral`]}),/* @__PURE__ */ (0,r.jsx)(`span`,{children:o})]});return a?/* @__PURE__ */ (0,r.jsx)(`button`,{type:`button`,"data-slot":`message-item-status`,"data-testid":`tool-more`,onClick:l,className:e.cn(`flex cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue`,t),children:u}):/* @__PURE__ */ (0,r.jsx)(`span`,{"data-slot":`message-item-status`,className:e.cn(`flex items-center gap-1.5 text-doom-faint`,t),...s,children:u})}exports.MessageItem=f,exports.MessageItemBody=v,exports.MessageItemGroup=p,exports.MessageItemHeader=_,exports.MessageItemStatus=x,exports.STATUS_GLYPH=y,exports.STATUS_LABEL=h,exports.messageItemRowVariants=d,exports.messageItemStatusVariants=b,exports.messageItemVariants=u,exports.toolTone=m,exports.useMessageItem=c;
|
|
1
|
+
require("../icons/icons.cjs");const e=require("../lib/cn.cjs"),t=require("./Button.cjs"),n=require("./StatusBadge.cjs");let r=require("react/jsx-runtime"),i=require("react"),a=require("class-variance-authority"),o=require("lucide-react");const s=(0,i.createContext)({tone:`neutral`,expandable:!1,expanded:!1,toggle:()=>void 0});function c(){return(0,i.useContext)(s)}const l=(0,i.createContext)(null),u=(0,a.cva)(`overflow-hidden rounded-md border bg-doom-panel transition-colors`,{variants:{tone:n.STATUS_EDGE},defaultVariants:{tone:`neutral`}}),d=(0,a.cva)(`overflow-hidden border-l-2 transition-colors`,{variants:{tone:n.STATUS_EDGE},defaultVariants:{tone:`neutral`}});function f({className:t,tone:n,expandable:a=!1,defaultExpanded:o=!1,expanded:c,onExpandedChange:f,children:p,...m}){let[h,g]=(0,i.useState)(o),_=(0,i.useContext)(l)!==null,v=c??h,y={tone:n??`neutral`,expandable:a,expanded:v,toggle:()=>{let e=!v;c===void 0&&g(e),f?.(e)}};return/* @__PURE__ */ (0,r.jsx)(s.Provider,{value:y,children:/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`message-item`,"data-expanded":v,"data-grouped":_,className:e.cn(_?d({tone:n}):u({tone:n}),t),...m,children:typeof p==`function`?p(y):p})})}function p({className:t,tone:i,title:a,summary:o,badge:s,children:c,...d}){let f=s===void 0?h[i??`neutral`]:s;return/* @__PURE__ */ (0,r.jsx)(l.Provider,{value:{tone:i??`neutral`},children:/* @__PURE__ */ (0,r.jsxs)(`div`,{"data-slot":`message-item-group`,className:e.cn(u({tone:i}),t),...d,children:[/* @__PURE__ */ (0,r.jsxs)(`div`,{className:`flex min-h-8 items-center gap-2 border-doom-border-soft border-b px-[11px] text-sm text-doom-dim`,children:[/* @__PURE__ */ (0,r.jsx)(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:a}),/* @__PURE__ */ (0,r.jsx)(`span`,{className:`min-w-0 flex-1 truncate text-doom-faint`,children:o}),f!==null&&f!==``?/* @__PURE__ */ (0,r.jsx)(n.StatusBadge,{tone:i??`neutral`,children:f}):null]}),/* @__PURE__ */ (0,r.jsx)(`div`,{className:`flex flex-col divide-y divide-doom-border-soft`,children:c})]})})}function m(e){return e.running?`running`:e.isError?`error`:`ok`}const h={neutral:``,running:`RUNNING`,ok:`OK`,error:`ERROR`,info:`INFO`,accent:`NOTE`},g=/* @__PURE__ */ new Set([`ok`,`neutral`]);function _({className:a,title:s,badge:u,children:d,...f}){let{tone:p,expandable:m,expanded:_,toggle:v}=c(),y=(0,i.useContext)(l),b=y!==null&&g.has(p)?null:h[p],x=u===void 0?b:u;return/* @__PURE__ */ (0,r.jsxs)(`div`,{"data-slot":`message-item-header`,className:e.cn(`flex min-h-8 items-center gap-2 px-[11px] text-sm text-doom-dim`,a),...f,children:[y===null?/* @__PURE__ */ (0,r.jsx)(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:s}):null,/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`message-item-summary`,className:`flex min-w-0 flex-1 items-center gap-2`,children:d}),x!==null&&x!==``?/* @__PURE__ */ (0,r.jsx)(n.StatusBadge,{tone:p,"data-testid":`tool-status`,children:x}):null,m?/* @__PURE__ */ (0,r.jsx)(t.Button,{variant:`ghost`,size:`icon`,"data-testid":`tool-expand`,"aria-expanded":_,"aria-label":_?`collapse`:`expand`,onClick:v,className:`text-doom-faint hover:text-doom-blue`,children:_?/* @__PURE__ */ (0,r.jsx)(o.ChevronUp,{className:`h-3 w-3`}):/* @__PURE__ */ (0,r.jsx)(o.ChevronDown,{className:`h-3 w-3`})}):null]})}function v({className:t,...n}){return/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`message-item-body`,className:e.cn(`border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim`,t),...n})}const y={neutral:`…`,running:`◐`,ok:`✓`,error:`✗`,info:`●`,accent:`●`},b=(0,a.cva)(`shrink-0`,{variants:{tone:{neutral:`text-doom-faint`,running:`text-doom-yellow`,ok:`text-doom-green`,error:`text-doom-red`,info:`text-doom-blue`,accent:`text-doom-magenta`}},defaultVariants:{tone:`neutral`}});function x({className:t,tone:n,glyph:i,expands:a=!1,children:o,...s}){let{toggle:l}=c(),u=/* @__PURE__ */ (0,r.jsxs)(r.Fragment,{children:[/* @__PURE__ */ (0,r.jsx)(`span`,{className:b({tone:n}),children:i??y[n??`neutral`]}),/* @__PURE__ */ (0,r.jsx)(`span`,{children:o})]});return a?/* @__PURE__ */ (0,r.jsx)(`button`,{type:`button`,"data-slot":`message-item-status`,"data-testid":`tool-more`,onClick:l,className:e.cn(`flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue`,t),children:u}):/* @__PURE__ */ (0,r.jsx)(`span`,{"data-slot":`message-item-status`,className:e.cn(`flex items-center gap-1.5 text-doom-faint`,t),...s,children:u})}exports.MessageItem=f,exports.MessageItemBody=v,exports.MessageItemGroup=p,exports.MessageItemHeader=_,exports.MessageItemStatus=x,exports.STATUS_GLYPH=y,exports.STATUS_LABEL=h,exports.messageItemRowVariants=d,exports.messageItemStatusVariants=b,exports.messageItemVariants=u,exports.toolTone=m,exports.useMessageItem=c;
|
|
2
2
|
//# sourceMappingURL=MessageItem.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageItem.cjs","names":["createContext","useContext","cva","STATUS_EDGE","useState","cn","StatusBadge","Button","ChevronUpIcon","ChevronDownIcon"],"sources":["../../../src/components/MessageItem.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { type ComponentProps, createContext, type ReactNode, useContext, useState } from 'react';\n\nimport { ChevronDownIcon, ChevronUpIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\nimport { STATUS_EDGE, StatusBadge, type StatusTone } from './StatusBadge';\n\n/**\n * The message item: the timeline card a tool call, a run, or a notice sits\n * in. The item owns its outcome tone and its expand state; the header, body,\n * and status parts read both from it, so a card composes the parts and never\n * threads `expanded` by hand. A tool message in a web plugin is built from\n * this, and so is the cockpit's own fallback item, which is what keeps them\n * looking alike.\n */\n\nexport interface MessageItemState {\n tone: StatusTone;\n /** Whether the header offers the toggle; an item that hides nothing offers none. */\n expandable: boolean;\n expanded: boolean;\n toggle: () => void;\n}\n\nconst MessageItemContext = createContext<MessageItemState>({\n tone: 'neutral',\n expandable: false,\n expanded: false,\n toggle: () => undefined,\n});\n\n/** The enclosing item's state, for a part that lives deeper than the item's render prop. */\nexport function useMessageItem(): MessageItemState {\n return useContext(MessageItemContext);\n}\n\n/**\n * The group an item is a row of, or null for an item that is a card of its\n * own. A row drops the frame the group already draws and keeps its tone as an\n * edge down its left side, and it stops repeating what the group's header has\n * said once: the tool's name, and an outcome the whole run shares.\n */\nconst MessageItemGroupContext = createContext<{ tone: StatusTone } | null>(null);\n\n/** The frame, wearing the edge STATUS_EDGE names for the tone, so the two never drift apart. */\nexport const messageItemVariants = cva('overflow-hidden rounded-md border bg-doom-panel transition-colors', {\n variants: { tone: STATUS_EDGE },\n defaultVariants: { tone: 'neutral' },\n});\n\n/** The same tone as a row: no card, one coloured edge, and the group's separators between rows. */\nexport const messageItemRowVariants = cva('overflow-hidden border-l-2 transition-colors', {\n variants: { tone: STATUS_EDGE },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemProps\n extends Omit<ComponentProps<'div'>, 'children'>, VariantProps<typeof messageItemVariants> {\n /** Whether the header offers the expand toggle. A toggle that reveals nothing reads as broken, so the card decides. */\n expandable?: boolean;\n defaultExpanded?: boolean;\n /** Controlled mode; pair with onExpandedChange. Omit it and the item keeps its own state. */\n expanded?: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n /** Plain content, or a function of the item's state for a card that picks its lines by `expanded`. */\n children?: ReactNode | ((state: MessageItemState) => ReactNode);\n}\n\nexport function MessageItem({\n className,\n tone,\n expandable = false,\n defaultExpanded = false,\n expanded,\n onExpandedChange,\n children,\n ...props\n}: MessageItemProps) {\n const [own, setOwn] = useState(defaultExpanded);\n const group = useContext(MessageItemGroupContext);\n const grouped = group !== null;\n const current = expanded ?? own;\n const state: MessageItemState = {\n tone: tone ?? 'neutral',\n expandable,\n expanded: current,\n toggle: () => {\n const next = !current;\n if (expanded === undefined) setOwn(next);\n onExpandedChange?.(next);\n },\n };\n return (\n <MessageItemContext.Provider value={state}>\n <div\n data-slot=\"message-item\"\n data-expanded={current}\n data-grouped={grouped}\n className={cn(grouped ? messageItemRowVariants({ tone }) : messageItemVariants({ tone }), className)}\n {...props}\n >\n {typeof children === 'function' ? children(state) : children}\n </div>\n </MessageItemContext.Provider>\n );\n}\n\nexport interface MessageItemGroupProps\n extends Omit<ComponentProps<'div'>, 'title'>, VariantProps<typeof messageItemVariants> {\n /** The bold label at the left of the group header: the tool the run belongs to. */\n title: ReactNode;\n /** The line beside it, such as how many calls the group holds. */\n summary?: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n children?: ReactNode;\n}\n\n/**\n * One frame around a run of items that belong together.\n *\n * A transcript that calls the same tool five times in a row is five identical\n * frames, five gutter labels and five gaps, and the repetition reads louder\n * than the commands do. The group draws the frame once and each item inside it\n * becomes a row: same header, same expand, no card of its own. The tone still\n * belongs to the row, as an edge, so a failure in the middle of a run is not\n * flattened into the group's own outcome.\n */\nexport function MessageItemGroup({\n className,\n tone,\n title,\n summary,\n badge,\n children,\n ...props\n}: MessageItemGroupProps) {\n const label = badge === undefined ? STATUS_LABEL[tone ?? 'neutral'] : badge;\n return (\n <MessageItemGroupContext.Provider value={{ tone: tone ?? 'neutral' }}>\n <div data-slot=\"message-item-group\" className={cn(messageItemVariants({ tone }), className)} {...props}>\n <div className=\"flex min-h-8 items-center gap-2 border-doom-border-soft border-b px-[11px] text-sm text-doom-dim\">\n <span className=\"shrink-0 font-bold text-doom-hi\">{title}</span>\n <span className=\"min-w-0 flex-1 truncate text-doom-faint\">{summary}</span>\n {label !== null && label !== '' ? <StatusBadge tone={tone ?? 'neutral'}>{label}</StatusBadge> : null}\n </div>\n <div className=\"flex flex-col divide-y divide-doom-border-soft\">{children}</div>\n </div>\n </MessageItemGroupContext.Provider>\n );\n}\n\n/** The tone a tool call's item wears: running while the tool runs, then its outcome. */\nexport function toolTone(state: { running: boolean; isError: boolean }): StatusTone {\n return state.running ? 'running' : state.isError ? 'error' : 'ok';\n}\n\n/** The badge text a tone reads as when the header is not told otherwise; empty hides the badge. */\nexport const STATUS_LABEL: Readonly<Record<StatusTone, string>> = {\n neutral: '',\n running: 'RUNNING',\n ok: 'OK',\n error: 'ERROR',\n info: 'INFO',\n accent: 'NOTE',\n};\n\nexport interface MessageItemHeaderProps extends Omit<ComponentProps<'div'>, 'title'> {\n /** The bold label at the left: the tool name. */\n title: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n /** The summary beside the title; it gets the remaining width. */\n children?: ReactNode;\n}\n\n/** Inside a group these two are the quiet outcome: the group's header has already said it. */\nconst SILENT_IN_GROUP: ReadonlySet<StatusTone> = new Set<StatusTone>(['ok', 'neutral']);\n\n/**\n * The title row: label, summary, the tone's badge, and the expand toggle when\n * the item is expandable.\n *\n * A row inside a group says less. The group's header has already named the\n * tool and stated the run's outcome, so the row drops its title and speaks up\n * only when something went wrong or is still going: five OK badges down a run\n * of five are noise, and the one ERROR among them is the point.\n */\nexport function MessageItemHeader({ className, title, badge, children, ...props }: MessageItemHeaderProps) {\n const { tone, expandable, expanded, toggle } = useMessageItem();\n const group = useContext(MessageItemGroupContext);\n const defaultLabel = group !== null && SILENT_IN_GROUP.has(tone) ? null : STATUS_LABEL[tone];\n const label = badge === undefined ? defaultLabel : badge;\n return (\n <div\n data-slot=\"message-item-header\"\n className={cn('flex min-h-8 items-center gap-2 px-[11px] text-sm text-doom-dim', className)}\n {...props}\n >\n {group === null ? <span className=\"shrink-0 font-bold text-doom-hi\">{title}</span> : null}\n <div data-slot=\"message-item-summary\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n {children}\n </div>\n {label !== null && label !== '' ? (\n <StatusBadge tone={tone} data-testid=\"tool-status\">\n {label}\n </StatusBadge>\n ) : null}\n {expandable ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"tool-expand\"\n aria-expanded={expanded}\n aria-label={expanded ? 'collapse' : 'expand'}\n onClick={toggle}\n className=\"text-doom-faint hover:text-doom-blue\"\n >\n {expanded ? <ChevronUpIcon className=\"h-3 w-3\" /> : <ChevronDownIcon className=\"h-3 w-3\" />}\n </Button>\n ) : null}\n </div>\n );\n}\n\n/** The recessed body under the header. */\nexport function MessageItemBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"message-item-body\"\n className={cn('border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim', className)}\n {...props}\n />\n );\n}\n\n/** The glyph a tone reads as in a status line. */\nexport const STATUS_GLYPH: Readonly<Record<StatusTone, string>> = {\n neutral: '…',\n running: '◐',\n ok: '✓',\n error: '✗',\n info: '●',\n accent: '●',\n};\n\nexport const messageItemStatusVariants = cva('shrink-0', {\n variants: {\n tone: {\n neutral: 'text-doom-faint',\n running: 'text-doom-yellow',\n ok: 'text-doom-green',\n error: 'text-doom-red',\n info: 'text-doom-blue',\n accent: 'text-doom-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemStatusProps extends ComponentProps<'span'>, VariantProps<typeof messageItemStatusVariants> {\n /** Replaces the tone's glyph. */\n glyph?: string;\n /** Renders as a button that expands the item: the \"N more line(s)\" hint. Only className carries over. */\n expands?: boolean;\n}\n\n/** The one-line status under a body: `◐ running`, `✗ failed`, `✓ done`, or the hint that more is hidden. */\nexport function MessageItemStatus({\n className,\n tone,\n glyph,\n expands = false,\n children,\n ...props\n}: MessageItemStatusProps) {\n const { toggle } = useMessageItem();\n const content = (\n <>\n <span className={messageItemStatusVariants({ tone })}>{glyph ?? STATUS_GLYPH[tone ?? 'neutral']}</span>\n <span>{children}</span>\n </>\n );\n if (expands) {\n return (\n <button\n type=\"button\"\n data-slot=\"message-item-status\"\n data-testid=\"tool-more\"\n onClick={toggle}\n className={cn('flex cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue', className)}\n >\n {content}\n </button>\n );\n }\n return (\n <span\n data-slot=\"message-item-status\"\n className={cn('flex items-center gap-1.5 text-doom-faint', className)}\n {...props}\n >\n {content}\n </span>\n );\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"MessageItem.cjs","names":["createContext","useContext","cva","STATUS_EDGE","useState","cn","StatusBadge","Button","ChevronUpIcon","ChevronDownIcon"],"sources":["../../../src/components/MessageItem.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { type ComponentProps, createContext, type ReactNode, useContext, useState } from 'react';\n\nimport { ChevronDownIcon, ChevronUpIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\nimport { STATUS_EDGE, StatusBadge, type StatusTone } from './StatusBadge';\n\n/**\n * The message item: the timeline card a tool call, a run, or a notice sits\n * in. The item owns its outcome tone and its expand state; the header, body,\n * and status parts read both from it, so a card composes the parts and never\n * threads `expanded` by hand. A tool message in a web plugin is built from\n * this, and so is the cockpit's own fallback item, which is what keeps them\n * looking alike.\n */\n\nexport interface MessageItemState {\n tone: StatusTone;\n /** Whether the header offers the toggle; an item that hides nothing offers none. */\n expandable: boolean;\n expanded: boolean;\n toggle: () => void;\n}\n\nconst MessageItemContext = createContext<MessageItemState>({\n tone: 'neutral',\n expandable: false,\n expanded: false,\n toggle: () => undefined,\n});\n\n/** The enclosing item's state, for a part that lives deeper than the item's render prop. */\nexport function useMessageItem(): MessageItemState {\n return useContext(MessageItemContext);\n}\n\n/**\n * The group an item is a row of, or null for an item that is a card of its\n * own. A row drops the frame the group already draws and keeps its tone as an\n * edge down its left side, and it stops repeating what the group's header has\n * said once: the tool's name, and an outcome the whole run shares.\n */\nconst MessageItemGroupContext = createContext<{ tone: StatusTone } | null>(null);\n\n/** The frame, wearing the edge STATUS_EDGE names for the tone, so the two never drift apart. */\nexport const messageItemVariants = cva('overflow-hidden rounded-md border bg-doom-panel transition-colors', {\n variants: { tone: STATUS_EDGE },\n defaultVariants: { tone: 'neutral' },\n});\n\n/** The same tone as a row: no card, one coloured edge, and the group's separators between rows. */\nexport const messageItemRowVariants = cva('overflow-hidden border-l-2 transition-colors', {\n variants: { tone: STATUS_EDGE },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemProps\n extends Omit<ComponentProps<'div'>, 'children'>, VariantProps<typeof messageItemVariants> {\n /** Whether the header offers the expand toggle. A toggle that reveals nothing reads as broken, so the card decides. */\n expandable?: boolean;\n defaultExpanded?: boolean;\n /** Controlled mode; pair with onExpandedChange. Omit it and the item keeps its own state. */\n expanded?: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n /** Plain content, or a function of the item's state for a card that picks its lines by `expanded`. */\n children?: ReactNode | ((state: MessageItemState) => ReactNode);\n}\n\nexport function MessageItem({\n className,\n tone,\n expandable = false,\n defaultExpanded = false,\n expanded,\n onExpandedChange,\n children,\n ...props\n}: MessageItemProps) {\n const [own, setOwn] = useState(defaultExpanded);\n const group = useContext(MessageItemGroupContext);\n const grouped = group !== null;\n const current = expanded ?? own;\n const state: MessageItemState = {\n tone: tone ?? 'neutral',\n expandable,\n expanded: current,\n toggle: () => {\n const next = !current;\n if (expanded === undefined) setOwn(next);\n onExpandedChange?.(next);\n },\n };\n return (\n <MessageItemContext.Provider value={state}>\n <div\n data-slot=\"message-item\"\n data-expanded={current}\n data-grouped={grouped}\n className={cn(grouped ? messageItemRowVariants({ tone }) : messageItemVariants({ tone }), className)}\n {...props}\n >\n {typeof children === 'function' ? children(state) : children}\n </div>\n </MessageItemContext.Provider>\n );\n}\n\nexport interface MessageItemGroupProps\n extends Omit<ComponentProps<'div'>, 'title'>, VariantProps<typeof messageItemVariants> {\n /** The bold label at the left of the group header: the tool the run belongs to. */\n title: ReactNode;\n /** The line beside it, such as how many calls the group holds. */\n summary?: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n children?: ReactNode;\n}\n\n/**\n * One frame around a run of items that belong together.\n *\n * A transcript that calls the same tool five times in a row is five identical\n * frames, five gutter labels and five gaps, and the repetition reads louder\n * than the commands do. The group draws the frame once and each item inside it\n * becomes a row: same header, same expand, no card of its own. The tone still\n * belongs to the row, as an edge, so a failure in the middle of a run is not\n * flattened into the group's own outcome.\n */\nexport function MessageItemGroup({\n className,\n tone,\n title,\n summary,\n badge,\n children,\n ...props\n}: MessageItemGroupProps) {\n const label = badge === undefined ? STATUS_LABEL[tone ?? 'neutral'] : badge;\n return (\n <MessageItemGroupContext.Provider value={{ tone: tone ?? 'neutral' }}>\n <div data-slot=\"message-item-group\" className={cn(messageItemVariants({ tone }), className)} {...props}>\n <div className=\"flex min-h-8 items-center gap-2 border-doom-border-soft border-b px-[11px] text-sm text-doom-dim\">\n <span className=\"shrink-0 font-bold text-doom-hi\">{title}</span>\n <span className=\"min-w-0 flex-1 truncate text-doom-faint\">{summary}</span>\n {label !== null && label !== '' ? <StatusBadge tone={tone ?? 'neutral'}>{label}</StatusBadge> : null}\n </div>\n <div className=\"flex flex-col divide-y divide-doom-border-soft\">{children}</div>\n </div>\n </MessageItemGroupContext.Provider>\n );\n}\n\n/** The tone a tool call's item wears: running while the tool runs, then its outcome. */\nexport function toolTone(state: { running: boolean; isError: boolean }): StatusTone {\n return state.running ? 'running' : state.isError ? 'error' : 'ok';\n}\n\n/** The badge text a tone reads as when the header is not told otherwise; empty hides the badge. */\nexport const STATUS_LABEL: Readonly<Record<StatusTone, string>> = {\n neutral: '',\n running: 'RUNNING',\n ok: 'OK',\n error: 'ERROR',\n info: 'INFO',\n accent: 'NOTE',\n};\n\nexport interface MessageItemHeaderProps extends Omit<ComponentProps<'div'>, 'title'> {\n /** The bold label at the left: the tool name. */\n title: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n /** The summary beside the title; it gets the remaining width. */\n children?: ReactNode;\n}\n\n/** Inside a group these two are the quiet outcome: the group's header has already said it. */\nconst SILENT_IN_GROUP: ReadonlySet<StatusTone> = new Set<StatusTone>(['ok', 'neutral']);\n\n/**\n * The title row: label, summary, the tone's badge, and the expand toggle when\n * the item is expandable.\n *\n * A row inside a group says less. The group's header has already named the\n * tool and stated the run's outcome, so the row drops its title and speaks up\n * only when something went wrong or is still going: five OK badges down a run\n * of five are noise, and the one ERROR among them is the point.\n */\nexport function MessageItemHeader({ className, title, badge, children, ...props }: MessageItemHeaderProps) {\n const { tone, expandable, expanded, toggle } = useMessageItem();\n const group = useContext(MessageItemGroupContext);\n const defaultLabel = group !== null && SILENT_IN_GROUP.has(tone) ? null : STATUS_LABEL[tone];\n const label = badge === undefined ? defaultLabel : badge;\n return (\n <div\n data-slot=\"message-item-header\"\n className={cn('flex min-h-8 items-center gap-2 px-[11px] text-sm text-doom-dim', className)}\n {...props}\n >\n {group === null ? <span className=\"shrink-0 font-bold text-doom-hi\">{title}</span> : null}\n <div data-slot=\"message-item-summary\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n {children}\n </div>\n {label !== null && label !== '' ? (\n <StatusBadge tone={tone} data-testid=\"tool-status\">\n {label}\n </StatusBadge>\n ) : null}\n {expandable ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"tool-expand\"\n aria-expanded={expanded}\n aria-label={expanded ? 'collapse' : 'expand'}\n onClick={toggle}\n className=\"text-doom-faint hover:text-doom-blue\"\n >\n {expanded ? <ChevronUpIcon className=\"h-3 w-3\" /> : <ChevronDownIcon className=\"h-3 w-3\" />}\n </Button>\n ) : null}\n </div>\n );\n}\n\n/** The recessed body under the header. */\nexport function MessageItemBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"message-item-body\"\n className={cn('border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim', className)}\n {...props}\n />\n );\n}\n\n/** The glyph a tone reads as in a status line. */\nexport const STATUS_GLYPH: Readonly<Record<StatusTone, string>> = {\n neutral: '…',\n running: '◐',\n ok: '✓',\n error: '✗',\n info: '●',\n accent: '●',\n};\n\nexport const messageItemStatusVariants = cva('shrink-0', {\n variants: {\n tone: {\n neutral: 'text-doom-faint',\n running: 'text-doom-yellow',\n ok: 'text-doom-green',\n error: 'text-doom-red',\n info: 'text-doom-blue',\n accent: 'text-doom-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemStatusProps extends ComponentProps<'span'>, VariantProps<typeof messageItemStatusVariants> {\n /** Replaces the tone's glyph. */\n glyph?: string;\n /** Renders as a button that expands the item: the \"N more line(s)\" hint. Only className carries over. */\n expands?: boolean;\n}\n\n/** The one-line status under a body: `◐ running`, `✗ failed`, `✓ done`, or the hint that more is hidden. */\nexport function MessageItemStatus({\n className,\n tone,\n glyph,\n expands = false,\n children,\n ...props\n}: MessageItemStatusProps) {\n const { toggle } = useMessageItem();\n const content = (\n <>\n <span className={messageItemStatusVariants({ tone })}>{glyph ?? STATUS_GLYPH[tone ?? 'neutral']}</span>\n <span>{children}</span>\n </>\n );\n if (expands) {\n return (\n <button\n type=\"button\"\n data-slot=\"message-item-status\"\n data-testid=\"tool-more\"\n onClick={toggle}\n className={cn(\n 'flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue',\n className,\n )}\n >\n {content}\n </button>\n );\n }\n return (\n <span\n data-slot=\"message-item-status\"\n className={cn('flex items-center gap-1.5 text-doom-faint', className)}\n {...props}\n >\n {content}\n </span>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{ChevronDownIcon as e,ChevronUpIcon as t}from"../icons/icons.mjs";import{cn as n}from"../lib/cn.mjs";import{Button as r}from"./Button.mjs";import{STATUS_EDGE as i,StatusBadge as a}from"./StatusBadge.mjs";import{Fragment as o,jsx as s,jsxs as c}from"react/jsx-runtime";import{createContext as l,useContext as u,useState as d}from"react";import{cva as f}from"class-variance-authority";const p=l({tone:`neutral`,expandable:!1,expanded:!1,toggle:()=>void 0});function m(){return u(p)}const h=l(null),g=f(`overflow-hidden rounded-md border bg-doom-panel transition-colors`,{variants:{tone:i},defaultVariants:{tone:`neutral`}}),_=f(`overflow-hidden border-l-2 transition-colors`,{variants:{tone:i},defaultVariants:{tone:`neutral`}});function v({className:e,tone:t,expandable:r=!1,defaultExpanded:i=!1,expanded:a,onExpandedChange:o,children:c,...l}){let[f,m]=d(i),v=u(h)!==null,y=a??f,b={tone:t??`neutral`,expandable:r,expanded:y,toggle:()=>{let e=!y;a===void 0&&m(e),o?.(e)}};return/* @__PURE__ */ s(p.Provider,{value:b,children:/* @__PURE__ */ s(`div`,{"data-slot":`message-item`,"data-expanded":y,"data-grouped":v,className:n(v?_({tone:t}):g({tone:t}),e),...l,children:typeof c==`function`?c(b):c})})}function y({className:e,tone:t,title:r,summary:i,badge:o,children:l,...u}){let d=o===void 0?x[t??`neutral`]:o;return/* @__PURE__ */ s(h.Provider,{value:{tone:t??`neutral`},children:/* @__PURE__ */ c(`div`,{"data-slot":`message-item-group`,className:n(g({tone:t}),e),...u,children:[/* @__PURE__ */ c(`div`,{className:`flex min-h-8 items-center gap-2 border-doom-border-soft border-b px-[11px] text-sm text-doom-dim`,children:[/* @__PURE__ */ s(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:r}),/* @__PURE__ */ s(`span`,{className:`min-w-0 flex-1 truncate text-doom-faint`,children:i}),d!==null&&d!==``?/* @__PURE__ */ s(a,{tone:t??`neutral`,children:d}):null]}),/* @__PURE__ */ s(`div`,{className:`flex flex-col divide-y divide-doom-border-soft`,children:l})]})})}function b(e){return e.running?`running`:e.isError?`error`:`ok`}const x={neutral:``,running:`RUNNING`,ok:`OK`,error:`ERROR`,info:`INFO`,accent:`NOTE`},S=/* @__PURE__ */ new Set([`ok`,`neutral`]);function C({className:i,title:o,badge:l,children:d,...f}){let{tone:p,expandable:g,expanded:_,toggle:v}=m(),y=u(h),b=y!==null&&S.has(p)?null:x[p],C=l===void 0?b:l;return/* @__PURE__ */ c(`div`,{"data-slot":`message-item-header`,className:n(`flex min-h-8 items-center gap-2 px-[11px] text-sm text-doom-dim`,i),...f,children:[y===null?/* @__PURE__ */ s(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:o}):null,/* @__PURE__ */ s(`div`,{"data-slot":`message-item-summary`,className:`flex min-w-0 flex-1 items-center gap-2`,children:d}),C!==null&&C!==``?/* @__PURE__ */ s(a,{tone:p,"data-testid":`tool-status`,children:C}):null,g?/* @__PURE__ */ s(r,{variant:`ghost`,size:`icon`,"data-testid":`tool-expand`,"aria-expanded":_,"aria-label":_?`collapse`:`expand`,onClick:v,className:`text-doom-faint hover:text-doom-blue`,children:s(_?t:e,{className:`h-3 w-3`})}):null]})}function w({className:e,...t}){return/* @__PURE__ */ s(`div`,{"data-slot":`message-item-body`,className:n(`border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim`,e),...t})}const T={neutral:`…`,running:`◐`,ok:`✓`,error:`✗`,info:`●`,accent:`●`},E=f(`shrink-0`,{variants:{tone:{neutral:`text-doom-faint`,running:`text-doom-yellow`,ok:`text-doom-green`,error:`text-doom-red`,info:`text-doom-blue`,accent:`text-doom-magenta`}},defaultVariants:{tone:`neutral`}});function D({className:e,tone:t,glyph:r,expands:i=!1,children:a,...l}){let{toggle:u}=m(),d=/* @__PURE__ */ c(o,{children:[/* @__PURE__ */ s(`span`,{className:E({tone:t}),children:r??T[t??`neutral`]}),/* @__PURE__ */ s(`span`,{children:a})]});return i?/* @__PURE__ */ s(`button`,{type:`button`,"data-slot":`message-item-status`,"data-testid":`tool-more`,onClick:u,className:n(`flex cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue`,e),children:d}):/* @__PURE__ */ s(`span`,{"data-slot":`message-item-status`,className:n(`flex items-center gap-1.5 text-doom-faint`,e),...l,children:d})}export{v as MessageItem,w as MessageItemBody,y as MessageItemGroup,C as MessageItemHeader,D as MessageItemStatus,T as STATUS_GLYPH,x as STATUS_LABEL,_ as messageItemRowVariants,E as messageItemStatusVariants,g as messageItemVariants,b as toolTone,m as useMessageItem};
|
|
1
|
+
import{ChevronDownIcon as e,ChevronUpIcon as t}from"../icons/icons.mjs";import{cn as n}from"../lib/cn.mjs";import{Button as r}from"./Button.mjs";import{STATUS_EDGE as i,StatusBadge as a}from"./StatusBadge.mjs";import{Fragment as o,jsx as s,jsxs as c}from"react/jsx-runtime";import{createContext as l,useContext as u,useState as d}from"react";import{cva as f}from"class-variance-authority";const p=l({tone:`neutral`,expandable:!1,expanded:!1,toggle:()=>void 0});function m(){return u(p)}const h=l(null),g=f(`overflow-hidden rounded-md border bg-doom-panel transition-colors`,{variants:{tone:i},defaultVariants:{tone:`neutral`}}),_=f(`overflow-hidden border-l-2 transition-colors`,{variants:{tone:i},defaultVariants:{tone:`neutral`}});function v({className:e,tone:t,expandable:r=!1,defaultExpanded:i=!1,expanded:a,onExpandedChange:o,children:c,...l}){let[f,m]=d(i),v=u(h)!==null,y=a??f,b={tone:t??`neutral`,expandable:r,expanded:y,toggle:()=>{let e=!y;a===void 0&&m(e),o?.(e)}};return/* @__PURE__ */ s(p.Provider,{value:b,children:/* @__PURE__ */ s(`div`,{"data-slot":`message-item`,"data-expanded":y,"data-grouped":v,className:n(v?_({tone:t}):g({tone:t}),e),...l,children:typeof c==`function`?c(b):c})})}function y({className:e,tone:t,title:r,summary:i,badge:o,children:l,...u}){let d=o===void 0?x[t??`neutral`]:o;return/* @__PURE__ */ s(h.Provider,{value:{tone:t??`neutral`},children:/* @__PURE__ */ c(`div`,{"data-slot":`message-item-group`,className:n(g({tone:t}),e),...u,children:[/* @__PURE__ */ c(`div`,{className:`flex min-h-8 items-center gap-2 border-doom-border-soft border-b px-[11px] text-sm text-doom-dim`,children:[/* @__PURE__ */ s(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:r}),/* @__PURE__ */ s(`span`,{className:`min-w-0 flex-1 truncate text-doom-faint`,children:i}),d!==null&&d!==``?/* @__PURE__ */ s(a,{tone:t??`neutral`,children:d}):null]}),/* @__PURE__ */ s(`div`,{className:`flex flex-col divide-y divide-doom-border-soft`,children:l})]})})}function b(e){return e.running?`running`:e.isError?`error`:`ok`}const x={neutral:``,running:`RUNNING`,ok:`OK`,error:`ERROR`,info:`INFO`,accent:`NOTE`},S=/* @__PURE__ */ new Set([`ok`,`neutral`]);function C({className:i,title:o,badge:l,children:d,...f}){let{tone:p,expandable:g,expanded:_,toggle:v}=m(),y=u(h),b=y!==null&&S.has(p)?null:x[p],C=l===void 0?b:l;return/* @__PURE__ */ c(`div`,{"data-slot":`message-item-header`,className:n(`flex min-h-8 items-center gap-2 px-[11px] text-sm text-doom-dim`,i),...f,children:[y===null?/* @__PURE__ */ s(`span`,{className:`shrink-0 font-bold text-doom-hi`,children:o}):null,/* @__PURE__ */ s(`div`,{"data-slot":`message-item-summary`,className:`flex min-w-0 flex-1 items-center gap-2`,children:d}),C!==null&&C!==``?/* @__PURE__ */ s(a,{tone:p,"data-testid":`tool-status`,children:C}):null,g?/* @__PURE__ */ s(r,{variant:`ghost`,size:`icon`,"data-testid":`tool-expand`,"aria-expanded":_,"aria-label":_?`collapse`:`expand`,onClick:v,className:`text-doom-faint hover:text-doom-blue`,children:s(_?t:e,{className:`h-3 w-3`})}):null]})}function w({className:e,...t}){return/* @__PURE__ */ s(`div`,{"data-slot":`message-item-body`,className:n(`border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim`,e),...t})}const T={neutral:`…`,running:`◐`,ok:`✓`,error:`✗`,info:`●`,accent:`●`},E=f(`shrink-0`,{variants:{tone:{neutral:`text-doom-faint`,running:`text-doom-yellow`,ok:`text-doom-green`,error:`text-doom-red`,info:`text-doom-blue`,accent:`text-doom-magenta`}},defaultVariants:{tone:`neutral`}});function D({className:e,tone:t,glyph:r,expands:i=!1,children:a,...l}){let{toggle:u}=m(),d=/* @__PURE__ */ c(o,{children:[/* @__PURE__ */ s(`span`,{className:E({tone:t}),children:r??T[t??`neutral`]}),/* @__PURE__ */ s(`span`,{children:a})]});return i?/* @__PURE__ */ s(`button`,{type:`button`,"data-slot":`message-item-status`,"data-testid":`tool-more`,onClick:u,className:n(`flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue`,e),children:d}):/* @__PURE__ */ s(`span`,{"data-slot":`message-item-status`,className:n(`flex items-center gap-1.5 text-doom-faint`,e),...l,children:d})}export{v as MessageItem,w as MessageItemBody,y as MessageItemGroup,C as MessageItemHeader,D as MessageItemStatus,T as STATUS_GLYPH,x as STATUS_LABEL,_ as messageItemRowVariants,E as messageItemStatusVariants,g as messageItemVariants,b as toolTone,m as useMessageItem};
|
|
2
2
|
//# sourceMappingURL=MessageItem.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"MessageItem.mjs","names":[],"sources":["../../../src/components/MessageItem.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { type ComponentProps, createContext, type ReactNode, useContext, useState } from 'react';\n\nimport { ChevronDownIcon, ChevronUpIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\nimport { STATUS_EDGE, StatusBadge, type StatusTone } from './StatusBadge';\n\n/**\n * The message item: the timeline card a tool call, a run, or a notice sits\n * in. The item owns its outcome tone and its expand state; the header, body,\n * and status parts read both from it, so a card composes the parts and never\n * threads `expanded` by hand. A tool message in a web plugin is built from\n * this, and so is the cockpit's own fallback item, which is what keeps them\n * looking alike.\n */\n\nexport interface MessageItemState {\n tone: StatusTone;\n /** Whether the header offers the toggle; an item that hides nothing offers none. */\n expandable: boolean;\n expanded: boolean;\n toggle: () => void;\n}\n\nconst MessageItemContext = createContext<MessageItemState>({\n tone: 'neutral',\n expandable: false,\n expanded: false,\n toggle: () => undefined,\n});\n\n/** The enclosing item's state, for a part that lives deeper than the item's render prop. */\nexport function useMessageItem(): MessageItemState {\n return useContext(MessageItemContext);\n}\n\n/**\n * The group an item is a row of, or null for an item that is a card of its\n * own. A row drops the frame the group already draws and keeps its tone as an\n * edge down its left side, and it stops repeating what the group's header has\n * said once: the tool's name, and an outcome the whole run shares.\n */\nconst MessageItemGroupContext = createContext<{ tone: StatusTone } | null>(null);\n\n/** The frame, wearing the edge STATUS_EDGE names for the tone, so the two never drift apart. */\nexport const messageItemVariants = cva('overflow-hidden rounded-md border bg-doom-panel transition-colors', {\n variants: { tone: STATUS_EDGE },\n defaultVariants: { tone: 'neutral' },\n});\n\n/** The same tone as a row: no card, one coloured edge, and the group's separators between rows. */\nexport const messageItemRowVariants = cva('overflow-hidden border-l-2 transition-colors', {\n variants: { tone: STATUS_EDGE },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemProps\n extends Omit<ComponentProps<'div'>, 'children'>, VariantProps<typeof messageItemVariants> {\n /** Whether the header offers the expand toggle. A toggle that reveals nothing reads as broken, so the card decides. */\n expandable?: boolean;\n defaultExpanded?: boolean;\n /** Controlled mode; pair with onExpandedChange. Omit it and the item keeps its own state. */\n expanded?: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n /** Plain content, or a function of the item's state for a card that picks its lines by `expanded`. */\n children?: ReactNode | ((state: MessageItemState) => ReactNode);\n}\n\nexport function MessageItem({\n className,\n tone,\n expandable = false,\n defaultExpanded = false,\n expanded,\n onExpandedChange,\n children,\n ...props\n}: MessageItemProps) {\n const [own, setOwn] = useState(defaultExpanded);\n const group = useContext(MessageItemGroupContext);\n const grouped = group !== null;\n const current = expanded ?? own;\n const state: MessageItemState = {\n tone: tone ?? 'neutral',\n expandable,\n expanded: current,\n toggle: () => {\n const next = !current;\n if (expanded === undefined) setOwn(next);\n onExpandedChange?.(next);\n },\n };\n return (\n <MessageItemContext.Provider value={state}>\n <div\n data-slot=\"message-item\"\n data-expanded={current}\n data-grouped={grouped}\n className={cn(grouped ? messageItemRowVariants({ tone }) : messageItemVariants({ tone }), className)}\n {...props}\n >\n {typeof children === 'function' ? children(state) : children}\n </div>\n </MessageItemContext.Provider>\n );\n}\n\nexport interface MessageItemGroupProps\n extends Omit<ComponentProps<'div'>, 'title'>, VariantProps<typeof messageItemVariants> {\n /** The bold label at the left of the group header: the tool the run belongs to. */\n title: ReactNode;\n /** The line beside it, such as how many calls the group holds. */\n summary?: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n children?: ReactNode;\n}\n\n/**\n * One frame around a run of items that belong together.\n *\n * A transcript that calls the same tool five times in a row is five identical\n * frames, five gutter labels and five gaps, and the repetition reads louder\n * than the commands do. The group draws the frame once and each item inside it\n * becomes a row: same header, same expand, no card of its own. The tone still\n * belongs to the row, as an edge, so a failure in the middle of a run is not\n * flattened into the group's own outcome.\n */\nexport function MessageItemGroup({\n className,\n tone,\n title,\n summary,\n badge,\n children,\n ...props\n}: MessageItemGroupProps) {\n const label = badge === undefined ? STATUS_LABEL[tone ?? 'neutral'] : badge;\n return (\n <MessageItemGroupContext.Provider value={{ tone: tone ?? 'neutral' }}>\n <div data-slot=\"message-item-group\" className={cn(messageItemVariants({ tone }), className)} {...props}>\n <div className=\"flex min-h-8 items-center gap-2 border-doom-border-soft border-b px-[11px] text-sm text-doom-dim\">\n <span className=\"shrink-0 font-bold text-doom-hi\">{title}</span>\n <span className=\"min-w-0 flex-1 truncate text-doom-faint\">{summary}</span>\n {label !== null && label !== '' ? <StatusBadge tone={tone ?? 'neutral'}>{label}</StatusBadge> : null}\n </div>\n <div className=\"flex flex-col divide-y divide-doom-border-soft\">{children}</div>\n </div>\n </MessageItemGroupContext.Provider>\n );\n}\n\n/** The tone a tool call's item wears: running while the tool runs, then its outcome. */\nexport function toolTone(state: { running: boolean; isError: boolean }): StatusTone {\n return state.running ? 'running' : state.isError ? 'error' : 'ok';\n}\n\n/** The badge text a tone reads as when the header is not told otherwise; empty hides the badge. */\nexport const STATUS_LABEL: Readonly<Record<StatusTone, string>> = {\n neutral: '',\n running: 'RUNNING',\n ok: 'OK',\n error: 'ERROR',\n info: 'INFO',\n accent: 'NOTE',\n};\n\nexport interface MessageItemHeaderProps extends Omit<ComponentProps<'div'>, 'title'> {\n /** The bold label at the left: the tool name. */\n title: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n /** The summary beside the title; it gets the remaining width. */\n children?: ReactNode;\n}\n\n/** Inside a group these two are the quiet outcome: the group's header has already said it. */\nconst SILENT_IN_GROUP: ReadonlySet<StatusTone> = new Set<StatusTone>(['ok', 'neutral']);\n\n/**\n * The title row: label, summary, the tone's badge, and the expand toggle when\n * the item is expandable.\n *\n * A row inside a group says less. The group's header has already named the\n * tool and stated the run's outcome, so the row drops its title and speaks up\n * only when something went wrong or is still going: five OK badges down a run\n * of five are noise, and the one ERROR among them is the point.\n */\nexport function MessageItemHeader({ className, title, badge, children, ...props }: MessageItemHeaderProps) {\n const { tone, expandable, expanded, toggle } = useMessageItem();\n const group = useContext(MessageItemGroupContext);\n const defaultLabel = group !== null && SILENT_IN_GROUP.has(tone) ? null : STATUS_LABEL[tone];\n const label = badge === undefined ? defaultLabel : badge;\n return (\n <div\n data-slot=\"message-item-header\"\n className={cn('flex min-h-8 items-center gap-2 px-[11px] text-sm text-doom-dim', className)}\n {...props}\n >\n {group === null ? <span className=\"shrink-0 font-bold text-doom-hi\">{title}</span> : null}\n <div data-slot=\"message-item-summary\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n {children}\n </div>\n {label !== null && label !== '' ? (\n <StatusBadge tone={tone} data-testid=\"tool-status\">\n {label}\n </StatusBadge>\n ) : null}\n {expandable ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"tool-expand\"\n aria-expanded={expanded}\n aria-label={expanded ? 'collapse' : 'expand'}\n onClick={toggle}\n className=\"text-doom-faint hover:text-doom-blue\"\n >\n {expanded ? <ChevronUpIcon className=\"h-3 w-3\" /> : <ChevronDownIcon className=\"h-3 w-3\" />}\n </Button>\n ) : null}\n </div>\n );\n}\n\n/** The recessed body under the header. */\nexport function MessageItemBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"message-item-body\"\n className={cn('border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim', className)}\n {...props}\n />\n );\n}\n\n/** The glyph a tone reads as in a status line. */\nexport const STATUS_GLYPH: Readonly<Record<StatusTone, string>> = {\n neutral: '…',\n running: '◐',\n ok: '✓',\n error: '✗',\n info: '●',\n accent: '●',\n};\n\nexport const messageItemStatusVariants = cva('shrink-0', {\n variants: {\n tone: {\n neutral: 'text-doom-faint',\n running: 'text-doom-yellow',\n ok: 'text-doom-green',\n error: 'text-doom-red',\n info: 'text-doom-blue',\n accent: 'text-doom-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemStatusProps extends ComponentProps<'span'>, VariantProps<typeof messageItemStatusVariants> {\n /** Replaces the tone's glyph. */\n glyph?: string;\n /** Renders as a button that expands the item: the \"N more line(s)\" hint. Only className carries over. */\n expands?: boolean;\n}\n\n/** The one-line status under a body: `◐ running`, `✗ failed`, `✓ done`, or the hint that more is hidden. */\nexport function MessageItemStatus({\n className,\n tone,\n glyph,\n expands = false,\n children,\n ...props\n}: MessageItemStatusProps) {\n const { toggle } = useMessageItem();\n const content = (\n <>\n <span className={messageItemStatusVariants({ tone })}>{glyph ?? STATUS_GLYPH[tone ?? 'neutral']}</span>\n <span>{children}</span>\n </>\n );\n if (expands) {\n return (\n <button\n type=\"button\"\n data-slot=\"message-item-status\"\n data-testid=\"tool-more\"\n onClick={toggle}\n className={cn('flex cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue', className)}\n >\n {content}\n </button>\n );\n }\n return (\n <span\n data-slot=\"message-item-status\"\n className={cn('flex items-center gap-1.5 text-doom-faint', className)}\n {...props}\n >\n {content}\n </span>\n );\n}\n"],"mappings":"qYAyBA,MAAM,EAAqB,EAAgC,CACzD,KAAM,UACN,WAAY,GACZ,SAAU,GACV,WAAc,IAAA,EAChB,CAAC,EAGD,SAAgB,GAAmC,CACjD,OAAO,EAAW,CAAkB,CACtC,CAQA,MAAM,EAA0B,EAA2C,IAAI,EAGlE,EAAsB,EAAI,oEAAqE,CAC1G,SAAU,CAAE,KAAM,CAAY,EAC9B,gBAAiB,CAAE,KAAM,SAAU,CACrC,CAAC,EAGY,EAAyB,EAAI,+CAAgD,CACxF,SAAU,CAAE,KAAM,CAAY,EAC9B,gBAAiB,CAAE,KAAM,SAAU,CACrC,CAAC,EAcD,SAAgB,EAAY,CAC1B,YACA,OACA,aAAa,GACb,kBAAkB,GAClB,WACA,mBACA,WACA,GAAG,GACgB,CACnB,GAAM,CAAC,EAAK,GAAU,EAAS,CAAe,EAExC,EADQ,EAAW,CACL,IAAM,KACpB,EAAU,GAAY,EACtB,EAA0B,CAC9B,KAAM,GAAQ,UACd,aACA,SAAU,EACV,WAAc,CACZ,IAAM,EAAO,CAAC,EACV,IAAa,IAAA,IAAW,EAAO,CAAI,EACvC,IAAmB,CAAI,CACzB,CACF,EACA,MACE,kBAAC,EAAmB,SAApB,CAA6B,MAAO,EAClC,SAAA,kBAAC,MAAD,CACE,YAAU,eACV,gBAAe,EACf,eAAc,EACd,UAAW,EAAG,EAAU,EAAuB,CAAE,MAAK,CAAC,EAAI,EAAoB,CAAE,MAAK,CAAC,EAAG,CAAS,EACnG,GAAI,EAEH,SAAA,OAAO,GAAa,WAAa,EAAS,CAAK,EAAI,CACjD,CAAA,CACsB,CAAA,CAEjC,CAuBA,SAAgB,EAAiB,CAC/B,YACA,OACA,QACA,UACA,QACA,WACA,GAAG,GACqB,CACxB,IAAM,EAAQ,IAAU,IAAA,GAAY,EAAa,GAAQ,WAAa,EACtE,MACE,kBAAC,EAAwB,SAAzB,CAAkC,MAAO,CAAE,KAAM,GAAQ,SAAU,EACjE,SAAA,kBAAC,MAAD,CAAK,YAAU,qBAAqB,UAAW,EAAG,EAAoB,CAAE,MAAK,CAAC,EAAG,CAAS,EAAG,GAAI,EAAjG,SAAA,CACE,kBAAC,MAAD,CAAK,UAAU,mGAAf,SAAA,CACE,kBAAC,OAAD,CAAM,UAAU,kCAAmC,SAAA,CAAY,CAAA,EAC/D,kBAAC,OAAD,CAAM,UAAU,0CAA2C,SAAA,CAAc,CAAA,EACxE,IAAU,MAAQ,IAAU,GAAK,kBAAC,EAAD,CAAa,KAAM,GAAQ,UAAY,SAAA,CAAmB,CAAA,EAAI,IAC7F,CACL,CAAA,EAAA,kBAAC,MAAD,CAAK,UAAU,iDAAkD,UAAc,CAAA,CAC5E,GAC2B,CAAA,CAEtC,CAGA,SAAgB,EAAS,EAA2D,CAClF,OAAO,EAAM,QAAU,UAAY,EAAM,QAAU,QAAU,IAC/D,CAGA,MAAa,EAAqD,CAChE,QAAS,GACT,QAAS,UACT,GAAI,KACJ,MAAO,QACP,KAAM,OACN,OAAQ,MACV,EAYM,kBAA2C,IAAI,IAAgB,CAAC,KAAM,SAAS,CAAC,EAWtF,SAAgB,EAAkB,CAAE,YAAW,QAAO,QAAO,WAAU,GAAG,GAAiC,CACzG,GAAM,CAAE,OAAM,aAAY,WAAU,UAAW,EAAe,EACxD,EAAQ,EAAW,CAAuB,EAC1C,EAAe,IAAU,MAAQ,EAAgB,IAAI,CAAI,EAAI,KAAO,EAAa,GACjF,EAAQ,IAAU,IAAA,GAAY,EAAe,EACnD,MACE,kBAAC,MAAD,CACE,YAAU,sBACV,UAAW,EAAG,kEAAmE,CAAS,EAC1F,GAAI,EAHN,SAAA,CAKG,IAAU,KAAO,kBAAC,OAAD,CAAM,UAAU,kCAAmC,SAAA,CAAY,CAAA,EAAI,KACrF,kBAAC,MAAD,CAAK,YAAU,uBAAuB,UAAU,yCAC7C,UACE,CAAA,EACJ,IAAU,MAAQ,IAAU,GAC3B,kBAAC,EAAD,CAAmB,OAAM,cAAY,cAClC,SAAA,CACU,CAAA,EACX,KACH,EACC,kBAAC,EAAD,CACE,QAAQ,QACR,KAAK,OACL,cAAY,cACZ,gBAAe,EACf,aAAY,EAAW,WAAa,SACpC,QAAS,EACT,UAAU,uCAET,SAAW,EAAX,EAAY,EAAwC,EAAzC,CAAe,UAAU,SAAW,CAA0C,CACpF,CAAA,EACN,IACD,GAET,CAGA,SAAgB,EAAgB,CAAE,YAAW,GAAG,GAAgC,CAC9E,MACE,kBAAC,MAAD,CACE,YAAU,oBACV,UAAW,EAAG,gFAAiF,CAAS,EACxG,GAAI,CACL,CAAA,CAEL,CAGA,MAAa,EAAqD,CAChE,QAAS,IACT,QAAS,IACT,GAAI,IACJ,MAAO,IACP,KAAM,IACN,OAAQ,GACV,EAEa,EAA4B,EAAI,WAAY,CACvD,SAAU,CACR,KAAM,CACJ,QAAS,kBACT,QAAS,mBACT,GAAI,kBACJ,MAAO,gBACP,KAAM,iBACN,OAAQ,mBACV,CACF,EACA,gBAAiB,CAAE,KAAM,SAAU,CACrC,CAAC,EAUD,SAAgB,EAAkB,CAChC,YACA,OACA,QACA,UAAU,GACV,WACA,GAAG,GACsB,CACzB,GAAM,CAAE,UAAW,EAAe,EAC5B,EACJ,kBAAA,EAAA,CAAA,SAAA,CACE,kBAAC,OAAD,CAAM,UAAW,EAA0B,CAAE,MAAK,CAAC,EAAI,SAAA,GAAS,EAAa,GAAQ,UAAiB,CAAA,EACtG,kBAAC,OAAD,CAAO,UAAe,CAAA,CACtB,CAAA,CAAA,EAeJ,OAbI,EAEA,kBAAC,SAAD,CACE,KAAK,SACL,YAAU,sBACV,cAAY,YACZ,QAAS,EACT,UAAW,EAAG,gFAAiF,CAAS,EAEvG,SAAA,CACK,CAAA,EAIV,kBAAC,OAAD,CACE,YAAU,sBACV,UAAW,EAAG,4CAA6C,CAAS,EACpE,GAAI,EAEH,SAAA,CACG,CAAA,CAEV"}
|
|
1
|
+
{"version":3,"file":"MessageItem.mjs","names":[],"sources":["../../../src/components/MessageItem.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { type ComponentProps, createContext, type ReactNode, useContext, useState } from 'react';\n\nimport { ChevronDownIcon, ChevronUpIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\nimport { STATUS_EDGE, StatusBadge, type StatusTone } from './StatusBadge';\n\n/**\n * The message item: the timeline card a tool call, a run, or a notice sits\n * in. The item owns its outcome tone and its expand state; the header, body,\n * and status parts read both from it, so a card composes the parts and never\n * threads `expanded` by hand. A tool message in a web plugin is built from\n * this, and so is the cockpit's own fallback item, which is what keeps them\n * looking alike.\n */\n\nexport interface MessageItemState {\n tone: StatusTone;\n /** Whether the header offers the toggle; an item that hides nothing offers none. */\n expandable: boolean;\n expanded: boolean;\n toggle: () => void;\n}\n\nconst MessageItemContext = createContext<MessageItemState>({\n tone: 'neutral',\n expandable: false,\n expanded: false,\n toggle: () => undefined,\n});\n\n/** The enclosing item's state, for a part that lives deeper than the item's render prop. */\nexport function useMessageItem(): MessageItemState {\n return useContext(MessageItemContext);\n}\n\n/**\n * The group an item is a row of, or null for an item that is a card of its\n * own. A row drops the frame the group already draws and keeps its tone as an\n * edge down its left side, and it stops repeating what the group's header has\n * said once: the tool's name, and an outcome the whole run shares.\n */\nconst MessageItemGroupContext = createContext<{ tone: StatusTone } | null>(null);\n\n/** The frame, wearing the edge STATUS_EDGE names for the tone, so the two never drift apart. */\nexport const messageItemVariants = cva('overflow-hidden rounded-md border bg-doom-panel transition-colors', {\n variants: { tone: STATUS_EDGE },\n defaultVariants: { tone: 'neutral' },\n});\n\n/** The same tone as a row: no card, one coloured edge, and the group's separators between rows. */\nexport const messageItemRowVariants = cva('overflow-hidden border-l-2 transition-colors', {\n variants: { tone: STATUS_EDGE },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemProps\n extends Omit<ComponentProps<'div'>, 'children'>, VariantProps<typeof messageItemVariants> {\n /** Whether the header offers the expand toggle. A toggle that reveals nothing reads as broken, so the card decides. */\n expandable?: boolean;\n defaultExpanded?: boolean;\n /** Controlled mode; pair with onExpandedChange. Omit it and the item keeps its own state. */\n expanded?: boolean;\n onExpandedChange?: (expanded: boolean) => void;\n /** Plain content, or a function of the item's state for a card that picks its lines by `expanded`. */\n children?: ReactNode | ((state: MessageItemState) => ReactNode);\n}\n\nexport function MessageItem({\n className,\n tone,\n expandable = false,\n defaultExpanded = false,\n expanded,\n onExpandedChange,\n children,\n ...props\n}: MessageItemProps) {\n const [own, setOwn] = useState(defaultExpanded);\n const group = useContext(MessageItemGroupContext);\n const grouped = group !== null;\n const current = expanded ?? own;\n const state: MessageItemState = {\n tone: tone ?? 'neutral',\n expandable,\n expanded: current,\n toggle: () => {\n const next = !current;\n if (expanded === undefined) setOwn(next);\n onExpandedChange?.(next);\n },\n };\n return (\n <MessageItemContext.Provider value={state}>\n <div\n data-slot=\"message-item\"\n data-expanded={current}\n data-grouped={grouped}\n className={cn(grouped ? messageItemRowVariants({ tone }) : messageItemVariants({ tone }), className)}\n {...props}\n >\n {typeof children === 'function' ? children(state) : children}\n </div>\n </MessageItemContext.Provider>\n );\n}\n\nexport interface MessageItemGroupProps\n extends Omit<ComponentProps<'div'>, 'title'>, VariantProps<typeof messageItemVariants> {\n /** The bold label at the left of the group header: the tool the run belongs to. */\n title: ReactNode;\n /** The line beside it, such as how many calls the group holds. */\n summary?: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n children?: ReactNode;\n}\n\n/**\n * One frame around a run of items that belong together.\n *\n * A transcript that calls the same tool five times in a row is five identical\n * frames, five gutter labels and five gaps, and the repetition reads louder\n * than the commands do. The group draws the frame once and each item inside it\n * becomes a row: same header, same expand, no card of its own. The tone still\n * belongs to the row, as an edge, so a failure in the middle of a run is not\n * flattened into the group's own outcome.\n */\nexport function MessageItemGroup({\n className,\n tone,\n title,\n summary,\n badge,\n children,\n ...props\n}: MessageItemGroupProps) {\n const label = badge === undefined ? STATUS_LABEL[tone ?? 'neutral'] : badge;\n return (\n <MessageItemGroupContext.Provider value={{ tone: tone ?? 'neutral' }}>\n <div data-slot=\"message-item-group\" className={cn(messageItemVariants({ tone }), className)} {...props}>\n <div className=\"flex min-h-8 items-center gap-2 border-doom-border-soft border-b px-[11px] text-sm text-doom-dim\">\n <span className=\"shrink-0 font-bold text-doom-hi\">{title}</span>\n <span className=\"min-w-0 flex-1 truncate text-doom-faint\">{summary}</span>\n {label !== null && label !== '' ? <StatusBadge tone={tone ?? 'neutral'}>{label}</StatusBadge> : null}\n </div>\n <div className=\"flex flex-col divide-y divide-doom-border-soft\">{children}</div>\n </div>\n </MessageItemGroupContext.Provider>\n );\n}\n\n/** The tone a tool call's item wears: running while the tool runs, then its outcome. */\nexport function toolTone(state: { running: boolean; isError: boolean }): StatusTone {\n return state.running ? 'running' : state.isError ? 'error' : 'ok';\n}\n\n/** The badge text a tone reads as when the header is not told otherwise; empty hides the badge. */\nexport const STATUS_LABEL: Readonly<Record<StatusTone, string>> = {\n neutral: '',\n running: 'RUNNING',\n ok: 'OK',\n error: 'ERROR',\n info: 'INFO',\n accent: 'NOTE',\n};\n\nexport interface MessageItemHeaderProps extends Omit<ComponentProps<'div'>, 'title'> {\n /** The bold label at the left: the tool name. */\n title: ReactNode;\n /** The badge text; defaults to the tone's label, null hides the badge. */\n badge?: ReactNode | null;\n /** The summary beside the title; it gets the remaining width. */\n children?: ReactNode;\n}\n\n/** Inside a group these two are the quiet outcome: the group's header has already said it. */\nconst SILENT_IN_GROUP: ReadonlySet<StatusTone> = new Set<StatusTone>(['ok', 'neutral']);\n\n/**\n * The title row: label, summary, the tone's badge, and the expand toggle when\n * the item is expandable.\n *\n * A row inside a group says less. The group's header has already named the\n * tool and stated the run's outcome, so the row drops its title and speaks up\n * only when something went wrong or is still going: five OK badges down a run\n * of five are noise, and the one ERROR among them is the point.\n */\nexport function MessageItemHeader({ className, title, badge, children, ...props }: MessageItemHeaderProps) {\n const { tone, expandable, expanded, toggle } = useMessageItem();\n const group = useContext(MessageItemGroupContext);\n const defaultLabel = group !== null && SILENT_IN_GROUP.has(tone) ? null : STATUS_LABEL[tone];\n const label = badge === undefined ? defaultLabel : badge;\n return (\n <div\n data-slot=\"message-item-header\"\n className={cn('flex min-h-8 items-center gap-2 px-[11px] text-sm text-doom-dim', className)}\n {...props}\n >\n {group === null ? <span className=\"shrink-0 font-bold text-doom-hi\">{title}</span> : null}\n <div data-slot=\"message-item-summary\" className=\"flex min-w-0 flex-1 items-center gap-2\">\n {children}\n </div>\n {label !== null && label !== '' ? (\n <StatusBadge tone={tone} data-testid=\"tool-status\">\n {label}\n </StatusBadge>\n ) : null}\n {expandable ? (\n <Button\n variant=\"ghost\"\n size=\"icon\"\n data-testid=\"tool-expand\"\n aria-expanded={expanded}\n aria-label={expanded ? 'collapse' : 'expand'}\n onClick={toggle}\n className=\"text-doom-faint hover:text-doom-blue\"\n >\n {expanded ? <ChevronUpIcon className=\"h-3 w-3\" /> : <ChevronDownIcon className=\"h-3 w-3\" />}\n </Button>\n ) : null}\n </div>\n );\n}\n\n/** The recessed body under the header. */\nexport function MessageItemBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"message-item-body\"\n className={cn('border-t border-doom-border-soft bg-doom-deep px-3 py-2 text-sm text-doom-dim', className)}\n {...props}\n />\n );\n}\n\n/** The glyph a tone reads as in a status line. */\nexport const STATUS_GLYPH: Readonly<Record<StatusTone, string>> = {\n neutral: '…',\n running: '◐',\n ok: '✓',\n error: '✗',\n info: '●',\n accent: '●',\n};\n\nexport const messageItemStatusVariants = cva('shrink-0', {\n variants: {\n tone: {\n neutral: 'text-doom-faint',\n running: 'text-doom-yellow',\n ok: 'text-doom-green',\n error: 'text-doom-red',\n info: 'text-doom-blue',\n accent: 'text-doom-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n});\n\nexport interface MessageItemStatusProps extends ComponentProps<'span'>, VariantProps<typeof messageItemStatusVariants> {\n /** Replaces the tone's glyph. */\n glyph?: string;\n /** Renders as a button that expands the item: the \"N more line(s)\" hint. Only className carries over. */\n expands?: boolean;\n}\n\n/** The one-line status under a body: `◐ running`, `✗ failed`, `✓ done`, or the hint that more is hidden. */\nexport function MessageItemStatus({\n className,\n tone,\n glyph,\n expands = false,\n children,\n ...props\n}: MessageItemStatusProps) {\n const { toggle } = useMessageItem();\n const content = (\n <>\n <span className={messageItemStatusVariants({ tone })}>{glyph ?? STATUS_GLYPH[tone ?? 'neutral']}</span>\n <span>{children}</span>\n </>\n );\n if (expands) {\n return (\n <button\n type=\"button\"\n data-slot=\"message-item-status\"\n data-testid=\"tool-more\"\n onClick={toggle}\n className={cn(\n 'flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 text-doom-faint hover:text-doom-blue',\n className,\n )}\n >\n {content}\n </button>\n );\n }\n return (\n <span\n data-slot=\"message-item-status\"\n className={cn('flex items-center gap-1.5 text-doom-faint', className)}\n {...props}\n >\n {content}\n </span>\n );\n}\n"],"mappings":"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"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../icons/icons.cjs");const e=require("../lib/cn.cjs"),t=require("./Button.cjs");let n=require("radix-ui"),r=require("react/jsx-runtime"),i=require("lucide-react");function a(e){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Root,{"data-slot":`sheet`,...e})}function o(e){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Trigger,{"data-slot":`sheet-trigger`,...e})}function s(e){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Close,{"data-slot":`sheet-close`,...e})}function c({className:t,...i}){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Overlay,{"data-slot":`sheet-overlay`,className:e.cn(`fixed inset-0 z-40 bg-doom-deep/70 data-[state=open]:animate-doom-fade`,t),...i})}const l={right:`inset-y-0 right-0 border-l data-[state=open]:animate-doom-slide-right`,left:`inset-y-0 left-0 border-r data-[state=open]:animate-doom-slide-left`},u={sm:`w-[360px]`,md:`w-[440px]`,lg:`w-[560px]`};function d({className:t,children:i,side:a=`right`,width:o=`md`,...s}){return/* @__PURE__ */ (0,r.jsxs)(n.Dialog.Portal,{children:[/* @__PURE__ */ (0,r.jsx)(c,{}),/* @__PURE__ */ (0,r.jsx)(n.Dialog.Content,{"data-slot":`sheet-content`,"data-side":a,className:e.cn(`fixed z-50 flex max-w-[calc(100vw-24px)] flex-col overflow-hidden border-doom-border bg-doom-rail font-mono shadow-2xl outline-none`,l[a],u[o],t),...s,children:i})]})}function f({className:a,dismissible:o=!0,closeLabel:s=`close`,children:c,...l}){return/* @__PURE__ */ (0,r.jsxs)(`div`,{"data-slot":`sheet-header`,className:e.cn(`flex h-11 min-w-0 shrink-0 items-center gap-2.5 border-b border-doom-border px-4`,a),...l,children:[c,o?/* @__PURE__ */ (0,r.jsx)(n.Dialog.Close,{asChild:!0,children:/* @__PURE__ */ (0,r.jsx)(t.Button,{variant:`ghost`,size:`icon`,"aria-label":s,className:`text-doom-faint hover:text-doom-hi`,children:/* @__PURE__ */ (0,r.jsx)(i.X,{className:`h-3 w-3`})})}):null]})}function p({className:t,...i}){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Title,{"data-slot":`sheet-title`,className:e.cn(`truncate text-base font-bold text-doom-hi`,t),...i})}function m({className:t,...i}){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Description,{"data-slot":`sheet-description`,className:e.cn(`text-sm leading-relaxed text-doom-dim`,t),...i})}function h({className:t,...n}){return/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`sheet-body`,className:e.cn(`flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto px-4 py-3`,t),...n})}function g({className:t,...n}){return/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`sheet-footer`,className:e.cn(`flex min-h-[34px] shrink-0 flex-wrap items-center justify-between gap-2 border-t border-doom-border-soft bg-doom-deep px-4 py-1.5`,t),...n})}exports.Sheet=a,exports.SheetBody=h,exports.SheetClose=s,exports.SheetContent=d,exports.SheetDescription=m,exports.SheetFooter=g,exports.SheetHeader=f,exports.SheetOverlay=c,exports.SheetTitle=p,exports.SheetTrigger=o;
|
|
1
|
+
require("../icons/icons.cjs");const e=require("../lib/cn.cjs"),t=require("./Button.cjs");let n=require("radix-ui"),r=require("react/jsx-runtime"),i=require("lucide-react");function a(e){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Root,{"data-slot":`sheet`,...e})}function o(e){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Trigger,{"data-slot":`sheet-trigger`,...e})}function s(e){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Close,{"data-slot":`sheet-close`,...e})}function c({className:t,...i}){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Overlay,{"data-slot":`sheet-overlay`,className:e.cn(`fixed inset-0 z-40 bg-doom-deep/70 data-[state=open]:animate-doom-fade`,t),...i})}const l={right:`inset-y-0 right-0 border-l data-[state=open]:animate-doom-slide-right`,left:`inset-y-0 left-0 border-r data-[state=open]:animate-doom-slide-left`},u={sm:`w-[360px]`,md:`w-[440px]`,lg:`w-[560px]`};function d({className:t,children:i,side:a=`right`,width:o=`md`,...s}){return/* @__PURE__ */ (0,r.jsxs)(n.Dialog.Portal,{children:[/* @__PURE__ */ (0,r.jsx)(c,{}),/* @__PURE__ */ (0,r.jsx)(n.Dialog.Content,{"data-slot":`sheet-content`,"data-side":a,className:e.cn(`fixed z-50 flex max-w-[calc(100vw-24px)] flex-col overflow-hidden border-doom-border bg-doom-rail font-mono shadow-2xl outline-none`,l[a],u[o],t),...s,children:i})]})}function f({className:a,dismissible:o=!0,closeLabel:s=`close`,children:c,...l}){return/* @__PURE__ */ (0,r.jsxs)(`div`,{"data-slot":`sheet-header`,className:e.cn(`flex h-11 min-w-0 shrink-0 items-center gap-2.5 border-b border-doom-border px-4`,a),...l,children:[c,o?/* @__PURE__ */ (0,r.jsx)(n.Dialog.Close,{asChild:!0,children:/* @__PURE__ */ (0,r.jsx)(t.Button,{variant:`ghost`,size:`icon`,"aria-label":s,className:`ml-auto text-doom-faint hover:text-doom-hi`,children:/* @__PURE__ */ (0,r.jsx)(i.X,{className:`h-3 w-3`})})}):null]})}function p({className:t,...i}){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Title,{"data-slot":`sheet-title`,className:e.cn(`truncate text-base font-bold text-doom-hi`,t),...i})}function m({className:t,...i}){return/* @__PURE__ */ (0,r.jsx)(n.Dialog.Description,{"data-slot":`sheet-description`,className:e.cn(`text-sm leading-relaxed text-doom-dim`,t),...i})}function h({className:t,...n}){return/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`sheet-body`,className:e.cn(`flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto px-4 py-3`,t),...n})}function g({className:t,...n}){return/* @__PURE__ */ (0,r.jsx)(`div`,{"data-slot":`sheet-footer`,className:e.cn(`flex min-h-[34px] shrink-0 flex-wrap items-center justify-between gap-2 border-t border-doom-border-soft bg-doom-deep px-4 py-1.5`,t),...n})}exports.Sheet=a,exports.SheetBody=h,exports.SheetClose=s,exports.SheetContent=d,exports.SheetDescription=m,exports.SheetFooter=g,exports.SheetHeader=f,exports.SheetOverlay=c,exports.SheetTitle=p,exports.SheetTrigger=o;
|
|
2
2
|
//# sourceMappingURL=Sheet.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sheet.cjs","names":["SheetPrimitive","cn","Button","CloseIcon"],"sources":["../../../src/components/Sheet.tsx"],"sourcesContent":["import { Dialog as SheetPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\n\n/**\n * A side panel on Radix's Dialog: an overlay that slides in from an edge,\n * with the focus trap, Escape, outside click and scroll lock a dialog has.\n *\n * It is the Dialog for content that reads as a column rather than a form: a\n * detail view beside what the reader was looking at. An inline aside cannot\n * do this, because it takes width from the surface underneath it.\n */\nexport function Sheet(props: ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />;\n}\n\nexport function SheetTrigger(props: ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\nexport function SheetClose(props: ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\nexport function SheetOverlay({ className, ...props }: ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn('fixed inset-0 z-40 bg-doom-deep/70 data-[state=open]:animate-doom-fade', className)}\n {...props}\n />\n );\n}\n\nconst SIDE_POSITION = {\n right: 'inset-y-0 right-0 border-l data-[state=open]:animate-doom-slide-right',\n left: 'inset-y-0 left-0 border-r data-[state=open]:animate-doom-slide-left',\n} as const;\n\nexport interface SheetContentProps extends ComponentProps<typeof SheetPrimitive.Content> {\n /** Which edge it comes from. */\n side?: 'right' | 'left';\n /** Width preset; `className` may still override. */\n width?: 'sm' | 'md' | 'lg';\n}\n\nconst CONTENT_WIDTH = { sm: 'w-[360px]', md: 'w-[440px]', lg: 'w-[560px]' } as const;\n\nexport function SheetContent({ className, children, side = 'right', width = 'md', ...props }: SheetContentProps) {\n return (\n <SheetPrimitive.Portal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n 'fixed z-50 flex max-w-[calc(100vw-24px)] flex-col overflow-hidden border-doom-border bg-doom-rail font-mono shadow-2xl outline-none',\n SIDE_POSITION[side],\n CONTENT_WIDTH[width],\n className,\n )}\n {...props}\n >\n {children}\n </SheetPrimitive.Content>\n </SheetPrimitive.Portal>\n );\n}\n\nexport interface SheetHeaderProps extends ComponentProps<'div'> {\n /** Show the close control at the right of the strip. On by default: a sheet is dismissed, not answered. */\n dismissible?: boolean;\n /** What the close control announces. */\n closeLabel?: string;\n}\n\nexport function SheetHeader({\n className,\n dismissible = true,\n closeLabel = 'close',\n children,\n ...props\n}: SheetHeaderProps) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn('flex h-11 min-w-0 shrink-0 items-center gap-2.5 border-b border-doom-border px-4', className)}\n {...props}\n >\n {children}\n {dismissible ? (\n <SheetPrimitive.Close asChild>\n <Button
|
|
1
|
+
{"version":3,"file":"Sheet.cjs","names":["SheetPrimitive","cn","Button","CloseIcon"],"sources":["../../../src/components/Sheet.tsx"],"sourcesContent":["import { Dialog as SheetPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\n\n/**\n * A side panel on Radix's Dialog: an overlay that slides in from an edge,\n * with the focus trap, Escape, outside click and scroll lock a dialog has.\n *\n * It is the Dialog for content that reads as a column rather than a form: a\n * detail view beside what the reader was looking at. An inline aside cannot\n * do this, because it takes width from the surface underneath it.\n */\nexport function Sheet(props: ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />;\n}\n\nexport function SheetTrigger(props: ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\nexport function SheetClose(props: ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\nexport function SheetOverlay({ className, ...props }: ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn('fixed inset-0 z-40 bg-doom-deep/70 data-[state=open]:animate-doom-fade', className)}\n {...props}\n />\n );\n}\n\nconst SIDE_POSITION = {\n right: 'inset-y-0 right-0 border-l data-[state=open]:animate-doom-slide-right',\n left: 'inset-y-0 left-0 border-r data-[state=open]:animate-doom-slide-left',\n} as const;\n\nexport interface SheetContentProps extends ComponentProps<typeof SheetPrimitive.Content> {\n /** Which edge it comes from. */\n side?: 'right' | 'left';\n /** Width preset; `className` may still override. */\n width?: 'sm' | 'md' | 'lg';\n}\n\nconst CONTENT_WIDTH = { sm: 'w-[360px]', md: 'w-[440px]', lg: 'w-[560px]' } as const;\n\nexport function SheetContent({ className, children, side = 'right', width = 'md', ...props }: SheetContentProps) {\n return (\n <SheetPrimitive.Portal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n 'fixed z-50 flex max-w-[calc(100vw-24px)] flex-col overflow-hidden border-doom-border bg-doom-rail font-mono shadow-2xl outline-none',\n SIDE_POSITION[side],\n CONTENT_WIDTH[width],\n className,\n )}\n {...props}\n >\n {children}\n </SheetPrimitive.Content>\n </SheetPrimitive.Portal>\n );\n}\n\nexport interface SheetHeaderProps extends ComponentProps<'div'> {\n /** Show the close control at the right of the strip. On by default: a sheet is dismissed, not answered. */\n dismissible?: boolean;\n /** What the close control announces. */\n closeLabel?: string;\n}\n\nexport function SheetHeader({\n className,\n dismissible = true,\n closeLabel = 'close',\n children,\n ...props\n}: SheetHeaderProps) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn('flex h-11 min-w-0 shrink-0 items-center gap-2.5 border-b border-doom-border px-4', className)}\n {...props}\n >\n {children}\n {dismissible ? (\n <SheetPrimitive.Close asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={closeLabel}\n className=\"ml-auto text-doom-faint hover:text-doom-hi\"\n >\n <CloseIcon className=\"h-3 w-3\" />\n </Button>\n </SheetPrimitive.Close>\n ) : null}\n </div>\n );\n}\n\nexport function SheetTitle({ className, ...props }: ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn('truncate text-base font-bold text-doom-hi', className)}\n {...props}\n />\n );\n}\n\nexport function SheetDescription({ className, ...props }: ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn('text-sm leading-relaxed text-doom-dim', className)}\n {...props}\n />\n );\n}\n\nexport function SheetBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-body\"\n className={cn('flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto px-4 py-3', className)}\n {...props}\n />\n );\n}\n\nexport function SheetFooter({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\n 'flex min-h-[34px] shrink-0 flex-wrap items-center justify-between gap-2 border-t border-doom-border-soft bg-doom-deep px-4 py-1.5',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"4KAeA,SAAgB,EAAM,EAAmD,CACvE,MAAO,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,OAAe,KAAhB,CAAqB,YAAU,QAAQ,GAAI,CAAQ,CAAA,CAC5D,CAEA,SAAgB,EAAa,EAAsD,CACjF,MAAO,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,OAAe,QAAhB,CAAwB,YAAU,gBAAgB,GAAI,CAAQ,CAAA,CACvE,CAEA,SAAgB,EAAW,EAAoD,CAC7E,MAAO,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,OAAe,MAAhB,CAAsB,YAAU,cAAc,GAAI,CAAQ,CAAA,CACnE,CAEA,SAAgB,EAAa,CAAE,YAAW,GAAG,GAAwD,CACnG,MACE,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,OAAe,QAAhB,CACE,YAAU,gBACV,UAAWC,EAAAA,GAAG,yEAA0E,CAAS,EACjG,GAAI,CACL,CAAA,CAEL,CAEA,MAAM,EAAgB,CACpB,MAAO,wEACP,KAAM,qEACR,EASM,EAAgB,CAAE,GAAI,YAAa,GAAI,YAAa,GAAI,WAAY,EAE1E,SAAgB,EAAa,CAAE,YAAW,WAAU,OAAO,QAAS,QAAQ,KAAM,GAAG,GAA4B,CAC/G,MACE,iBAAA,EAAA,EAAA,KAAA,CAACD,EAAAA,OAAe,OAAhB,CAAA,SAAA,CACE,iBAAA,EAAA,EAAA,IAAA,CAAC,EAAD,CAAe,CAAA,EACf,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,OAAe,QAAhB,CACE,YAAU,gBACV,YAAW,EACX,UAAWC,EAAAA,GACT,sIACA,EAAc,GACd,EAAc,GACd,CACF,EACA,GAAI,EAEH,UACqB,CAAA,CACH,CAAA,CAAA,CAE3B,CASA,SAAgB,EAAY,CAC1B,YACA,cAAc,GACd,aAAa,QACb,WACA,GAAG,GACgB,CACnB,MACE,iBAAA,EAAA,EAAA,KAAA,CAAC,MAAD,CACE,YAAU,eACV,UAAWA,EAAAA,GAAG,mFAAoF,CAAS,EAC3G,GAAI,EAHN,SAAA,CAKG,EACA,EACC,iBAAA,EAAA,EAAA,IAAA,CAACD,EAAAA,OAAe,MAAhB,CAAsB,QAAA,GACpB,SAAA,iBAAA,EAAA,EAAA,IAAA,CAACE,EAAAA,OAAD,CACE,QAAQ,QACR,KAAK,OACL,aAAY,EACZ,UAAU,6CAEV,SAAA,iBAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,EAAD,CAAW,UAAU,SAAW,CAAA,CAC1B,CAAA,CACY,CAAA,EACpB,IACD,GAET,CAEA,SAAgB,EAAW,CAAE,YAAW,GAAG,GAAsD,CAC/F,MACE,iBAAA,EAAA,EAAA,IAAA,CAACH,EAAAA,OAAe,MAAhB,CACE,YAAU,cACV,UAAWC,EAAAA,GAAG,4CAA6C,CAAS,EACpE,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAiB,CAAE,YAAW,GAAG,GAA4D,CAC3G,MACE,iBAAA,EAAA,EAAA,IAAA,CAACD,EAAAA,OAAe,YAAhB,CACE,YAAU,oBACV,UAAWC,EAAAA,GAAG,wCAAyC,CAAS,EAChE,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAU,CAAE,YAAW,GAAG,GAAgC,CACxE,MACE,iBAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,YAAU,aACV,UAAWA,EAAAA,GAAG,+DAAgE,CAAS,EACvF,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAgC,CAC1E,MACE,iBAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,YAAU,eACV,UAAWA,EAAAA,GACT,oIACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sheet.d.mts","names":[],"sources":["../../../src/components/Sheet.tsx"],"mappings":";;;;;;;;;;;wBAegB,MAAM,OAAO,sBAAsB,OAAe,wBAAK,IAAA;wBAIvD,aAAa,OAAO,sBAAsB,OAAe,2BAAQ,IAAA;wBAIjE,WAAW,OAAO,sBAAsB,OAAe,yBAAM,IAAA;wBAI7D,eAAe,cAAc,SAAS,sBAAsB,OAAe,2BAAQ,IAAA;iBAelF,0BAA0B,sBAAsB,OAAe;;EAE9E;;EAEA;;wBAKc,eAAe,WAAW,UAAU,MAAgB,UAAiB,SAAS,oCAAiB,IAAA;iBAqB9F,yBAAyB;;EAExC;;EAEA;;wBAGc,cACd,WACA,aACA,YACA,aACG,SACF,mCAAgB,IAAA;
|
|
1
|
+
{"version":3,"file":"Sheet.d.mts","names":[],"sources":["../../../src/components/Sheet.tsx"],"mappings":";;;;;;;;;;;wBAegB,MAAM,OAAO,sBAAsB,OAAe,wBAAK,IAAA;wBAIvD,aAAa,OAAO,sBAAsB,OAAe,2BAAQ,IAAA;wBAIjE,WAAW,OAAO,sBAAsB,OAAe,yBAAM,IAAA;wBAI7D,eAAe,cAAc,SAAS,sBAAsB,OAAe,2BAAQ,IAAA;iBAelF,0BAA0B,sBAAsB,OAAe;;EAE9E;;EAEA;;wBAKc,eAAe,WAAW,UAAU,MAAgB,UAAiB,SAAS,oCAAiB,IAAA;iBAqB9F,yBAAyB;;EAExC;;EAEA;;wBAGc,cACd,WACA,aACA,YACA,aACG,SACF,mCAAgB,IAAA;wBAwBH,aAAa,cAAc,SAAS,sBAAsB,OAAe,yBAAM,IAAA;wBAU/E,mBAAmB,cAAc,SAAS,sBAAsB,OAAe,+BAAY,IAAA;wBAU3F,YAAY,cAAc,SAAS,wCAAqB,IAAA;wBAUxD,cAAc,cAAc,SAAS,wCAAqB,IAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{CloseIcon as e}from"../icons/icons.mjs";import{cn as t}from"../lib/cn.mjs";import{Button as n}from"./Button.mjs";import{Dialog as r}from"radix-ui";import{jsx as i,jsxs as a}from"react/jsx-runtime";function o(e){return/* @__PURE__ */ i(r.Root,{"data-slot":`sheet`,...e})}function s(e){return/* @__PURE__ */ i(r.Trigger,{"data-slot":`sheet-trigger`,...e})}function c(e){return/* @__PURE__ */ i(r.Close,{"data-slot":`sheet-close`,...e})}function l({className:e,...n}){return/* @__PURE__ */ i(r.Overlay,{"data-slot":`sheet-overlay`,className:t(`fixed inset-0 z-40 bg-doom-deep/70 data-[state=open]:animate-doom-fade`,e),...n})}const u={right:`inset-y-0 right-0 border-l data-[state=open]:animate-doom-slide-right`,left:`inset-y-0 left-0 border-r data-[state=open]:animate-doom-slide-left`},d={sm:`w-[360px]`,md:`w-[440px]`,lg:`w-[560px]`};function f({className:e,children:n,side:o=`right`,width:s=`md`,...c}){return/* @__PURE__ */ a(r.Portal,{children:[/* @__PURE__ */ i(l,{}),/* @__PURE__ */ i(r.Content,{"data-slot":`sheet-content`,"data-side":o,className:t(`fixed z-50 flex max-w-[calc(100vw-24px)] flex-col overflow-hidden border-doom-border bg-doom-rail font-mono shadow-2xl outline-none`,u[o],d[s],e),...c,children:n})]})}function p({className:o,dismissible:s=!0,closeLabel:c=`close`,children:l,...u}){return/* @__PURE__ */ a(`div`,{"data-slot":`sheet-header`,className:t(`flex h-11 min-w-0 shrink-0 items-center gap-2.5 border-b border-doom-border px-4`,o),...u,children:[l,s?/* @__PURE__ */ i(r.Close,{asChild:!0,children:/* @__PURE__ */ i(n,{variant:`ghost`,size:`icon`,"aria-label":c,className:`text-doom-faint hover:text-doom-hi`,children:/* @__PURE__ */ i(e,{className:`h-3 w-3`})})}):null]})}function m({className:e,...n}){return/* @__PURE__ */ i(r.Title,{"data-slot":`sheet-title`,className:t(`truncate text-base font-bold text-doom-hi`,e),...n})}function h({className:e,...n}){return/* @__PURE__ */ i(r.Description,{"data-slot":`sheet-description`,className:t(`text-sm leading-relaxed text-doom-dim`,e),...n})}function g({className:e,...n}){return/* @__PURE__ */ i(`div`,{"data-slot":`sheet-body`,className:t(`flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto px-4 py-3`,e),...n})}function _({className:e,...n}){return/* @__PURE__ */ i(`div`,{"data-slot":`sheet-footer`,className:t(`flex min-h-[34px] shrink-0 flex-wrap items-center justify-between gap-2 border-t border-doom-border-soft bg-doom-deep px-4 py-1.5`,e),...n})}export{o as Sheet,g as SheetBody,c as SheetClose,f as SheetContent,h as SheetDescription,_ as SheetFooter,p as SheetHeader,l as SheetOverlay,m as SheetTitle,s as SheetTrigger};
|
|
1
|
+
import{CloseIcon as e}from"../icons/icons.mjs";import{cn as t}from"../lib/cn.mjs";import{Button as n}from"./Button.mjs";import{Dialog as r}from"radix-ui";import{jsx as i,jsxs as a}from"react/jsx-runtime";function o(e){return/* @__PURE__ */ i(r.Root,{"data-slot":`sheet`,...e})}function s(e){return/* @__PURE__ */ i(r.Trigger,{"data-slot":`sheet-trigger`,...e})}function c(e){return/* @__PURE__ */ i(r.Close,{"data-slot":`sheet-close`,...e})}function l({className:e,...n}){return/* @__PURE__ */ i(r.Overlay,{"data-slot":`sheet-overlay`,className:t(`fixed inset-0 z-40 bg-doom-deep/70 data-[state=open]:animate-doom-fade`,e),...n})}const u={right:`inset-y-0 right-0 border-l data-[state=open]:animate-doom-slide-right`,left:`inset-y-0 left-0 border-r data-[state=open]:animate-doom-slide-left`},d={sm:`w-[360px]`,md:`w-[440px]`,lg:`w-[560px]`};function f({className:e,children:n,side:o=`right`,width:s=`md`,...c}){return/* @__PURE__ */ a(r.Portal,{children:[/* @__PURE__ */ i(l,{}),/* @__PURE__ */ i(r.Content,{"data-slot":`sheet-content`,"data-side":o,className:t(`fixed z-50 flex max-w-[calc(100vw-24px)] flex-col overflow-hidden border-doom-border bg-doom-rail font-mono shadow-2xl outline-none`,u[o],d[s],e),...c,children:n})]})}function p({className:o,dismissible:s=!0,closeLabel:c=`close`,children:l,...u}){return/* @__PURE__ */ a(`div`,{"data-slot":`sheet-header`,className:t(`flex h-11 min-w-0 shrink-0 items-center gap-2.5 border-b border-doom-border px-4`,o),...u,children:[l,s?/* @__PURE__ */ i(r.Close,{asChild:!0,children:/* @__PURE__ */ i(n,{variant:`ghost`,size:`icon`,"aria-label":c,className:`ml-auto text-doom-faint hover:text-doom-hi`,children:/* @__PURE__ */ i(e,{className:`h-3 w-3`})})}):null]})}function m({className:e,...n}){return/* @__PURE__ */ i(r.Title,{"data-slot":`sheet-title`,className:t(`truncate text-base font-bold text-doom-hi`,e),...n})}function h({className:e,...n}){return/* @__PURE__ */ i(r.Description,{"data-slot":`sheet-description`,className:t(`text-sm leading-relaxed text-doom-dim`,e),...n})}function g({className:e,...n}){return/* @__PURE__ */ i(`div`,{"data-slot":`sheet-body`,className:t(`flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto px-4 py-3`,e),...n})}function _({className:e,...n}){return/* @__PURE__ */ i(`div`,{"data-slot":`sheet-footer`,className:t(`flex min-h-[34px] shrink-0 flex-wrap items-center justify-between gap-2 border-t border-doom-border-soft bg-doom-deep px-4 py-1.5`,e),...n})}export{o as Sheet,g as SheetBody,c as SheetClose,f as SheetContent,h as SheetDescription,_ as SheetFooter,p as SheetHeader,l as SheetOverlay,m as SheetTitle,s as SheetTrigger};
|
|
2
2
|
//# sourceMappingURL=Sheet.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Sheet.mjs","names":["SheetPrimitive"],"sources":["../../../src/components/Sheet.tsx"],"sourcesContent":["import { Dialog as SheetPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\n\n/**\n * A side panel on Radix's Dialog: an overlay that slides in from an edge,\n * with the focus trap, Escape, outside click and scroll lock a dialog has.\n *\n * It is the Dialog for content that reads as a column rather than a form: a\n * detail view beside what the reader was looking at. An inline aside cannot\n * do this, because it takes width from the surface underneath it.\n */\nexport function Sheet(props: ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />;\n}\n\nexport function SheetTrigger(props: ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\nexport function SheetClose(props: ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\nexport function SheetOverlay({ className, ...props }: ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn('fixed inset-0 z-40 bg-doom-deep/70 data-[state=open]:animate-doom-fade', className)}\n {...props}\n />\n );\n}\n\nconst SIDE_POSITION = {\n right: 'inset-y-0 right-0 border-l data-[state=open]:animate-doom-slide-right',\n left: 'inset-y-0 left-0 border-r data-[state=open]:animate-doom-slide-left',\n} as const;\n\nexport interface SheetContentProps extends ComponentProps<typeof SheetPrimitive.Content> {\n /** Which edge it comes from. */\n side?: 'right' | 'left';\n /** Width preset; `className` may still override. */\n width?: 'sm' | 'md' | 'lg';\n}\n\nconst CONTENT_WIDTH = { sm: 'w-[360px]', md: 'w-[440px]', lg: 'w-[560px]' } as const;\n\nexport function SheetContent({ className, children, side = 'right', width = 'md', ...props }: SheetContentProps) {\n return (\n <SheetPrimitive.Portal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n 'fixed z-50 flex max-w-[calc(100vw-24px)] flex-col overflow-hidden border-doom-border bg-doom-rail font-mono shadow-2xl outline-none',\n SIDE_POSITION[side],\n CONTENT_WIDTH[width],\n className,\n )}\n {...props}\n >\n {children}\n </SheetPrimitive.Content>\n </SheetPrimitive.Portal>\n );\n}\n\nexport interface SheetHeaderProps extends ComponentProps<'div'> {\n /** Show the close control at the right of the strip. On by default: a sheet is dismissed, not answered. */\n dismissible?: boolean;\n /** What the close control announces. */\n closeLabel?: string;\n}\n\nexport function SheetHeader({\n className,\n dismissible = true,\n closeLabel = 'close',\n children,\n ...props\n}: SheetHeaderProps) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn('flex h-11 min-w-0 shrink-0 items-center gap-2.5 border-b border-doom-border px-4', className)}\n {...props}\n >\n {children}\n {dismissible ? (\n <SheetPrimitive.Close asChild>\n <Button
|
|
1
|
+
{"version":3,"file":"Sheet.mjs","names":["SheetPrimitive"],"sources":["../../../src/components/Sheet.tsx"],"sourcesContent":["import { Dialog as SheetPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport { Button } from './Button';\n\n/**\n * A side panel on Radix's Dialog: an overlay that slides in from an edge,\n * with the focus trap, Escape, outside click and scroll lock a dialog has.\n *\n * It is the Dialog for content that reads as a column rather than a form: a\n * detail view beside what the reader was looking at. An inline aside cannot\n * do this, because it takes width from the surface underneath it.\n */\nexport function Sheet(props: ComponentProps<typeof SheetPrimitive.Root>) {\n return <SheetPrimitive.Root data-slot=\"sheet\" {...props} />;\n}\n\nexport function SheetTrigger(props: ComponentProps<typeof SheetPrimitive.Trigger>) {\n return <SheetPrimitive.Trigger data-slot=\"sheet-trigger\" {...props} />;\n}\n\nexport function SheetClose(props: ComponentProps<typeof SheetPrimitive.Close>) {\n return <SheetPrimitive.Close data-slot=\"sheet-close\" {...props} />;\n}\n\nexport function SheetOverlay({ className, ...props }: ComponentProps<typeof SheetPrimitive.Overlay>) {\n return (\n <SheetPrimitive.Overlay\n data-slot=\"sheet-overlay\"\n className={cn('fixed inset-0 z-40 bg-doom-deep/70 data-[state=open]:animate-doom-fade', className)}\n {...props}\n />\n );\n}\n\nconst SIDE_POSITION = {\n right: 'inset-y-0 right-0 border-l data-[state=open]:animate-doom-slide-right',\n left: 'inset-y-0 left-0 border-r data-[state=open]:animate-doom-slide-left',\n} as const;\n\nexport interface SheetContentProps extends ComponentProps<typeof SheetPrimitive.Content> {\n /** Which edge it comes from. */\n side?: 'right' | 'left';\n /** Width preset; `className` may still override. */\n width?: 'sm' | 'md' | 'lg';\n}\n\nconst CONTENT_WIDTH = { sm: 'w-[360px]', md: 'w-[440px]', lg: 'w-[560px]' } as const;\n\nexport function SheetContent({ className, children, side = 'right', width = 'md', ...props }: SheetContentProps) {\n return (\n <SheetPrimitive.Portal>\n <SheetOverlay />\n <SheetPrimitive.Content\n data-slot=\"sheet-content\"\n data-side={side}\n className={cn(\n 'fixed z-50 flex max-w-[calc(100vw-24px)] flex-col overflow-hidden border-doom-border bg-doom-rail font-mono shadow-2xl outline-none',\n SIDE_POSITION[side],\n CONTENT_WIDTH[width],\n className,\n )}\n {...props}\n >\n {children}\n </SheetPrimitive.Content>\n </SheetPrimitive.Portal>\n );\n}\n\nexport interface SheetHeaderProps extends ComponentProps<'div'> {\n /** Show the close control at the right of the strip. On by default: a sheet is dismissed, not answered. */\n dismissible?: boolean;\n /** What the close control announces. */\n closeLabel?: string;\n}\n\nexport function SheetHeader({\n className,\n dismissible = true,\n closeLabel = 'close',\n children,\n ...props\n}: SheetHeaderProps) {\n return (\n <div\n data-slot=\"sheet-header\"\n className={cn('flex h-11 min-w-0 shrink-0 items-center gap-2.5 border-b border-doom-border px-4', className)}\n {...props}\n >\n {children}\n {dismissible ? (\n <SheetPrimitive.Close asChild>\n <Button\n variant=\"ghost\"\n size=\"icon\"\n aria-label={closeLabel}\n className=\"ml-auto text-doom-faint hover:text-doom-hi\"\n >\n <CloseIcon className=\"h-3 w-3\" />\n </Button>\n </SheetPrimitive.Close>\n ) : null}\n </div>\n );\n}\n\nexport function SheetTitle({ className, ...props }: ComponentProps<typeof SheetPrimitive.Title>) {\n return (\n <SheetPrimitive.Title\n data-slot=\"sheet-title\"\n className={cn('truncate text-base font-bold text-doom-hi', className)}\n {...props}\n />\n );\n}\n\nexport function SheetDescription({ className, ...props }: ComponentProps<typeof SheetPrimitive.Description>) {\n return (\n <SheetPrimitive.Description\n data-slot=\"sheet-description\"\n className={cn('text-sm leading-relaxed text-doom-dim', className)}\n {...props}\n />\n );\n}\n\nexport function SheetBody({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-body\"\n className={cn('flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto px-4 py-3', className)}\n {...props}\n />\n );\n}\n\nexport function SheetFooter({ className, ...props }: ComponentProps<'div'>) {\n return (\n <div\n data-slot=\"sheet-footer\"\n className={cn(\n 'flex min-h-[34px] shrink-0 flex-wrap items-center justify-between gap-2 border-t border-doom-border-soft bg-doom-deep px-4 py-1.5',\n className,\n )}\n {...props}\n />\n );\n}\n"],"mappings":"4MAeA,SAAgB,EAAM,EAAmD,CACvE,MAAO,kBAACA,EAAe,KAAhB,CAAqB,YAAU,QAAQ,GAAI,CAAQ,CAAA,CAC5D,CAEA,SAAgB,EAAa,EAAsD,CACjF,MAAO,kBAACA,EAAe,QAAhB,CAAwB,YAAU,gBAAgB,GAAI,CAAQ,CAAA,CACvE,CAEA,SAAgB,EAAW,EAAoD,CAC7E,MAAO,kBAACA,EAAe,MAAhB,CAAsB,YAAU,cAAc,GAAI,CAAQ,CAAA,CACnE,CAEA,SAAgB,EAAa,CAAE,YAAW,GAAG,GAAwD,CACnG,MACE,kBAACA,EAAe,QAAhB,CACE,YAAU,gBACV,UAAW,EAAG,yEAA0E,CAAS,EACjG,GAAI,CACL,CAAA,CAEL,CAEA,MAAM,EAAgB,CACpB,MAAO,wEACP,KAAM,qEACR,EASM,EAAgB,CAAE,GAAI,YAAa,GAAI,YAAa,GAAI,WAAY,EAE1E,SAAgB,EAAa,CAAE,YAAW,WAAU,OAAO,QAAS,QAAQ,KAAM,GAAG,GAA4B,CAC/G,MACE,kBAACA,EAAe,OAAhB,CAAA,SAAA,CACE,kBAAC,EAAD,CAAe,CAAA,EACf,kBAACA,EAAe,QAAhB,CACE,YAAU,gBACV,YAAW,EACX,UAAW,EACT,sIACA,EAAc,GACd,EAAc,GACd,CACF,EACA,GAAI,EAEH,UACqB,CAAA,CACH,CAAA,CAAA,CAE3B,CASA,SAAgB,EAAY,CAC1B,YACA,cAAc,GACd,aAAa,QACb,WACA,GAAG,GACgB,CACnB,MACE,kBAAC,MAAD,CACE,YAAU,eACV,UAAW,EAAG,mFAAoF,CAAS,EAC3G,GAAI,EAHN,SAAA,CAKG,EACA,EACC,kBAACA,EAAe,MAAhB,CAAsB,QAAA,GACpB,SAAA,kBAAC,EAAD,CACE,QAAQ,QACR,KAAK,OACL,aAAY,EACZ,UAAU,6CAEV,SAAA,kBAAC,EAAD,CAAW,UAAU,SAAW,CAAA,CAC1B,CAAA,CACY,CAAA,EACpB,IACD,GAET,CAEA,SAAgB,EAAW,CAAE,YAAW,GAAG,GAAsD,CAC/F,MACE,kBAACA,EAAe,MAAhB,CACE,YAAU,cACV,UAAW,EAAG,4CAA6C,CAAS,EACpE,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAiB,CAAE,YAAW,GAAG,GAA4D,CAC3G,MACE,kBAACA,EAAe,YAAhB,CACE,YAAU,oBACV,UAAW,EAAG,wCAAyC,CAAS,EAChE,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAU,CAAE,YAAW,GAAG,GAAgC,CACxE,MACE,kBAAC,MAAD,CACE,YAAU,aACV,UAAW,EAAG,+DAAgE,CAAS,EACvF,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAgC,CAC1E,MACE,kBAAC,MAAD,CACE,YAAU,eACV,UAAW,EACT,oIACA,CACF,EACA,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../lib/cn.cjs");let t=require("radix-ui"),n=require("react/jsx-runtime"),r=require("class-variance-authority");const i=(0,r.cva)(`flex cursor-pointer items-center gap-1.5 rounded px-2 py-1 text-xs transition-colors outline-none`,{variants:{active:{true:`bg-doom-tint-blue font-bold text-doom-blue`,false:`text-doom-dim hover:bg-doom-panel hover:text-doom-hi`}},defaultVariants:{active:!1}}),a=(0,r.cva)(`flex h-[15px] min-w-[15px] items-center justify-center rounded-full px-1 text-2xs font-bold`,{variants:{active:{true:`bg-doom-blue text-doom-rail`,false:`bg-doom-panel text-doom-dim`}},defaultVariants:{active:!1}});function o({className:r,active:a,asChild:o=!1,...s}){let c=o?t.Slot.Root:`a`;return/* @__PURE__ */ (0,n.jsx)(c,{"data-slot":`nav-tab`,"data-active":a??!1,className:e.cn(i({active:a}),r),...s})}function s({className:t,active:r,...i}){return/* @__PURE__ */ (0,n.jsx)(`span`,{"data-slot":`nav-tab-badge`,className:e.cn(a({active:r}),t),...i})}function c(e){return/* @__PURE__ */ (0,n.jsx)(t.Tabs.Root,{"data-slot":`tabs`,...e})}function l({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Tabs.List,{"data-slot":`tabs-list`,className:e.cn(`flex items-center gap-1`,r),...i})}function u({className:r,...a}){return/* @__PURE__ */ (0,n.jsx)(t.Tabs.Trigger,{"data-slot":`tabs-trigger`,className:e.cn(i({active:!1}),`data-[state=active]:bg-doom-tint-blue data-[state=active]:font-bold data-[state=active]:text-doom-blue`,r),...a})}function d({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Tabs.Content,{"data-slot":`tabs-content`,className:e.cn(`min-h-0 flex-1`,r),...i})}exports.NavTab=o,exports.NavTabBadge=s,exports.Tabs=c,exports.TabsContent=d,exports.TabsList=l,exports.TabsTrigger=u,exports.tabBadgeVariants=a,exports.tabVariants=i;
|
|
1
|
+
const e=require("../lib/cn.cjs");let t=require("radix-ui"),n=require("react/jsx-runtime"),r=require("class-variance-authority");const i=(0,r.cva)(`flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 rounded px-2 py-1 text-xs transition-colors outline-none`,{variants:{active:{true:`bg-doom-tint-blue font-bold text-doom-blue`,false:`text-doom-dim hover:bg-doom-panel hover:text-doom-hi`}},defaultVariants:{active:!1}}),a=(0,r.cva)(`flex h-[15px] min-w-[15px] items-center justify-center rounded-full px-1 text-2xs font-bold`,{variants:{active:{true:`bg-doom-blue text-doom-rail`,false:`bg-doom-panel text-doom-dim`}},defaultVariants:{active:!1}});function o({className:r,active:a,asChild:o=!1,...s}){let c=o?t.Slot.Root:`a`;return/* @__PURE__ */ (0,n.jsx)(c,{"data-slot":`nav-tab`,"data-active":a??!1,className:e.cn(i({active:a}),r),...s})}function s({className:t,active:r,...i}){return/* @__PURE__ */ (0,n.jsx)(`span`,{"data-slot":`nav-tab-badge`,className:e.cn(a({active:r}),t),...i})}function c(e){return/* @__PURE__ */ (0,n.jsx)(t.Tabs.Root,{"data-slot":`tabs`,...e})}function l({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Tabs.List,{"data-slot":`tabs-list`,className:e.cn(`flex items-center gap-1`,r),...i})}function u({className:r,...a}){return/* @__PURE__ */ (0,n.jsx)(t.Tabs.Trigger,{"data-slot":`tabs-trigger`,className:e.cn(i({active:!1}),`data-[state=active]:bg-doom-tint-blue data-[state=active]:font-bold data-[state=active]:text-doom-blue`,r),...a})}function d({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Tabs.Content,{"data-slot":`tabs-content`,className:e.cn(`min-h-0 flex-1`,r),...i})}exports.NavTab=o,exports.NavTabBadge=s,exports.Tabs=c,exports.TabsContent=d,exports.TabsList=l,exports.TabsTrigger=u,exports.tabBadgeVariants=a,exports.tabVariants=i;
|
|
2
2
|
//# sourceMappingURL=Tabs.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.cjs","names":["cva","Slot","cn","TabsPrimitive"],"sources":["../../../src/components/Tabs.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Tabs as TabsPrimitive } from 'radix-ui';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The look a tab wears, whether Radix drives it or a router link does. It is\n * exported because the cockpit's own tabs navigate routes rather than swap\n * panels, and a link that looks like a tab must not be a second implementation.\n */\nexport const tabVariants = cva(\n 'flex cursor-pointer items-center gap-1.5 rounded px-2 py-1 text-xs transition-colors outline-none',\n {\n variants: {\n active: {\n true: 'bg-doom-tint-blue font-bold text-doom-blue',\n false: 'text-doom-dim hover:bg-doom-panel hover:text-doom-hi',\n },\n },\n defaultVariants: { active: false },\n },\n);\n\n/** The count a tab carries; it inverts on the active tab so it stays readable on the tint. */\nexport const tabBadgeVariants = cva(\n 'flex h-[15px] min-w-[15px] items-center justify-center rounded-full px-1 text-2xs font-bold',\n {\n variants: {\n active: { true: 'bg-doom-blue text-doom-rail', false: 'bg-doom-panel text-doom-dim' },\n },\n defaultVariants: { active: false },\n },\n);\n\nexport interface NavTabProps extends ComponentProps<'a'>, VariantProps<typeof tabVariants> {\n /** Render the child element instead of an <a>, so a router Link can be the tab. */\n asChild?: boolean;\n}\n\n/**\n * A tab that navigates. Radix Tabs owns panels and roving focus over content\n * it renders; a route-driven tab strip has neither, so it gets the styling and\n * leaves the semantics to the router.\n */\nexport function NavTab({ className, active, asChild = false, ...props }: NavTabProps) {\n const Component = asChild ? Slot.Root : 'a';\n return (\n <Component\n data-slot=\"nav-tab\"\n data-active={active ?? false}\n className={cn(tabVariants({ active }), className)}\n {...props}\n />\n );\n}\n\n/** The count beside a tab's label. */\nexport function NavTabBadge({\n className,\n active,\n ...props\n}: ComponentProps<'span'> & VariantProps<typeof tabBadgeVariants>) {\n return <span data-slot=\"nav-tab-badge\" className={cn(tabBadgeVariants({ active }), className)} {...props} />;\n}\n\n/** Radix Tabs, for a surface that swaps panels in place rather than navigating. */\nexport function Tabs(props: ComponentProps<typeof TabsPrimitive.Root>) {\n return <TabsPrimitive.Root data-slot=\"tabs\" {...props} />;\n}\n\nexport function TabsList({ className, ...props }: ComponentProps<typeof TabsPrimitive.List>) {\n return <TabsPrimitive.List data-slot=\"tabs-list\" className={cn('flex items-center gap-1', className)} {...props} />;\n}\n\nexport function TabsTrigger({ className, ...props }: ComponentProps<typeof TabsPrimitive.Trigger>) {\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n tabVariants({ active: false }),\n 'data-[state=active]:bg-doom-tint-blue data-[state=active]:font-bold data-[state=active]:text-doom-blue',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function TabsContent({ className, ...props }: ComponentProps<typeof TabsPrimitive.Content>) {\n return <TabsPrimitive.Content data-slot=\"tabs-content\" className={cn('min-h-0 flex-1', className)} {...props} />;\n}\n"],"mappings":"gIAYA,MAAa,GAAA,EAAcA,EAAAA,IAAAA,CACzB,
|
|
1
|
+
{"version":3,"file":"Tabs.cjs","names":["cva","Slot","cn","TabsPrimitive"],"sources":["../../../src/components/Tabs.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Tabs as TabsPrimitive } from 'radix-ui';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The look a tab wears, whether Radix drives it or a router link does. It is\n * exported because the cockpit's own tabs navigate routes rather than swap\n * panels, and a link that looks like a tab must not be a second implementation.\n */\nexport const tabVariants = cva(\n 'flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 rounded px-2 py-1 text-xs transition-colors outline-none',\n {\n variants: {\n active: {\n true: 'bg-doom-tint-blue font-bold text-doom-blue',\n false: 'text-doom-dim hover:bg-doom-panel hover:text-doom-hi',\n },\n },\n defaultVariants: { active: false },\n },\n);\n\n/** The count a tab carries; it inverts on the active tab so it stays readable on the tint. */\nexport const tabBadgeVariants = cva(\n 'flex h-[15px] min-w-[15px] items-center justify-center rounded-full px-1 text-2xs font-bold',\n {\n variants: {\n active: { true: 'bg-doom-blue text-doom-rail', false: 'bg-doom-panel text-doom-dim' },\n },\n defaultVariants: { active: false },\n },\n);\n\nexport interface NavTabProps extends ComponentProps<'a'>, VariantProps<typeof tabVariants> {\n /** Render the child element instead of an <a>, so a router Link can be the tab. */\n asChild?: boolean;\n}\n\n/**\n * A tab that navigates. Radix Tabs owns panels and roving focus over content\n * it renders; a route-driven tab strip has neither, so it gets the styling and\n * leaves the semantics to the router.\n */\nexport function NavTab({ className, active, asChild = false, ...props }: NavTabProps) {\n const Component = asChild ? Slot.Root : 'a';\n return (\n <Component\n data-slot=\"nav-tab\"\n data-active={active ?? false}\n className={cn(tabVariants({ active }), className)}\n {...props}\n />\n );\n}\n\n/** The count beside a tab's label. */\nexport function NavTabBadge({\n className,\n active,\n ...props\n}: ComponentProps<'span'> & VariantProps<typeof tabBadgeVariants>) {\n return <span data-slot=\"nav-tab-badge\" className={cn(tabBadgeVariants({ active }), className)} {...props} />;\n}\n\n/** Radix Tabs, for a surface that swaps panels in place rather than navigating. */\nexport function Tabs(props: ComponentProps<typeof TabsPrimitive.Root>) {\n return <TabsPrimitive.Root data-slot=\"tabs\" {...props} />;\n}\n\nexport function TabsList({ className, ...props }: ComponentProps<typeof TabsPrimitive.List>) {\n return <TabsPrimitive.List data-slot=\"tabs-list\" className={cn('flex items-center gap-1', className)} {...props} />;\n}\n\nexport function TabsTrigger({ className, ...props }: ComponentProps<typeof TabsPrimitive.Trigger>) {\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n tabVariants({ active: false }),\n 'data-[state=active]:bg-doom-tint-blue data-[state=active]:font-bold data-[state=active]:text-doom-blue',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function TabsContent({ className, ...props }: ComponentProps<typeof TabsPrimitive.Content>) {\n return <TabsPrimitive.Content data-slot=\"tabs-content\" className={cn('min-h-0 flex-1', className)} {...props} />;\n}\n"],"mappings":"gIAYA,MAAa,GAAA,EAAcA,EAAAA,IAAAA,CACzB,oHACA,CACE,SAAU,CACR,OAAQ,CACN,KAAM,6CACN,MAAO,sDACT,CACF,EACA,gBAAiB,CAAE,OAAQ,EAAM,CACnC,CACF,EAGa,GAAA,EAAmBA,EAAAA,IAAAA,CAC9B,8FACA,CACE,SAAU,CACR,OAAQ,CAAE,KAAM,8BAA+B,MAAO,6BAA8B,CACtF,EACA,gBAAiB,CAAE,OAAQ,EAAM,CACnC,CACF,EAYA,SAAgB,EAAO,CAAE,YAAW,SAAQ,UAAU,GAAO,GAAG,GAAsB,CACpF,IAAM,EAAY,EAAUC,EAAAA,KAAK,KAAO,IACxC,MACE,iBAAA,EAAA,EAAA,IAAA,CAAC,EAAD,CACE,YAAU,UACV,cAAa,GAAU,GACvB,UAAWC,EAAAA,GAAG,EAAY,CAAE,QAAO,CAAC,EAAG,CAAS,EAChD,GAAI,CACL,CAAA,CAEL,CAGA,SAAgB,EAAY,CAC1B,YACA,SACA,GAAG,GAC8D,CACjE,MAAO,iBAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CAAM,YAAU,gBAAgB,UAAWA,EAAAA,GAAG,EAAiB,CAAE,QAAO,CAAC,EAAG,CAAS,EAAG,GAAI,CAAQ,CAAA,CAC7G,CAGA,SAAgB,EAAK,EAAkD,CACrE,MAAO,iBAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,KAAc,KAAf,CAAoB,YAAU,OAAO,GAAI,CAAQ,CAAA,CAC1D,CAEA,SAAgB,EAAS,CAAE,YAAW,GAAG,GAAoD,CAC3F,MAAO,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,KAAc,KAAf,CAAoB,YAAU,YAAY,UAAWD,EAAAA,GAAG,0BAA2B,CAAS,EAAG,GAAI,CAAQ,CAAA,CACpH,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAuD,CACjG,MACE,iBAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,KAAc,QAAf,CACE,YAAU,eACV,UAAWD,EAAAA,GACT,EAAY,CAAE,OAAQ,EAAM,CAAC,EAC7B,yGACA,CACF,EACA,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAuD,CACjG,MAAO,iBAAA,EAAA,EAAA,IAAA,CAACC,EAAAA,KAAc,QAAf,CAAuB,YAAU,eAAe,UAAWD,EAAAA,GAAG,iBAAkB,CAAS,EAAG,GAAI,CAAQ,CAAA,CACjH"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cn as e}from"../lib/cn.mjs";import{Slot as t,Tabs as n}from"radix-ui";import{jsx as r}from"react/jsx-runtime";import{cva as i}from"class-variance-authority";const a=i(`flex cursor-pointer items-center gap-1.5 rounded px-2 py-1 text-xs transition-colors outline-none`,{variants:{active:{true:`bg-doom-tint-blue font-bold text-doom-blue`,false:`text-doom-dim hover:bg-doom-panel hover:text-doom-hi`}},defaultVariants:{active:!1}}),o=i(`flex h-[15px] min-w-[15px] items-center justify-center rounded-full px-1 text-2xs font-bold`,{variants:{active:{true:`bg-doom-blue text-doom-rail`,false:`bg-doom-panel text-doom-dim`}},defaultVariants:{active:!1}});function s({className:n,active:i,asChild:o=!1,...s}){let c=o?t.Root:`a`;return/* @__PURE__ */ r(c,{"data-slot":`nav-tab`,"data-active":i??!1,className:e(a({active:i}),n),...s})}function c({className:t,active:n,...i}){return/* @__PURE__ */ r(`span`,{"data-slot":`nav-tab-badge`,className:e(o({active:n}),t),...i})}function l(e){return/* @__PURE__ */ r(n.Root,{"data-slot":`tabs`,...e})}function u({className:t,...i}){return/* @__PURE__ */ r(n.List,{"data-slot":`tabs-list`,className:e(`flex items-center gap-1`,t),...i})}function d({className:t,...i}){return/* @__PURE__ */ r(n.Trigger,{"data-slot":`tabs-trigger`,className:e(a({active:!1}),`data-[state=active]:bg-doom-tint-blue data-[state=active]:font-bold data-[state=active]:text-doom-blue`,t),...i})}function f({className:t,...i}){return/* @__PURE__ */ r(n.Content,{"data-slot":`tabs-content`,className:e(`min-h-0 flex-1`,t),...i})}export{s as NavTab,c as NavTabBadge,l as Tabs,f as TabsContent,u as TabsList,d as TabsTrigger,o as tabBadgeVariants,a as tabVariants};
|
|
1
|
+
import{cn as e}from"../lib/cn.mjs";import{Slot as t,Tabs as n}from"radix-ui";import{jsx as r}from"react/jsx-runtime";import{cva as i}from"class-variance-authority";const a=i(`flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 rounded px-2 py-1 text-xs transition-colors outline-none`,{variants:{active:{true:`bg-doom-tint-blue font-bold text-doom-blue`,false:`text-doom-dim hover:bg-doom-panel hover:text-doom-hi`}},defaultVariants:{active:!1}}),o=i(`flex h-[15px] min-w-[15px] items-center justify-center rounded-full px-1 text-2xs font-bold`,{variants:{active:{true:`bg-doom-blue text-doom-rail`,false:`bg-doom-panel text-doom-dim`}},defaultVariants:{active:!1}});function s({className:n,active:i,asChild:o=!1,...s}){let c=o?t.Root:`a`;return/* @__PURE__ */ r(c,{"data-slot":`nav-tab`,"data-active":i??!1,className:e(a({active:i}),n),...s})}function c({className:t,active:n,...i}){return/* @__PURE__ */ r(`span`,{"data-slot":`nav-tab-badge`,className:e(o({active:n}),t),...i})}function l(e){return/* @__PURE__ */ r(n.Root,{"data-slot":`tabs`,...e})}function u({className:t,...i}){return/* @__PURE__ */ r(n.List,{"data-slot":`tabs-list`,className:e(`flex items-center gap-1`,t),...i})}function d({className:t,...i}){return/* @__PURE__ */ r(n.Trigger,{"data-slot":`tabs-trigger`,className:e(a({active:!1}),`data-[state=active]:bg-doom-tint-blue data-[state=active]:font-bold data-[state=active]:text-doom-blue`,t),...i})}function f({className:t,...i}){return/* @__PURE__ */ r(n.Content,{"data-slot":`tabs-content`,className:e(`min-h-0 flex-1`,t),...i})}export{s as NavTab,c as NavTabBadge,l as Tabs,f as TabsContent,u as TabsList,d as TabsTrigger,o as tabBadgeVariants,a as tabVariants};
|
|
2
2
|
//# sourceMappingURL=Tabs.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.mjs","names":["Tabs","TabsPrimitive"],"sources":["../../../src/components/Tabs.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Tabs as TabsPrimitive } from 'radix-ui';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The look a tab wears, whether Radix drives it or a router link does. It is\n * exported because the cockpit's own tabs navigate routes rather than swap\n * panels, and a link that looks like a tab must not be a second implementation.\n */\nexport const tabVariants = cva(\n 'flex cursor-pointer items-center gap-1.5 rounded px-2 py-1 text-xs transition-colors outline-none',\n {\n variants: {\n active: {\n true: 'bg-doom-tint-blue font-bold text-doom-blue',\n false: 'text-doom-dim hover:bg-doom-panel hover:text-doom-hi',\n },\n },\n defaultVariants: { active: false },\n },\n);\n\n/** The count a tab carries; it inverts on the active tab so it stays readable on the tint. */\nexport const tabBadgeVariants = cva(\n 'flex h-[15px] min-w-[15px] items-center justify-center rounded-full px-1 text-2xs font-bold',\n {\n variants: {\n active: { true: 'bg-doom-blue text-doom-rail', false: 'bg-doom-panel text-doom-dim' },\n },\n defaultVariants: { active: false },\n },\n);\n\nexport interface NavTabProps extends ComponentProps<'a'>, VariantProps<typeof tabVariants> {\n /** Render the child element instead of an <a>, so a router Link can be the tab. */\n asChild?: boolean;\n}\n\n/**\n * A tab that navigates. Radix Tabs owns panels and roving focus over content\n * it renders; a route-driven tab strip has neither, so it gets the styling and\n * leaves the semantics to the router.\n */\nexport function NavTab({ className, active, asChild = false, ...props }: NavTabProps) {\n const Component = asChild ? Slot.Root : 'a';\n return (\n <Component\n data-slot=\"nav-tab\"\n data-active={active ?? false}\n className={cn(tabVariants({ active }), className)}\n {...props}\n />\n );\n}\n\n/** The count beside a tab's label. */\nexport function NavTabBadge({\n className,\n active,\n ...props\n}: ComponentProps<'span'> & VariantProps<typeof tabBadgeVariants>) {\n return <span data-slot=\"nav-tab-badge\" className={cn(tabBadgeVariants({ active }), className)} {...props} />;\n}\n\n/** Radix Tabs, for a surface that swaps panels in place rather than navigating. */\nexport function Tabs(props: ComponentProps<typeof TabsPrimitive.Root>) {\n return <TabsPrimitive.Root data-slot=\"tabs\" {...props} />;\n}\n\nexport function TabsList({ className, ...props }: ComponentProps<typeof TabsPrimitive.List>) {\n return <TabsPrimitive.List data-slot=\"tabs-list\" className={cn('flex items-center gap-1', className)} {...props} />;\n}\n\nexport function TabsTrigger({ className, ...props }: ComponentProps<typeof TabsPrimitive.Trigger>) {\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n tabVariants({ active: false }),\n 'data-[state=active]:bg-doom-tint-blue data-[state=active]:font-bold data-[state=active]:text-doom-blue',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function TabsContent({ className, ...props }: ComponentProps<typeof TabsPrimitive.Content>) {\n return <TabsPrimitive.Content data-slot=\"tabs-content\" className={cn('min-h-0 flex-1', className)} {...props} />;\n}\n"],"mappings":"oKAYA,MAAa,EAAc,EACzB,
|
|
1
|
+
{"version":3,"file":"Tabs.mjs","names":["Tabs","TabsPrimitive"],"sources":["../../../src/components/Tabs.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Tabs as TabsPrimitive } from 'radix-ui';\nimport { Slot } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { cn } from '../lib/cn';\n\n/**\n * The look a tab wears, whether Radix drives it or a router link does. It is\n * exported because the cockpit's own tabs navigate routes rather than swap\n * panels, and a link that looks like a tab must not be a second implementation.\n */\nexport const tabVariants = cva(\n 'flex min-h-6 min-w-6 cursor-pointer items-center gap-1.5 rounded px-2 py-1 text-xs transition-colors outline-none',\n {\n variants: {\n active: {\n true: 'bg-doom-tint-blue font-bold text-doom-blue',\n false: 'text-doom-dim hover:bg-doom-panel hover:text-doom-hi',\n },\n },\n defaultVariants: { active: false },\n },\n);\n\n/** The count a tab carries; it inverts on the active tab so it stays readable on the tint. */\nexport const tabBadgeVariants = cva(\n 'flex h-[15px] min-w-[15px] items-center justify-center rounded-full px-1 text-2xs font-bold',\n {\n variants: {\n active: { true: 'bg-doom-blue text-doom-rail', false: 'bg-doom-panel text-doom-dim' },\n },\n defaultVariants: { active: false },\n },\n);\n\nexport interface NavTabProps extends ComponentProps<'a'>, VariantProps<typeof tabVariants> {\n /** Render the child element instead of an <a>, so a router Link can be the tab. */\n asChild?: boolean;\n}\n\n/**\n * A tab that navigates. Radix Tabs owns panels and roving focus over content\n * it renders; a route-driven tab strip has neither, so it gets the styling and\n * leaves the semantics to the router.\n */\nexport function NavTab({ className, active, asChild = false, ...props }: NavTabProps) {\n const Component = asChild ? Slot.Root : 'a';\n return (\n <Component\n data-slot=\"nav-tab\"\n data-active={active ?? false}\n className={cn(tabVariants({ active }), className)}\n {...props}\n />\n );\n}\n\n/** The count beside a tab's label. */\nexport function NavTabBadge({\n className,\n active,\n ...props\n}: ComponentProps<'span'> & VariantProps<typeof tabBadgeVariants>) {\n return <span data-slot=\"nav-tab-badge\" className={cn(tabBadgeVariants({ active }), className)} {...props} />;\n}\n\n/** Radix Tabs, for a surface that swaps panels in place rather than navigating. */\nexport function Tabs(props: ComponentProps<typeof TabsPrimitive.Root>) {\n return <TabsPrimitive.Root data-slot=\"tabs\" {...props} />;\n}\n\nexport function TabsList({ className, ...props }: ComponentProps<typeof TabsPrimitive.List>) {\n return <TabsPrimitive.List data-slot=\"tabs-list\" className={cn('flex items-center gap-1', className)} {...props} />;\n}\n\nexport function TabsTrigger({ className, ...props }: ComponentProps<typeof TabsPrimitive.Trigger>) {\n return (\n <TabsPrimitive.Trigger\n data-slot=\"tabs-trigger\"\n className={cn(\n tabVariants({ active: false }),\n 'data-[state=active]:bg-doom-tint-blue data-[state=active]:font-bold data-[state=active]:text-doom-blue',\n className,\n )}\n {...props}\n />\n );\n}\n\nexport function TabsContent({ className, ...props }: ComponentProps<typeof TabsPrimitive.Content>) {\n return <TabsPrimitive.Content data-slot=\"tabs-content\" className={cn('min-h-0 flex-1', className)} {...props} />;\n}\n"],"mappings":"oKAYA,MAAa,EAAc,EACzB,oHACA,CACE,SAAU,CACR,OAAQ,CACN,KAAM,6CACN,MAAO,sDACT,CACF,EACA,gBAAiB,CAAE,OAAQ,EAAM,CACnC,CACF,EAGa,EAAmB,EAC9B,8FACA,CACE,SAAU,CACR,OAAQ,CAAE,KAAM,8BAA+B,MAAO,6BAA8B,CACtF,EACA,gBAAiB,CAAE,OAAQ,EAAM,CACnC,CACF,EAYA,SAAgB,EAAO,CAAE,YAAW,SAAQ,UAAU,GAAO,GAAG,GAAsB,CACpF,IAAM,EAAY,EAAU,EAAK,KAAO,IACxC,MACE,kBAAC,EAAD,CACE,YAAU,UACV,cAAa,GAAU,GACvB,UAAW,EAAG,EAAY,CAAE,QAAO,CAAC,EAAG,CAAS,EAChD,GAAI,CACL,CAAA,CAEL,CAGA,SAAgB,EAAY,CAC1B,YACA,SACA,GAAG,GAC8D,CACjE,MAAO,kBAAC,OAAD,CAAM,YAAU,gBAAgB,UAAW,EAAG,EAAiB,CAAE,QAAO,CAAC,EAAG,CAAS,EAAG,GAAI,CAAQ,CAAA,CAC7G,CAGA,SAAgBA,EAAK,EAAkD,CACrE,MAAO,kBAACC,EAAc,KAAf,CAAoB,YAAU,OAAO,GAAI,CAAQ,CAAA,CAC1D,CAEA,SAAgB,EAAS,CAAE,YAAW,GAAG,GAAoD,CAC3F,MAAO,kBAACA,EAAc,KAAf,CAAoB,YAAU,YAAY,UAAW,EAAG,0BAA2B,CAAS,EAAG,GAAI,CAAQ,CAAA,CACpH,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAuD,CACjG,MACE,kBAACA,EAAc,QAAf,CACE,YAAU,eACV,UAAW,EACT,EAAY,CAAE,OAAQ,EAAM,CAAC,EAC7B,yGACA,CACF,EACA,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAY,CAAE,YAAW,GAAG,GAAuD,CACjG,MAAO,kBAACA,EAAc,QAAf,CAAuB,YAAU,eAAe,UAAW,EAAG,iBAAkB,CAAS,EAAG,GAAI,CAAQ,CAAA,CACjH"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../lib/cn.cjs"),t=require("../types/theme.cjs");let n=require("react/jsx-runtime"),r=require("react");function i(e,n){return getComputedStyle(e).getPropertyValue(t.themeVariable(n)).trim()}function a({onData:t,onReady:a,ref:o,fontSize:s=11,className:c,...l}){let u=(0,r.useRef)(null),d=(0,r.useRef)(void 0),f=(0,r.useRef)(t),[p,m]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{f.current=t}),(0,r.useImperativeHandle)(o,()=>({write:e=>d.current?.write(e),reset:()=>d.current?.reset()})),(0,r.useEffect)(()=>{let e=u.current;if(e===null)return;let t=!1,n=()=>void 0;return(async()=>{let[{Terminal:r}]=await Promise.all([import(`@xterm/xterm`),import(`@xterm/xterm/css/xterm.css`)]);if(t)return;let o=new r({cursorBlink:!0,fontFamily:`ui-monospace, SFMono-Regular, Menlo, monospace`,fontSize:s,allowTransparency:!0,theme:{background:i(e,`deep`),foreground:i(e,`dim`),cursor:i(e,`hi`),selectionBackground:i(e,`selected`)}});o.open(e),o.onData(e=>f.current?.(e)),d.current={write:e=>o.write(e),reset:()=>o.reset()},m(!0),a?.(),n=()=>{d.current=void 0,o.dispose()}})(),()=>{t=!0,n()}},[]),/* @__PURE__ */ (0,n.jsx)(`div`,{ref:u,"data-slot":`terminal-view`,"data-ready":p,className:e.cn(`h-full w-full`,c),...l})}exports.TerminalView=a;
|
|
1
|
+
const e=require("../lib/cn.cjs"),t=require("../types/theme.cjs");let n=require("react/jsx-runtime"),r=require("react");function i(e,n){return getComputedStyle(e).getPropertyValue(t.themeVariable(n)).trim()}function a({onData:t,onReady:a,ref:o,fontSize:s=11,className:c,...l}){let u=(0,r.useRef)(null),d=(0,r.useRef)(void 0),f=(0,r.useRef)(t),[p,m]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{f.current=t}),(0,r.useImperativeHandle)(o,()=>({write:e=>d.current?.write(e),reset:()=>d.current?.reset()})),(0,r.useEffect)(()=>{let e=u.current;if(e===null)return;let t=!1,n=()=>void 0;return(async()=>{let[{Terminal:r}]=await Promise.all([import(`@xterm/xterm`),import(`@xterm/xterm/css/xterm.css`)]);if(t)return;let o=new r({cursorBlink:!0,fontFamily:`ui-monospace, SFMono-Regular, Menlo, monospace`,fontSize:s,allowTransparency:!0,theme:{background:i(e,`deep`),foreground:i(e,`dim`),cursor:i(e,`hi`),selectionBackground:i(e,`selected`)}});o.open(e),o.onData(e=>f.current?.(e)),d.current={write:e=>o.write(e),reset:()=>o.reset()},m(!0),a?.(),n=()=>{d.current=void 0,o.dispose()}})(),()=>{t=!0,n()}},[]),/* @__PURE__ */ (0,n.jsx)(`div`,{ref:u,"data-slot":`terminal-view`,"data-ready":p,className:e.cn(`h-full min-w-0 w-full overflow-auto`,c),...l})}exports.TerminalView=a;
|
|
2
2
|
//# sourceMappingURL=TerminalView.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TerminalView.cjs","names":["themeVariable","useRef","useState","cn"],"sources":["../../../src/components/TerminalView.tsx"],"sourcesContent":["import { type ComponentProps, useEffect, useImperativeHandle, useRef, useState } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { themeVariable } from '../types/theme';\n\n/**\n * A terminal emulator, for output that is a screen rather than a document.\n *\n * `AnsiText` beside it renders colour in text that happens to carry escapes.\n * This is the other thing: a full VT emulator that keeps a cursor, a grid and\n * an alternate screen, so a prompt, a progress bar or a full-screen program\n * behaves the way it would in a shell. Give it the bytes a pty produced and it\n * draws them; take its `onData` and you have what the reader typed.\n *\n * The emulator is loaded on mount rather than with the bundle. It is not a\n * small dependency, and most surfaces never show a terminal.\n */\n\nexport interface TerminalHandle {\n /** Writes pane bytes, escapes and all. */\n write(data: Uint8Array | string): void;\n /** Clears the screen and scrollback, for a stream that restarted. */\n reset(): void;\n}\n\nexport interface TerminalViewProps extends Omit<ComponentProps<'div'>, 'children' | 'onData' | 'ref'> {\n /** What the reader typed, already encoded the way a terminal sends it. */\n onData?: (text: string) => void;\n /** Called once the emulator is live, so a caller can start feeding it. */\n onReady?: () => void;\n ref?: React.Ref<TerminalHandle>;\n fontSize?: number;\n}\n\nconst DEFAULT_FONT_SIZE = 11;\nconst FONT_STACK = 'ui-monospace, SFMono-Regular, Menlo, monospace';\n\n/** Reads a theme token from the document, so the terminal follows the active theme. */\nfunction tokenColour(root: HTMLElement, token: Parameters<typeof themeVariable>[0]): string {\n return getComputedStyle(root).getPropertyValue(themeVariable(token)).trim();\n}\n\nexport function TerminalView({\n onData,\n onReady,\n ref,\n fontSize = DEFAULT_FONT_SIZE,\n className,\n ...props\n}: TerminalViewProps) {\n const mount = useRef<HTMLDivElement | null>(null);\n const handle = useRef<TerminalHandle | undefined>(undefined);\n const dataRef = useRef<((text: string) => void) | undefined>(onData);\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n dataRef.current = onData;\n });\n\n useImperativeHandle(ref, () => ({\n write: (data) => handle.current?.write(data),\n reset: () => handle.current?.reset(),\n }));\n\n useEffect(() => {\n const element = mount.current;\n if (element === null) return;\n let disposed = false;\n let dispose = (): void => undefined;\n\n void (async () => {\n const [{ Terminal }] = await Promise.all([import('@xterm/xterm'), import('@xterm/xterm/css/xterm.css')]);\n if (disposed) return;\n const terminal = new Terminal({\n cursorBlink: true,\n fontFamily: FONT_STACK,\n fontSize,\n allowTransparency: true,\n // Taken from the document's own custom properties rather than written\n // here, so a theme switch is the only place a colour is ever decided.\n theme: {\n background: tokenColour(element, 'deep'),\n foreground: tokenColour(element, 'dim'),\n cursor: tokenColour(element, 'hi'),\n selectionBackground: tokenColour(element, 'selected'),\n },\n });\n terminal.open(element);\n terminal.onData((text) => dataRef.current?.(text));\n handle.current = {\n write: (data) => terminal.write(data),\n reset: () => terminal.reset(),\n };\n setReady(true);\n onReady?.();\n\n dispose = () => {\n handle.current = undefined;\n terminal.dispose();\n };\n })();\n\n return () => {\n disposed = true;\n dispose();\n };\n // The emulator is built once for the life of the surface; later prop\n // changes reach it through the refs above rather than rebuilding it.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div\n ref={mount}\n data-slot=\"terminal-view\"\n data-ready={ready}\n className={cn('h-full w-full', className)}\n {...props}\n />\n );\n}\n"],"mappings":"uHAsCA,SAAS,EAAY,EAAmB,EAAoD,CAC1F,OAAO,iBAAiB,CAAI,CAAC,CAAC,iBAAiBA,EAAAA,cAAc,CAAK,CAAC,CAAC,CAAC,KAAK,CAC5E,CAEA,SAAgB,EAAa,CAC3B,SACA,UACA,MACA,WAAW,GACX,YACA,GAAG,GACiB,CACpB,IAAM,GAAA,EAAQC,EAAAA,OAAAA,CAA8B,IAAI,EAC1C,GAAA,EAASA,EAAAA,OAAAA,CAAmC,IAAA,EAAS,EACrD,GAAA,EAAUA,EAAAA,OAAAA,CAA6C,CAAM,EAC7D,CAAC,EAAO,IAAA,EAAYC,EAAAA,SAAAA,CAAS,EAAK,EA0DxC,OAxDA,EAAA,EAAA,UAAA,KAAgB,CACd,EAAQ,QAAU,CACpB,CAAC,GAED,EAAA,EAAA,oBAAA,CAAoB,OAAY,CAC9B,MAAQ,GAAS,EAAO,SAAS,MAAM,CAAI,EAC3C,UAAa,EAAO,SAAS,MAAM,CACrC,EAAE,GAEF,EAAA,EAAA,UAAA,KAAgB,CACd,IAAM,EAAU,EAAM,QACtB,GAAI,IAAY,KAAM,OACtB,IAAI,EAAW,GACX,MAAsB,IAAA,GAkC1B,OAhCM,SAAY,CAChB,GAAM,CAAC,CAAE,aAAc,MAAM,QAAQ,IAAI,CAAC,OAAO,gBAAiB,OAAO,6BAA6B,CAAC,EACvG,GAAI,EAAU,OACd,IAAM,EAAW,IAAI,EAAS,CAC5B,YAAa,GACb,WAAY,iDACZ,WACA,kBAAmB,GAGnB,MAAO,CACL,WAAY,EAAY,EAAS,MAAM,EACvC,WAAY,EAAY,EAAS,KAAK,EACtC,OAAQ,EAAY,EAAS,IAAI,EACjC,oBAAqB,EAAY,EAAS,UAAU,CACtD,CACF,CAAC,EACD,EAAS,KAAK,CAAO,EACrB,EAAS,OAAQ,GAAS,EAAQ,UAAU,CAAI,CAAC,EACjD,EAAO,QAAU,CACf,MAAQ,GAAS,EAAS,MAAM,CAAI,EACpC,UAAa,EAAS,MAAM,CAC9B,EACA,EAAS,EAAI,EACb,IAAU,EAEV,MAAgB,CACd,EAAO,QAAU,IAAA,GACjB,EAAS,QAAQ,CACnB,CACF,EAAA,CAAG,MAEU,CACX,EAAW,GACX,EAAQ,CACV,CAIF,EAAG,CAAC,CAAC,EAGH,iBAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,IAAK,EACL,YAAU,gBACV,aAAY,EACZ,UAAWC,EAAAA,GAAG,
|
|
1
|
+
{"version":3,"file":"TerminalView.cjs","names":["themeVariable","useRef","useState","cn"],"sources":["../../../src/components/TerminalView.tsx"],"sourcesContent":["import { type ComponentProps, useEffect, useImperativeHandle, useRef, useState } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { themeVariable } from '../types/theme';\n\n/**\n * A terminal emulator, for output that is a screen rather than a document.\n *\n * `AnsiText` beside it renders colour in text that happens to carry escapes.\n * This is the other thing: a full VT emulator that keeps a cursor, a grid and\n * an alternate screen, so a prompt, a progress bar or a full-screen program\n * behaves the way it would in a shell. Give it the bytes a pty produced and it\n * draws them; take its `onData` and you have what the reader typed.\n *\n * The emulator is loaded on mount rather than with the bundle. It is not a\n * small dependency, and most surfaces never show a terminal.\n */\n\nexport interface TerminalHandle {\n /** Writes pane bytes, escapes and all. */\n write(data: Uint8Array | string): void;\n /** Clears the screen and scrollback, for a stream that restarted. */\n reset(): void;\n}\n\nexport interface TerminalViewProps extends Omit<ComponentProps<'div'>, 'children' | 'onData' | 'ref'> {\n /** What the reader typed, already encoded the way a terminal sends it. */\n onData?: (text: string) => void;\n /** Called once the emulator is live, so a caller can start feeding it. */\n onReady?: () => void;\n ref?: React.Ref<TerminalHandle>;\n fontSize?: number;\n}\n\nconst DEFAULT_FONT_SIZE = 11;\nconst FONT_STACK = 'ui-monospace, SFMono-Regular, Menlo, monospace';\n\n/** Reads a theme token from the document, so the terminal follows the active theme. */\nfunction tokenColour(root: HTMLElement, token: Parameters<typeof themeVariable>[0]): string {\n return getComputedStyle(root).getPropertyValue(themeVariable(token)).trim();\n}\n\nexport function TerminalView({\n onData,\n onReady,\n ref,\n fontSize = DEFAULT_FONT_SIZE,\n className,\n ...props\n}: TerminalViewProps) {\n const mount = useRef<HTMLDivElement | null>(null);\n const handle = useRef<TerminalHandle | undefined>(undefined);\n const dataRef = useRef<((text: string) => void) | undefined>(onData);\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n dataRef.current = onData;\n });\n\n useImperativeHandle(ref, () => ({\n write: (data) => handle.current?.write(data),\n reset: () => handle.current?.reset(),\n }));\n\n useEffect(() => {\n const element = mount.current;\n if (element === null) return;\n let disposed = false;\n let dispose = (): void => undefined;\n\n void (async () => {\n const [{ Terminal }] = await Promise.all([import('@xterm/xterm'), import('@xterm/xterm/css/xterm.css')]);\n if (disposed) return;\n const terminal = new Terminal({\n cursorBlink: true,\n fontFamily: FONT_STACK,\n fontSize,\n allowTransparency: true,\n // Taken from the document's own custom properties rather than written\n // here, so a theme switch is the only place a colour is ever decided.\n theme: {\n background: tokenColour(element, 'deep'),\n foreground: tokenColour(element, 'dim'),\n cursor: tokenColour(element, 'hi'),\n selectionBackground: tokenColour(element, 'selected'),\n },\n });\n terminal.open(element);\n terminal.onData((text) => dataRef.current?.(text));\n handle.current = {\n write: (data) => terminal.write(data),\n reset: () => terminal.reset(),\n };\n setReady(true);\n onReady?.();\n\n dispose = () => {\n handle.current = undefined;\n terminal.dispose();\n };\n })();\n\n return () => {\n disposed = true;\n dispose();\n };\n // The emulator is built once for the life of the surface; later prop\n // changes reach it through the refs above rather than rebuilding it.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div\n ref={mount}\n data-slot=\"terminal-view\"\n data-ready={ready}\n className={cn('h-full min-w-0 w-full overflow-auto', className)}\n {...props}\n />\n );\n}\n"],"mappings":"uHAsCA,SAAS,EAAY,EAAmB,EAAoD,CAC1F,OAAO,iBAAiB,CAAI,CAAC,CAAC,iBAAiBA,EAAAA,cAAc,CAAK,CAAC,CAAC,CAAC,KAAK,CAC5E,CAEA,SAAgB,EAAa,CAC3B,SACA,UACA,MACA,WAAW,GACX,YACA,GAAG,GACiB,CACpB,IAAM,GAAA,EAAQC,EAAAA,OAAAA,CAA8B,IAAI,EAC1C,GAAA,EAASA,EAAAA,OAAAA,CAAmC,IAAA,EAAS,EACrD,GAAA,EAAUA,EAAAA,OAAAA,CAA6C,CAAM,EAC7D,CAAC,EAAO,IAAA,EAAYC,EAAAA,SAAAA,CAAS,EAAK,EA0DxC,OAxDA,EAAA,EAAA,UAAA,KAAgB,CACd,EAAQ,QAAU,CACpB,CAAC,GAED,EAAA,EAAA,oBAAA,CAAoB,OAAY,CAC9B,MAAQ,GAAS,EAAO,SAAS,MAAM,CAAI,EAC3C,UAAa,EAAO,SAAS,MAAM,CACrC,EAAE,GAEF,EAAA,EAAA,UAAA,KAAgB,CACd,IAAM,EAAU,EAAM,QACtB,GAAI,IAAY,KAAM,OACtB,IAAI,EAAW,GACX,MAAsB,IAAA,GAkC1B,OAhCM,SAAY,CAChB,GAAM,CAAC,CAAE,aAAc,MAAM,QAAQ,IAAI,CAAC,OAAO,gBAAiB,OAAO,6BAA6B,CAAC,EACvG,GAAI,EAAU,OACd,IAAM,EAAW,IAAI,EAAS,CAC5B,YAAa,GACb,WAAY,iDACZ,WACA,kBAAmB,GAGnB,MAAO,CACL,WAAY,EAAY,EAAS,MAAM,EACvC,WAAY,EAAY,EAAS,KAAK,EACtC,OAAQ,EAAY,EAAS,IAAI,EACjC,oBAAqB,EAAY,EAAS,UAAU,CACtD,CACF,CAAC,EACD,EAAS,KAAK,CAAO,EACrB,EAAS,OAAQ,GAAS,EAAQ,UAAU,CAAI,CAAC,EACjD,EAAO,QAAU,CACf,MAAQ,GAAS,EAAS,MAAM,CAAI,EACpC,UAAa,EAAS,MAAM,CAC9B,EACA,EAAS,EAAI,EACb,IAAU,EAEV,MAAgB,CACd,EAAO,QAAU,IAAA,GACjB,EAAS,QAAQ,CACnB,CACF,EAAA,CAAG,MAEU,CACX,EAAW,GACX,EAAQ,CACV,CAIF,EAAG,CAAC,CAAC,EAGH,iBAAA,EAAA,EAAA,IAAA,CAAC,MAAD,CACE,IAAK,EACL,YAAU,gBACV,aAAY,EACZ,UAAWC,EAAAA,GAAG,sCAAuC,CAAS,EAC9D,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cn as e}from"../lib/cn.mjs";import{themeVariable as t}from"../types/theme.mjs";import{jsx as n}from"react/jsx-runtime";import{useEffect as r,useImperativeHandle as i,useRef as a,useState as o}from"react";function s(e,n){return getComputedStyle(e).getPropertyValue(t(n)).trim()}function c({onData:t,onReady:c,ref:l,fontSize:u=11,className:d,...f}){let p=a(null),m=a(void 0),h=a(t),[g,_]=o(!1);return r(()=>{h.current=t}),i(l,()=>({write:e=>m.current?.write(e),reset:()=>m.current?.reset()})),r(()=>{let e=p.current;if(e===null)return;let t=!1,n=()=>void 0;return(async()=>{let[{Terminal:r}]=await Promise.all([import(`@xterm/xterm`),import(`@xterm/xterm/css/xterm.css`)]);if(t)return;let i=new r({cursorBlink:!0,fontFamily:`ui-monospace, SFMono-Regular, Menlo, monospace`,fontSize:u,allowTransparency:!0,theme:{background:s(e,`deep`),foreground:s(e,`dim`),cursor:s(e,`hi`),selectionBackground:s(e,`selected`)}});i.open(e),i.onData(e=>h.current?.(e)),m.current={write:e=>i.write(e),reset:()=>i.reset()},_(!0),c?.(),n=()=>{m.current=void 0,i.dispose()}})(),()=>{t=!0,n()}},[]),/* @__PURE__ */ n(`div`,{ref:p,"data-slot":`terminal-view`,"data-ready":g,className:e(`h-full w-full`,d),...f})}export{c as TerminalView};
|
|
1
|
+
import{cn as e}from"../lib/cn.mjs";import{themeVariable as t}from"../types/theme.mjs";import{jsx as n}from"react/jsx-runtime";import{useEffect as r,useImperativeHandle as i,useRef as a,useState as o}from"react";function s(e,n){return getComputedStyle(e).getPropertyValue(t(n)).trim()}function c({onData:t,onReady:c,ref:l,fontSize:u=11,className:d,...f}){let p=a(null),m=a(void 0),h=a(t),[g,_]=o(!1);return r(()=>{h.current=t}),i(l,()=>({write:e=>m.current?.write(e),reset:()=>m.current?.reset()})),r(()=>{let e=p.current;if(e===null)return;let t=!1,n=()=>void 0;return(async()=>{let[{Terminal:r}]=await Promise.all([import(`@xterm/xterm`),import(`@xterm/xterm/css/xterm.css`)]);if(t)return;let i=new r({cursorBlink:!0,fontFamily:`ui-monospace, SFMono-Regular, Menlo, monospace`,fontSize:u,allowTransparency:!0,theme:{background:s(e,`deep`),foreground:s(e,`dim`),cursor:s(e,`hi`),selectionBackground:s(e,`selected`)}});i.open(e),i.onData(e=>h.current?.(e)),m.current={write:e=>i.write(e),reset:()=>i.reset()},_(!0),c?.(),n=()=>{m.current=void 0,i.dispose()}})(),()=>{t=!0,n()}},[]),/* @__PURE__ */ n(`div`,{ref:p,"data-slot":`terminal-view`,"data-ready":g,className:e(`h-full min-w-0 w-full overflow-auto`,d),...f})}export{c as TerminalView};
|
|
2
2
|
//# sourceMappingURL=TerminalView.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"TerminalView.mjs","names":[],"sources":["../../../src/components/TerminalView.tsx"],"sourcesContent":["import { type ComponentProps, useEffect, useImperativeHandle, useRef, useState } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { themeVariable } from '../types/theme';\n\n/**\n * A terminal emulator, for output that is a screen rather than a document.\n *\n * `AnsiText` beside it renders colour in text that happens to carry escapes.\n * This is the other thing: a full VT emulator that keeps a cursor, a grid and\n * an alternate screen, so a prompt, a progress bar or a full-screen program\n * behaves the way it would in a shell. Give it the bytes a pty produced and it\n * draws them; take its `onData` and you have what the reader typed.\n *\n * The emulator is loaded on mount rather than with the bundle. It is not a\n * small dependency, and most surfaces never show a terminal.\n */\n\nexport interface TerminalHandle {\n /** Writes pane bytes, escapes and all. */\n write(data: Uint8Array | string): void;\n /** Clears the screen and scrollback, for a stream that restarted. */\n reset(): void;\n}\n\nexport interface TerminalViewProps extends Omit<ComponentProps<'div'>, 'children' | 'onData' | 'ref'> {\n /** What the reader typed, already encoded the way a terminal sends it. */\n onData?: (text: string) => void;\n /** Called once the emulator is live, so a caller can start feeding it. */\n onReady?: () => void;\n ref?: React.Ref<TerminalHandle>;\n fontSize?: number;\n}\n\nconst DEFAULT_FONT_SIZE = 11;\nconst FONT_STACK = 'ui-monospace, SFMono-Regular, Menlo, monospace';\n\n/** Reads a theme token from the document, so the terminal follows the active theme. */\nfunction tokenColour(root: HTMLElement, token: Parameters<typeof themeVariable>[0]): string {\n return getComputedStyle(root).getPropertyValue(themeVariable(token)).trim();\n}\n\nexport function TerminalView({\n onData,\n onReady,\n ref,\n fontSize = DEFAULT_FONT_SIZE,\n className,\n ...props\n}: TerminalViewProps) {\n const mount = useRef<HTMLDivElement | null>(null);\n const handle = useRef<TerminalHandle | undefined>(undefined);\n const dataRef = useRef<((text: string) => void) | undefined>(onData);\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n dataRef.current = onData;\n });\n\n useImperativeHandle(ref, () => ({\n write: (data) => handle.current?.write(data),\n reset: () => handle.current?.reset(),\n }));\n\n useEffect(() => {\n const element = mount.current;\n if (element === null) return;\n let disposed = false;\n let dispose = (): void => undefined;\n\n void (async () => {\n const [{ Terminal }] = await Promise.all([import('@xterm/xterm'), import('@xterm/xterm/css/xterm.css')]);\n if (disposed) return;\n const terminal = new Terminal({\n cursorBlink: true,\n fontFamily: FONT_STACK,\n fontSize,\n allowTransparency: true,\n // Taken from the document's own custom properties rather than written\n // here, so a theme switch is the only place a colour is ever decided.\n theme: {\n background: tokenColour(element, 'deep'),\n foreground: tokenColour(element, 'dim'),\n cursor: tokenColour(element, 'hi'),\n selectionBackground: tokenColour(element, 'selected'),\n },\n });\n terminal.open(element);\n terminal.onData((text) => dataRef.current?.(text));\n handle.current = {\n write: (data) => terminal.write(data),\n reset: () => terminal.reset(),\n };\n setReady(true);\n onReady?.();\n\n dispose = () => {\n handle.current = undefined;\n terminal.dispose();\n };\n })();\n\n return () => {\n disposed = true;\n dispose();\n };\n // The emulator is built once for the life of the surface; later prop\n // changes reach it through the refs above rather than rebuilding it.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div\n ref={mount}\n data-slot=\"terminal-view\"\n data-ready={ready}\n className={cn('h-full w-full', className)}\n {...props}\n />\n );\n}\n"],"mappings":"mNAsCA,SAAS,EAAY,EAAmB,EAAoD,CAC1F,OAAO,iBAAiB,CAAI,CAAC,CAAC,iBAAiB,EAAc,CAAK,CAAC,CAAC,CAAC,KAAK,CAC5E,CAEA,SAAgB,EAAa,CAC3B,SACA,UACA,MACA,WAAW,GACX,YACA,GAAG,GACiB,CACpB,IAAM,EAAQ,EAA8B,IAAI,EAC1C,EAAS,EAAmC,IAAA,EAAS,EACrD,EAAU,EAA6C,CAAM,EAC7D,CAAC,EAAO,GAAY,EAAS,EAAK,EA0DxC,OAxDA,MAAgB,CACd,EAAQ,QAAU,CACpB,CAAC,EAED,EAAoB,OAAY,CAC9B,MAAQ,GAAS,EAAO,SAAS,MAAM,CAAI,EAC3C,UAAa,EAAO,SAAS,MAAM,CACrC,EAAE,EAEF,MAAgB,CACd,IAAM,EAAU,EAAM,QACtB,GAAI,IAAY,KAAM,OACtB,IAAI,EAAW,GACX,MAAsB,IAAA,GAkC1B,OAhCM,SAAY,CAChB,GAAM,CAAC,CAAE,aAAc,MAAM,QAAQ,IAAI,CAAC,OAAO,gBAAiB,OAAO,6BAA6B,CAAC,EACvG,GAAI,EAAU,OACd,IAAM,EAAW,IAAI,EAAS,CAC5B,YAAa,GACb,WAAY,iDACZ,WACA,kBAAmB,GAGnB,MAAO,CACL,WAAY,EAAY,EAAS,MAAM,EACvC,WAAY,EAAY,EAAS,KAAK,EACtC,OAAQ,EAAY,EAAS,IAAI,EACjC,oBAAqB,EAAY,EAAS,UAAU,CACtD,CACF,CAAC,EACD,EAAS,KAAK,CAAO,EACrB,EAAS,OAAQ,GAAS,EAAQ,UAAU,CAAI,CAAC,EACjD,EAAO,QAAU,CACf,MAAQ,GAAS,EAAS,MAAM,CAAI,EACpC,UAAa,EAAS,MAAM,CAC9B,EACA,EAAS,EAAI,EACb,IAAU,EAEV,MAAgB,CACd,EAAO,QAAU,IAAA,GACjB,EAAS,QAAQ,CACnB,CACF,EAAA,CAAG,MAEU,CACX,EAAW,GACX,EAAQ,CACV,CAIF,EAAG,CAAC,CAAC,EAGH,kBAAC,MAAD,CACE,IAAK,EACL,YAAU,gBACV,aAAY,EACZ,UAAW,EAAG,
|
|
1
|
+
{"version":3,"file":"TerminalView.mjs","names":[],"sources":["../../../src/components/TerminalView.tsx"],"sourcesContent":["import { type ComponentProps, useEffect, useImperativeHandle, useRef, useState } from 'react';\n\nimport { cn } from '../lib/cn';\nimport { themeVariable } from '../types/theme';\n\n/**\n * A terminal emulator, for output that is a screen rather than a document.\n *\n * `AnsiText` beside it renders colour in text that happens to carry escapes.\n * This is the other thing: a full VT emulator that keeps a cursor, a grid and\n * an alternate screen, so a prompt, a progress bar or a full-screen program\n * behaves the way it would in a shell. Give it the bytes a pty produced and it\n * draws them; take its `onData` and you have what the reader typed.\n *\n * The emulator is loaded on mount rather than with the bundle. It is not a\n * small dependency, and most surfaces never show a terminal.\n */\n\nexport interface TerminalHandle {\n /** Writes pane bytes, escapes and all. */\n write(data: Uint8Array | string): void;\n /** Clears the screen and scrollback, for a stream that restarted. */\n reset(): void;\n}\n\nexport interface TerminalViewProps extends Omit<ComponentProps<'div'>, 'children' | 'onData' | 'ref'> {\n /** What the reader typed, already encoded the way a terminal sends it. */\n onData?: (text: string) => void;\n /** Called once the emulator is live, so a caller can start feeding it. */\n onReady?: () => void;\n ref?: React.Ref<TerminalHandle>;\n fontSize?: number;\n}\n\nconst DEFAULT_FONT_SIZE = 11;\nconst FONT_STACK = 'ui-monospace, SFMono-Regular, Menlo, monospace';\n\n/** Reads a theme token from the document, so the terminal follows the active theme. */\nfunction tokenColour(root: HTMLElement, token: Parameters<typeof themeVariable>[0]): string {\n return getComputedStyle(root).getPropertyValue(themeVariable(token)).trim();\n}\n\nexport function TerminalView({\n onData,\n onReady,\n ref,\n fontSize = DEFAULT_FONT_SIZE,\n className,\n ...props\n}: TerminalViewProps) {\n const mount = useRef<HTMLDivElement | null>(null);\n const handle = useRef<TerminalHandle | undefined>(undefined);\n const dataRef = useRef<((text: string) => void) | undefined>(onData);\n const [ready, setReady] = useState(false);\n\n useEffect(() => {\n dataRef.current = onData;\n });\n\n useImperativeHandle(ref, () => ({\n write: (data) => handle.current?.write(data),\n reset: () => handle.current?.reset(),\n }));\n\n useEffect(() => {\n const element = mount.current;\n if (element === null) return;\n let disposed = false;\n let dispose = (): void => undefined;\n\n void (async () => {\n const [{ Terminal }] = await Promise.all([import('@xterm/xterm'), import('@xterm/xterm/css/xterm.css')]);\n if (disposed) return;\n const terminal = new Terminal({\n cursorBlink: true,\n fontFamily: FONT_STACK,\n fontSize,\n allowTransparency: true,\n // Taken from the document's own custom properties rather than written\n // here, so a theme switch is the only place a colour is ever decided.\n theme: {\n background: tokenColour(element, 'deep'),\n foreground: tokenColour(element, 'dim'),\n cursor: tokenColour(element, 'hi'),\n selectionBackground: tokenColour(element, 'selected'),\n },\n });\n terminal.open(element);\n terminal.onData((text) => dataRef.current?.(text));\n handle.current = {\n write: (data) => terminal.write(data),\n reset: () => terminal.reset(),\n };\n setReady(true);\n onReady?.();\n\n dispose = () => {\n handle.current = undefined;\n terminal.dispose();\n };\n })();\n\n return () => {\n disposed = true;\n dispose();\n };\n // The emulator is built once for the life of the surface; later prop\n // changes reach it through the refs above rather than rebuilding it.\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, []);\n\n return (\n <div\n ref={mount}\n data-slot=\"terminal-view\"\n data-ready={ready}\n className={cn('h-full min-w-0 w-full overflow-auto', className)}\n {...props}\n />\n );\n}\n"],"mappings":"mNAsCA,SAAS,EAAY,EAAmB,EAAoD,CAC1F,OAAO,iBAAiB,CAAI,CAAC,CAAC,iBAAiB,EAAc,CAAK,CAAC,CAAC,CAAC,KAAK,CAC5E,CAEA,SAAgB,EAAa,CAC3B,SACA,UACA,MACA,WAAW,GACX,YACA,GAAG,GACiB,CACpB,IAAM,EAAQ,EAA8B,IAAI,EAC1C,EAAS,EAAmC,IAAA,EAAS,EACrD,EAAU,EAA6C,CAAM,EAC7D,CAAC,EAAO,GAAY,EAAS,EAAK,EA0DxC,OAxDA,MAAgB,CACd,EAAQ,QAAU,CACpB,CAAC,EAED,EAAoB,OAAY,CAC9B,MAAQ,GAAS,EAAO,SAAS,MAAM,CAAI,EAC3C,UAAa,EAAO,SAAS,MAAM,CACrC,EAAE,EAEF,MAAgB,CACd,IAAM,EAAU,EAAM,QACtB,GAAI,IAAY,KAAM,OACtB,IAAI,EAAW,GACX,MAAsB,IAAA,GAkC1B,OAhCM,SAAY,CAChB,GAAM,CAAC,CAAE,aAAc,MAAM,QAAQ,IAAI,CAAC,OAAO,gBAAiB,OAAO,6BAA6B,CAAC,EACvG,GAAI,EAAU,OACd,IAAM,EAAW,IAAI,EAAS,CAC5B,YAAa,GACb,WAAY,iDACZ,WACA,kBAAmB,GAGnB,MAAO,CACL,WAAY,EAAY,EAAS,MAAM,EACvC,WAAY,EAAY,EAAS,KAAK,EACtC,OAAQ,EAAY,EAAS,IAAI,EACjC,oBAAqB,EAAY,EAAS,UAAU,CACtD,CACF,CAAC,EACD,EAAS,KAAK,CAAO,EACrB,EAAS,OAAQ,GAAS,EAAQ,UAAU,CAAI,CAAC,EACjD,EAAO,QAAU,CACf,MAAQ,GAAS,EAAS,MAAM,CAAI,EACpC,UAAa,EAAS,MAAM,CAC9B,EACA,EAAS,EAAI,EACb,IAAU,EAEV,MAAgB,CACd,EAAO,QAAU,IAAA,GACjB,EAAS,QAAQ,CACnB,CACF,EAAA,CAAG,MAEU,CACX,EAAW,GACX,EAAQ,CACV,CAIF,EAAG,CAAC,CAAC,EAGH,kBAAC,MAAD,CACE,IAAK,EACL,YAAU,gBACV,aAAY,EACZ,UAAW,EAAG,sCAAuC,CAAS,EAC9D,GAAI,CACL,CAAA,CAEL"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
require("../icons/icons.cjs");const e=require("../lib/cn.cjs");let t=require("radix-ui"),n=require("react/jsx-runtime"),r=require("class-variance-authority"),i=require("lucide-react");function a(e){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Provider,{...e})}function o({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Viewport,{"data-slot":`toast-viewport`,className:e.cn(`fixed right-4 bottom-4 z-50 flex w-[360px] max-w-full flex-col gap-2 outline-none`,r),...i})}const s=(0,r.cva)(`flex items-start gap-3 rounded-md border bg-doom-panel px-3 py-2.5 font-mono shadow-2xl data-[state=open]:animate-doom-rise`,{variants:{tone:{neutral:`border-doom-border`,running:`border-doom-edge-yellow`,ok:`border-doom-edge-green`,error:`border-doom-edge-red`,info:`border-doom-edge-blue`,accent:`border-doom-edge-magenta`}},defaultVariants:{tone:`neutral`}});function c({className:r,tone:i,...a}){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Root,{"data-slot":`toast`,className:e.cn(s({tone:i}),r),...a})}function l({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Title,{"data-slot":`toast-title`,className:e.cn(`text-sm font-bold text-doom-hi`,r),...i})}function u({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Description,{"data-slot":`toast-description`,className:e.cn(`text-sm leading-relaxed text-doom-dim`,r),...i})}function d(e){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Action,{"data-slot":`toast-action`,...e})}function f({className:r,...a}){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Close,{"data-slot":`toast-close`,"aria-label":`dismiss`,className:e.cn(`shrink-0 cursor-pointer text-doom-faint transition-colors hover:text-doom-hi`,r),...a,children:/* @__PURE__ */ (0,n.jsx)(i.X,{className:`h-3 w-3`})})}exports.Toast=c,exports.ToastAction=d,exports.ToastClose=f,exports.ToastDescription=u,exports.ToastProvider=a,exports.ToastTitle=l,exports.ToastViewport=o,exports.toastVariants=s;
|
|
1
|
+
require("../icons/icons.cjs");const e=require("../lib/cn.cjs");let t=require("radix-ui"),n=require("react/jsx-runtime"),r=require("class-variance-authority"),i=require("lucide-react");function a(e){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Provider,{...e})}function o({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Viewport,{"data-slot":`toast-viewport`,className:e.cn(`fixed right-4 bottom-4 z-50 flex w-[360px] max-w-full flex-col gap-2 outline-none`,r),...i})}const s=(0,r.cva)(`flex items-start gap-3 rounded-md border bg-doom-panel px-3 py-2.5 font-mono shadow-2xl data-[state=open]:animate-doom-rise`,{variants:{tone:{neutral:`border-doom-border`,running:`border-doom-edge-yellow`,ok:`border-doom-edge-green`,error:`border-doom-edge-red`,info:`border-doom-edge-blue`,accent:`border-doom-edge-magenta`}},defaultVariants:{tone:`neutral`}});function c({className:r,tone:i,...a}){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Root,{"data-slot":`toast`,className:e.cn(s({tone:i}),r),...a})}function l({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Title,{"data-slot":`toast-title`,className:e.cn(`text-sm font-bold text-doom-hi`,r),...i})}function u({className:r,...i}){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Description,{"data-slot":`toast-description`,className:e.cn(`text-sm leading-relaxed text-doom-dim`,r),...i})}function d(e){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Action,{"data-slot":`toast-action`,...e})}function f({className:r,...a}){return/* @__PURE__ */ (0,n.jsx)(t.Toast.Close,{"data-slot":`toast-close`,"aria-label":`dismiss`,className:e.cn(`inline-flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded text-doom-faint transition-colors hover:text-doom-hi`,r),...a,children:/* @__PURE__ */ (0,n.jsx)(i.X,{className:`h-3 w-3`})})}exports.Toast=c,exports.ToastAction=d,exports.ToastClose=f,exports.ToastDescription=u,exports.ToastProvider=a,exports.ToastTitle=l,exports.ToastViewport=o,exports.toastVariants=s;
|
|
2
2
|
//# sourceMappingURL=Toast.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toast.cjs","names":["ToastPrimitive","cn","cva","CloseIcon"],"sources":["../../../src/components/Toast.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Toast as ToastPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport type { StatusTone } from '../types/tone';\n\n/**\n * A transient notice. Radix owns the part that is easy to get wrong: it\n * announces through a live region, pauses its timer on hover and on window\n * blur, and restores focus when it leaves. Mount one ToastProvider and one\n * ToastViewport per page.\n */\nexport function ToastProvider(props: ComponentProps<typeof ToastPrimitive.Provider>) {\n return <ToastPrimitive.Provider {...props} />;\n}\n\nexport function ToastViewport({ className, ...props }: ComponentProps<typeof ToastPrimitive.Viewport>) {\n return (\n <ToastPrimitive.Viewport\n data-slot=\"toast-viewport\"\n className={cn('fixed right-4 bottom-4 z-50 flex w-[360px] max-w-full flex-col gap-2 outline-none', className)}\n {...props}\n />\n );\n}\n\nexport const toastVariants = cva(\n 'flex items-start gap-3 rounded-md border bg-doom-panel px-3 py-2.5 font-mono shadow-2xl data-[state=open]:animate-doom-rise',\n {\n variants: {\n tone: {\n neutral: 'border-doom-border',\n running: 'border-doom-edge-yellow',\n ok: 'border-doom-edge-green',\n error: 'border-doom-edge-red',\n info: 'border-doom-edge-blue',\n accent: 'border-doom-edge-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n },\n);\n\nexport interface ToastProps extends ComponentProps<typeof ToastPrimitive.Root>, VariantProps<typeof toastVariants> {}\n\nexport function Toast({ className, tone, ...props }: ToastProps) {\n return <ToastPrimitive.Root data-slot=\"toast\" className={cn(toastVariants({ tone }), className)} {...props} />;\n}\n\nexport function ToastTitle({ className, ...props }: ComponentProps<typeof ToastPrimitive.Title>) {\n return (\n <ToastPrimitive.Title\n data-slot=\"toast-title\"\n className={cn('text-sm font-bold text-doom-hi', className)}\n {...props}\n />\n );\n}\n\nexport function ToastDescription({ className, ...props }: ComponentProps<typeof ToastPrimitive.Description>) {\n return (\n <ToastPrimitive.Description\n data-slot=\"toast-description\"\n className={cn('text-sm leading-relaxed text-doom-dim', className)}\n {...props}\n />\n );\n}\n\nexport function ToastAction(props: ComponentProps<typeof ToastPrimitive.Action>) {\n return <ToastPrimitive.Action data-slot=\"toast-action\" {...props} />;\n}\n\nexport function ToastClose({ className, ...props }: ComponentProps<typeof ToastPrimitive.Close>) {\n return (\n <ToastPrimitive.Close\n data-slot=\"toast-close\"\n aria-label=\"dismiss\"\n className={cn('shrink-0 cursor-pointer text-doom-faint transition-colors hover:text-doom-hi'
|
|
1
|
+
{"version":3,"file":"Toast.cjs","names":["ToastPrimitive","cn","cva","CloseIcon"],"sources":["../../../src/components/Toast.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Toast as ToastPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport type { StatusTone } from '../types/tone';\n\n/**\n * A transient notice. Radix owns the part that is easy to get wrong: it\n * announces through a live region, pauses its timer on hover and on window\n * blur, and restores focus when it leaves. Mount one ToastProvider and one\n * ToastViewport per page.\n */\nexport function ToastProvider(props: ComponentProps<typeof ToastPrimitive.Provider>) {\n return <ToastPrimitive.Provider {...props} />;\n}\n\nexport function ToastViewport({ className, ...props }: ComponentProps<typeof ToastPrimitive.Viewport>) {\n return (\n <ToastPrimitive.Viewport\n data-slot=\"toast-viewport\"\n className={cn('fixed right-4 bottom-4 z-50 flex w-[360px] max-w-full flex-col gap-2 outline-none', className)}\n {...props}\n />\n );\n}\n\nexport const toastVariants = cva(\n 'flex items-start gap-3 rounded-md border bg-doom-panel px-3 py-2.5 font-mono shadow-2xl data-[state=open]:animate-doom-rise',\n {\n variants: {\n tone: {\n neutral: 'border-doom-border',\n running: 'border-doom-edge-yellow',\n ok: 'border-doom-edge-green',\n error: 'border-doom-edge-red',\n info: 'border-doom-edge-blue',\n accent: 'border-doom-edge-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n },\n);\n\nexport interface ToastProps extends ComponentProps<typeof ToastPrimitive.Root>, VariantProps<typeof toastVariants> {}\n\nexport function Toast({ className, tone, ...props }: ToastProps) {\n return <ToastPrimitive.Root data-slot=\"toast\" className={cn(toastVariants({ tone }), className)} {...props} />;\n}\n\nexport function ToastTitle({ className, ...props }: ComponentProps<typeof ToastPrimitive.Title>) {\n return (\n <ToastPrimitive.Title\n data-slot=\"toast-title\"\n className={cn('text-sm font-bold text-doom-hi', className)}\n {...props}\n />\n );\n}\n\nexport function ToastDescription({ className, ...props }: ComponentProps<typeof ToastPrimitive.Description>) {\n return (\n <ToastPrimitive.Description\n data-slot=\"toast-description\"\n className={cn('text-sm leading-relaxed text-doom-dim', className)}\n {...props}\n />\n );\n}\n\nexport function ToastAction(props: ComponentProps<typeof ToastPrimitive.Action>) {\n return <ToastPrimitive.Action data-slot=\"toast-action\" {...props} />;\n}\n\nexport function ToastClose({ className, ...props }: ComponentProps<typeof ToastPrimitive.Close>) {\n return (\n <ToastPrimitive.Close\n data-slot=\"toast-close\"\n aria-label=\"dismiss\"\n className={cn(\n 'inline-flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded text-doom-faint transition-colors hover:text-doom-hi',\n className,\n )}\n {...props}\n >\n <CloseIcon className=\"h-3 w-3\" />\n </ToastPrimitive.Close>\n );\n}\n"],"mappings":"wLAcA,SAAgB,EAAc,EAAuD,CACnF,MAAO,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,MAAe,SAAhB,CAAyB,GAAI,CAAQ,CAAA,CAC9C,CAEA,SAAgB,EAAc,CAAE,YAAW,GAAG,GAAyD,CACrG,MACE,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,MAAe,SAAhB,CACE,YAAU,iBACV,UAAWC,EAAAA,GAAG,oFAAqF,CAAS,EAC5G,GAAI,CACL,CAAA,CAEL,CAEA,MAAa,GAAA,EAAgBC,EAAAA,IAAAA,CAC3B,8HACA,CACE,SAAU,CACR,KAAM,CACJ,QAAS,qBACT,QAAS,0BACT,GAAI,yBACJ,MAAO,uBACP,KAAM,wBACN,OAAQ,0BACV,CACF,EACA,gBAAiB,CAAE,KAAM,SAAU,CACrC,CACF,EAIA,SAAgB,EAAM,CAAE,YAAW,OAAM,GAAG,GAAqB,CAC/D,MAAO,iBAAA,EAAA,EAAA,IAAA,CAACF,EAAAA,MAAe,KAAhB,CAAqB,YAAU,QAAQ,UAAWC,EAAAA,GAAG,EAAc,CAAE,MAAK,CAAC,EAAG,CAAS,EAAG,GAAI,CAAQ,CAAA,CAC/G,CAEA,SAAgB,EAAW,CAAE,YAAW,GAAG,GAAsD,CAC/F,MACE,iBAAA,EAAA,EAAA,IAAA,CAACD,EAAAA,MAAe,MAAhB,CACE,YAAU,cACV,UAAWC,EAAAA,GAAG,iCAAkC,CAAS,EACzD,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAiB,CAAE,YAAW,GAAG,GAA4D,CAC3G,MACE,iBAAA,EAAA,EAAA,IAAA,CAACD,EAAAA,MAAe,YAAhB,CACE,YAAU,oBACV,UAAWC,EAAAA,GAAG,wCAAyC,CAAS,EAChE,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAY,EAAqD,CAC/E,MAAO,iBAAA,EAAA,EAAA,IAAA,CAACD,EAAAA,MAAe,OAAhB,CAAuB,YAAU,eAAe,GAAI,CAAQ,CAAA,CACrE,CAEA,SAAgB,EAAW,CAAE,YAAW,GAAG,GAAsD,CAC/F,MACE,iBAAA,EAAA,EAAA,IAAA,CAACA,EAAAA,MAAe,MAAhB,CACE,YAAU,cACV,aAAW,UACX,UAAWC,EAAAA,GACT,uIACA,CACF,EACA,GAAI,EAEJ,SAAA,iBAAA,EAAA,EAAA,IAAA,CAACE,EAAAA,EAAD,CAAW,UAAU,SAAW,CAAA,CACZ,CAAA,CAE1B"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{CloseIcon as e}from"../icons/icons.mjs";import{cn as t}from"../lib/cn.mjs";import{Toast as n}from"radix-ui";import{jsx as r}from"react/jsx-runtime";import{cva as i}from"class-variance-authority";function a(e){return/* @__PURE__ */ r(n.Provider,{...e})}function o({className:e,...i}){return/* @__PURE__ */ r(n.Viewport,{"data-slot":`toast-viewport`,className:t(`fixed right-4 bottom-4 z-50 flex w-[360px] max-w-full flex-col gap-2 outline-none`,e),...i})}const s=i(`flex items-start gap-3 rounded-md border bg-doom-panel px-3 py-2.5 font-mono shadow-2xl data-[state=open]:animate-doom-rise`,{variants:{tone:{neutral:`border-doom-border`,running:`border-doom-edge-yellow`,ok:`border-doom-edge-green`,error:`border-doom-edge-red`,info:`border-doom-edge-blue`,accent:`border-doom-edge-magenta`}},defaultVariants:{tone:`neutral`}});function c({className:e,tone:i,...a}){return/* @__PURE__ */ r(n.Root,{"data-slot":`toast`,className:t(s({tone:i}),e),...a})}function l({className:e,...i}){return/* @__PURE__ */ r(n.Title,{"data-slot":`toast-title`,className:t(`text-sm font-bold text-doom-hi`,e),...i})}function u({className:e,...i}){return/* @__PURE__ */ r(n.Description,{"data-slot":`toast-description`,className:t(`text-sm leading-relaxed text-doom-dim`,e),...i})}function d(e){return/* @__PURE__ */ r(n.Action,{"data-slot":`toast-action`,...e})}function f({className:i,...a}){return/* @__PURE__ */ r(n.Close,{"data-slot":`toast-close`,"aria-label":`dismiss`,className:t(`shrink-0 cursor-pointer text-doom-faint transition-colors hover:text-doom-hi`,i),...a,children:/* @__PURE__ */ r(e,{className:`h-3 w-3`})})}export{c as Toast,d as ToastAction,f as ToastClose,u as ToastDescription,a as ToastProvider,l as ToastTitle,o as ToastViewport,s as toastVariants};
|
|
1
|
+
import{CloseIcon as e}from"../icons/icons.mjs";import{cn as t}from"../lib/cn.mjs";import{Toast as n}from"radix-ui";import{jsx as r}from"react/jsx-runtime";import{cva as i}from"class-variance-authority";function a(e){return/* @__PURE__ */ r(n.Provider,{...e})}function o({className:e,...i}){return/* @__PURE__ */ r(n.Viewport,{"data-slot":`toast-viewport`,className:t(`fixed right-4 bottom-4 z-50 flex w-[360px] max-w-full flex-col gap-2 outline-none`,e),...i})}const s=i(`flex items-start gap-3 rounded-md border bg-doom-panel px-3 py-2.5 font-mono shadow-2xl data-[state=open]:animate-doom-rise`,{variants:{tone:{neutral:`border-doom-border`,running:`border-doom-edge-yellow`,ok:`border-doom-edge-green`,error:`border-doom-edge-red`,info:`border-doom-edge-blue`,accent:`border-doom-edge-magenta`}},defaultVariants:{tone:`neutral`}});function c({className:e,tone:i,...a}){return/* @__PURE__ */ r(n.Root,{"data-slot":`toast`,className:t(s({tone:i}),e),...a})}function l({className:e,...i}){return/* @__PURE__ */ r(n.Title,{"data-slot":`toast-title`,className:t(`text-sm font-bold text-doom-hi`,e),...i})}function u({className:e,...i}){return/* @__PURE__ */ r(n.Description,{"data-slot":`toast-description`,className:t(`text-sm leading-relaxed text-doom-dim`,e),...i})}function d(e){return/* @__PURE__ */ r(n.Action,{"data-slot":`toast-action`,...e})}function f({className:i,...a}){return/* @__PURE__ */ r(n.Close,{"data-slot":`toast-close`,"aria-label":`dismiss`,className:t(`inline-flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded text-doom-faint transition-colors hover:text-doom-hi`,i),...a,children:/* @__PURE__ */ r(e,{className:`h-3 w-3`})})}export{c as Toast,d as ToastAction,f as ToastClose,u as ToastDescription,a as ToastProvider,l as ToastTitle,o as ToastViewport,s as toastVariants};
|
|
2
2
|
//# sourceMappingURL=Toast.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Toast.mjs","names":["ToastPrimitive","Toast"],"sources":["../../../src/components/Toast.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Toast as ToastPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport type { StatusTone } from '../types/tone';\n\n/**\n * A transient notice. Radix owns the part that is easy to get wrong: it\n * announces through a live region, pauses its timer on hover and on window\n * blur, and restores focus when it leaves. Mount one ToastProvider and one\n * ToastViewport per page.\n */\nexport function ToastProvider(props: ComponentProps<typeof ToastPrimitive.Provider>) {\n return <ToastPrimitive.Provider {...props} />;\n}\n\nexport function ToastViewport({ className, ...props }: ComponentProps<typeof ToastPrimitive.Viewport>) {\n return (\n <ToastPrimitive.Viewport\n data-slot=\"toast-viewport\"\n className={cn('fixed right-4 bottom-4 z-50 flex w-[360px] max-w-full flex-col gap-2 outline-none', className)}\n {...props}\n />\n );\n}\n\nexport const toastVariants = cva(\n 'flex items-start gap-3 rounded-md border bg-doom-panel px-3 py-2.5 font-mono shadow-2xl data-[state=open]:animate-doom-rise',\n {\n variants: {\n tone: {\n neutral: 'border-doom-border',\n running: 'border-doom-edge-yellow',\n ok: 'border-doom-edge-green',\n error: 'border-doom-edge-red',\n info: 'border-doom-edge-blue',\n accent: 'border-doom-edge-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n },\n);\n\nexport interface ToastProps extends ComponentProps<typeof ToastPrimitive.Root>, VariantProps<typeof toastVariants> {}\n\nexport function Toast({ className, tone, ...props }: ToastProps) {\n return <ToastPrimitive.Root data-slot=\"toast\" className={cn(toastVariants({ tone }), className)} {...props} />;\n}\n\nexport function ToastTitle({ className, ...props }: ComponentProps<typeof ToastPrimitive.Title>) {\n return (\n <ToastPrimitive.Title\n data-slot=\"toast-title\"\n className={cn('text-sm font-bold text-doom-hi', className)}\n {...props}\n />\n );\n}\n\nexport function ToastDescription({ className, ...props }: ComponentProps<typeof ToastPrimitive.Description>) {\n return (\n <ToastPrimitive.Description\n data-slot=\"toast-description\"\n className={cn('text-sm leading-relaxed text-doom-dim', className)}\n {...props}\n />\n );\n}\n\nexport function ToastAction(props: ComponentProps<typeof ToastPrimitive.Action>) {\n return <ToastPrimitive.Action data-slot=\"toast-action\" {...props} />;\n}\n\nexport function ToastClose({ className, ...props }: ComponentProps<typeof ToastPrimitive.Close>) {\n return (\n <ToastPrimitive.Close\n data-slot=\"toast-close\"\n aria-label=\"dismiss\"\n className={cn('shrink-0 cursor-pointer text-doom-faint transition-colors hover:text-doom-hi'
|
|
1
|
+
{"version":3,"file":"Toast.mjs","names":["ToastPrimitive","Toast"],"sources":["../../../src/components/Toast.tsx"],"sourcesContent":["import { cva, type VariantProps } from 'class-variance-authority';\nimport { Toast as ToastPrimitive } from 'radix-ui';\nimport type { ComponentProps } from 'react';\n\nimport { CloseIcon } from '../icons/icons';\nimport { cn } from '../lib/cn';\nimport type { StatusTone } from '../types/tone';\n\n/**\n * A transient notice. Radix owns the part that is easy to get wrong: it\n * announces through a live region, pauses its timer on hover and on window\n * blur, and restores focus when it leaves. Mount one ToastProvider and one\n * ToastViewport per page.\n */\nexport function ToastProvider(props: ComponentProps<typeof ToastPrimitive.Provider>) {\n return <ToastPrimitive.Provider {...props} />;\n}\n\nexport function ToastViewport({ className, ...props }: ComponentProps<typeof ToastPrimitive.Viewport>) {\n return (\n <ToastPrimitive.Viewport\n data-slot=\"toast-viewport\"\n className={cn('fixed right-4 bottom-4 z-50 flex w-[360px] max-w-full flex-col gap-2 outline-none', className)}\n {...props}\n />\n );\n}\n\nexport const toastVariants = cva(\n 'flex items-start gap-3 rounded-md border bg-doom-panel px-3 py-2.5 font-mono shadow-2xl data-[state=open]:animate-doom-rise',\n {\n variants: {\n tone: {\n neutral: 'border-doom-border',\n running: 'border-doom-edge-yellow',\n ok: 'border-doom-edge-green',\n error: 'border-doom-edge-red',\n info: 'border-doom-edge-blue',\n accent: 'border-doom-edge-magenta',\n } satisfies Record<StatusTone, string>,\n },\n defaultVariants: { tone: 'neutral' },\n },\n);\n\nexport interface ToastProps extends ComponentProps<typeof ToastPrimitive.Root>, VariantProps<typeof toastVariants> {}\n\nexport function Toast({ className, tone, ...props }: ToastProps) {\n return <ToastPrimitive.Root data-slot=\"toast\" className={cn(toastVariants({ tone }), className)} {...props} />;\n}\n\nexport function ToastTitle({ className, ...props }: ComponentProps<typeof ToastPrimitive.Title>) {\n return (\n <ToastPrimitive.Title\n data-slot=\"toast-title\"\n className={cn('text-sm font-bold text-doom-hi', className)}\n {...props}\n />\n );\n}\n\nexport function ToastDescription({ className, ...props }: ComponentProps<typeof ToastPrimitive.Description>) {\n return (\n <ToastPrimitive.Description\n data-slot=\"toast-description\"\n className={cn('text-sm leading-relaxed text-doom-dim', className)}\n {...props}\n />\n );\n}\n\nexport function ToastAction(props: ComponentProps<typeof ToastPrimitive.Action>) {\n return <ToastPrimitive.Action data-slot=\"toast-action\" {...props} />;\n}\n\nexport function ToastClose({ className, ...props }: ComponentProps<typeof ToastPrimitive.Close>) {\n return (\n <ToastPrimitive.Close\n data-slot=\"toast-close\"\n aria-label=\"dismiss\"\n className={cn(\n 'inline-flex h-6 w-6 shrink-0 cursor-pointer items-center justify-center rounded text-doom-faint transition-colors hover:text-doom-hi',\n className,\n )}\n {...props}\n >\n <CloseIcon className=\"h-3 w-3\" />\n </ToastPrimitive.Close>\n );\n}\n"],"mappings":"0MAcA,SAAgB,EAAc,EAAuD,CACnF,MAAO,kBAACA,EAAe,SAAhB,CAAyB,GAAI,CAAQ,CAAA,CAC9C,CAEA,SAAgB,EAAc,CAAE,YAAW,GAAG,GAAyD,CACrG,MACE,kBAACA,EAAe,SAAhB,CACE,YAAU,iBACV,UAAW,EAAG,oFAAqF,CAAS,EAC5G,GAAI,CACL,CAAA,CAEL,CAEA,MAAa,EAAgB,EAC3B,8HACA,CACE,SAAU,CACR,KAAM,CACJ,QAAS,qBACT,QAAS,0BACT,GAAI,yBACJ,MAAO,uBACP,KAAM,wBACN,OAAQ,0BACV,CACF,EACA,gBAAiB,CAAE,KAAM,SAAU,CACrC,CACF,EAIA,SAAgBC,EAAM,CAAE,YAAW,OAAM,GAAG,GAAqB,CAC/D,MAAO,kBAACD,EAAe,KAAhB,CAAqB,YAAU,QAAQ,UAAW,EAAG,EAAc,CAAE,MAAK,CAAC,EAAG,CAAS,EAAG,GAAI,CAAQ,CAAA,CAC/G,CAEA,SAAgB,EAAW,CAAE,YAAW,GAAG,GAAsD,CAC/F,MACE,kBAACA,EAAe,MAAhB,CACE,YAAU,cACV,UAAW,EAAG,iCAAkC,CAAS,EACzD,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAiB,CAAE,YAAW,GAAG,GAA4D,CAC3G,MACE,kBAACA,EAAe,YAAhB,CACE,YAAU,oBACV,UAAW,EAAG,wCAAyC,CAAS,EAChE,GAAI,CACL,CAAA,CAEL,CAEA,SAAgB,EAAY,EAAqD,CAC/E,MAAO,kBAACA,EAAe,OAAhB,CAAuB,YAAU,eAAe,GAAI,CAAQ,CAAA,CACrE,CAEA,SAAgB,EAAW,CAAE,YAAW,GAAG,GAAsD,CAC/F,MACE,kBAACA,EAAe,MAAhB,CACE,YAAU,cACV,aAAW,UACX,UAAW,EACT,uIACA,CACF,EACA,GAAI,EAEJ,SAAA,kBAAC,EAAD,CAAW,UAAU,SAAW,CAAA,CACZ,CAAA,CAE1B"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
const e=require("../lib/cn.cjs");let t=require("react/jsx-runtime");function n({path:n,onOpen:r,className:i,"data-testid":a=`tool-path`,...o}){return r===void 0?/* @__PURE__ */ (0,t.jsx)(`span`,{"data-slot":`tool-path`,"data-testid":a,className:e.cn(`truncate text-doom-text`,i),...o,children:n}):/* @__PURE__ */ (0,t.jsx)(`button`,{type:`button`,"data-slot":`tool-path`,"data-testid":a,title:`open ${n}`,onClick:r,className:e.cn(`cursor-pointer truncate text-left text-doom-text hover:text-doom-blue hover:underline`,i),...o,children:n})}exports.ToolPathLink=n;
|
|
1
|
+
const e=require("../lib/cn.cjs");let t=require("react/jsx-runtime");function n({path:n,onOpen:r,className:i,"data-testid":a=`tool-path`,...o}){return r===void 0?/* @__PURE__ */ (0,t.jsx)(`span`,{"data-slot":`tool-path`,"data-testid":a,className:e.cn(`inline-block max-w-full min-w-0 truncate align-bottom text-doom-text`,i),...o,children:n}):/* @__PURE__ */ (0,t.jsx)(`button`,{type:`button`,"data-slot":`tool-path`,"data-testid":a,title:`open ${n}`,onClick:r,className:e.cn(`min-h-6 max-w-full min-w-0 cursor-pointer truncate text-left text-doom-text hover:text-doom-blue hover:underline`,i),...o,children:n})}exports.ToolPathLink=n;
|
|
2
2
|
//# sourceMappingURL=ToolPathLink.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolPathLink.cjs","names":["cn"],"sources":["../../../src/components/ToolPathLink.tsx"],"sourcesContent":["import { cn } from '../lib/cn';\n\n/**\n * The file path in a tool call's header, as a link when something can open it.\n *\n * A read, a write and an edit all put a path in the same place, and a reader\n * who wants to see that file should not have to go looking for it in a file\n * list. Whether the path can be opened is not this component's business: the\n * host resolves it against whatever plugin owns files, and hands the answer\n * down as `onOpen`. Without one the path stays exactly what it was, plain\n * text, because a link that opens nothing is worse than no link.\n */\n\nexport interface ToolPathLinkProps {\n path: string;\n /** Opens the file; omitted when nothing installed can show it. */\n onOpen?: () => void;\n className?: string;\n /** Defaults to `tool-path`, which is how a test finds the link inside a call header. */\n 'data-testid'?: string;\n}\n\nexport function ToolPathLink({\n path,\n onOpen,\n className,\n 'data-testid': testId = 'tool-path',\n ...props\n}: ToolPathLinkProps) {\n if (onOpen === undefined) {\n return (\n <span
|
|
1
|
+
{"version":3,"file":"ToolPathLink.cjs","names":["cn"],"sources":["../../../src/components/ToolPathLink.tsx"],"sourcesContent":["import { cn } from '../lib/cn';\n\n/**\n * The file path in a tool call's header, as a link when something can open it.\n *\n * A read, a write and an edit all put a path in the same place, and a reader\n * who wants to see that file should not have to go looking for it in a file\n * list. Whether the path can be opened is not this component's business: the\n * host resolves it against whatever plugin owns files, and hands the answer\n * down as `onOpen`. Without one the path stays exactly what it was, plain\n * text, because a link that opens nothing is worse than no link.\n */\n\nexport interface ToolPathLinkProps {\n path: string;\n /** Opens the file; omitted when nothing installed can show it. */\n onOpen?: () => void;\n className?: string;\n /** Defaults to `tool-path`, which is how a test finds the link inside a call header. */\n 'data-testid'?: string;\n}\n\nexport function ToolPathLink({\n path,\n onOpen,\n className,\n 'data-testid': testId = 'tool-path',\n ...props\n}: ToolPathLinkProps) {\n if (onOpen === undefined) {\n return (\n <span\n data-slot=\"tool-path\"\n data-testid={testId}\n className={cn('inline-block max-w-full min-w-0 truncate align-bottom text-doom-text', className)}\n {...props}\n >\n {path}\n </span>\n );\n }\n return (\n <button\n type=\"button\"\n data-slot=\"tool-path\"\n data-testid={testId}\n title={`open ${path}`}\n onClick={onOpen}\n className={cn(\n 'min-h-6 max-w-full min-w-0 cursor-pointer truncate text-left text-doom-text hover:text-doom-blue hover:underline',\n className,\n )}\n {...props}\n >\n {path}\n </button>\n );\n}\n"],"mappings":"oEAsBA,SAAgB,EAAa,CAC3B,OACA,SACA,YACA,cAAe,EAAS,YACxB,GAAG,GACiB,CAapB,OAZI,IAAW,IAAA,GAEX,iBAAA,EAAA,EAAA,IAAA,CAAC,OAAD,CACE,YAAU,YACV,cAAa,EACb,UAAWA,EAAAA,GAAG,uEAAwE,CAAS,EAC/F,GAAI,EAEH,SAAA,CACG,CAAA,EAIR,iBAAA,EAAA,EAAA,IAAA,CAAC,SAAD,CACE,KAAK,SACL,YAAU,YACV,cAAa,EACb,MAAO,QAAQ,IACf,QAAS,EACT,UAAWA,EAAAA,GACT,mHACA,CACF,EACA,GAAI,EAEH,SAAA,CACK,CAAA,CAEZ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{cn as e}from"../lib/cn.mjs";import{jsx as t}from"react/jsx-runtime";function n({path:n,onOpen:r,className:i,"data-testid":a=`tool-path`,...o}){return r===void 0?/* @__PURE__ */ t(`span`,{"data-slot":`tool-path`,"data-testid":a,className:e(`truncate text-doom-text`,i),...o,children:n}):/* @__PURE__ */ t(`button`,{type:`button`,"data-slot":`tool-path`,"data-testid":a,title:`open ${n}`,onClick:r,className:e(`cursor-pointer truncate text-left text-doom-text hover:text-doom-blue hover:underline`,i),...o,children:n})}export{n as ToolPathLink};
|
|
1
|
+
import{cn as e}from"../lib/cn.mjs";import{jsx as t}from"react/jsx-runtime";function n({path:n,onOpen:r,className:i,"data-testid":a=`tool-path`,...o}){return r===void 0?/* @__PURE__ */ t(`span`,{"data-slot":`tool-path`,"data-testid":a,className:e(`inline-block max-w-full min-w-0 truncate align-bottom text-doom-text`,i),...o,children:n}):/* @__PURE__ */ t(`button`,{type:`button`,"data-slot":`tool-path`,"data-testid":a,title:`open ${n}`,onClick:r,className:e(`min-h-6 max-w-full min-w-0 cursor-pointer truncate text-left text-doom-text hover:text-doom-blue hover:underline`,i),...o,children:n})}export{n as ToolPathLink};
|
|
2
2
|
//# sourceMappingURL=ToolPathLink.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ToolPathLink.mjs","names":[],"sources":["../../../src/components/ToolPathLink.tsx"],"sourcesContent":["import { cn } from '../lib/cn';\n\n/**\n * The file path in a tool call's header, as a link when something can open it.\n *\n * A read, a write and an edit all put a path in the same place, and a reader\n * who wants to see that file should not have to go looking for it in a file\n * list. Whether the path can be opened is not this component's business: the\n * host resolves it against whatever plugin owns files, and hands the answer\n * down as `onOpen`. Without one the path stays exactly what it was, plain\n * text, because a link that opens nothing is worse than no link.\n */\n\nexport interface ToolPathLinkProps {\n path: string;\n /** Opens the file; omitted when nothing installed can show it. */\n onOpen?: () => void;\n className?: string;\n /** Defaults to `tool-path`, which is how a test finds the link inside a call header. */\n 'data-testid'?: string;\n}\n\nexport function ToolPathLink({\n path,\n onOpen,\n className,\n 'data-testid': testId = 'tool-path',\n ...props\n}: ToolPathLinkProps) {\n if (onOpen === undefined) {\n return (\n <span
|
|
1
|
+
{"version":3,"file":"ToolPathLink.mjs","names":[],"sources":["../../../src/components/ToolPathLink.tsx"],"sourcesContent":["import { cn } from '../lib/cn';\n\n/**\n * The file path in a tool call's header, as a link when something can open it.\n *\n * A read, a write and an edit all put a path in the same place, and a reader\n * who wants to see that file should not have to go looking for it in a file\n * list. Whether the path can be opened is not this component's business: the\n * host resolves it against whatever plugin owns files, and hands the answer\n * down as `onOpen`. Without one the path stays exactly what it was, plain\n * text, because a link that opens nothing is worse than no link.\n */\n\nexport interface ToolPathLinkProps {\n path: string;\n /** Opens the file; omitted when nothing installed can show it. */\n onOpen?: () => void;\n className?: string;\n /** Defaults to `tool-path`, which is how a test finds the link inside a call header. */\n 'data-testid'?: string;\n}\n\nexport function ToolPathLink({\n path,\n onOpen,\n className,\n 'data-testid': testId = 'tool-path',\n ...props\n}: ToolPathLinkProps) {\n if (onOpen === undefined) {\n return (\n <span\n data-slot=\"tool-path\"\n data-testid={testId}\n className={cn('inline-block max-w-full min-w-0 truncate align-bottom text-doom-text', className)}\n {...props}\n >\n {path}\n </span>\n );\n }\n return (\n <button\n type=\"button\"\n data-slot=\"tool-path\"\n data-testid={testId}\n title={`open ${path}`}\n onClick={onOpen}\n className={cn(\n 'min-h-6 max-w-full min-w-0 cursor-pointer truncate text-left text-doom-text hover:text-doom-blue hover:underline',\n className,\n )}\n {...props}\n >\n {path}\n </button>\n );\n}\n"],"mappings":"2EAsBA,SAAgB,EAAa,CAC3B,OACA,SACA,YACA,cAAe,EAAS,YACxB,GAAG,GACiB,CAapB,OAZI,IAAW,IAAA,GAEX,kBAAC,OAAD,CACE,YAAU,YACV,cAAa,EACb,UAAW,EAAG,uEAAwE,CAAS,EAC/F,GAAI,EAEH,SAAA,CACG,CAAA,EAIR,kBAAC,SAAD,CACE,KAAK,SACL,YAAU,YACV,cAAa,EACb,MAAO,QAAQ,IACf,QAAS,EACT,UAAW,EACT,mHACA,CACF,EACA,GAAI,EAEH,SAAA,CACK,CAAA,CAEZ"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={name:`doom-nord-dark`,label:`Doom Nord (dark)`,scheme:`dark`,tokens:{bg:`#2e3440`,rail:`#272c36`,panel:`#2b313d`,deep:`#232831`,border:`#434c5e`,"border-soft":`#353c4a`,hi:`#eceff4`,text:`#d8dee9`,dim:`#9aa4b8`,faint:`#
|
|
1
|
+
var e={name:`doom-nord-dark`,label:`Doom Nord (dark)`,scheme:`dark`,tokens:{bg:`#2e3440`,rail:`#272c36`,panel:`#2b313d`,deep:`#232831`,border:`#434c5e`,"border-soft":`#353c4a`,hi:`#eceff4`,text:`#d8dee9`,dim:`#9aa4b8`,faint:`#939db1`,blue:`#81a1c1`,green:`#a3be8c`,yellow:`#ebcb8b`,red:`#bf616a`,magenta:`#b48ead`,violet:`#a3a7d6`,cyan:`#88c0d0`,orange:`#d08770`,teal:`#8fbcbb`,selected:`#4c6a92`}};Object.defineProperty(exports,"default",{enumerable:!0,get:function(){return e}});
|
|
2
2
|
//# sourceMappingURL=doom-nord-dark.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={name:`doom-nord-dark`,label:`Doom Nord (dark)`,scheme:`dark`,tokens:{bg:`#2e3440`,rail:`#272c36`,panel:`#2b313d`,deep:`#232831`,border:`#434c5e`,"border-soft":`#353c4a`,hi:`#eceff4`,text:`#d8dee9`,dim:`#9aa4b8`,faint:`#
|
|
1
|
+
var e={name:`doom-nord-dark`,label:`Doom Nord (dark)`,scheme:`dark`,tokens:{bg:`#2e3440`,rail:`#272c36`,panel:`#2b313d`,deep:`#232831`,border:`#434c5e`,"border-soft":`#353c4a`,hi:`#eceff4`,text:`#d8dee9`,dim:`#9aa4b8`,faint:`#939db1`,blue:`#81a1c1`,green:`#a3be8c`,yellow:`#ebcb8b`,red:`#bf616a`,magenta:`#b48ead`,violet:`#a3a7d6`,cyan:`#88c0d0`,orange:`#d08770`,teal:`#8fbcbb`,selected:`#4c6a92`}};export{e as default};
|
|
2
2
|
//# sourceMappingURL=doom-nord-dark.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={name:`doom-one-dark`,label:`Doom One (dark)`,scheme:`dark`,tokens:{bg:`#282c34`,rail:`#21242b`,panel:`#23272e`,deep:`#1c1f24`,border:`#3f444a`,"border-soft":`#2a2e35`,hi:`#dfdfdf`,text:`#bbc2cf`,dim:`#9ca0a4`,faint:`#
|
|
1
|
+
var e={name:`doom-one-dark`,label:`Doom One (dark)`,scheme:`dark`,tokens:{bg:`#282c34`,rail:`#21242b`,panel:`#23272e`,deep:`#1c1f24`,border:`#3f444a`,"border-soft":`#2a2e35`,hi:`#dfdfdf`,text:`#bbc2cf`,dim:`#9ca0a4`,faint:`#92989f`,blue:`#51afef`,green:`#98be65`,yellow:`#ecbe7b`,red:`#ff6c6b`,magenta:`#c678dd`,violet:`#a9a1e1`,cyan:`#46d9ff`,orange:`#da8548`,teal:`#4db5bd`,selected:`#2257a0`,"tint-blue":`#21313f`,"tint-green":`#262e1e`,"tint-yellow":`#312a1c`,"tint-red":`#332428`,"tint-magenta":`#2e2136`,"tint-violet":`#2d253f`,"edge-blue":`#2f4a68`,"edge-green":`#35452e`,"edge-yellow":`#574427`,"edge-red":`#6b3a3a`,"edge-magenta":`#4a3358`,"edge-violet":`#3b3558`}};Object.defineProperty(exports,"default",{enumerable:!0,get:function(){return e}});
|
|
2
2
|
//# sourceMappingURL=doom-one-dark.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={name:`doom-one-dark`,label:`Doom One (dark)`,scheme:`dark`,tokens:{bg:`#282c34`,rail:`#21242b`,panel:`#23272e`,deep:`#1c1f24`,border:`#3f444a`,"border-soft":`#2a2e35`,hi:`#dfdfdf`,text:`#bbc2cf`,dim:`#9ca0a4`,faint:`#
|
|
1
|
+
var e={name:`doom-one-dark`,label:`Doom One (dark)`,scheme:`dark`,tokens:{bg:`#282c34`,rail:`#21242b`,panel:`#23272e`,deep:`#1c1f24`,border:`#3f444a`,"border-soft":`#2a2e35`,hi:`#dfdfdf`,text:`#bbc2cf`,dim:`#9ca0a4`,faint:`#92989f`,blue:`#51afef`,green:`#98be65`,yellow:`#ecbe7b`,red:`#ff6c6b`,magenta:`#c678dd`,violet:`#a9a1e1`,cyan:`#46d9ff`,orange:`#da8548`,teal:`#4db5bd`,selected:`#2257a0`,"tint-blue":`#21313f`,"tint-green":`#262e1e`,"tint-yellow":`#312a1c`,"tint-red":`#332428`,"tint-magenta":`#2e2136`,"tint-violet":`#2d253f`,"edge-blue":`#2f4a68`,"edge-green":`#35452e`,"edge-yellow":`#574427`,"edge-red":`#6b3a3a`,"edge-magenta":`#4a3358`,"edge-violet":`#3b3558`}};export{e as default};
|
|
2
2
|
//# sourceMappingURL=doom-one-dark.mjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={name:`doom-one-light`,label:`Doom One (light)`,scheme:`light`,tokens:{bg:`#fafafa`,rail:`#f0f0f0`,panel:`#f4f4f5`,deep:`#e7e7e8`,border:`#d4d4d8`,"border-soft":`#e4e4e7`,hi:`#1c1f24`,text:`#383a42`,dim:`#
|
|
1
|
+
var e={name:`doom-one-light`,label:`Doom One (light)`,scheme:`light`,tokens:{bg:`#fafafa`,rail:`#f0f0f0`,panel:`#f4f4f5`,deep:`#e7e7e8`,border:`#d4d4d8`,"border-soft":`#e4e4e7`,hi:`#1c1f24`,text:`#383a42`,dim:`#5f6269`,faint:`#65666b`,blue:`#4078f2`,green:`#50a14f`,yellow:`#986801`,red:`#e45649`,magenta:`#a626a4`,violet:`#7c5bcf`,cyan:`#0184bc`,orange:`#da8548`,teal:`#2f9c9c`,selected:`#4078f2`}};Object.defineProperty(exports,"default",{enumerable:!0,get:function(){return e}});
|
|
2
2
|
//# sourceMappingURL=doom-one-light.cjs.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e={name:`doom-one-light`,label:`Doom One (light)`,scheme:`light`,tokens:{bg:`#fafafa`,rail:`#f0f0f0`,panel:`#f4f4f5`,deep:`#e7e7e8`,border:`#d4d4d8`,"border-soft":`#e4e4e7`,hi:`#1c1f24`,text:`#383a42`,dim:`#
|
|
1
|
+
var e={name:`doom-one-light`,label:`Doom One (light)`,scheme:`light`,tokens:{bg:`#fafafa`,rail:`#f0f0f0`,panel:`#f4f4f5`,deep:`#e7e7e8`,border:`#d4d4d8`,"border-soft":`#e4e4e7`,hi:`#1c1f24`,text:`#383a42`,dim:`#5f6269`,faint:`#65666b`,blue:`#4078f2`,green:`#50a14f`,yellow:`#986801`,red:`#e45649`,magenta:`#a626a4`,violet:`#7c5bcf`,cyan:`#0184bc`,orange:`#da8548`,teal:`#2f9c9c`,selected:`#4078f2`}};export{e as default};
|
|
2
2
|
//# sourceMappingURL=doom-one-light.mjs.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agimon-ai/doompi-web-components",
|
|
3
|
-
"version": "0.0.1-alpha.
|
|
3
|
+
"version": "0.0.1-alpha.45",
|
|
4
4
|
"description": "Shared web components and theme tokens for the DoomPi cockpit and its web plugins: shadcn-style primitives on Radix, tuned to the Doom palette, with runtime theme configs.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai",
|
|
@@ -84,8 +84,8 @@
|
|
|
84
84
|
"tailwind-merge": "3.7.0"
|
|
85
85
|
},
|
|
86
86
|
"devDependencies": {
|
|
87
|
-
"@agimon-ai/doompi-core": "0.0.1-alpha.
|
|
88
|
-
"@agimon-ai/vibe-lint-plugin-doom-web": "0.0.1-alpha.
|
|
87
|
+
"@agimon-ai/doompi-core": "0.0.1-alpha.87",
|
|
88
|
+
"@agimon-ai/vibe-lint-plugin-doom-web": "0.0.1-alpha.78",
|
|
89
89
|
"@types/node": "26.6.1",
|
|
90
90
|
"@types/react": "19.3.0",
|
|
91
91
|
"@types/react-dom": "19.3.0",
|
package/styles/tokens.css
CHANGED