@mikenotthepope/substrateui 0.1.3 → 0.2.1

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.
@@ -86,6 +86,12 @@ declare function PageTabsTrigger({ className, ref, ...props }: React.ComponentPr
86
86
  /** Content panel associated with a page tab value. */
87
87
  declare function PageTabsContent({ className, ref, ...props }: React.ComponentPropsWithRef<typeof TabsContent>): react_jsx_runtime.JSX.Element;
88
88
 
89
+ /** Translatable strings used by StatCard. All keys have English defaults. */
90
+ interface StatCardLabels {
91
+ increase?: (change: string) => string;
92
+ decrease?: (change: string) => string;
93
+ change?: (change: string) => string;
94
+ }
89
95
  /** Props for StatCard including title, value, and optional change indicator. */
90
96
  interface StatCardProps extends Omit<React.ComponentPropsWithRef<"div">, "title"> {
91
97
  title: string;
@@ -95,6 +101,7 @@ interface StatCardProps extends Omit<React.ComponentPropsWithRef<"div">, "title"
95
101
  icon?: React.ComponentType<{
96
102
  className?: string;
97
103
  }>;
104
+ labels?: StatCardLabels;
98
105
  }
99
106
  /** Card displaying a key metric with title, value, optional change badge, and icon.
100
107
  *
@@ -107,6 +114,6 @@ interface StatCardProps extends Omit<React.ComponentPropsWithRef<"div">, "title"
107
114
  * @prop changeType - Color coding: "positive", "negative", or "neutral".
108
115
  * @prop icon - Optional icon component displayed at top-right.
109
116
  */
110
- declare function StatCard({ title, value, change, changeType, icon: Icon, className, ref, ...props }: StatCardProps): react_jsx_runtime.JSX.Element;
117
+ declare function StatCard({ title, value, change, changeType, icon: Icon, className, labels: labelsProp, ref, ...props }: StatCardProps): react_jsx_runtime.JSX.Element;
111
118
 
112
- export { AppShell, AppShellFooter, AppShellLogo, AppShellMain, AppShellNav, AppShellNavItem, type AppShellNavItemProps, AppShellSidebar, PageBody, type PageBodyProps, PageHeader, PageHeaderActions, PageHeaderBreadcrumb, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageTabs, PageTabsContent, PageTabsList, PageTabsTrigger, StatCard, type StatCardProps };
119
+ export { AppShell, AppShellFooter, AppShellLogo, AppShellMain, AppShellNav, AppShellNavItem, type AppShellNavItemProps, AppShellSidebar, PageBody, type PageBodyProps, PageHeader, PageHeaderActions, PageHeaderBreadcrumb, PageHeaderContent, PageHeaderDescription, PageHeaderTitle, PageTabs, PageTabsContent, PageTabsList, PageTabsTrigger, StatCard, type StatCardLabels, type StatCardProps };
package/dist/organisms.js CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { Stack, Center, Tabs, TabsList, TabsTrigger, TabsContent, Card, CardContent } from './chunk-IRBORST3.js';
2
+ import { Stack, Center, Tabs, TabsList, TabsTrigger, TabsContent, useLabels, resolveLabels, Card, CardContent } from './chunk-GK4MVBBR.js';
3
3
  import { __objRest, __spreadValues, cn, __spreadProps } from './chunk-IQWAGBDM.js';
4
4
  import { jsx, jsxs } from 'react/jsx-runtime';
5
5
 
@@ -350,15 +350,25 @@ function PageTabsContent(_a) {
350
350
  }, props)
351
351
  );
352
352
  }
353
+ var defaultStatCardLabels = {
354
+ increase: (change) => `Increase of ${change}`,
355
+ decrease: (change) => `Decrease of ${change}`,
356
+ change: (change) => `Change of ${change}`
357
+ };
353
358
  var changeTypeStyles = {
354
359
  positive: "text-status-success-text",
355
360
  negative: "text-status-error-text",
356
361
  neutral: "text-muted-foreground"
357
362
  };
