@nocoo/basalt 2.1.0 → 2.1.7
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/ai/COMPATIBILITY.md +1 -1
- package/ai/INTEGRATION.md +17 -1
- package/ai/USAGE.md +1 -1
- package/ai/registry.json +80 -80
- package/dist/assets/brand-mark.d.ts +1 -1
- package/dist/assets/brand-mark.js +1 -1
- package/dist/assets/brand-mark.js.map +1 -1
- package/dist/charts/charts.d.ts +1 -1
- package/dist/charts/charts.js +3 -16
- package/dist/charts/charts.js.map +1 -1
- package/dist/charts/custom-chart.d.ts +1 -1
- package/dist/charts/custom-chart.js +3 -16
- package/dist/charts/custom-chart.js.map +1 -1
- package/dist/charts/grouped-bar.d.ts +1 -1
- package/dist/charts/grouped-bar.js +11 -48
- package/dist/charts/grouped-bar.js.map +1 -1
- package/dist/charts/heatmap-calendar.js +80 -136
- package/dist/charts/heatmap-calendar.js.map +1 -1
- package/dist/charts/slot-bar.js +2 -12
- package/dist/charts/slot-bar.js.map +1 -1
- package/dist/charts/stat-card.js +2 -7
- package/dist/charts/stat-card.js.map +1 -1
- package/dist/charts/timeseries.d.ts +1 -1
- package/dist/charts/timeseries.js +3 -16
- package/dist/charts/timeseries.js.map +1 -1
- package/dist/charts/tooltip.js +13 -51
- package/dist/charts/tooltip.js.map +1 -1
- package/dist/components/app-shell.js +2 -2
- package/dist/components/app-shell.js.map +1 -1
- package/dist/components/autocomplete.d.ts +1 -1
- package/dist/components/autocomplete.js +3 -16
- package/dist/components/autocomplete.js.map +1 -1
- package/dist/components/badge.js +6 -6
- package/dist/components/badge.js.map +1 -1
- package/dist/components/banner.js +28 -28
- package/dist/components/banner.js.map +1 -1
- package/dist/components/button.js +6 -7
- package/dist/components/button.js.map +1 -1
- package/dist/components/chat-composer.js +1 -2
- package/dist/components/chat-composer.js.map +1 -1
- package/dist/components/checkbox.js +50 -82
- package/dist/components/checkbox.js.map +1 -1
- package/dist/components/code.js +1 -1
- package/dist/components/code.js.map +1 -1
- package/dist/components/combobox.d.ts +1 -1
- package/dist/components/combobox.js +3 -16
- package/dist/components/combobox.js.map +1 -1
- package/dist/components/context-menu.d.ts +1 -67
- package/dist/components/context-menu.js.map +1 -1
- package/dist/components/data-table.js +111 -123
- package/dist/components/data-table.js.map +1 -1
- package/dist/components/date-picker.js +236 -245
- package/dist/components/date-picker.js.map +1 -1
- package/dist/components/dock.js +15 -16
- package/dist/components/dock.js.map +1 -1
- package/dist/components/field.js +20 -23
- package/dist/components/field.js.map +1 -1
- package/dist/components/layer-card.d.ts +1 -1
- package/dist/components/layer-card.js +44 -51
- package/dist/components/layer-card.js.map +1 -1
- package/dist/components/sidebar.js +3 -3
- package/dist/components/sidebar.js.map +1 -1
- package/dist/components/skeleton-line.d.ts +2 -2
- package/dist/components/skeleton-line.js +1 -1
- package/dist/components/skeleton-line.js.map +1 -1
- package/dist/components/switch.js +46 -78
- package/dist/components/switch.js.map +1 -1
- package/dist/providers/accent.js +89 -198
- package/dist/providers/accent.js.map +1 -1
- package/dist/providers/theme.js +46 -144
- package/dist/providers/theme.js.map +1 -1
- package/dist/styles/standalone.css +12 -24
- package/dist/styles/tokens.css +6 -6
- package/dist/utils/preference-store.d.ts +16 -0
- package/dist/utils/preference-store.js +106 -0
- package/dist/utils/preference-store.js.map +1 -0
- package/dist/utils/use-checkable-group.d.ts +19 -0
- package/dist/utils/use-checkable-group.js +61 -0
- package/dist/utils/use-checkable-group.js.map +1 -0
- package/package.json +1 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stat-card.js","names":[],"sources":["../../src/charts/stat-card.tsx"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport type StatCardProps = {\n\t/**\n\t * Secondary heading label for the metric card (overridden by title).\n\t */\n\tlabel?: string;\n\t/**\n\t * Primary heading title for the metric card (takes precedence over label).\n\t */\n\ttitle?: string;\n\t/**\n\t * Metric value, formatted via toLocaleString() if a number is provided.\n\t * Overridden by the status slot if provided.\n\t */\n\tvalue: string | number;\n\t/**\n\t * Supporting descriptive subtitle text rendered below value.\n\t */\n\tsubtitle?: string;\n\t/**\n\t * Optional decorative Lucide icon component.\n\t */\n\ticon?: LucideIcon;\n\t/**\n\t * Color class applied to the icon wrapper.\n\t * @default \"text-basalt-muted-foreground\"\n\t */\n\ticonColor?: string;\n\t/**\n\t * Structured percentage trend value and optional label.\n\t * Overridden by the trendContent slot if provided.\n\t */\n\ttrend?: { value: number; label?: string };\n\t/**\n\t * Optional header action or interactive element (e.g. tooltip trigger or button).\n\t * Renders alongside the title/icon. Switches card role to group for accessible descendants.\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Optional custom status replacement slot (e.g. loading skeleton, error state, or empty state).\n\t * Takes precedence over the default value display and excludes value from accessible name.\n\t * Subtitle and trend remain caller-managed; when error/empty state is shown, callers should omit trend.\n\t */\n\tstatus?: ReactNode;\n\t/**\n\t * Optional custom trend replacement slot (e.g. custom badge, sparkline, or localized trend indicator).\n\t * Takes precedence over the default trend calculation and excludes default trend from accessible name.\n\t */\n\ttrendContent?: ReactNode;\n\t/**\n\t * Optional custom content rendered below the metric value and above or alongside the trend.\n\t */\n\tchildren?: ReactNode;\n\t/**\n\t * Explicit accessible label overriding automatic accessible name calculation.\n\t */\n\tariaLabel?: string;\n\t/**\n\t * Additional CSS class names for styling the card root.\n\t */\n\tclassName?: string;\n};\n\nfunction hasSlotContent(slot: ReactNode | undefined): boolean {\n\treturn slot !== undefined && slot !== null && slot !== false;\n}\n\nexport function StatCard({\n\tlabel,\n\ttitle,\n\tvalue,\n\tsubtitle,\n\ticon: Icon,\n\ticonColor = \"text-basalt-muted-foreground\",\n\ttrend,\n\taction,\n\tstatus,\n\ttrendContent,\n\tchildren,\n\tariaLabel,\n\tclassName,\n}: StatCardProps) {\n\tconst heading = title ?? label;\n\tconst hasStatus = hasSlotContent(status);\n\tconst hasTrendContent = hasSlotContent(trendContent);\n\tconst hasAction = hasSlotContent(action);\n\tconst hasChildren = hasSlotContent(children);\n\tconst isInteractive = hasAction || hasStatus || hasTrendContent || hasChildren;\n\tconst hasHeaderEnd = hasAction || Boolean(Icon);\n\n\tconst display = typeof value === \"number\" ? value.toLocaleString() : value;\n\tconst isPositiveTrend = trend && trend.value > 0;\n\tconst isNegativeTrend = trend && trend.value < 0;\n\n\t// Accessible name: If custom status or custom trendContent is provided, do not report\n\t// the overridden hidden default value or default trend to assistive technology.\n\tconst named =\n\t\tariaLabel ??\n\t\t[\n\t\t\theading,\n\t\t\t!hasStatus ? display : null,\n\t\t\tsubtitle,\n\t\t\t!hasTrendContent && trend\n\t\t\t\t? `${isPositiveTrend ? \"+\" : \"\"}${trend.value}% ${trend.label ?? \"\"}`\n\t\t\t\t: null,\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(\" \")\n\t\t\t.trim();\n\n\tconst cardContent = (\n\t\t<>\n\t\t\t<div className=\"flex items-start justify-between gap-3\">\n\t\t\t\t<div className=\"min-w-0 flex-1 space-y-1\">\n\t\t\t\t\t<p className=\"text-xs text-basalt-muted-foreground md:text-sm\">{heading}</p>\n\t\t\t\t\t{hasStatus ? (\n\t\t\t\t\t\t<div className=\"pt-0.5\">{status}</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<p className=\"font-display text-xl font-semibold tracking-tight text-basalt-foreground md:text-2xl\">\n\t\t\t\t\t\t\t{display}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t\t{subtitle ? <p className=\"text-xs text-basalt-muted-foreground\">{subtitle}</p> : null}\n\t\t\t\t</div>\n\t\t\t\t{hasHeaderEnd ? (\n\t\t\t\t\t<div className=\"flex items-center gap-2 shrink-0\">\n\t\t\t\t\t\t{hasAction ? <div className=\"flex items-center\">{action}</div> : null}\n\t\t\t\t\t\t{Icon ? (\n\t\t\t\t\t\t\t<div className={cn(\"rounded-md bg-basalt-card p-2\", iconColor)}>\n\t\t\t\t\t\t\t\t<Icon className=\"h-5 w-5\" strokeWidth={1.5} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\t\t\t</div>\n\n\t\t\t{hasChildren ? <div className=\"mt-2\">{children}</div> : null}\n\n\t\t\t{hasTrendContent ? (\n\t\t\t\t<div className=\"mt-3 flex items-center gap-1 text-xs\">{trendContent}</div>\n\t\t\t) : trend ? (\n\t\t\t\t<div className=\"mt-3 flex items-center gap-1 text-xs\">\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"font-medium\",\n\t\t\t\t\t\t\tisPositiveTrend && \"text-basalt-heatmap-green-4\",\n\t\t\t\t\t\t\tisNegativeTrend && \"text-basalt-destructive\",\n\t\t\t\t\t\t\t!isPositiveTrend && !isNegativeTrend && \"text-basalt-muted-foreground\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{`${isPositiveTrend ? \"+\" : \"\"}${trend.value}%`}\n\t\t\t\t\t</span>\n\t\t\t\t\t{trend.label ? <span className=\"text-basalt-muted-foreground\">{trend.label}</span> : null}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</>\n\t);\n\n\
|
|
1
|
+
{"version":3,"file":"stat-card.js","names":[],"sources":["../../src/charts/stat-card.tsx"],"sourcesContent":["import type { LucideIcon } from \"lucide-react\";\nimport type { ReactNode } from \"react\";\nimport { cn } from \"../utils/cn\";\n\nexport type StatCardProps = {\n\t/**\n\t * Secondary heading label for the metric card (overridden by title).\n\t */\n\tlabel?: string;\n\t/**\n\t * Primary heading title for the metric card (takes precedence over label).\n\t */\n\ttitle?: string;\n\t/**\n\t * Metric value, formatted via toLocaleString() if a number is provided.\n\t * Overridden by the status slot if provided.\n\t */\n\tvalue: string | number;\n\t/**\n\t * Supporting descriptive subtitle text rendered below value.\n\t */\n\tsubtitle?: string;\n\t/**\n\t * Optional decorative Lucide icon component.\n\t */\n\ticon?: LucideIcon;\n\t/**\n\t * Color class applied to the icon wrapper.\n\t * @default \"text-basalt-muted-foreground\"\n\t */\n\ticonColor?: string;\n\t/**\n\t * Structured percentage trend value and optional label.\n\t * Overridden by the trendContent slot if provided.\n\t */\n\ttrend?: { value: number; label?: string };\n\t/**\n\t * Optional header action or interactive element (e.g. tooltip trigger or button).\n\t * Renders alongside the title/icon. Switches card role to group for accessible descendants.\n\t */\n\taction?: ReactNode;\n\t/**\n\t * Optional custom status replacement slot (e.g. loading skeleton, error state, or empty state).\n\t * Takes precedence over the default value display and excludes value from accessible name.\n\t * Subtitle and trend remain caller-managed; when error/empty state is shown, callers should omit trend.\n\t */\n\tstatus?: ReactNode;\n\t/**\n\t * Optional custom trend replacement slot (e.g. custom badge, sparkline, or localized trend indicator).\n\t * Takes precedence over the default trend calculation and excludes default trend from accessible name.\n\t */\n\ttrendContent?: ReactNode;\n\t/**\n\t * Optional custom content rendered below the metric value and above or alongside the trend.\n\t */\n\tchildren?: ReactNode;\n\t/**\n\t * Explicit accessible label overriding automatic accessible name calculation.\n\t */\n\tariaLabel?: string;\n\t/**\n\t * Additional CSS class names for styling the card root.\n\t */\n\tclassName?: string;\n};\n\nfunction hasSlotContent(slot: ReactNode | undefined): boolean {\n\treturn slot !== undefined && slot !== null && slot !== false;\n}\n\nexport function StatCard({\n\tlabel,\n\ttitle,\n\tvalue,\n\tsubtitle,\n\ticon: Icon,\n\ticonColor = \"text-basalt-muted-foreground\",\n\ttrend,\n\taction,\n\tstatus,\n\ttrendContent,\n\tchildren,\n\tariaLabel,\n\tclassName,\n}: StatCardProps) {\n\tconst heading = title ?? label;\n\tconst hasStatus = hasSlotContent(status);\n\tconst hasTrendContent = hasSlotContent(trendContent);\n\tconst hasAction = hasSlotContent(action);\n\tconst hasChildren = hasSlotContent(children);\n\tconst isInteractive = hasAction || hasStatus || hasTrendContent || hasChildren;\n\tconst hasHeaderEnd = hasAction || Boolean(Icon);\n\n\tconst display = typeof value === \"number\" ? value.toLocaleString() : value;\n\tconst isPositiveTrend = trend && trend.value > 0;\n\tconst isNegativeTrend = trend && trend.value < 0;\n\n\t// Accessible name: If custom status or custom trendContent is provided, do not report\n\t// the overridden hidden default value or default trend to assistive technology.\n\tconst named =\n\t\tariaLabel ??\n\t\t[\n\t\t\theading,\n\t\t\t!hasStatus ? display : null,\n\t\t\tsubtitle,\n\t\t\t!hasTrendContent && trend\n\t\t\t\t? `${isPositiveTrend ? \"+\" : \"\"}${trend.value}% ${trend.label ?? \"\"}`\n\t\t\t\t: null,\n\t\t]\n\t\t\t.filter(Boolean)\n\t\t\t.join(\" \")\n\t\t\t.trim();\n\n\tconst cardContent = (\n\t\t<>\n\t\t\t<div className=\"flex items-start justify-between gap-3\">\n\t\t\t\t<div className=\"min-w-0 flex-1 space-y-1\">\n\t\t\t\t\t<p className=\"text-xs text-basalt-muted-foreground md:text-sm\">{heading}</p>\n\t\t\t\t\t{hasStatus ? (\n\t\t\t\t\t\t<div className=\"pt-0.5\">{status}</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<p className=\"font-display text-xl font-semibold tracking-tight text-basalt-foreground md:text-2xl\">\n\t\t\t\t\t\t\t{display}\n\t\t\t\t\t\t</p>\n\t\t\t\t\t)}\n\t\t\t\t\t{subtitle ? <p className=\"text-xs text-basalt-muted-foreground\">{subtitle}</p> : null}\n\t\t\t\t</div>\n\t\t\t\t{hasHeaderEnd ? (\n\t\t\t\t\t<div className=\"flex items-center gap-2 shrink-0\">\n\t\t\t\t\t\t{hasAction ? <div className=\"flex items-center\">{action}</div> : null}\n\t\t\t\t\t\t{Icon ? (\n\t\t\t\t\t\t\t<div className={cn(\"rounded-md bg-basalt-card p-2\", iconColor)}>\n\t\t\t\t\t\t\t\t<Icon className=\"h-5 w-5\" strokeWidth={1.5} />\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t</div>\n\t\t\t\t) : null}\n\t\t\t</div>\n\n\t\t\t{hasChildren ? <div className=\"mt-2\">{children}</div> : null}\n\n\t\t\t{hasTrendContent ? (\n\t\t\t\t<div className=\"mt-3 flex items-center gap-1 text-xs\">{trendContent}</div>\n\t\t\t) : trend ? (\n\t\t\t\t<div className=\"mt-3 flex items-center gap-1 text-xs\">\n\t\t\t\t\t<span\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\"font-medium\",\n\t\t\t\t\t\t\tisPositiveTrend && \"text-basalt-heatmap-green-4\",\n\t\t\t\t\t\t\tisNegativeTrend && \"text-basalt-destructive\",\n\t\t\t\t\t\t\t!isPositiveTrend && !isNegativeTrend && \"text-basalt-muted-foreground\",\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t{`${isPositiveTrend ? \"+\" : \"\"}${trend.value}%`}\n\t\t\t\t\t</span>\n\t\t\t\t\t{trend.label ? <span className=\"text-basalt-muted-foreground\">{trend.label}</span> : null}\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t</>\n\t);\n\n\treturn (\n\t\t// biome-ignore lint/a11y/useAriaPropsSupportedByRole: dynamic role is \"group\" | \"img\", both support aria-label\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"rounded-basalt-md border border-basalt-border bg-basalt-secondary p-4\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\trole={isInteractive ? \"group\" : \"img\"}\n\t\t\taria-label={named}\n\t\t>\n\t\t\t{cardContent}\n\t\t</div>\n\t);\n}\n\nexport type StatGridProps = {\n\tchildren: ReactNode;\n\tcolumns?: 2 | 3 | 4;\n\tclassName?: string;\n};\n\nexport function StatGrid({ children, columns = 4, className }: StatGridProps) {\n\tconst gridCols = {\n\t\t2: \"grid-cols-1 sm:grid-cols-2\",\n\t\t3: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\",\n\t\t4: \"grid-cols-1 sm:grid-cols-2 lg:grid-cols-4\",\n\t};\n\treturn <div className={cn(\"grid gap-3 md:gap-4\", gridCols[columns], className)}>{children}</div>;\n}\n"],"mappings":";;;;AAkEA,SAAS,EAAe,GAAsC;CAC7D,OAAO,KAA+B,QAAQ,MAAS;AACxD;AAEA,SAAgB,EAAS,EACxB,UACA,UACA,UACA,aACA,MAAM,GACN,eAAY,gCACZ,UACA,WACA,WACA,iBACA,aACA,cACA,gBACiB;CACjB,IAAM,IAAU,KAAS,GACnB,IAAY,EAAe,CAAM,GACjC,IAAkB,EAAe,CAAY,GAC7C,IAAY,EAAe,CAAM,GACjC,IAAc,EAAe,CAAQ,GACrC,IAAgB,KAAa,KAAa,KAAmB,GAC7D,IAAe,KAAa,EAAQ,GAEpC,IAAU,OAAO,KAAU,WAAW,EAAM,eAAe,IAAI,GAC/D,IAAkB,KAAS,EAAM,QAAQ,GACzC,IAAkB,KAAS,EAAM,QAAQ,GAIzC,IACL,KACA;EACC;EACC,IAAsB,OAAV;EACb;EACA,CAAC,KAAmB,IACjB,GAAG,IAAkB,MAAM,KAAK,EAAM,MAAM,IAAI,EAAM,SAAS,OAC/D;CACJ,CAAC,CACC,OAAO,OAAO,CAAC,CACf,KAAK,GAAG,CAAC,CACT,KAAK,GAEF,IACL,kBAAA,GAAA,EAAA,UAAA;EACC,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACC,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA;KACC,kBAAC,KAAD;MAAG,WAAU;MAAmD,UAAA;KAAW,CAAA;KAC1E,IACA,kBAAC,OAAD;MAAK,WAAU;MAAU,UAAA;KAAY,CAAA,IAErC,kBAAC,KAAD;MAAG,WAAU;MACX,UAAA;KACC,CAAA;KAEH,IAAW,kBAAC,KAAD;MAAG,WAAU;MAAwC,UAAA;KAAY,CAAA,IAAI;IAC7E;GACJ,CAAA,GAAA,IACA,kBAAC,OAAD;IAAK,WAAU;IAAf,UAAA,CACE,IAAY,kBAAC,OAAD;KAAK,WAAU;KAAqB,UAAA;IAAY,CAAA,IAAI,MAChE,IACA,kBAAC,OAAD;KAAK,WAAW,EAAG,iCAAiC,CAAS;KAC5D,UAAA,kBAAC,GAAD;MAAM,WAAU;MAAU,aAAa;KAAM,CAAA;IACzC,CAAA,IACF,IACA;GACF,CAAA,IAAA,IACA;;EAEJ,IAAc,kBAAC,OAAD;GAAK,WAAU;GAAQ;EAAc,CAAA,IAAI;EAEvD,IACA,kBAAC,OAAD;GAAK,WAAU;GAAwC,UAAA;EAAkB,CAAA,IACtE,IACH,kBAAC,OAAD;GAAK,WAAU;GAAf,UAAA,CACC,kBAAC,QAAD;IACC,WAAW,EACV,eACA,KAAmB,+BACnB,KAAmB,2BACnB,CAAC,KAAmB,CAAC,KAAmB,8BACzC;IAEC,UAAA,GAAG,IAAkB,MAAM,KAAK,EAAM,MAAM;GACxC,CAAA,GACL,EAAM,QAAQ,kBAAC,QAAD;IAAM,WAAU;IAAgC,UAAA,EAAM;GAAY,CAAA,IAAI,IACjF;EACF,CAAA,IAAA;CACH,EAAA,CAAA;CAGH,OAEC,kBAAC,OAAD;EACC,WAAW,EACV,yEACA,CACD;EACA,MAAM,IAAgB,UAAU;EAChC,cAAY;EAEX,UAAA;CACG,CAAA;AAEP;AAQA,SAAgB,EAAS,EAAE,aAAU,aAAU,GAAG,gBAA4B;CAM7E,OAAO,kBAAC,OAAD;EAAK,WAAW,EAAG,uBAAuB;GAJhD,GAAG;GACH,GAAG;GACH,GAAG;EAE6C,EAAS,IAAU,CAAS;EAAI;CAAc,CAAA;AAChG"}
|
|
@@ -58,4 +58,4 @@ export type TimeseriesProps<TData extends {
|
|
|
58
58
|
};
|
|
59
59
|
export declare function Timeseries<TData extends {
|
|
60
60
|
x: string | number;
|
|
61
|
-
} = XYPoint, K extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string>({
|
|
61
|
+
} = XYPoint, K extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string>({ ariaLabel, ...props }: TimeseriesProps<TData, K>): import("react").JSX.Element;
|
|
@@ -2,23 +2,10 @@
|
|
|
2
2
|
import { LineChart as e } from "./line.js";
|
|
3
3
|
import { jsx as t } from "react/jsx-runtime";
|
|
4
4
|
//#region src/charts/timeseries.tsx
|
|
5
|
-
function n({
|
|
5
|
+
function n({ ariaLabel: n = "Timeseries", ...r }) {
|
|
6
6
|
return /* @__PURE__ */ t(e, {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
ariaLabel: i,
|
|
10
|
-
className: a,
|
|
11
|
-
showAxes: o,
|
|
12
|
-
showLegend: s,
|
|
13
|
-
color: c,
|
|
14
|
-
valueFormatter: l,
|
|
15
|
-
xValueFormatter: u,
|
|
16
|
-
yDomain: d,
|
|
17
|
-
legend: f,
|
|
18
|
-
customTooltip: p,
|
|
19
|
-
summary: m,
|
|
20
|
-
dataAlternative: h,
|
|
21
|
-
accessibilityLayer: g
|
|
7
|
+
ariaLabel: n,
|
|
8
|
+
...r
|
|
22
9
|
});
|
|
23
10
|
}
|
|
24
11
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"timeseries.js","names":[],"sources":["../../src/charts/timeseries.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport {\n\tLineChart,\n\ttype LineChartAxisDomain,\n\ttype LineChartLegendRenderer,\n\ttype LineChartNumericKeys,\n\ttype LineChartTooltipRenderer,\n} from \"./line\";\nimport type { ChartSeriesDescriptor, XYPoint } from \"./series\";\n\nexport type TimeseriesProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\tcolor?: string;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function Timeseries<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({
|
|
1
|
+
{"version":3,"file":"timeseries.js","names":[],"sources":["../../src/charts/timeseries.tsx"],"sourcesContent":["import type { ReactNode } from \"react\";\nimport {\n\tLineChart,\n\ttype LineChartAxisDomain,\n\ttype LineChartLegendRenderer,\n\ttype LineChartNumericKeys,\n\ttype LineChartTooltipRenderer,\n} from \"./line\";\nimport type { ChartSeriesDescriptor, XYPoint } from \"./series\";\n\nexport type TimeseriesProps<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n> = {\n\t/**\n\t * Dataset array where each record requires an `x` category or time coordinate.\n\t * Any remaining fields with numeric, nullable, or optional number values are inferred as valid series keys.\n\t */\n\tdata: TData[];\n\t/**\n\t * Series descriptors identifying which numeric keys to plot.\n\t * Inferred strictly from numeric keys of `TData` (rejects non-numeric fields, `x`, and typos).\n\t */\n\tseries?: Array<ChartSeriesDescriptor<NoInfer<K>>>;\n\tariaLabel?: string;\n\tclassName?: string;\n\tshowAxes?: boolean;\n\tshowLegend?: boolean;\n\tcolor?: string;\n\t/**\n\t * Value formatter for Y-axis tick values and fallback tooltip values.\n\t */\n\tvalueFormatter?: (value: number) => string;\n\t/**\n\t * Formatter for X-axis category or time tick labels.\n\t */\n\txValueFormatter?: (value: string | number) => string;\n\t/**\n\t * Custom numerical or keyword bounds for the Y-axis.\n\t */\n\tyDomain?: LineChartAxisDomain;\n\t/**\n\t * Custom legend slot or render function receiving resolved series descriptors.\n\t */\n\tlegend?: ReactNode | LineChartLegendRenderer<K>;\n\t/**\n\t * Custom tooltip content renderer receiving Recharts payload, active status, and coordinate label.\n\t */\n\tcustomTooltip?: LineChartTooltipRenderer;\n\t/**\n\t * Textual summary describing key insights, highs, lows, and keyboard exploration instructions.\n\t * Associated with the chart via useId and aria-describedby.\n\t */\n\tsummary?: ReactNode;\n\t/**\n\t * Accessible tabular or structured data alternative rendered outside the plot area.\n\t */\n\tdataAlternative?: ReactNode;\n\t/**\n\t * Whether the interactive accessibility layer is enabled on the underlying Recharts graphic.\n\t * Enables keyboard exploration with Tab and arrow keys where supported by the underlying chart type.\n\t * Non-interactive compact or decorative charts without tooltip navigation should provide summary or dataAlternative.\n\t * @default true\n\t */\n\taccessibilityLayer?: boolean;\n};\n\nexport function Timeseries<\n\tTData extends { x: string | number } = XYPoint,\n\tK extends LineChartNumericKeys<TData> & string = LineChartNumericKeys<TData> & string,\n>({ ariaLabel = \"Timeseries\", ...props }: TimeseriesProps<TData, K>) {\n\treturn <LineChart<TData, K> ariaLabel={ariaLabel} {...props} />;\n}\n"],"mappings":";;;;AAmEA,SAAgB,EAGd,EAAE,eAAY,cAAc,GAAG,KAAoC;CACpE,OAAO,kBAAC,GAAD;EAAgC;EAAW,GAAI;CAAQ,CAAA;AAC/D"}
|
package/dist/charts/tooltip.js
CHANGED
|
@@ -135,9 +135,9 @@ function f({ label: n = "Total", value: r, unit: a, formatter: o, style: s, ...c
|
|
|
135
135
|
})]
|
|
136
136
|
});
|
|
137
137
|
}
|
|
138
|
-
function p({ active: n, payload:
|
|
139
|
-
if (!n || !
|
|
140
|
-
let
|
|
138
|
+
function p({ active: n, payload: i, label: a, formatter: l }) {
|
|
139
|
+
if (!n || !i?.length) return null;
|
|
140
|
+
let d = l ?? o, f = a == null || a === "" ? void 0 : String(a);
|
|
141
141
|
return /* @__PURE__ */ t("div", {
|
|
142
142
|
"data-testid": "chart-tooltip",
|
|
143
143
|
style: {
|
|
@@ -150,7 +150,7 @@ function p({ active: n, payload: l, label: u, formatter: d }) {
|
|
|
150
150
|
minWidth: 128,
|
|
151
151
|
padding: "8px 12px"
|
|
152
152
|
},
|
|
153
|
-
children: [
|
|
153
|
+
children: [f ? /* @__PURE__ */ e("p", {
|
|
154
154
|
style: {
|
|
155
155
|
color: "hsl(var(--basalt-popover-foreground))",
|
|
156
156
|
fontSize: r,
|
|
@@ -159,59 +159,21 @@ function p({ active: n, payload: l, label: u, formatter: d }) {
|
|
|
159
159
|
lineHeight: 1.2,
|
|
160
160
|
margin: "0 0 8px"
|
|
161
161
|
},
|
|
162
|
-
children:
|
|
162
|
+
children: f
|
|
163
163
|
}) : null, /* @__PURE__ */ e("div", {
|
|
164
164
|
style: {
|
|
165
165
|
display: "flex",
|
|
166
166
|
flexDirection: "column",
|
|
167
167
|
gap: 4
|
|
168
168
|
},
|
|
169
|
-
children:
|
|
170
|
-
let
|
|
171
|
-
return /* @__PURE__ */
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
lineHeight: "20px",
|
|
178
|
-
minWidth: 0
|
|
179
|
-
},
|
|
180
|
-
children: [
|
|
181
|
-
/* @__PURE__ */ e("span", {
|
|
182
|
-
"aria-hidden": "true",
|
|
183
|
-
style: {
|
|
184
|
-
background: c(n),
|
|
185
|
-
borderRadius: 999,
|
|
186
|
-
boxShadow: "0 0 0 1px hsl(var(--basalt-popover-foreground) / 0.12)",
|
|
187
|
-
flexShrink: 0,
|
|
188
|
-
height: a,
|
|
189
|
-
width: a
|
|
190
|
-
}
|
|
191
|
-
}),
|
|
192
|
-
u ? /* @__PURE__ */ e("span", {
|
|
193
|
-
style: {
|
|
194
|
-
color: "hsl(var(--basalt-muted-foreground))",
|
|
195
|
-
flex: 1,
|
|
196
|
-
minWidth: 0,
|
|
197
|
-
overflow: "hidden",
|
|
198
|
-
textOverflow: "ellipsis",
|
|
199
|
-
whiteSpace: "nowrap"
|
|
200
|
-
},
|
|
201
|
-
children: u
|
|
202
|
-
}) : null,
|
|
203
|
-
/* @__PURE__ */ e("span", {
|
|
204
|
-
style: {
|
|
205
|
-
color: "hsl(var(--basalt-popover-foreground))",
|
|
206
|
-
flexShrink: 0,
|
|
207
|
-
fontVariantNumeric: "tabular-nums",
|
|
208
|
-
fontWeight: 600,
|
|
209
|
-
marginLeft: u ? 0 : "auto"
|
|
210
|
-
},
|
|
211
|
-
children: Number.isFinite(l) ? f(l) : String(o ?? "—")
|
|
212
|
-
})
|
|
213
|
-
]
|
|
214
|
-
}, d);
|
|
169
|
+
children: i.map((t, n) => {
|
|
170
|
+
let r = t.value, i = typeof r == "number" ? r : typeof r == "string" ? Number(r) : NaN, a = s(t), o = `${String(t.dataKey ?? t.name ?? n)}-${String(n)}`;
|
|
171
|
+
return /* @__PURE__ */ e(u, {
|
|
172
|
+
label: a,
|
|
173
|
+
color: c(t),
|
|
174
|
+
value: Number.isFinite(i) ? d(i) : String(r ?? "—"),
|
|
175
|
+
"data-testid": void 0
|
|
176
|
+
}, o);
|
|
215
177
|
})
|
|
216
178
|
})]
|
|
217
179
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tooltip.js","names":[],"sources":["../../src/charts/tooltip.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from \"react\";\n\nconst HIDDEN_SERIES_KEYS = new Set([\"y\", \"y2\", \"y3\", \"value\", \"target\"]);\nconst TITLE_SIZE = 12;\nconst BODY_SIZE = 12;\nconst DOT_SIZE = 8;\n\nexport type ChartTooltipItem = {\n\tname?: string;\n\tvalue?: number | string;\n\tcolor?: string;\n\tfill?: string;\n\tstroke?: string;\n\tdataKey?: string | number;\n};\n\nexport type ChartTooltipContentProps = {\n\tactive?: boolean;\n\tpayload?: readonly ChartTooltipItem[];\n\tlabel?: string | number;\n\tformatter?: (value: number) => string;\n};\n\nexport interface ChartTooltipRowProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Series or metric name displayed beside the color dot.\n\t * Preserves numeric `0` and React nodes; nullish values omit the label element.\n\t */\n\tlabel?: ReactNode;\n\t/**\n\t * Display value of the point or metric.\n\t * Finite numbers are automatically formatted via `formatter` or `formatChartNumber`.\n\t * `null` or `undefined` renders placeholder \"—\". ReactNode values are passed through.\n\t */\n\tvalue?: ReactNode;\n\t/**\n\t * Dot swatch indicator color. Defaults to `--basalt-chart-1`.\n\t */\n\tcolor?: string;\n\t/**\n\t * Optional unit suffix (e.g., \"ms\", \"req/s\", \"%\") rendered adjacent to valid values.\n\t * Omitted when `value` evaluates to placeholder \"—\".\n\t */\n\tunit?: ReactNode;\n\t/**\n\t * Custom numeric value formatter overriding `formatChartNumber`.\n\t */\n\tformatter?: (value: number) => string;\n\t/**\n\t * When true, suppresses rendering of the decorative color dot.\n\t * @default false\n\t */\n\thideIndicator?: boolean;\n}\n\nexport interface ChartTooltipSummaryProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Summary row heading label.\n\t * Preserves numeric `0` and custom nodes.\n\t * @default \"Total\"\n\t */\n\tlabel?: ReactNode;\n\t/**\n\t * Aggregated metric value. Finite numbers are formatted; nullish renders \"—\".\n\t */\n\tvalue?: ReactNode;\n\t/**\n\t * Optional unit suffix appended to the summary value.\n\t */\n\tunit?: ReactNode;\n\t/**\n\t * Custom numeric formatter for the summary value.\n\t */\n\tformatter?: (value: number) => string;\n}\n\nexport interface ChartTooltipDividerProps extends Omit<ComponentProps<\"hr\">, \"children\"> {}\n\nexport function formatChartNumber(value: number): string {\n\tif (!Number.isFinite(value)) {\n\t\treturn \"—\";\n\t}\n\treturn new Intl.NumberFormat(undefined, {\n\t\tmaximumFractionDigits: Number.isInteger(value) ? 0 : 1,\n\t}).format(value);\n}\n\nfunction seriesLabel(item: ChartTooltipItem): string | undefined {\n\tconst name = item.name == null ? \"\" : String(item.name);\n\tconst key = item.dataKey == null ? \"\" : String(item.dataKey);\n\tif (HIDDEN_SERIES_KEYS.has(name) || HIDDEN_SERIES_KEYS.has(key)) {\n\t\treturn undefined;\n\t}\n\treturn name || undefined;\n}\n\nfunction seriesSwatch(item: ChartTooltipItem): string {\n\treturn item.color ?? item.fill ?? item.stroke ?? \"hsl(var(--basalt-chart-1))\";\n}\n\nfunction formatTooltipValue(val: ReactNode, formatter?: (value: number) => string): ReactNode {\n\tif (val == null) {\n\t\treturn \"—\";\n\t}\n\tif (typeof val === \"number\") {\n\t\treturn formatter ? formatter(val) : formatChartNumber(val);\n\t}\n\treturn val;\n}\n\nexport function ChartTooltipRow({\n\tlabel,\n\tvalue,\n\tcolor,\n\tunit,\n\tformatter,\n\thideIndicator = false,\n\tstyle,\n\t...rest\n}: ChartTooltipRowProps) {\n\tconst formattedValue = formatTooltipValue(value, formatter);\n\tconst hasLabel = label != null;\n\tconst swatchColor = color ?? \"hsl(var(--basalt-chart-1))\";\n\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip-row\"\n\t\t\tstyle={{\n\t\t\t\talignItems: \"center\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tfontSize: BODY_SIZE,\n\t\t\t\tgap: 8,\n\t\t\t\tlineHeight: \"20px\",\n\t\t\t\tminWidth: 0,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{!hideIndicator ? (\n\t\t\t\t<span\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackground: swatchColor,\n\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\tboxShadow: \"0 0 0 1px hsl(var(--basalt-popover-foreground) / 0.12)\",\n\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\theight: DOT_SIZE,\n\t\t\t\t\t\twidth: DOT_SIZE,\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{hasLabel ? (\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{label}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tfontVariantNumeric: \"tabular-nums\",\n\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\tmarginLeft: hasLabel ? 0 : \"auto\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{formattedValue}\n\t\t\t\t{unit != null && formattedValue !== \"—\" ? (\n\t\t\t\t\t<span style={{ fontWeight: 400, marginLeft: 2 }}>{unit}</span>\n\t\t\t\t) : null}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n\nexport function ChartTooltipDivider({ style, ...rest }: ChartTooltipDividerProps) {\n\treturn (\n\t\t<hr\n\t\t\taria-orientation=\"horizontal\"\n\t\t\tdata-testid=\"chart-tooltip-divider\"\n\t\t\tstyle={{\n\t\t\t\tbackgroundColor: \"hsl(var(--basalt-border) / 0.55)\",\n\t\t\t\tborder: 0,\n\t\t\t\theight: 1,\n\t\t\t\tmargin: \"4px 0\",\n\t\t\t\twidth: \"100%\",\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t/>\n\t);\n}\n\nexport function ChartTooltipSummary({\n\tlabel = \"Total\",\n\tvalue,\n\tunit,\n\tformatter,\n\tstyle,\n\t...rest\n}: ChartTooltipSummaryProps) {\n\tconst formattedValue = formatTooltipValue(value, formatter);\n\tconst hasLabel = label != null;\n\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip-summary\"\n\t\t\tstyle={{\n\t\t\t\talignItems: \"center\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tfontSize: BODY_SIZE,\n\t\t\t\tgap: 8,\n\t\t\t\tlineHeight: \"20px\",\n\t\t\t\tminWidth: 0,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{hasLabel ? (\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{label}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tfontVariantNumeric: \"tabular-nums\",\n\t\t\t\t\tfontWeight: 700,\n\t\t\t\t\tmarginLeft: hasLabel ? 0 : \"auto\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{formattedValue}\n\t\t\t\t{unit != null && formattedValue !== \"—\" ? (\n\t\t\t\t\t<span style={{ fontWeight: 500, marginLeft: 2 }}>{unit}</span>\n\t\t\t\t) : null}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n\nexport function ChartTooltipContent({\n\tactive,\n\tpayload,\n\tlabel,\n\tformatter,\n}: ChartTooltipContentProps) {\n\tif (!active || !payload?.length) {\n\t\treturn null;\n\t}\n\tconst format = formatter ?? formatChartNumber;\n\tconst title = label == null || label === \"\" ? undefined : String(label);\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip\"\n\t\t\tstyle={{\n\t\t\t\tbackground: \"hsl(var(--basalt-popover))\",\n\t\t\t\tborder: \"1px solid hsl(var(--basalt-border) / 0.55)\",\n\t\t\t\tborderRadius: 10,\n\t\t\t\tboxShadow: \"0 12px 28px -8px rgb(0 0 0 / 0.28), 0 4px 10px -4px rgb(0 0 0 / 0.16)\",\n\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\tmaxWidth: 220,\n\t\t\t\tminWidth: 128,\n\t\t\t\tpadding: \"8px 12px\",\n\t\t\t}}\n\t\t>\n\t\t\t{title ? (\n\t\t\t\t<p\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\t\tfontSize: TITLE_SIZE,\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\tletterSpacing: \"-0.01em\",\n\t\t\t\t\t\tlineHeight: 1.2,\n\t\t\t\t\t\tmargin: \"0 0 8px\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{title}\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t<div style={{ display: \"flex\", flexDirection: \"column\", gap: 4 }}>\n\t\t\t\t{payload.map((item, index) => {\n\t\t\t\t\tconst raw = item.value;\n\t\t\t\t\tconst numeric =\n\t\t\t\t\t\ttypeof raw === \"number\" ? raw : typeof raw === \"string\" ? Number(raw) : Number.NaN;\n\t\t\t\t\tconst labelText = seriesLabel(item);\n\t\t\t\t\tconst key = `${String(item.dataKey ?? item.name ?? index)}-${String(index)}`;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tkey={key}\n\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\talignItems: \"center\",\n\t\t\t\t\t\t\t\tdisplay: \"flex\",\n\t\t\t\t\t\t\t\tfontSize: BODY_SIZE,\n\t\t\t\t\t\t\t\tgap: 8,\n\t\t\t\t\t\t\t\tlineHeight: \"20px\",\n\t\t\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tbackground: seriesSwatch(item),\n\t\t\t\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\t\t\t\tboxShadow: \"0 0 0 1px hsl(var(--basalt-popover-foreground) / 0.12)\",\n\t\t\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t\t\t\theight: DOT_SIZE,\n\t\t\t\t\t\t\t\t\twidth: DOT_SIZE,\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t{labelText ? (\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\t\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{labelText}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\tstyle={{\n\t\t\t\t\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\t\t\t\tfontVariantNumeric: \"tabular-nums\",\n\t\t\t\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\t\t\t\tmarginLeft: labelText ? 0 : \"auto\",\n\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{Number.isFinite(numeric) ? format(numeric) : String(raw ?? \"—\")}\n\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"tooltip.js","names":[],"sources":["../../src/charts/tooltip.tsx"],"sourcesContent":["import type { ComponentProps, ReactNode } from \"react\";\n\nconst HIDDEN_SERIES_KEYS = new Set([\"y\", \"y2\", \"y3\", \"value\", \"target\"]);\nconst TITLE_SIZE = 12;\nconst BODY_SIZE = 12;\nconst DOT_SIZE = 8;\n\nexport type ChartTooltipItem = {\n\tname?: string;\n\tvalue?: number | string;\n\tcolor?: string;\n\tfill?: string;\n\tstroke?: string;\n\tdataKey?: string | number;\n};\n\nexport type ChartTooltipContentProps = {\n\tactive?: boolean;\n\tpayload?: readonly ChartTooltipItem[];\n\tlabel?: string | number;\n\tformatter?: (value: number) => string;\n};\n\nexport interface ChartTooltipRowProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Series or metric name displayed beside the color dot.\n\t * Preserves numeric `0` and React nodes; nullish values omit the label element.\n\t */\n\tlabel?: ReactNode;\n\t/**\n\t * Display value of the point or metric.\n\t * Finite numbers are automatically formatted via `formatter` or `formatChartNumber`.\n\t * `null` or `undefined` renders placeholder \"—\". ReactNode values are passed through.\n\t */\n\tvalue?: ReactNode;\n\t/**\n\t * Dot swatch indicator color. Defaults to `--basalt-chart-1`.\n\t */\n\tcolor?: string;\n\t/**\n\t * Optional unit suffix (e.g., \"ms\", \"req/s\", \"%\") rendered adjacent to valid values.\n\t * Omitted when `value` evaluates to placeholder \"—\".\n\t */\n\tunit?: ReactNode;\n\t/**\n\t * Custom numeric value formatter overriding `formatChartNumber`.\n\t */\n\tformatter?: (value: number) => string;\n\t/**\n\t * When true, suppresses rendering of the decorative color dot.\n\t * @default false\n\t */\n\thideIndicator?: boolean;\n}\n\nexport interface ChartTooltipSummaryProps extends Omit<ComponentProps<\"div\">, \"children\"> {\n\t/**\n\t * Summary row heading label.\n\t * Preserves numeric `0` and custom nodes.\n\t * @default \"Total\"\n\t */\n\tlabel?: ReactNode;\n\t/**\n\t * Aggregated metric value. Finite numbers are formatted; nullish renders \"—\".\n\t */\n\tvalue?: ReactNode;\n\t/**\n\t * Optional unit suffix appended to the summary value.\n\t */\n\tunit?: ReactNode;\n\t/**\n\t * Custom numeric formatter for the summary value.\n\t */\n\tformatter?: (value: number) => string;\n}\n\nexport interface ChartTooltipDividerProps extends Omit<ComponentProps<\"hr\">, \"children\"> {}\n\nexport function formatChartNumber(value: number): string {\n\tif (!Number.isFinite(value)) {\n\t\treturn \"—\";\n\t}\n\treturn new Intl.NumberFormat(undefined, {\n\t\tmaximumFractionDigits: Number.isInteger(value) ? 0 : 1,\n\t}).format(value);\n}\n\nfunction seriesLabel(item: ChartTooltipItem): string | undefined {\n\tconst name = item.name == null ? \"\" : String(item.name);\n\tconst key = item.dataKey == null ? \"\" : String(item.dataKey);\n\tif (HIDDEN_SERIES_KEYS.has(name) || HIDDEN_SERIES_KEYS.has(key)) {\n\t\treturn undefined;\n\t}\n\treturn name || undefined;\n}\n\nfunction seriesSwatch(item: ChartTooltipItem): string {\n\treturn item.color ?? item.fill ?? item.stroke ?? \"hsl(var(--basalt-chart-1))\";\n}\n\nfunction formatTooltipValue(val: ReactNode, formatter?: (value: number) => string): ReactNode {\n\tif (val == null) {\n\t\treturn \"—\";\n\t}\n\tif (typeof val === \"number\") {\n\t\treturn formatter ? formatter(val) : formatChartNumber(val);\n\t}\n\treturn val;\n}\n\nexport function ChartTooltipRow({\n\tlabel,\n\tvalue,\n\tcolor,\n\tunit,\n\tformatter,\n\thideIndicator = false,\n\tstyle,\n\t...rest\n}: ChartTooltipRowProps) {\n\tconst formattedValue = formatTooltipValue(value, formatter);\n\tconst hasLabel = label != null;\n\tconst swatchColor = color ?? \"hsl(var(--basalt-chart-1))\";\n\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip-row\"\n\t\t\tstyle={{\n\t\t\t\talignItems: \"center\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tfontSize: BODY_SIZE,\n\t\t\t\tgap: 8,\n\t\t\t\tlineHeight: \"20px\",\n\t\t\t\tminWidth: 0,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{!hideIndicator ? (\n\t\t\t\t<span\n\t\t\t\t\taria-hidden=\"true\"\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tbackground: swatchColor,\n\t\t\t\t\t\tborderRadius: 999,\n\t\t\t\t\t\tboxShadow: \"0 0 0 1px hsl(var(--basalt-popover-foreground) / 0.12)\",\n\t\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\t\theight: DOT_SIZE,\n\t\t\t\t\t\twidth: DOT_SIZE,\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t{hasLabel ? (\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{label}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tfontVariantNumeric: \"tabular-nums\",\n\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\tmarginLeft: hasLabel ? 0 : \"auto\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{formattedValue}\n\t\t\t\t{unit != null && formattedValue !== \"—\" ? (\n\t\t\t\t\t<span style={{ fontWeight: 400, marginLeft: 2 }}>{unit}</span>\n\t\t\t\t) : null}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n\nexport function ChartTooltipDivider({ style, ...rest }: ChartTooltipDividerProps) {\n\treturn (\n\t\t<hr\n\t\t\taria-orientation=\"horizontal\"\n\t\t\tdata-testid=\"chart-tooltip-divider\"\n\t\t\tstyle={{\n\t\t\t\tbackgroundColor: \"hsl(var(--basalt-border) / 0.55)\",\n\t\t\t\tborder: 0,\n\t\t\t\theight: 1,\n\t\t\t\tmargin: \"4px 0\",\n\t\t\t\twidth: \"100%\",\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t/>\n\t);\n}\n\nexport function ChartTooltipSummary({\n\tlabel = \"Total\",\n\tvalue,\n\tunit,\n\tformatter,\n\tstyle,\n\t...rest\n}: ChartTooltipSummaryProps) {\n\tconst formattedValue = formatTooltipValue(value, formatter);\n\tconst hasLabel = label != null;\n\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip-summary\"\n\t\t\tstyle={{\n\t\t\t\talignItems: \"center\",\n\t\t\t\tdisplay: \"flex\",\n\t\t\t\tfontSize: BODY_SIZE,\n\t\t\t\tgap: 8,\n\t\t\t\tlineHeight: \"20px\",\n\t\t\t\tminWidth: 0,\n\t\t\t\t...style,\n\t\t\t}}\n\t\t\t{...rest}\n\t\t>\n\t\t\t{hasLabel ? (\n\t\t\t\t<span\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-muted-foreground))\",\n\t\t\t\t\t\tflex: 1,\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\tminWidth: 0,\n\t\t\t\t\t\toverflow: \"hidden\",\n\t\t\t\t\t\ttextOverflow: \"ellipsis\",\n\t\t\t\t\t\twhiteSpace: \"nowrap\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{label}\n\t\t\t\t</span>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tstyle={{\n\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\tflexShrink: 0,\n\t\t\t\t\tfontVariantNumeric: \"tabular-nums\",\n\t\t\t\t\tfontWeight: 700,\n\t\t\t\t\tmarginLeft: hasLabel ? 0 : \"auto\",\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{formattedValue}\n\t\t\t\t{unit != null && formattedValue !== \"—\" ? (\n\t\t\t\t\t<span style={{ fontWeight: 500, marginLeft: 2 }}>{unit}</span>\n\t\t\t\t) : null}\n\t\t\t</span>\n\t\t</div>\n\t);\n}\n\nexport function ChartTooltipContent({\n\tactive,\n\tpayload,\n\tlabel,\n\tformatter,\n}: ChartTooltipContentProps) {\n\tif (!active || !payload?.length) {\n\t\treturn null;\n\t}\n\tconst format = formatter ?? formatChartNumber;\n\tconst title = label == null || label === \"\" ? undefined : String(label);\n\treturn (\n\t\t<div\n\t\t\tdata-testid=\"chart-tooltip\"\n\t\t\tstyle={{\n\t\t\t\tbackground: \"hsl(var(--basalt-popover))\",\n\t\t\t\tborder: \"1px solid hsl(var(--basalt-border) / 0.55)\",\n\t\t\t\tborderRadius: 10,\n\t\t\t\tboxShadow: \"0 12px 28px -8px rgb(0 0 0 / 0.28), 0 4px 10px -4px rgb(0 0 0 / 0.16)\",\n\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\tmaxWidth: 220,\n\t\t\t\tminWidth: 128,\n\t\t\t\tpadding: \"8px 12px\",\n\t\t\t}}\n\t\t>\n\t\t\t{title ? (\n\t\t\t\t<p\n\t\t\t\t\tstyle={{\n\t\t\t\t\t\tcolor: \"hsl(var(--basalt-popover-foreground))\",\n\t\t\t\t\t\tfontSize: TITLE_SIZE,\n\t\t\t\t\t\tfontWeight: 600,\n\t\t\t\t\t\tletterSpacing: \"-0.01em\",\n\t\t\t\t\t\tlineHeight: 1.2,\n\t\t\t\t\t\tmargin: \"0 0 8px\",\n\t\t\t\t\t}}\n\t\t\t\t>\n\t\t\t\t\t{title}\n\t\t\t\t</p>\n\t\t\t) : null}\n\t\t\t<div style={{ display: \"flex\", flexDirection: \"column\", gap: 4 }}>\n\t\t\t\t{payload.map((item, index) => {\n\t\t\t\t\tconst raw = item.value;\n\t\t\t\t\tconst numeric =\n\t\t\t\t\t\ttypeof raw === \"number\" ? raw : typeof raw === \"string\" ? Number(raw) : Number.NaN;\n\t\t\t\t\tconst labelText = seriesLabel(item);\n\t\t\t\t\tconst key = `${String(item.dataKey ?? item.name ?? index)}-${String(index)}`;\n\t\t\t\t\treturn (\n\t\t\t\t\t\t<ChartTooltipRow\n\t\t\t\t\t\t\tkey={key}\n\t\t\t\t\t\t\tlabel={labelText}\n\t\t\t\t\t\t\tcolor={seriesSwatch(item)}\n\t\t\t\t\t\t\tvalue={Number.isFinite(numeric) ? format(numeric) : String(raw ?? \"—\")}\n\t\t\t\t\t\t\tdata-testid={undefined}\n\t\t\t\t\t\t/>\n\t\t\t\t\t);\n\t\t\t\t})}\n\t\t\t</div>\n\t\t</div>\n\t);\n}\n"],"mappings":"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"}
|
|
@@ -13,14 +13,14 @@ function r({ href: r = "#main-content", className: i, children: a, ...o }) {
|
|
|
13
13
|
}
|
|
14
14
|
function i({ className: t, ...r }) {
|
|
15
15
|
return /* @__PURE__ */ n("div", {
|
|
16
|
-
className: e("flex h-screen w-full overflow-hidden bg-basalt-background", t),
|
|
16
|
+
className: e("flex h-screen w-full overflow-hidden overscroll-none bg-basalt-background", t),
|
|
17
17
|
...r
|
|
18
18
|
});
|
|
19
19
|
}
|
|
20
20
|
function a({ className: t, ...r }) {
|
|
21
21
|
return /* @__PURE__ */ n("main", {
|
|
22
22
|
id: "main-content",
|
|
23
|
-
className: e("flex h-full min-w-0 flex-1 flex-col overflow-hidden", t),
|
|
23
|
+
className: e("flex h-full min-h-0 min-w-0 flex-1 flex-col overflow-hidden", t),
|
|
24
24
|
...r
|
|
25
25
|
});
|
|
26
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-shell.js","names":[],"sources":["../../src/components/app-shell.tsx"],"sourcesContent":["import type { AnchorHTMLAttributes, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\nexport function AppSkipLink({\n\thref = \"#main-content\",\n\tclassName,\n\tchildren,\n\t...props\n}: AnchorHTMLAttributes<HTMLAnchorElement>) {\n\treturn (\n\t\t<a\n\t\t\thref={href}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:z-[100] focus:rounded-lg focus:bg-basalt-primary focus:px-4 focus:py-2 focus:text-sm focus:font-medium focus:text-basalt-primary-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</a>\n\t);\n}\n\nexport function AppShell({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\"flex h-screen w-full overflow-hidden bg-basalt-background\"
|
|
1
|
+
{"version":3,"file":"app-shell.js","names":[],"sources":["../../src/components/app-shell.tsx"],"sourcesContent":["import type { AnchorHTMLAttributes, HTMLAttributes } from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\nexport function AppSkipLink({\n\thref = \"#main-content\",\n\tclassName,\n\tchildren,\n\t...props\n}: AnchorHTMLAttributes<HTMLAnchorElement>) {\n\treturn (\n\t\t<a\n\t\t\thref={href}\n\t\t\tclassName={cn(\n\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\"sr-only focus:not-sr-only focus:absolute focus:top-2 focus:left-2 focus:z-[100] focus:rounded-lg focus:bg-basalt-primary focus:px-4 focus:py-2 focus:text-sm focus:font-medium focus:text-basalt-primary-foreground\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</a>\n\t);\n}\n\nexport function AppShell({ className, ...props }: HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t\"flex h-screen w-full overflow-hidden overscroll-none bg-basalt-background\",\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n\nexport function AppMain({ className, ...props }: HTMLAttributes<HTMLElement>) {\n\treturn (\n\t\t<main\n\t\t\tid=\"main-content\"\n\t\t\tclassName={cn(\"flex h-full min-h-0 min-w-0 flex-1 flex-col overflow-hidden\", className)}\n\t\t\t{...props}\n\t\t/>\n\t);\n}\n"],"mappings":";;;;;AAIA,SAAgB,EAAY,EAC3B,UAAO,iBACP,cACA,aACA,GAAG,KACwC;CAC3C,OACC,kBAAC,KAAD;EACO;EACN,WAAW,EACV,GACA,uNACA,CACD;EACA,GAAI;EAEH;CACC,CAAA;AAEL;AAEA,SAAgB,EAAS,EAAE,cAAW,GAAG,KAAyC;CACjF,OACC,kBAAC,OAAD;EACC,WAAW,EACV,6EACA,CACD;EACA,GAAI;CACJ,CAAA;AAEH;AAEA,SAAgB,EAAQ,EAAE,cAAW,GAAG,KAAsC;CAC7E,OACC,kBAAC,QAAD;EACC,IAAG;EACH,WAAW,EAAG,+DAA+D,CAAS;EACtF,GAAI;CACJ,CAAA;AAEH"}
|
|
@@ -48,4 +48,4 @@ export type AutocompleteProps = Omit<ComponentPropsWithoutRef<"div">, "children"
|
|
|
48
48
|
*/
|
|
49
49
|
size?: InputSize;
|
|
50
50
|
};
|
|
51
|
-
export declare function Autocomplete({
|
|
51
|
+
export declare function Autocomplete({ placeholder, ...rest }: AutocompleteProps): import("react").JSX.Element;
|
|
@@ -2,24 +2,11 @@
|
|
|
2
2
|
import { TypeaheadField as e } from "./typeahead-field.js";
|
|
3
3
|
import { jsx as t } from "react/jsx-runtime";
|
|
4
4
|
//#region src/components/autocomplete.tsx
|
|
5
|
-
function n({
|
|
5
|
+
function n({ placeholder: n = "Search…", ...r }) {
|
|
6
6
|
return /* @__PURE__ */ t(e, {
|
|
7
|
-
|
|
8
|
-
value: r,
|
|
9
|
-
defaultValue: i,
|
|
10
|
-
onValueChange: a,
|
|
11
|
-
name: o,
|
|
12
|
-
placeholder: s,
|
|
13
|
-
disabled: c,
|
|
14
|
-
loading: l,
|
|
15
|
-
size: u,
|
|
16
|
-
className: d,
|
|
17
|
-
id: f,
|
|
7
|
+
placeholder: n,
|
|
18
8
|
allowFreeform: !0,
|
|
19
|
-
|
|
20
|
-
"aria-describedby": m,
|
|
21
|
-
"aria-invalid": h,
|
|
22
|
-
...g
|
|
9
|
+
...r
|
|
23
10
|
});
|
|
24
11
|
}
|
|
25
12
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"autocomplete.js","names":[],"sources":["../../src/components/autocomplete.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef } from \"react\";\nimport type { InputSize } from \"./input\";\nimport { TypeaheadField, type TypeaheadItem } from \"./typeahead-field\";\n\nexport type AutocompleteItem = TypeaheadItem;\n\nexport type AutocompleteProps = Omit<\n\tComponentPropsWithoutRef<\"div\">,\n\t\"children\" | \"defaultValue\" | \"onChange\"\n> & {\n\t/**\n\t * Suggestions shown as the query matches. Values outside the list are allowed.\n\t *\n\t * Note: When focus leaves the field (via pointer click or Tab/Shift+Tab navigation),\n\t * any uncommitted text or matching suggestion is committed once without stealing focus\n\t * back to the input, allowing natural focus traversal.\n\t */\n\titems: AutocompleteItem[];\n\t/**\n\t * The controlled value.\n\t */\n\tvalue?: string;\n\t/**\n\t * The uncontrolled initial value.\n\t */\n\tdefaultValue?: string;\n\t/**\n\t * Called when the value changes, including freeform text.\n\t */\n\tonValueChange?: (value: string) => void;\n\t/**\n\t * Native form field name.\n\t */\n\tname?: string;\n\t/**\n\t * Placeholder shown when the field is empty.\n\t * @default Search…\n\t */\n\tplaceholder?: string;\n\t/**\n\t * Disable the field.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * Disable the field and mark it busy.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * The visual size of the field.\n\t * @default default\n\t */\n\tsize?: InputSize;\n};\n\nexport function Autocomplete({
|
|
1
|
+
{"version":3,"file":"autocomplete.js","names":[],"sources":["../../src/components/autocomplete.tsx"],"sourcesContent":["import type { ComponentPropsWithoutRef } from \"react\";\nimport type { InputSize } from \"./input\";\nimport { TypeaheadField, type TypeaheadItem } from \"./typeahead-field\";\n\nexport type AutocompleteItem = TypeaheadItem;\n\nexport type AutocompleteProps = Omit<\n\tComponentPropsWithoutRef<\"div\">,\n\t\"children\" | \"defaultValue\" | \"onChange\"\n> & {\n\t/**\n\t * Suggestions shown as the query matches. Values outside the list are allowed.\n\t *\n\t * Note: When focus leaves the field (via pointer click or Tab/Shift+Tab navigation),\n\t * any uncommitted text or matching suggestion is committed once without stealing focus\n\t * back to the input, allowing natural focus traversal.\n\t */\n\titems: AutocompleteItem[];\n\t/**\n\t * The controlled value.\n\t */\n\tvalue?: string;\n\t/**\n\t * The uncontrolled initial value.\n\t */\n\tdefaultValue?: string;\n\t/**\n\t * Called when the value changes, including freeform text.\n\t */\n\tonValueChange?: (value: string) => void;\n\t/**\n\t * Native form field name.\n\t */\n\tname?: string;\n\t/**\n\t * Placeholder shown when the field is empty.\n\t * @default Search…\n\t */\n\tplaceholder?: string;\n\t/**\n\t * Disable the field.\n\t * @default false\n\t */\n\tdisabled?: boolean;\n\t/**\n\t * Disable the field and mark it busy.\n\t * @default false\n\t */\n\tloading?: boolean;\n\t/**\n\t * The visual size of the field.\n\t * @default default\n\t */\n\tsize?: InputSize;\n};\n\nexport function Autocomplete({ placeholder = \"Search…\", ...rest }: AutocompleteProps) {\n\treturn <TypeaheadField placeholder={placeholder} allowFreeform {...rest} />;\n}\n"],"mappings":";;;;AAwDA,SAAgB,EAAa,EAAE,iBAAc,WAAW,GAAG,KAA2B;CACrF,OAAO,kBAAC,GAAD;EAA6B;EAAa,eAAA;EAAc,GAAI;CAAO,CAAA;AAC3E"}
|
package/dist/components/badge.js
CHANGED
|
@@ -11,14 +11,14 @@ var a = n("inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 te
|
|
|
11
11
|
destructive: "border-transparent bg-basalt-destructive text-basalt-destructive-foreground",
|
|
12
12
|
outline: "border-basalt-border text-basalt-foreground",
|
|
13
13
|
info: "border-transparent bg-basalt-info-tint text-basalt-info",
|
|
14
|
-
success: "border-transparent bg-basalt-heatmap-green-3 text-
|
|
14
|
+
success: "border-transparent bg-basalt-heatmap-green-3 text-white",
|
|
15
15
|
warning: "border-transparent bg-basalt-warning-tint text-basalt-warning",
|
|
16
16
|
error: "border-transparent bg-basalt-danger-tint text-basalt-danger",
|
|
17
|
-
red: "border-transparent bg-basalt-danger text-
|
|
18
|
-
orange: "border-transparent bg-basalt-warning text-
|
|
19
|
-
teal: "border-transparent bg-basalt-badge-teal text-
|
|
20
|
-
blue: "border-transparent bg-basalt-info text-
|
|
21
|
-
purple: "border-transparent bg-basalt-badge-purple text-
|
|
17
|
+
red: "border-transparent bg-basalt-danger text-white",
|
|
18
|
+
orange: "border-transparent bg-basalt-warning text-white",
|
|
19
|
+
teal: "border-transparent bg-basalt-badge-teal text-white",
|
|
20
|
+
blue: "border-transparent bg-basalt-info text-white",
|
|
21
|
+
purple: "border-transparent bg-basalt-badge-purple text-white"
|
|
22
22
|
} },
|
|
23
23
|
defaultVariants: { variant: "default" }
|
|
24
24
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"badge.js","names":[],"sources":["../../src/components/badge.tsx"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport type * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\nconst badgeVariants = cva(\n\t\"inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium\",\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: \"border-transparent bg-basalt-primary text-basalt-primary-foreground\",\n\t\t\t\tsecondary: \"border-transparent bg-basalt-secondary text-basalt-foreground\",\n\t\t\t\tdestructive: \"border-transparent bg-basalt-destructive text-basalt-destructive-foreground\",\n\t\t\t\toutline: \"border-basalt-border text-basalt-foreground\",\n\t\t\t\tinfo: \"border-transparent bg-basalt-info-tint text-basalt-info\",\n\t\t\t\tsuccess: \"border-transparent bg-basalt-heatmap-green-3 text-
|
|
1
|
+
{"version":3,"file":"badge.js","names":[],"sources":["../../src/components/badge.tsx"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport type * as React from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\n\nconst badgeVariants = cva(\n\t\"inline-flex items-center gap-1.5 rounded-full border px-2.5 py-0.5 text-xs font-medium\",\n\t{\n\t\tvariants: {\n\t\t\tvariant: {\n\t\t\t\tdefault: \"border-transparent bg-basalt-primary text-basalt-primary-foreground\",\n\t\t\t\tsecondary: \"border-transparent bg-basalt-secondary text-basalt-foreground\",\n\t\t\t\tdestructive: \"border-transparent bg-basalt-destructive text-basalt-destructive-foreground\",\n\t\t\t\toutline: \"border-basalt-border text-basalt-foreground\",\n\t\t\t\tinfo: \"border-transparent bg-basalt-info-tint text-basalt-info\",\n\t\t\t\tsuccess: \"border-transparent bg-basalt-heatmap-green-3 text-white\",\n\t\t\t\twarning: \"border-transparent bg-basalt-warning-tint text-basalt-warning\",\n\t\t\t\terror: \"border-transparent bg-basalt-danger-tint text-basalt-danger\",\n\t\t\t\tred: \"border-transparent bg-basalt-danger text-white\",\n\t\t\t\torange: \"border-transparent bg-basalt-warning text-white\",\n\t\t\t\tteal: \"border-transparent bg-basalt-badge-teal text-white\",\n\t\t\t\tblue: \"border-transparent bg-basalt-info text-white\",\n\t\t\t\tpurple: \"border-transparent bg-basalt-badge-purple text-white\",\n\t\t\t},\n\t\t},\n\t\tdefaultVariants: { variant: \"default\" },\n\t},\n);\n\nexport interface BadgeProps\n\textends React.HTMLAttributes<HTMLSpanElement>,\n\t\tOmit<VariantProps<typeof badgeVariants>, \"variant\"> {\n\t/**\n\t * Visual style variant for the badge.\n\t *\n\t * Note: Supports standard semantic tones and decorative color tokens.\n\t * Pass null to omit variant styling.\n\t *\n\t * @default \"default\"\n\t */\n\tvariant?: VariantProps<typeof badgeVariants>[\"variant\"];\n\n\t/**\n\t * Renders a small circular dot indicator before children.\n\t *\n\t * @default false\n\t */\n\tdot?: boolean;\n}\n\nexport function Badge({ className, variant, dot, children, ...props }: BadgeProps) {\n\treturn (\n\t\t<span className={cn(BASALT_UI_CLASS, badgeVariants({ variant }), className)} {...props}>\n\t\t\t{dot ? <span className=\"size-1.5 rounded-full bg-current\" aria-hidden=\"true\" /> : null}\n\t\t\t{children}\n\t\t</span>\n\t);\n}\n"],"mappings":";;;;;;AAKA,IAAM,IAAgB,EACrB,0FACA;CACC,UAAU,EACT,SAAS;EACR,SAAS;EACT,WAAW;EACX,aAAa;EACb,SAAS;EACT,MAAM;EACN,SAAS;EACT,SAAS;EACT,OAAO;EACP,KAAK;EACL,QAAQ;EACR,MAAM;EACN,MAAM;EACN,QAAQ;CACT,EACD;CACA,iBAAiB,EAAE,SAAS,UAAU;AACvC,CACD;AAuBA,SAAgB,EAAM,EAAE,cAAW,YAAS,QAAK,aAAU,GAAG,KAAqB;CAClF,OACC,kBAAC,QAAD;EAAM,WAAW,EAAG,GAAiB,EAAc,EAAE,WAAQ,CAAC,GAAG,CAAS;EAAG,GAAI;EAAjF,UAAA,CACE,IAAM,kBAAC,QAAD;GAAM,WAAU;GAAmC,eAAY;EAAQ,CAAA,IAAI,MACjF,CACI;;AAER"}
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import { cn as e } from "../utils/cn.js";
|
|
3
3
|
import { BASALT_UI_CLASS as t } from "../utils/control-surface.js";
|
|
4
4
|
import { Button as n } from "./button.js";
|
|
5
|
-
import { Children as r, createContext as i,
|
|
6
|
-
import { cva as
|
|
7
|
-
import { Fragment as
|
|
5
|
+
import { Children as r, createContext as i, isValidElement as a, useContext as o } from "react";
|
|
6
|
+
import { cva as s } from "class-variance-authority";
|
|
7
|
+
import { Fragment as c, jsx as l, jsxs as u } from "react/jsx-runtime";
|
|
8
8
|
//#region src/components/banner.tsx
|
|
9
|
-
var
|
|
9
|
+
var d = s("flex w-full items-start gap-3 rounded-basalt-md text-sm", {
|
|
10
10
|
variants: {
|
|
11
11
|
variant: {
|
|
12
12
|
default: "bg-basalt-info-tint text-basalt-info",
|
|
@@ -23,46 +23,46 @@ var u = o("flex w-full items-start gap-3 rounded-basalt-md text-sm", {
|
|
|
23
23
|
variant: "default",
|
|
24
24
|
size: "base"
|
|
25
25
|
}
|
|
26
|
-
}),
|
|
26
|
+
}), f = i({
|
|
27
27
|
variant: "default",
|
|
28
28
|
size: "base"
|
|
29
29
|
});
|
|
30
|
-
function
|
|
31
|
-
return
|
|
30
|
+
function p(e) {
|
|
31
|
+
return a(e) && e.type === h;
|
|
32
32
|
}
|
|
33
|
-
function
|
|
34
|
-
let v = i ?? "default", y = a ?? "base", b = o != null ||
|
|
35
|
-
return /* @__PURE__ */
|
|
33
|
+
function m({ className: n, variant: i = "default", size: a = "base", title: o, description: s, icon: m, action: h, children: g, ..._ }) {
|
|
34
|
+
let v = i ?? "default", y = a ?? "base", b = o != null || s != null, x = r.toArray(h), S = x.filter(p), C = x.filter((e) => !p(e)), w = y === "sm" ? S : [...C, ...S], T = y === "sm" ? C : [];
|
|
35
|
+
return /* @__PURE__ */ l(f.Provider, {
|
|
36
36
|
value: {
|
|
37
37
|
variant: v,
|
|
38
38
|
size: y
|
|
39
39
|
},
|
|
40
|
-
children: /* @__PURE__ */
|
|
41
|
-
className: e(t,
|
|
40
|
+
children: /* @__PURE__ */ u("div", {
|
|
41
|
+
className: e(t, d({
|
|
42
42
|
variant: v,
|
|
43
43
|
size: y
|
|
44
44
|
}), n),
|
|
45
45
|
..._,
|
|
46
46
|
children: [
|
|
47
|
-
m ? /* @__PURE__ */
|
|
47
|
+
m ? /* @__PURE__ */ l("span", {
|
|
48
48
|
className: "mt-0.5 inline-flex shrink-0 [&_svg]:size-5",
|
|
49
49
|
children: m
|
|
50
50
|
}) : null,
|
|
51
|
-
/* @__PURE__ */
|
|
51
|
+
/* @__PURE__ */ u("div", {
|
|
52
52
|
className: "min-w-0 flex-1 space-y-0.5",
|
|
53
53
|
children: [
|
|
54
|
-
o ? /* @__PURE__ */
|
|
54
|
+
o ? /* @__PURE__ */ l("p", {
|
|
55
55
|
className: "font-medium",
|
|
56
56
|
children: o
|
|
57
57
|
}) : null,
|
|
58
|
-
|
|
58
|
+
s ? /* @__PURE__ */ u("div", {
|
|
59
59
|
className: e(v === "secondary" ? "text-basalt-muted-foreground" : "text-current"),
|
|
60
|
-
children: [
|
|
61
|
-
}) : T.length > 0 ? /* @__PURE__ */
|
|
60
|
+
children: [s, T.length > 0 ? /* @__PURE__ */ u(c, { children: [" ", T] }) : null]
|
|
61
|
+
}) : T.length > 0 ? /* @__PURE__ */ l("div", { children: T }) : null,
|
|
62
62
|
b ? null : g
|
|
63
63
|
]
|
|
64
64
|
}),
|
|
65
|
-
w.length > 0 ? /* @__PURE__ */
|
|
65
|
+
w.length > 0 ? /* @__PURE__ */ l("div", {
|
|
66
66
|
className: "flex shrink-0 items-center gap-2",
|
|
67
67
|
children: w
|
|
68
68
|
}) : null
|
|
@@ -70,20 +70,20 @@ function p({ className: n, variant: i = "default", size: a = "base", title: o, d
|
|
|
70
70
|
})
|
|
71
71
|
});
|
|
72
72
|
}
|
|
73
|
-
function
|
|
74
|
-
let u =
|
|
75
|
-
return /* @__PURE__ */
|
|
76
|
-
variant:
|
|
73
|
+
function h({ className: t, variant: r = "default", size: i, icon: a, children: s, ...c }) {
|
|
74
|
+
let u = o(f), d = r === "ghost" ? "ghost" : r === "secondary" ? "secondary" : u.variant === "error" ? "destructive" : "default", p = s == null || s === "";
|
|
75
|
+
return /* @__PURE__ */ l(n, {
|
|
76
|
+
variant: d,
|
|
77
77
|
size: i ?? (p ? "icon" : u.size === "sm" ? "sm" : "default"),
|
|
78
|
-
icon:
|
|
78
|
+
icon: a,
|
|
79
79
|
className: e(p && "size-8", t),
|
|
80
|
-
...
|
|
80
|
+
...c,
|
|
81
81
|
children: s
|
|
82
82
|
});
|
|
83
83
|
}
|
|
84
|
-
|
|
85
|
-
var
|
|
84
|
+
h.displayName = "Banner.Action";
|
|
85
|
+
var g = Object.assign(m, { Action: h });
|
|
86
86
|
//#endregion
|
|
87
|
-
export {
|
|
87
|
+
export { g as Banner, h as BannerAction };
|
|
88
88
|
|
|
89
89
|
//# sourceMappingURL=banner.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"banner.js","names":[],"sources":["../../src/components/banner.tsx"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport {
|
|
1
|
+
{"version":3,"file":"banner.js","names":[],"sources":["../../src/components/banner.tsx"],"sourcesContent":["import { cva, type VariantProps } from \"class-variance-authority\";\nimport {\n\tChildren,\n\tcreateContext,\n\ttype HTMLAttributes,\n\tisValidElement,\n\ttype ReactNode,\n\tuseContext,\n} from \"react\";\nimport { cn } from \"../utils/cn\";\nimport { BASALT_UI_CLASS } from \"../utils/control-surface\";\nimport { Button, type ButtonProps } from \"./button\";\n\nconst bannerVariants = cva(\"flex w-full items-start gap-3 rounded-basalt-md text-sm\", {\n\tvariants: {\n\t\tvariant: {\n\t\t\tdefault: \"bg-basalt-info-tint text-basalt-info\",\n\t\t\talert: \"bg-basalt-warning-tint text-basalt-warning\",\n\t\t\terror: \"bg-basalt-danger-tint text-basalt-danger\",\n\t\t\tsecondary: \"bg-basalt-muted text-basalt-foreground\",\n\t\t},\n\t\tsize: {\n\t\t\tbase: \"px-4 py-3\",\n\t\t\tsm: \"px-3 py-2\",\n\t\t},\n\t},\n\tdefaultVariants: { variant: \"default\", size: \"base\" },\n});\n\ntype BannerVariant = NonNullable<VariantProps<typeof bannerVariants>[\"variant\"]>;\ntype BannerSize = NonNullable<VariantProps<typeof bannerVariants>[\"size\"]>;\n\nconst BannerContext = createContext<{ variant: BannerVariant; size: BannerSize }>({\n\tvariant: \"default\",\n\tsize: \"base\",\n});\n\nexport interface BannerProps\n\textends Omit<HTMLAttributes<HTMLDivElement>, \"title\" | \"children\">,\n\t\tOmit<VariantProps<typeof bannerVariants>, \"variant\" | \"size\"> {\n\t/**\n\t * Visual tone variant of the banner.\n\t *\n\t * Note: Defaults to \"default\" (informational). Passing null falls back to \"default\".\n\t *\n\t * @default \"default\"\n\t */\n\tvariant?: VariantProps<typeof bannerVariants>[\"variant\"];\n\n\t/**\n\t * Sizing preset controlling padding geometry and action placement.\n\t *\n\t * Note: Defaults to \"base\". In compact mode (\"sm\"), only direct `<Banner.Action>` elements\n\t * are placed in the trailing slot, while other action content renders inline next to the description.\n\t * Passing null falls back to \"base\".\n\t *\n\t * @default \"base\"\n\t */\n\tsize?: VariantProps<typeof bannerVariants>[\"size\"];\n\n\t/**\n\t * Primary heading text.\n\t *\n\t * Note: When present (or when description is present), structured mode is enabled\n\t * and standard children are not rendered.\n\t */\n\ttitle?: string;\n\n\t/**\n\t * Secondary copy rendered below the title.\n\t */\n\tdescription?: ReactNode;\n\n\t/**\n\t * Visual icon rendered before the banner content.\n\t */\n\ticon?: ReactNode;\n\n\t/**\n\t * Trailing or inline call-to-action slot.\n\t * Pass `<Banner.Action>` elements for contextual styling.\n\t * In compact mode (\"sm\"), only direct `<Banner.Action>` elements are placed in the trailing slot,\n\t * while other action content renders inline next to the description.\n\t */\n\taction?: ReactNode;\n\n\t/**\n\t * Unstructured child content rendered only when both title and description are null or undefined.\n\t * When title or description is non-null/non-undefined (including empty string or false),\n\t * structured mode is active and children are ignored.\n\t */\n\tchildren?: HTMLAttributes<HTMLDivElement>[\"children\"];\n}\n\nexport interface BannerActionProps\n\textends Omit<\n\t\tButtonProps,\n\t\t\"variant\" | \"size\" | \"asChild\" | \"type\" | \"loading\" | \"icon\" | \"children\"\n\t> {\n\t/**\n\t * Visual style variant. Preserves \"ghost\" and \"secondary\"; all other values\n\t * are mapped contextually to \"destructive\" (when parent Banner variant is \"error\")\n\t * or \"default\".\n\t *\n\t * Note: Ordinary function component without forwarded ref.\n\t *\n\t * @default \"default\"\n\t */\n\tvariant?: ButtonProps[\"variant\"];\n\n\t/**\n\t * Sizing preset. When unspecified or null, resolves to \"icon\" if children are omitted,\n\t * null, or an empty string, \"sm\" when parent Banner is compact (\"sm\"), or \"default\" otherwise.\n\t * When iconOnly mode is resolved, an additional \"size-8\" class is attached.\n\t */\n\tsize?: ButtonProps[\"size\"];\n\n\t/**\n\t * Pass control to child element slot.\n\t *\n\t * @default false\n\t */\n\tasChild?: ButtonProps[\"asChild\"];\n\n\t/**\n\t * Button type attribute.\n\t *\n\t * @default \"button\"\n\t */\n\ttype?: ButtonProps[\"type\"];\n\n\t/**\n\t * Display loading spinner and disable interactions.\n\t *\n\t * @default false\n\t */\n\tloading?: ButtonProps[\"loading\"];\n\n\t/**\n\t * Optional leading icon slot.\n\t */\n\ticon?: ButtonProps[\"icon\"];\n\n\t/**\n\t * Action label content. When null, undefined, or empty string, enables iconOnly sizing mode.\n\t */\n\tchildren?: ButtonProps[\"children\"];\n}\n\nfunction isBannerAction(node: ReactNode): boolean {\n\treturn isValidElement(node) && node.type === BannerAction;\n}\n\nfunction BannerRoot({\n\tclassName,\n\tvariant = \"default\",\n\tsize = \"base\",\n\ttitle,\n\tdescription,\n\ticon,\n\taction,\n\tchildren,\n\t...props\n}: BannerProps) {\n\tconst resolvedVariant = variant ?? \"default\";\n\tconst resolvedSize = size ?? \"base\";\n\tconst structured = title != null || description != null;\n\tconst nodes = Children.toArray(action);\n\tconst ctas = nodes.filter(isBannerAction);\n\tconst other = nodes.filter((node) => !isBannerAction(node));\n\tconst trailing = resolvedSize === \"sm\" ? ctas : [...other, ...ctas];\n\tconst inlineActions = resolvedSize === \"sm\" ? other : [];\n\n\treturn (\n\t\t<BannerContext.Provider value={{ variant: resolvedVariant, size: resolvedSize }}>\n\t\t\t<div\n\t\t\t\tclassName={cn(\n\t\t\t\t\tBASALT_UI_CLASS,\n\t\t\t\t\tbannerVariants({ variant: resolvedVariant, size: resolvedSize }),\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{icon ? <span className=\"mt-0.5 inline-flex shrink-0 [&_svg]:size-5\">{icon}</span> : null}\n\t\t\t\t<div className=\"min-w-0 flex-1 space-y-0.5\">\n\t\t\t\t\t{title ? <p className=\"font-medium\">{title}</p> : null}\n\t\t\t\t\t{description ? (\n\t\t\t\t\t\t<div\n\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\tresolvedVariant === \"secondary\" ? \"text-basalt-muted-foreground\" : \"text-current\",\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t{description}\n\t\t\t\t\t\t\t{inlineActions.length > 0 ? <> {inlineActions}</> : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : inlineActions.length > 0 ? (\n\t\t\t\t\t\t<div>{inlineActions}</div>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{structured ? null : children}\n\t\t\t\t</div>\n\t\t\t\t{trailing.length > 0 ? (\n\t\t\t\t\t<div className=\"flex shrink-0 items-center gap-2\">{trailing}</div>\n\t\t\t\t) : null}\n\t\t\t</div>\n\t\t</BannerContext.Provider>\n\t);\n}\n\nexport function BannerAction({\n\tclassName,\n\tvariant = \"default\",\n\tsize,\n\ticon,\n\tchildren,\n\t...props\n}: BannerActionProps) {\n\tconst banner = useContext(BannerContext);\n\tconst mapped =\n\t\tvariant === \"ghost\"\n\t\t\t? \"ghost\"\n\t\t\t: variant === \"secondary\"\n\t\t\t\t? \"secondary\"\n\t\t\t\t: banner.variant === \"error\"\n\t\t\t\t\t? \"destructive\"\n\t\t\t\t\t: \"default\";\n\tconst iconOnly = children == null || children === \"\";\n\treturn (\n\t\t<Button\n\t\t\tvariant={mapped}\n\t\t\tsize={size ?? (iconOnly ? \"icon\" : banner.size === \"sm\" ? \"sm\" : \"default\")}\n\t\t\ticon={icon}\n\t\t\tclassName={cn(iconOnly && \"size-8\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{children}\n\t\t</Button>\n\t);\n}\nBannerAction.displayName = \"Banner.Action\";\n\nexport const Banner = Object.assign(BannerRoot, { Action: BannerAction });\n"],"mappings":";;;;;;;;AAaA,IAAM,IAAiB,EAAI,2DAA2D;CACrF,UAAU;EACT,SAAS;GACR,SAAS;GACT,OAAO;GACP,OAAO;GACP,WAAW;EACZ;EACA,MAAM;GACL,MAAM;GACN,IAAI;EACL;CACD;CACA,iBAAiB;EAAE,SAAS;EAAW,MAAM;CAAO;AACrD,CAAC,GAKK,IAAgB,EAA4D;CACjF,SAAS;CACT,MAAM;AACP,CAAC;AAkHD,SAAS,EAAe,GAA0B;CACjD,OAAO,EAAe,CAAI,KAAK,EAAK,SAAS;AAC9C;AAEA,SAAS,EAAW,EACnB,cACA,aAAU,WACV,UAAO,QACP,UACA,gBACA,SACA,WACA,aACA,GAAG,KACY;CACf,IAAM,IAAkB,KAAW,WAC7B,IAAe,KAAQ,QACvB,IAAa,KAAS,QAAQ,KAAe,MAC7C,IAAQ,EAAS,QAAQ,CAAM,GAC/B,IAAO,EAAM,OAAO,CAAc,GAClC,IAAQ,EAAM,QAAQ,MAAS,CAAC,EAAe,CAAI,CAAC,GACpD,IAAW,MAAiB,OAAO,IAAO,CAAC,GAAG,GAAO,GAAG,CAAI,GAC5D,IAAgB,MAAiB,OAAO,IAAQ,CAAC;CAEvD,OACC,kBAAC,EAAc,UAAf;EAAwB,OAAO;GAAE,SAAS;GAAiB,MAAM;EAAa;EAC7E,UAAA,kBAAC,OAAD;GACC,WAAW,EACV,GACA,EAAe;IAAE,SAAS;IAAiB,MAAM;GAAa,CAAC,GAC/D,CACD;GACA,GAAI;GANL,UAAA;IAQE,IAAO,kBAAC,QAAD;KAAM,WAAU;KAA8C,UAAA;IAAW,CAAA,IAAI;IACrF,kBAAC,OAAD;KAAK,WAAU;KAAf,UAAA;MACE,IAAQ,kBAAC,KAAD;OAAG,WAAU;OAAe,UAAA;MAAS,CAAA,IAAI;MACjD,IACA,kBAAC,OAAD;OACC,WAAW,EACV,MAAoB,cAAc,iCAAiC,cACpE;OAHD,UAAA,CAKE,GACA,EAAc,SAAS,IAAI,kBAAA,GAAA,EAAA,UAAA,CAAE,KAAE,CAAgB,EAAA,CAAA,IAAI,IAChD;MACF,CAAA,IAAA,EAAc,SAAS,IAC1B,kBAAC,OAAD,EAAA,UAAM,EAAmB,CAAA,IACtB;MACH,IAAa,OAAO;KACjB;;IACJ,EAAS,SAAS,IAClB,kBAAC,OAAD;KAAK,WAAU;KAAoC,UAAA;IAAc,CAAA,IAC9D;GACA;;CACkB,CAAA;AAE1B;AAEA,SAAgB,EAAa,EAC5B,cACA,aAAU,WACV,SACA,SACA,aACA,GAAG,KACkB;CACrB,IAAM,IAAS,EAAW,CAAa,GACjC,IACL,MAAY,UACT,UACA,MAAY,cACX,cACA,EAAO,YAAY,UAClB,gBACA,WACA,IAAW,KAAY,QAAQ,MAAa;CAClD,OACC,kBAAC,GAAD;EACC,SAAS;EACT,MAAM,MAAS,IAAW,SAAS,EAAO,SAAS,OAAO,OAAO;EAC3D;EACN,WAAW,EAAG,KAAY,UAAU,CAAS;EAC7C,GAAI;EAEH;CACM,CAAA;AAEV;AACA,EAAa,cAAc;AAE3B,IAAa,IAAS,OAAO,OAAO,GAAY,EAAE,QAAQ,EAAa,CAAC"}
|
|
@@ -36,7 +36,7 @@ var l = a(`${t} inline-flex items-center justify-center gap-2 rounded-basalt-md
|
|
|
36
36
|
let o = m, c = typeof o.type == "string" && o.type.toLowerCase() === "button", u = (e) => {
|
|
37
37
|
e.preventDefault(), e.stopPropagation(), "stopImmediatePropagation" in e && typeof e.stopImmediatePropagation == "function" && e.stopImmediatePropagation();
|
|
38
38
|
}, d = (e) => {
|
|
39
|
-
e.key === "Enter" || e.key === " " || e.key === "Spacebar"
|
|
39
|
+
(e.key === "Enter" || e.key === " " || e.key === "Spacebar") && e.preventDefault(), e.stopPropagation(), typeof e.nativeEvent?.stopImmediatePropagation == "function" && e.nativeEvent.stopImmediatePropagation();
|
|
40
40
|
}, p = {
|
|
41
41
|
onClick: u,
|
|
42
42
|
onClickCapture: u,
|
|
@@ -56,28 +56,27 @@ var l = a(`${t} inline-flex items-center justify-center gap-2 rounded-basalt-md
|
|
|
56
56
|
onPointerUpCapture: u,
|
|
57
57
|
onAuxClick: u,
|
|
58
58
|
onAuxClickCapture: u
|
|
59
|
-
},
|
|
60
|
-
...v,
|
|
59
|
+
}, h = r.cloneElement(o, {
|
|
61
60
|
...p,
|
|
62
61
|
...c ? { disabled: !0 } : {},
|
|
63
62
|
"aria-disabled": !0,
|
|
64
63
|
"aria-busy": f ? !0 : void 0,
|
|
65
64
|
tabIndex: -1
|
|
66
|
-
}),
|
|
65
|
+
}), v = {
|
|
67
66
|
...g,
|
|
68
67
|
...p,
|
|
69
68
|
"aria-disabled": !0,
|
|
70
69
|
"aria-busy": f ? "true" : void 0,
|
|
71
70
|
tabIndex: -1
|
|
72
71
|
};
|
|
73
|
-
return c && (
|
|
72
|
+
return c && (v.disabled = !0), /* @__PURE__ */ s(i, {
|
|
74
73
|
className: e(l({
|
|
75
74
|
variant: n,
|
|
76
75
|
size: a
|
|
77
76
|
}), t),
|
|
78
77
|
ref: _,
|
|
79
|
-
...
|
|
80
|
-
children:
|
|
78
|
+
...v,
|
|
79
|
+
children: h
|
|
81
80
|
});
|
|
82
81
|
}
|
|
83
82
|
return /* @__PURE__ */ s(i, {
|