358
- var changeTypeIndicators = {
359
- positive: { glyph: "\u25B2", label: "Increase of" },
360
- negative: { glyph: "\u25BC", label: "Decrease of" },
361
- neutral: { glyph: "\u2022", label: "Change of" }
363
+ var changeTypeGlyphs = {
364
+ positive: "\u25B2",
365
+ negative: "\u25BC",
366
+ neutral: "\u2022"
367
+ };
368
+ var changeTypeLabelKeys = {
369
+ positive: "increase",
370
+ negative: "decrease",
371
+ neutral: "change"
362
372
  };
363
373
  function StatCard(_a) {
364
374
  var _b = _a, {
@@ -368,6 +378,7 @@ function StatCard(_a) {
368
378
  changeType = "neutral",
369
379
  icon: Icon,
370
380
  className,
381
+ labels: labelsProp,
371
382
  ref
372
383
  } = _b, props = __objRest(_b, [
373
384
  "title",
@@ -376,19 +387,22 @@ function StatCard(_a) {
376
387
  "changeType",
377
388
  "icon",
378
389
  "className",
390
+ "labels",
379
391
  "ref"
380
392
  ]);
393
+ const ctx = useLabels();
394
+ const labels = resolveLabels(defaultStatCardLabels, ctx.statCard, labelsProp);
381
395
  return /* @__PURE__ */ jsx(Card, __spreadProps(__spreadValues({ ref, "data-slot": "stat-card", className }, props), { children: /* @__PURE__ */ jsx(CardContent, { className: "p-6", children: /* @__PURE__ */ jsxs("div", { className: "flex items-start justify-between", children: [
382
396
  /* @__PURE__ */ jsxs("div", { children: [
383
397
  /* @__PURE__ */ jsx("p", { className: "text-sm font-medium text-muted-foreground font-mono uppercase tracking-wider", children: title }),
384
398
  /* @__PURE__ */ jsx("p", { className: "text-3xl font-bold tracking-tight mt-1", children: value }),
385
399
  change && /* @__PURE__ */ jsxs("p", { className: cn("text-xs font-mono mt-1", changeTypeStyles[changeType]), children: [
386
400
  /* @__PURE__ */ jsxs("span", { "aria-hidden": "true", children: [
387
- changeTypeIndicators[changeType].glyph,
401
+ changeTypeGlyphs[changeType],
388
402
  " "
389
403
  ] }),
390
404
  /* @__PURE__ */ jsxs("span", { className: "sr-only", children: [
391
- changeTypeIndicators[changeType].label,
405
+ labels[changeTypeLabelKeys[changeType]](change),
392
406
  " "
393
407
  ] }),
394
408
  change
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/app-shell.tsx","../src/components/page-body.tsx","../src/components/page-header.tsx","../src/components/page-tabs.tsx","../src/components/stat-card.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"organisms.js","sourcesContent":["import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Stack } from \"@/components/ui/stack\"\n\n/** Full-height application shell container with horizontal flex layout.\n *\n * @example\n * <AppShell><AppShellSidebar>...</AppShellSidebar><AppShellMain>...</AppShellMain></AppShell>\n */\nfunction AppShell({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"app-shell\"\n className={cn(\"flex h-screen overflow-hidden bg-background\", className)}\n {...props}\n />\n )\n}\n\n/** Fixed-width sidebar panel hidden on mobile, visible on md+ screens.\n *\n * @prop collapsed - Whether the sidebar is in collapsed state.\n */\nfunction AppShellSidebar({\n collapsed = false,\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"aside\"> & { collapsed?: boolean }) {\n return (\n <aside\n ref={ref}\n data-slot=\"app-shell-sidebar\"\n className={cn(\n \"flex-col w-64 shrink-0 border-e-2 bg-card\",\n collapsed ? \"hidden md:flex\" : \"hidden md:flex\",\n className,\n )}\n {...props}\n />\n )\n}\n\n/** Logo area at the top of the sidebar with a bottom border. */\nfunction AppShellLogo({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"app-shell-logo\"\n className={cn(\n \"flex items-center h-16 px-6 border-b-2 shrink-0\",\n className,\n )}\n {...props}\n />\n )\n}\n\n/** Scrollable navigation region within the sidebar. */\nfunction AppShellNav({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"nav\">) {\n return (\n <nav\n ref={ref}\n data-slot=\"app-shell-nav\"\n className={cn(\"flex-1 overflow-y-auto py-4 px-3\", className)}\n >\n <Stack gap=\"xs\" {...props} />\n </nav>\n )\n}\n\n/** Props for AppShellNavItem including optional icon and active state. */\ninterface AppShellNavItemProps extends React.ComponentPropsWithRef<\"a\"> {\n icon?: React.ComponentType<{ className?: string }>\n active?: boolean\n}\n\n/** Navigation link with optional leading icon and active highlight.\n *\n * @example\n * <AppShellNavItem icon={HomeIcon} active href=\"/\">Home</AppShellNavItem>\n *\n * @prop icon - Optional icon component rendered before the label.\n * @prop active - Whether this item represents the current page.\n */\nfunction AppShellNavItem({\n icon: Icon,\n active = false,\n className,\n children,\n ref,\n ...props\n}: AppShellNavItemProps) {\n return (\n <a\n ref={ref}\n data-slot=\"app-shell-nav-item\"\n data-active={active || undefined}\n className={cn(\n \"flex items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors active:translate-y-[1.5px] transition-transform\",\n active\n ? \"bg-accent text-accent-foreground font-medium\"\n : \"text-muted-foreground hover:bg-surface-interactive hover:text-foreground\",\n className,\n )}\n {...props}\n >\n {Icon && <Icon className=\"size-4\" />}\n {children}\n </a>\n )\n}\n\n/** Footer area pinned to the bottom of the sidebar with a top border. */\nfunction AppShellFooter({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"app-shell-footer\"\n className={cn(\"shrink-0 border-t-2 p-4\", className)}\n {...props}\n />\n )\n}\n\n/** Scrollable main content area that fills remaining horizontal space. */\nfunction AppShellMain({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"main\">) {\n return (\n <main\n ref={ref}\n data-slot=\"app-shell-main\"\n className={cn(\"flex-1 overflow-y-auto\", className)}\n {...props}\n />\n )\n}\n\nexport {\n AppShell,\n AppShellSidebar,\n AppShellLogo,\n AppShellNav,\n AppShellNavItem,\n AppShellFooter,\n AppShellMain,\n type AppShellNavItemProps,\n}\n","import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Center } from \"@/components/ui/center\"\n\n/** Props for PageBody including optional full-width mode and padding control. */\ninterface PageBodyProps extends React.ComponentPropsWithRef<\"div\"> {\n fullWidth?: boolean\n padding?: \"default\" | \"none\"\n}\n\n/** Main page content area with optional max-width centering and padding.\n *\n * @example\n * <PageBody fullWidth>{children}</PageBody>\n *\n * @prop fullWidth - Skip the max-width Center wrapper when true.\n * @prop padding - Use \"none\" to remove default padding.\n */\nfunction PageBody({\n fullWidth = false,\n padding = \"default\",\n className,\n children,\n ref,\n ...props\n}: PageBodyProps) {\n return (\n <div\n ref={ref}\n data-slot=\"page-body\"\n className={cn(padding === \"default\" && \"px-6 py-6\", className)}\n {...props}\n >\n {fullWidth ? children : <Center max=\"2xl\">{children}</Center>}\n </div>\n )\n}\n\nexport { PageBody, type PageBodyProps }\n","import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Stack } from \"@/components/ui/stack\"\n\n/** Page-level header with bottom border, card background, and vertical stack layout.\n *\n * @example\n * <PageHeader><PageHeaderContent><PageHeaderTitle>Dashboard</PageHeaderTitle></PageHeaderContent></PageHeader>\n */\nfunction PageHeader({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"header\">) {\n return (\n <header\n ref={ref}\n data-slot=\"page-header\"\n className={cn(\"border-b-2 bg-card px-6 py-6\", className)}\n >\n <Stack gap=\"md\" {...props} />\n </header>\n )\n}\n\n/** Container for breadcrumb navigation above the page title. */\nfunction PageHeaderBreadcrumb({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"page-header-breadcrumb\"\n className={className}\n {...props}\n />\n )\n}\n\n/** Flex row that spaces the title area and actions apart responsively. */\nfunction PageHeaderContent({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"page-header-content\"\n className={cn(\n \"flex flex-col sm:flex-row sm:items-center justify-between gap-4\",\n className,\n )}\n {...props}\n />\n )\n}\n\n/** Primary page heading rendered as a bold h1. */\nfunction PageHeaderTitle({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"h1\">) {\n return (\n <h1\n ref={ref}\n data-slot=\"page-header-title\"\n className={cn(\"text-2xl font-bold tracking-tight\", className)}\n {...props}\n />\n )\n}\n\n/** Short muted description text displayed below the page title. */\nfunction PageHeaderDescription({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"p\">) {\n return (\n <p\n ref={ref}\n data-slot=\"page-header-description\"\n className={cn(\"text-sm text-muted-foreground mt-1\", className)}\n {...props}\n />\n )\n}\n\n/** Container for action buttons aligned to the right of the header. */\nfunction PageHeaderActions({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"page-header-actions\"\n className={cn(\"flex items-center gap-2 shrink-0\", className)}\n {...props}\n />\n )\n}\n\nexport {\n PageHeader,\n PageHeaderBreadcrumb,\n PageHeaderContent,\n PageHeaderTitle,\n PageHeaderDescription,\n PageHeaderActions,\n}\n","\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"@/components/ui/tabs\"\n\n/** Full-width page-level tabs container.\n *\n * @example\n * <PageTabs defaultValue=\"overview\"><PageTabsList><PageTabsTrigger value=\"overview\">Overview</PageTabsTrigger></PageTabsList><PageTabsContent value=\"overview\">...</PageTabsContent></PageTabs>\n */\nfunction PageTabs({\n className,\n ...props\n}: React.ComponentProps<typeof Tabs>) {\n return (\n <Tabs\n data-slot=\"page-tabs\"\n className={cn(\"w-full\", className)}\n {...props}\n />\n )\n}\n\n/** Underline-style tab list with transparent background and bottom border. */\nfunction PageTabsList({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<typeof TabsList>) {\n return (\n <TabsList\n ref={ref}\n data-slot=\"page-tabs-list\"\n className={cn(\n \"bg-transparent border-b-2 rounded-none h-auto p-0 w-full justify-start\",\n className,\n )}\n {...props}\n />\n )\n}\n\n/** Individual page tab trigger with an active underline indicator. */\nfunction PageTabsTrigger({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<typeof TabsTrigger>) {\n return (\n <TabsTrigger\n ref={ref}\n data-slot=\"page-tabs-trigger\"\n className={cn(\n \"rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 pb-3 pt-2\",\n className,\n )}\n {...props}\n />\n )\n}\n\n/** Content panel associated with a page tab value. */\nfunction PageTabsContent({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<typeof TabsContent>) {\n return (\n <TabsContent\n ref={ref}\n data-slot=\"page-tabs-content\"\n className={className}\n {...props}\n />\n )\n}\n\nexport { PageTabs, PageTabsList, PageTabsTrigger, PageTabsContent }\n","import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Card, CardContent } from \"@/components/ui/card\"\n\n/** Props for StatCard including title, value, and optional change indicator. */\ninterface StatCardProps extends Omit<React.ComponentPropsWithRef<\"div\">, \"title\"> {\n title: string\n value: string\n change?: string\n changeType?: \"positive\" | \"negative\" | \"neutral\"\n icon?: React.ComponentType<{ className?: string }>\n}\n\n/** Color map for stat change indicators keyed by sentiment. */\nconst changeTypeStyles = {\n positive: \"text-status-success-text\",\n negative: \"text-status-error-text\",\n neutral: \"text-muted-foreground\",\n} as const\n\n/** Non-color sentiment indicators (prefixed glyphs + screen-reader text). */\nconst changeTypeIndicators = {\n positive: { glyph: \"▲\", label: \"Increase of\" },\n negative: { glyph: \"▼\", label: \"Decrease of\" },\n neutral: { glyph: \"•\", label: \"Change of\" },\n} as const\n\n/** Card displaying a key metric with title, value, optional change badge, and icon.\n *\n * @example\n * <StatCard title=\"Revenue\" value=\"$12,345\" change=\"+12%\" changeType=\"positive\" />\n *\n * @prop title - Metric label displayed in uppercase monospace.\n * @prop value - Primary numeric or text value.\n * @prop change - Optional change indicator text (e.g. \"+5%\").\n * @prop changeType - Color coding: \"positive\", \"negative\", or \"neutral\".\n * @prop icon - Optional icon component displayed at top-right.\n */\nfunction StatCard({\n title,\n value,\n change,\n changeType = \"neutral\",\n icon: Icon,\n className,\n ref,\n ...props\n}: StatCardProps) {\n return (\n <Card ref={ref} data-slot=\"stat-card\" className={className} {...props}>\n <CardContent className=\"p-6\">\n <div className=\"flex items-start justify-between\">\n <div>\n <p className=\"text-sm font-medium text-muted-foreground font-mono uppercase tracking-wider\">\n {title}\n </p>\n <p className=\"text-3xl font-bold tracking-tight mt-1\">{value}</p>\n {change && (\n <p className={cn(\"text-xs font-mono mt-1\", changeTypeStyles[changeType])}>\n <span aria-hidden=\"true\">{changeTypeIndicators[changeType].glyph} </span>\n <span className=\"sr-only\">{changeTypeIndicators[changeType].label} </span>\n {change}\n </p>\n )}\n </div>\n {Icon && <Icon className=\"text-muted-foreground size-5\" />}\n </div>\n </CardContent>\n </Card>\n )\n}\n\nexport { StatCard, type StatCardProps }\n"]}
1
+ {"version":3,"sources":["../src/components/app-shell.tsx","../src/components/page-body.tsx","../src/components/page-header.tsx","../src/components/page-tabs.tsx","../src/components/stat-card.tsx"],"names":["jsx","jsxs"],"mappings":"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","file":"organisms.js","sourcesContent":["import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Stack } from \"@/components/ui/stack\"\n\n/** Full-height application shell container with horizontal flex layout.\n *\n * @example\n * <AppShell><AppShellSidebar>...</AppShellSidebar><AppShellMain>...</AppShellMain></AppShell>\n */\nfunction AppShell({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"app-shell\"\n className={cn(\"flex h-screen overflow-hidden bg-background\", className)}\n {...props}\n />\n )\n}\n\n/** Fixed-width sidebar panel hidden on mobile, visible on md+ screens.\n *\n * @prop collapsed - Whether the sidebar is in collapsed state.\n */\nfunction AppShellSidebar({\n collapsed = false,\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"aside\"> & { collapsed?: boolean }) {\n return (\n <aside\n ref={ref}\n data-slot=\"app-shell-sidebar\"\n className={cn(\n \"flex-col w-64 shrink-0 border-e-2 bg-card\",\n collapsed ? \"hidden md:flex\" : \"hidden md:flex\",\n className,\n )}\n {...props}\n />\n )\n}\n\n/** Logo area at the top of the sidebar with a bottom border. */\nfunction AppShellLogo({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"app-shell-logo\"\n className={cn(\n \"flex items-center h-16 px-6 border-b-2 shrink-0\",\n className,\n )}\n {...props}\n />\n )\n}\n\n/** Scrollable navigation region within the sidebar. */\nfunction AppShellNav({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"nav\">) {\n return (\n <nav\n ref={ref}\n data-slot=\"app-shell-nav\"\n className={cn(\"flex-1 overflow-y-auto py-4 px-3\", className)}\n >\n <Stack gap=\"xs\" {...props} />\n </nav>\n )\n}\n\n/** Props for AppShellNavItem including optional icon and active state. */\ninterface AppShellNavItemProps extends React.ComponentPropsWithRef<\"a\"> {\n icon?: React.ComponentType<{ className?: string }>\n active?: boolean\n}\n\n/** Navigation link with optional leading icon and active highlight.\n *\n * @example\n * <AppShellNavItem icon={HomeIcon} active href=\"/\">Home</AppShellNavItem>\n *\n * @prop icon - Optional icon component rendered before the label.\n * @prop active - Whether this item represents the current page.\n */\nfunction AppShellNavItem({\n icon: Icon,\n active = false,\n className,\n children,\n ref,\n ...props\n}: AppShellNavItemProps) {\n return (\n <a\n ref={ref}\n data-slot=\"app-shell-nav-item\"\n data-active={active || undefined}\n className={cn(\n \"flex items-center gap-3 rounded-md px-3 py-2 text-sm transition-colors active:translate-y-[1.5px] transition-transform\",\n active\n ? \"bg-accent text-accent-foreground font-medium\"\n : \"text-muted-foreground hover:bg-surface-interactive hover:text-foreground\",\n className,\n )}\n {...props}\n >\n {Icon && <Icon className=\"size-4\" />}\n {children}\n </a>\n )\n}\n\n/** Footer area pinned to the bottom of the sidebar with a top border. */\nfunction AppShellFooter({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"app-shell-footer\"\n className={cn(\"shrink-0 border-t-2 p-4\", className)}\n {...props}\n />\n )\n}\n\n/** Scrollable main content area that fills remaining horizontal space. */\nfunction AppShellMain({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"main\">) {\n return (\n <main\n ref={ref}\n data-slot=\"app-shell-main\"\n className={cn(\"flex-1 overflow-y-auto\", className)}\n {...props}\n />\n )\n}\n\nexport {\n AppShell,\n AppShellSidebar,\n AppShellLogo,\n AppShellNav,\n AppShellNavItem,\n AppShellFooter,\n AppShellMain,\n type AppShellNavItemProps,\n}\n","import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Center } from \"@/components/ui/center\"\n\n/** Props for PageBody including optional full-width mode and padding control. */\ninterface PageBodyProps extends React.ComponentPropsWithRef<\"div\"> {\n fullWidth?: boolean\n padding?: \"default\" | \"none\"\n}\n\n/** Main page content area with optional max-width centering and padding.\n *\n * @example\n * <PageBody fullWidth>{children}</PageBody>\n *\n * @prop fullWidth - Skip the max-width Center wrapper when true.\n * @prop padding - Use \"none\" to remove default padding.\n */\nfunction PageBody({\n fullWidth = false,\n padding = \"default\",\n className,\n children,\n ref,\n ...props\n}: PageBodyProps) {\n return (\n <div\n ref={ref}\n data-slot=\"page-body\"\n className={cn(padding === \"default\" && \"px-6 py-6\", className)}\n {...props}\n >\n {fullWidth ? children : <Center max=\"2xl\">{children}</Center>}\n </div>\n )\n}\n\nexport { PageBody, type PageBodyProps }\n","import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Stack } from \"@/components/ui/stack\"\n\n/** Page-level header with bottom border, card background, and vertical stack layout.\n *\n * @example\n * <PageHeader><PageHeaderContent><PageHeaderTitle>Dashboard</PageHeaderTitle></PageHeaderContent></PageHeader>\n */\nfunction PageHeader({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"header\">) {\n return (\n <header\n ref={ref}\n data-slot=\"page-header\"\n className={cn(\"border-b-2 bg-card px-6 py-6\", className)}\n >\n <Stack gap=\"md\" {...props} />\n </header>\n )\n}\n\n/** Container for breadcrumb navigation above the page title. */\nfunction PageHeaderBreadcrumb({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"page-header-breadcrumb\"\n className={className}\n {...props}\n />\n )\n}\n\n/** Flex row that spaces the title area and actions apart responsively. */\nfunction PageHeaderContent({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"page-header-content\"\n className={cn(\n \"flex flex-col sm:flex-row sm:items-center justify-between gap-4\",\n className,\n )}\n {...props}\n />\n )\n}\n\n/** Primary page heading rendered as a bold h1. */\nfunction PageHeaderTitle({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"h1\">) {\n return (\n <h1\n ref={ref}\n data-slot=\"page-header-title\"\n className={cn(\"text-2xl font-bold tracking-tight\", className)}\n {...props}\n />\n )\n}\n\n/** Short muted description text displayed below the page title. */\nfunction PageHeaderDescription({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"p\">) {\n return (\n <p\n ref={ref}\n data-slot=\"page-header-description\"\n className={cn(\"text-sm text-muted-foreground mt-1\", className)}\n {...props}\n />\n )\n}\n\n/** Container for action buttons aligned to the right of the header. */\nfunction PageHeaderActions({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"page-header-actions\"\n className={cn(\"flex items-center gap-2 shrink-0\", className)}\n {...props}\n />\n )\n}\n\nexport {\n PageHeader,\n PageHeaderBreadcrumb,\n PageHeaderContent,\n PageHeaderTitle,\n PageHeaderDescription,\n PageHeaderActions,\n}\n","\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Tabs, TabsList, TabsTrigger, TabsContent } from \"@/components/ui/tabs\"\n\n/** Full-width page-level tabs container.\n *\n * @example\n * <PageTabs defaultValue=\"overview\"><PageTabsList><PageTabsTrigger value=\"overview\">Overview</PageTabsTrigger></PageTabsList><PageTabsContent value=\"overview\">...</PageTabsContent></PageTabs>\n */\nfunction PageTabs({\n className,\n ...props\n}: React.ComponentProps<typeof Tabs>) {\n return (\n <Tabs\n data-slot=\"page-tabs\"\n className={cn(\"w-full\", className)}\n {...props}\n />\n )\n}\n\n/** Underline-style tab list with transparent background and bottom border. */\nfunction PageTabsList({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<typeof TabsList>) {\n return (\n <TabsList\n ref={ref}\n data-slot=\"page-tabs-list\"\n className={cn(\n \"bg-transparent border-b-2 rounded-none h-auto p-0 w-full justify-start\",\n className,\n )}\n {...props}\n />\n )\n}\n\n/** Individual page tab trigger with an active underline indicator. */\nfunction PageTabsTrigger({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<typeof TabsTrigger>) {\n return (\n <TabsTrigger\n ref={ref}\n data-slot=\"page-tabs-trigger\"\n className={cn(\n \"rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:bg-transparent data-[state=active]:shadow-none px-4 pb-3 pt-2\",\n className,\n )}\n {...props}\n />\n )\n}\n\n/** Content panel associated with a page tab value. */\nfunction PageTabsContent({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<typeof TabsContent>) {\n return (\n <TabsContent\n ref={ref}\n data-slot=\"page-tabs-content\"\n className={className}\n {...props}\n />\n )\n}\n\nexport { PageTabs, PageTabsList, PageTabsTrigger, PageTabsContent }\n","\"use client\"\n\nimport * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\nimport { Card, CardContent } from \"@/components/ui/card\"\nimport { resolveLabels } from \"@/lib/resolve-labels\"\nimport { useLabels } from \"@/components/providers/labels-provider\"\n\n// ─── i18n labels ────────────────────────────────────────────────────\n\n/** Translatable strings used by StatCard. All keys have English defaults. */\ninterface StatCardLabels {\n increase?: (change: string) => string\n decrease?: (change: string) => string\n change?: (change: string) => string\n}\n\nconst defaultStatCardLabels: Required<StatCardLabels> = {\n increase: (change) => `Increase of ${change}`,\n decrease: (change) => `Decrease of ${change}`,\n change: (change) => `Change of ${change}`,\n}\n\n/** Props for StatCard including title, value, and optional change indicator. */\ninterface StatCardProps extends Omit<React.ComponentPropsWithRef<\"div\">, \"title\"> {\n title: string\n value: string\n change?: string\n changeType?: \"positive\" | \"negative\" | \"neutral\"\n icon?: React.ComponentType<{ className?: string }>\n labels?: StatCardLabels\n}\n\n/** Color map for stat change indicators keyed by sentiment. */\nconst changeTypeStyles = {\n positive: \"text-status-success-text\",\n negative: \"text-status-error-text\",\n neutral: \"text-muted-foreground\",\n} as const\n\n/** Glyph indicators keyed by sentiment. */\nconst changeTypeGlyphs = {\n positive: \"▲\",\n negative: \"▼\",\n neutral: \"•\",\n} as const\n\n/** Maps changeType to the corresponding label function key. */\nconst changeTypeLabelKeys = {\n positive: \"increase\",\n negative: \"decrease\",\n neutral: \"change\",\n} as const\n\n/** Card displaying a key metric with title, value, optional change badge, and icon.\n *\n * @example\n * <StatCard title=\"Revenue\" value=\"$12,345\" change=\"+12%\" changeType=\"positive\" />\n *\n * @prop title - Metric label displayed in uppercase monospace.\n * @prop value - Primary numeric or text value.\n * @prop change - Optional change indicator text (e.g. \"+5%\").\n * @prop changeType - Color coding: \"positive\", \"negative\", or \"neutral\".\n * @prop icon - Optional icon component displayed at top-right.\n */\nfunction StatCard({\n title,\n value,\n change,\n changeType = \"neutral\",\n icon: Icon,\n className,\n labels: labelsProp,\n ref,\n ...props\n}: StatCardProps) {\n const ctx = useLabels()\n const labels = resolveLabels(defaultStatCardLabels, ctx.statCard, labelsProp)\n\n return (\n <Card ref={ref} data-slot=\"stat-card\" className={className} {...props}>\n <CardContent className=\"p-6\">\n <div className=\"flex items-start justify-between\">\n <div>\n <p className=\"text-sm font-medium text-muted-foreground font-mono uppercase tracking-wider\">\n {title}\n </p>\n <p className=\"text-3xl font-bold tracking-tight mt-1\">{value}</p>\n {change && (\n <p className={cn(\"text-xs font-mono mt-1\", changeTypeStyles[changeType])}>\n <span aria-hidden=\"true\">{changeTypeGlyphs[changeType]} </span>\n <span className=\"sr-only\">{labels[changeTypeLabelKeys[changeType]](change)} </span>\n {change}\n </p>\n )}\n </div>\n {Icon && <Icon className=\"text-muted-foreground size-5\" />}\n </div>\n </CardContent>\n </Card>\n )\n}\n\nexport { StatCard, type StatCardProps, type StatCardLabels }\n"]}
package/dist/styles.css CHANGED
@@ -66,32 +66,6 @@
66
66
  --raw-success: oklch(0.614 0.130 152);
67
67
  --raw-warning: oklch(0.711 0.147 78);
68
68
  --raw-error: oklch(0.570 0.180 25);
69
-
70
- /* ── Forest (green base — demonstration alt theme) ── */
71
- --raw-forest-50: oklch(0.975 0.018 155);
72
- --raw-forest-100: oklch(0.935 0.038 155);
73
- --raw-forest-200: oklch(0.865 0.068 155);
74
- --raw-forest-300: oklch(0.765 0.105 155);
75
- --raw-forest-400: oklch(0.655 0.135 155);
76
- --raw-forest-500: oklch(0.555 0.150 155);
77
- --raw-forest-600: oklch(0.465 0.145 155);
78
- --raw-forest-700: oklch(0.385 0.120 155);
79
- --raw-forest-800: oklch(0.305 0.090 155);
80
- --raw-forest-900: oklch(0.225 0.060 155);
81
- --raw-forest-950: oklch(0.150 0.040 155);
82
-
83
- /* ── Terracotta (warm accent for forest theme) ── */
84
- --raw-terracotta-50: oklch(0.975 0.018 40);
85
- --raw-terracotta-100: oklch(0.935 0.040 40);
86
- --raw-terracotta-200: oklch(0.865 0.075 40);
87
- --raw-terracotta-300: oklch(0.765 0.115 40);
88
- --raw-terracotta-400: oklch(0.680 0.145 40);
89
- --raw-terracotta-500: oklch(0.600 0.165 40);
90
- --raw-terracotta-600: oklch(0.520 0.155 40);
91
- --raw-terracotta-700: oklch(0.440 0.125 40);
92
- --raw-terracotta-800: oklch(0.360 0.098 40);
93
- --raw-terracotta-900: oklch(0.280 0.070 40);
94
- --raw-terracotta-950: oklch(0.200 0.050 40);
95
69
  }
96
70
 
97
71
 
@@ -158,6 +132,9 @@
158
132
  --border-subtle: var(--raw-warm-200);
159
133
  --border-accent: var(--raw-plum-500);
160
134
 
135
+ /* Spinner track: a subtle light gray so the plum arc reads as it spins */
136
+ --spinner-track: var(--raw-warm-300);
137
+
161
138
  /* ── SubstrateUI extended: Accent fills ── */
162
139
  --accent-fill: var(--raw-plum-600);
163
140
  --accent-fill-hover: var(--raw-plum-700);
@@ -240,6 +217,9 @@
240
217
  --border-subtle: var(--raw-warm-800);
241
218
  --border-accent: var(--raw-plum-400);
242
219
 
220
+ /* Spinner track: unchanged from the previously tuned dark-mode value */
221
+ --spinner-track: var(--raw-warm-400);
222
+
243
223
  /* ── SubstrateUI extended: Accent fills ── */
244
224
  --accent-fill: var(--raw-plum-500);
245
225
  --accent-fill-hover: var(--raw-plum-400);
@@ -264,167 +244,6 @@
264
244
  }
265
245
 
266
246
 
267
- /* ================================================================
268
- LAYER 2b: ALT THEME — FOREST
269
-
270
- Attached via [data-theme="forest"] on <html>. Mirrors every
271
- semantic token from :root / .dark, remapped to the forest +
272
- terracotta palettes. Orthogonal to light/dark — the .dark class
273
- still toggles modes within the forest theme.
274
- ================================================================ */
275
-
276
- [data-theme="forest"] {
277
- /* ── Shadcn core tokens ── */
278
- --background: var(--raw-forest-50);
279
- --foreground: var(--raw-forest-900);
280
- --card: oklch(0.992 0.006 155);
281
- --card-foreground: var(--raw-forest-900);
282
- --popover: oklch(0.992 0.006 155);
283
- --popover-foreground: var(--raw-forest-900);
284
- --primary: var(--raw-forest-600);
285
- --primary-foreground: oklch(1 0 0);
286
- --secondary: var(--raw-forest-100);
287
- --secondary-foreground: var(--raw-forest-900);
288
- --muted: var(--raw-forest-100);
289
- --muted-foreground: var(--raw-forest-700);
290
- --accent: var(--raw-terracotta-100);
291
- --accent-foreground: var(--raw-terracotta-800);
292
- --destructive: var(--raw-error);
293
- --border: var(--raw-forest-500);
294
- --input: var(--raw-forest-500);
295
- --ring: var(--raw-forest-500);
296
-
297
- /* ── Chart colors ── */
298
- --chart-1: var(--raw-forest-600);
299
- --chart-2: var(--raw-terracotta-500);
300
- --chart-3: var(--raw-forest-400);
301
- --chart-4: var(--raw-terracotta-300);
302
- --chart-5: var(--raw-forest-200);
303
-
304
- /* ── Sidebar ── */
305
- --sidebar: oklch(0.992 0.006 155);
306
- --sidebar-foreground: var(--raw-forest-900);
307
- --sidebar-primary: var(--raw-forest-600);
308
- --sidebar-primary-foreground: oklch(1 0 0);
309
- --sidebar-accent: var(--raw-terracotta-100);
310
- --sidebar-accent-foreground: var(--raw-terracotta-800);
311
- --sidebar-border: var(--raw-forest-200);
312
- --sidebar-ring: var(--raw-forest-500);
313
-
314
- /* ── Surfaces ── */
315
- --surface-ground: var(--raw-forest-50);
316
- --surface-page: oklch(0.992 0.006 155);
317
- --surface-raised: oklch(0.992 0.006 155);
318
- --surface-sunken: var(--raw-forest-100);
319
- --surface-interactive: var(--raw-forest-100);
320
- --surface-interactive-hover: var(--raw-forest-200);
321
-
322
- /* ── Borders ── */
323
- --border-default: var(--raw-forest-500);
324
- --border-strong: var(--raw-forest-700);
325
- --border-subtle: var(--raw-forest-200);
326
- --border-accent: var(--raw-forest-500);
327
-
328
- /* ── Accent fills ── */
329
- --accent-fill: var(--raw-forest-600);
330
- --accent-fill-hover: var(--raw-forest-700);
331
- --accent-surface: var(--raw-forest-100);
332
-
333
- /* ── Secondary (terracotta) ── */
334
- --secondary-fill: var(--raw-terracotta-500);
335
- --secondary-fill-hover: var(--raw-terracotta-600);
336
- --secondary-surface: var(--raw-terracotta-100);
337
- --secondary-text: var(--raw-terracotta-700);
338
-
339
- /* ── Status (shared across themes) ── */
340
- --status-success: var(--raw-success);
341
- --status-success-surface: oklch(0.92 0.05 152);
342
- --status-success-text: oklch(0.45 0.10 152);
343
- --status-warning: var(--raw-warning);
344
- --status-warning-surface: var(--raw-terracotta-100);
345
- --status-warning-text: oklch(0.45 0.09 78);
346
- --status-error: var(--raw-error);
347
- --status-error-surface: oklch(0.93 0.04 25);
348
- --status-error-text: oklch(0.45 0.14 25);
349
- }
350
-
351
-
352
- [data-theme="forest"].dark {
353
- /* ── Shadcn core ── */
354
- --background: var(--raw-forest-950);
355
- --foreground: var(--raw-forest-100);
356
- --card: var(--raw-forest-900);
357
- --card-foreground: var(--raw-forest-100);
358
- --popover: var(--raw-forest-800);
359
- --popover-foreground: var(--raw-forest-100);
360
- --primary: var(--raw-forest-600);
361
- --primary-foreground: oklch(1 0 0);
362
- --secondary: var(--raw-forest-800);
363
- --secondary-foreground: var(--raw-forest-100);
364
- --muted: var(--raw-forest-800);
365
- --muted-foreground: var(--raw-forest-300);
366
- --accent: oklch(0.600 0.165 40 / 0.18);
367
- --accent-foreground: var(--raw-terracotta-300);
368
- --destructive: oklch(0.58 0.18 25);
369
- --border: var(--raw-forest-400);
370
- --input: var(--raw-forest-400);
371
- --ring: var(--raw-forest-400);
372
-
373
- /* ── Chart ── */
374
- --chart-1: var(--raw-forest-400);
375
- --chart-2: var(--raw-terracotta-400);
376
- --chart-3: var(--raw-forest-300);
377
- --chart-4: var(--raw-terracotta-300);
378
- --chart-5: var(--raw-forest-600);
379
-
380
- /* ── Sidebar ── */
381
- --sidebar: var(--raw-forest-900);
382
- --sidebar-foreground: var(--raw-forest-100);
383
- --sidebar-primary: var(--raw-forest-600);
384
- --sidebar-primary-foreground: oklch(1 0 0);
385
- --sidebar-accent: oklch(0.600 0.165 40 / 0.18);
386
- --sidebar-accent-foreground: var(--raw-terracotta-300);
387
- --sidebar-border: var(--raw-forest-700);
388
- --sidebar-ring: var(--raw-forest-400);
389
-
390
- /* ── Surfaces ── */
391
- --surface-ground: var(--raw-forest-950);
392
- --surface-page: var(--raw-forest-900);
393
- --surface-raised: var(--raw-forest-800);
394
- --surface-sunken: var(--raw-forest-950);
395
- --surface-interactive: var(--raw-forest-800);
396
- --surface-interactive-hover: var(--raw-forest-700);
397
-
398
- /* ── Borders ── */
399
- --border-default: var(--raw-forest-400);
400
- --border-strong: var(--raw-forest-300);
401
- --border-subtle: var(--raw-forest-800);
402
- --border-accent: var(--raw-forest-400);
403
-
404
- /* ── Accent fills ── */
405
- --accent-fill: var(--raw-forest-500);
406
- --accent-fill-hover: var(--raw-forest-400);
407
- --accent-surface: oklch(0.600 0.165 40 / 0.18);
408
-
409
- /* ── Secondary (terracotta) ── */
410
- --secondary-fill: var(--raw-terracotta-400);
411
- --secondary-fill-hover: var(--raw-terracotta-300);
412
- --secondary-surface: oklch(0.680 0.145 40 / 0.15);
413
- --secondary-text: var(--raw-terracotta-300);
414
-
415
- /* ── Status ── */
416
- --status-success: oklch(0.70 0.13 152);
417
- --status-success-surface: oklch(0.614 0.130 152 / 0.15);
418
- --status-success-text: oklch(0.75 0.10 152);
419
- --status-warning: var(--raw-terracotta-400);
420
- --status-warning-surface: oklch(0.600 0.165 40 / 0.18);
421
- --status-warning-text: var(--raw-terracotta-300);
422
- --status-error: oklch(0.65 0.18 25);
423
- --status-error-surface: oklch(0.570 0.180 25 / 0.15);
424
- --status-error-text: oklch(0.75 0.12 25);
425
- }
426
-
427
-
428
247
  /* ================================================================
429
248
  @theme inline — MAPS VARIABLES TO TAILWIND UTILITIES
430
249
 
@@ -542,7 +361,7 @@
542
361
  }
543
362
  [data-slot="spinner"] {
544
363
  animation: sui-spin 1s linear infinite;
545
- border-color: var(--border);
364
+ border-color: var(--spinner-track);
546
365
  border-top-color: var(--primary);
547
366
  }
548
367
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mikenotthepope/substrateui",
3
- "version": "0.1.3",
3
+ "version": "0.2.1",
4
4
  "description": "A chunky, OKLCH-powered design system for Next.js — built on Tailwind CSS v4, Radix UI, and Atomic Design principles.",
5
5
  "license": "MIT",
6
6
  "author": "SubstrateUI",
@@ -8,6 +8,7 @@
8
8
  "type": "git",
9
9
  "url": "git+https://github.com/MikeNotThePope/substrateui.git"
10
10
  },
11
+ "homepage": "https://www.substrateui.dev/",
11
12
  "keywords": [
12
13
  "design-system",
13
14
  "react",
@@ -63,6 +64,9 @@
63
64
  "test:visual": "playwright test",
64
65
  "test:visual:update": "playwright test --update-snapshots",
65
66
  "test:visual:report": "playwright show-report",
67
+ "snapshots:download": "bun scripts/snapshots.ts download",
68
+ "snapshots:upload": "bun scripts/snapshots.ts upload",
69
+ "snapshots:regenerate": "bash scripts/snapshots-regenerate.sh",
66
70
  "scan:deprecations": "tsx scripts/scan-deprecations.ts",
67
71
  "storybook": "storybook dev -p 6006",
68
72
  "build-storybook": "storybook build -o public/storybook && node .storybook/rewrite-base-paths.mjs",
@@ -130,6 +134,7 @@
130
134
  "vaul": "^1.1.2"
131
135
  },
132
136
  "devDependencies": {
137
+ "@aws-sdk/client-s3": "^3.1024.0",
133
138
  "@changesets/changelog-github": "^0.6.0",
134
139
  "@changesets/cli": "^2.30.0",
135
140
  "@playwright/test": "^1.59.1",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/components/ui/card.tsx","../src/components/ui/center.tsx","../src/components/ui/stack.tsx","../src/components/ui/tabs.tsx"],"names":["jsx","Slot"],"mappings":"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","file":"chunk-IRBORST3.js","sourcesContent":["import * as React from \"react\"\n\nimport { cn } from \"@/lib/utils\"\n\n/**\n * Bordered container for grouping related content.\n *\n * @example\n * <Card><CardHeader><CardTitle>Title</CardTitle></CardHeader><CardContent>Body</CardContent></Card>\n *\n * @prop interactive - Adds hover and click styles when true\n */\nfunction Card({\n className,\n interactive = false,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\"> & { interactive?: boolean }) {\n return (\n <div\n ref={ref}\n data-slot=\"card\"\n className={cn(\n \"rounded-lg border-2 bg-card text-card-foreground shadow-sm\",\n interactive &&\n \"cursor-pointer hover:border-ring hover:shadow-md transition-all active:translate-y-[1.5px]\",\n className\n )}\n {...props}\n />\n )\n}\n\n/** Top section of a Card containing the title and description. */\nfunction CardHeader({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"card-header\"\n className={cn(\"flex flex-col space-y-1.5 p-6\", className)}\n {...props}\n />\n )\n}\n\n/** Primary heading inside a CardHeader. */\nfunction CardTitle({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"card-title\"\n className={cn(\n \"text-2xl font-semibold leading-none tracking-tight\",\n className\n )}\n {...props}\n />\n )\n}\n\n/** Secondary description text inside a CardHeader. */\nfunction CardDescription({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"card-description\"\n className={cn(\"text-sm text-muted-foreground\", className)}\n {...props}\n />\n )\n}\n\n/** Main body area of a Card. */\nfunction CardContent({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"card-content\"\n className={cn(\"p-6 pt-0\", className)}\n {...props}\n />\n )\n}\n\n/** Bottom section of a Card, typically for actions. */\nfunction CardFooter({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<\"div\">) {\n return (\n <div\n ref={ref}\n data-slot=\"card-footer\"\n className={cn(\"flex items-center p-6 pt-0\", className)}\n {...props}\n />\n )\n}\n\nexport { Card, CardHeader, CardFooter, CardTitle, CardDescription, CardContent }\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst maxMap = {\n sm: \"max-w-screen-sm\",\n md: \"max-w-screen-md\",\n lg: \"max-w-screen-lg\",\n xl: \"max-w-screen-xl\",\n \"2xl\": \"max-w-screen-2xl\",\n full: \"max-w-full\",\n} as const\n\ntype Max = keyof typeof maxMap\n\n/** Props accepted by the Center component. */\ninterface CenterProps extends React.ComponentPropsWithRef<\"div\"> {\n max?: Max\n padding?: boolean\n asChild?: boolean\n}\n\n/**\n * Horizontally centers its content with a configurable max-width and optional padding.\n *\n * @example\n * <Center max=\"lg\" padding>Content</Center>\n *\n * @prop max - Max-width breakpoint: \"sm\" | \"md\" | \"lg\" | \"xl\" | \"2xl\" | \"full\"\n * @prop padding - Adds responsive horizontal padding when true\n * @prop asChild - Merge props onto child element instead of rendering a div\n */\nfunction Center({\n max = \"2xl\",\n padding = true,\n asChild = false,\n className,\n ref,\n ...props\n}: CenterProps) {\n const Comp = asChild ? Slot : \"div\"\n return (\n <Comp\n data-slot=\"center\"\n className={cn(\n \"mx-auto w-full\",\n maxMap[max],\n padding && \"px-4 sm:px-6 lg:px-8\",\n className,\n )}\n ref={ref}\n {...props}\n />\n )\n}\n\nexport { Center, type CenterProps }\n","import * as React from \"react\"\nimport { Slot } from \"@radix-ui/react-slot\"\n\nimport { cn } from \"@/lib/utils\"\n\nconst gapMap = {\n none: \"gap-0\",\n xs: \"gap-1\",\n sm: \"gap-2\",\n md: \"gap-4\",\n lg: \"gap-6\",\n xl: \"gap-8\",\n \"2xl\": \"gap-12\",\n} as const\n\nconst alignMap = {\n start: \"items-start\",\n center: \"items-center\",\n end: \"items-end\",\n stretch: \"items-stretch\",\n} as const\n\ntype Gap = keyof typeof gapMap\ntype Align = keyof typeof alignMap\n\ninterface StackProps extends React.ComponentPropsWithRef<\"div\"> {\n gap?: Gap\n align?: Align\n asChild?: boolean\n}\n\n/**\n * A vertical flex container with configurable gap and alignment.\n *\n * @example\n * <Stack gap=\"lg\" align=\"center\">\n * <div>Item 1</div>\n * <div>Item 2</div>\n * </Stack>\n *\n * @prop gap - The spacing between children (none, xs, sm, md, lg, xl, 2xl).\n * @prop align - Cross-axis alignment of children.\n * @prop asChild - Merge props onto the child element instead of rendering a div.\n */\nfunction Stack({\n gap = \"md\",\n align = \"stretch\",\n asChild = false,\n className,\n ref,\n ...props\n}: StackProps) {\n const Comp = asChild ? Slot : \"div\"\n return (\n <Comp\n data-slot=\"stack\"\n className={cn(\"flex flex-col\", gapMap[gap], alignMap[align], className)}\n ref={ref}\n {...props}\n />\n )\n}\n\nexport { Stack, type StackProps }\n","\"use client\"\n\nimport * as React from \"react\"\nimport * as TabsPrimitive from \"@radix-ui/react-tabs\"\n\nimport { cn } from \"@/lib/utils\"\n\n/** Root container for a tabbed interface built on Radix Tabs.\n *\n * @example\n * <Tabs defaultValue=\"tab1\"><TabsList><TabsTrigger value=\"tab1\">Tab</TabsTrigger></TabsList><TabsContent value=\"tab1\">Content</TabsContent></Tabs>\n */\nconst Tabs = TabsPrimitive.Root\n\n/** Horizontal container for tab triggers with a sunken background. */\nfunction TabsList({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<typeof TabsPrimitive.List>) {\n return (\n <TabsPrimitive.List\n ref={ref}\n data-slot=\"tabs-list\"\n className={cn(\n \"inline-flex h-10 items-center justify-center rounded-lg bg-surface-sunken border-2 p-1 text-muted-foreground\",\n className\n )}\n {...props}\n />\n )\n}\n\n/** Individual tab button that activates its associated content panel. */\nfunction TabsTrigger({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<typeof TabsPrimitive.Trigger>) {\n return (\n <TabsPrimitive.Trigger\n ref={ref}\n data-slot=\"tabs-trigger\"\n className={cn(\n \"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1.5 text-sm font-medium ring-offset-background transition-all active:translate-y-[1.5px] transition-transform focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm\",\n className\n )}\n {...props}\n />\n )\n}\n\n/** Content panel displayed when its matching tab trigger is active. */\nfunction TabsContent({\n className,\n ref,\n ...props\n}: React.ComponentPropsWithRef<typeof TabsPrimitive.Content>) {\n return (\n <TabsPrimitive.Content\n ref={ref}\n data-slot=\"tabs-content\"\n className={cn(\n \"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\",\n className\n )}\n {...props}\n />\n )\n}\n\nexport { Tabs, TabsList, TabsTrigger, TabsContent }\n"]}