@archetypeai/ds-ui-svelte-labs 0.7.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.
Files changed (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +120 -0
  3. package/dist/primitives/aspect-ratio/aspect-ratio.svelte +8 -0
  4. package/dist/primitives/aspect-ratio/aspect-ratio.svelte.d.ts +4 -0
  5. package/dist/primitives/aspect-ratio/index.d.ts +4 -0
  6. package/dist/primitives/aspect-ratio/index.js +6 -0
  7. package/dist/primitives/aspect-ratio/types.d.ts +2 -0
  8. package/dist/primitives/aspect-ratio/types.js +1 -0
  9. package/dist/primitives/chart/chart-container.svelte +36 -0
  10. package/dist/primitives/chart/chart-container.svelte.d.ts +4 -0
  11. package/dist/primitives/chart/chart-style.svelte +37 -0
  12. package/dist/primitives/chart/chart-style.svelte.d.ts +8 -0
  13. package/dist/primitives/chart/chart-tooltip.svelte +136 -0
  14. package/dist/primitives/chart/chart-tooltip.svelte.d.ts +4 -0
  15. package/dist/primitives/chart/chart-utils.d.ts +45 -0
  16. package/dist/primitives/chart/chart-utils.js +52 -0
  17. package/dist/primitives/chart/index.d.ts +7 -0
  18. package/dist/primitives/chart/index.js +7 -0
  19. package/dist/primitives/chart/scatter-tooltip.svelte +40 -0
  20. package/dist/primitives/chart/scatter-tooltip.svelte.d.ts +4 -0
  21. package/dist/primitives/chart/types.d.ts +33 -0
  22. package/dist/primitives/chart/types.js +45 -0
  23. package/dist/primitives/kbd/index.d.ts +5 -0
  24. package/dist/primitives/kbd/index.js +7 -0
  25. package/dist/primitives/kbd/kbd-group.svelte +10 -0
  26. package/dist/primitives/kbd/kbd-group.svelte.d.ts +4 -0
  27. package/dist/primitives/kbd/kbd.svelte +10 -0
  28. package/dist/primitives/kbd/kbd.svelte.d.ts +4 -0
  29. package/dist/primitives/kbd/types.d.ts +6 -0
  30. package/dist/primitives/kbd/types.js +8 -0
  31. package/dist/primitives/logo/index.d.ts +4 -0
  32. package/dist/primitives/logo/index.js +6 -0
  33. package/dist/primitives/logo/logo.svelte +22 -0
  34. package/dist/primitives/logo/logo.svelte.d.ts +4 -0
  35. package/dist/primitives/logo/types.d.ts +25 -0
  36. package/dist/primitives/logo/types.js +14 -0
  37. package/dist/primitives/menubar/index.d.ts +4 -0
  38. package/dist/primitives/menubar/index.js +6 -0
  39. package/dist/primitives/menubar/menubar.svelte +67 -0
  40. package/dist/primitives/menubar/menubar.svelte.d.ts +4 -0
  41. package/dist/primitives/menubar/types.d.ts +10 -0
  42. package/dist/primitives/menubar/types.js +5 -0
  43. package/dist/primitives/scatter-chart/index.d.ts +4 -0
  44. package/dist/primitives/scatter-chart/index.js +6 -0
  45. package/dist/primitives/scatter-chart/scatter-chart.svelte +147 -0
  46. package/dist/primitives/scatter-chart/scatter-chart.svelte.d.ts +5 -0
  47. package/dist/primitives/scatter-chart/types.d.ts +34 -0
  48. package/dist/primitives/scatter-chart/types.js +6 -0
  49. package/dist/primitives/sensor-chart/index.d.ts +4 -0
  50. package/dist/primitives/sensor-chart/index.js +6 -0
  51. package/dist/primitives/sensor-chart/sensor-chart.svelte +138 -0
  52. package/dist/primitives/sensor-chart/sensor-chart.svelte.d.ts +4 -0
  53. package/dist/primitives/sensor-chart/types.d.ts +27 -0
  54. package/dist/primitives/sensor-chart/types.js +6 -0
  55. package/dist/primitives/slider/index.d.ts +4 -0
  56. package/dist/primitives/slider/index.js +6 -0
  57. package/dist/primitives/slider/slider.svelte +47 -0
  58. package/dist/primitives/slider/slider.svelte.d.ts +4 -0
  59. package/dist/primitives/slider/types.d.ts +7 -0
  60. package/dist/primitives/slider/types.js +14 -0
  61. package/dist/primitives/switch/index.d.ts +4 -0
  62. package/dist/primitives/switch/index.js +6 -0
  63. package/dist/primitives/switch/switch.svelte +28 -0
  64. package/dist/primitives/switch/switch.svelte.d.ts +4 -0
  65. package/dist/primitives/switch/types.d.ts +45 -0
  66. package/dist/primitives/switch/types.js +27 -0
  67. package/dist/primitives/toggle/index.d.ts +4 -0
  68. package/dist/primitives/toggle/index.js +6 -0
  69. package/dist/primitives/toggle/toggle.svelte +24 -0
  70. package/dist/primitives/toggle/toggle.svelte.d.ts +4 -0
  71. package/dist/primitives/toggle/types.d.ts +39 -0
  72. package/dist/primitives/toggle/types.js +19 -0
  73. package/dist/primitives/utils.d.ts +4 -0
  74. package/dist/primitives/utils.js +29 -0
  75. package/dist/primitives/video-player/index.d.ts +4 -0
  76. package/dist/primitives/video-player/index.js +6 -0
  77. package/dist/primitives/video-player/types.d.ts +49 -0
  78. package/dist/primitives/video-player/types.js +32 -0
  79. package/dist/primitives/video-player/video-player.svelte +139 -0
  80. package/dist/primitives/video-player/video-player.svelte.d.ts +4 -0
  81. package/package.json +127 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Archetype AI
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,120 @@
1
+ # @archetypeai/ds-ui-svelte-labs
2
+
3
+ Labs primitives of the Archetype AI design system - the **experimental 0.x tier** built on top of the frozen [`@archetypeai/ds-ui-svelte-console`](./DS-UI-SVELTE-CONSOLE.md) base. Svelte 5 primitives styled with Tailwind v4 and `tailwind-variants`, wired to the `@archetypeai/ds-lib-tokens` theme, composing console primitives (Button, Card, Badge) where they need stable building blocks. TypeScript source ships as `.svelte` files (no precompilation) so consumers get full type-checking and IDE go-to-definition.
4
+
5
+ Labs is versioned 0.x: breaking changes are in-contract between minor versions. Components that prove themselves graduate toward console; console itself never changes to accommodate labs.
6
+
7
+ Like console, the labs flavor ships two ways from the same source:
8
+
9
+ - **npm package** (this document's default) - how apps **consume** primitives: they stay in `node_modules`, imported per-subpath, updated by version bump. The package is the source of truth.
10
+ - **shadcn-svelte registry** - how primitives get **modified or extended**: pull a primitive's editable source into your app, change it, then port the change back into the package.
11
+
12
+ ## Install
13
+
14
+ ```sh
15
+ npm i @archetypeai/ds-ui-svelte-labs @archetypeai/ds-ui-svelte-console
16
+ ```
17
+
18
+ Then install the peer dependencies shared by all subpaths:
19
+
20
+ ```sh
21
+ npm i svelte tailwindcss bits-ui tailwind-variants tailwind-merge clsx @lucide/svelte @archetypeai/ds-lib-tokens
22
+ ```
23
+
24
+ ### Per-subpath peer dependencies
25
+
26
+ The chart-family subpaths additionally require heavy visualization peers that the other subpaths never load (they are declared as optional peers, so npm does not auto-install them):
27
+
28
+ | Subpath | Extra peers |
29
+ |---|---|
30
+ | `primitives/chart` | `layerchart` |
31
+ | `primitives/scatter-chart` | `layerchart`, `d3-scale` |
32
+ | `primitives/sensor-chart` | `layerchart`, `d3-scale`, `d3-shape` |
33
+
34
+ ```sh
35
+ npm i layerchart@2.0.0-next.46 d3-scale d3-shape
36
+ ```
37
+
38
+ `layerchart` is pinned to an exact 2.0 pre-release - prerelease versions break APIs between builds, so install the pinned version (labs is 0.x - churn here is in-contract).
39
+
40
+ ## Tailwind v4 setup (mandatory)
41
+
42
+ Tailwind v4 does not scan `node_modules` by default. Without the `@source` directives below, every class in this package is purged at consumer build time and components render unstyled.
43
+
44
+ In your consumer's `app.css`, in this order:
45
+
46
+ ```css
47
+ @import 'tailwindcss';
48
+ @import '@archetypeai/ds-lib-tokens/theme.css';
49
+ @source "../node_modules/@archetypeai/ds-ui-svelte-console/dist";
50
+ @source "../node_modules/@archetypeai/ds-ui-svelte-labs/dist";
51
+ ```
52
+
53
+ Order matters:
54
+
55
+ - `tailwindcss` registers the engine.
56
+ - `@archetypeai/ds-lib-tokens/theme.css` declares the CSS variables that component classes consume.
57
+ - The two `@source` directives make Tailwind scan both packages - labs components compose console primitives, so both dists must be scanned.
58
+
59
+ Adjust the `@source` paths if your `app.css` lives elsewhere - they must resolve to each package's `dist/` directory.
60
+
61
+ ## TypeScript setup
62
+
63
+ In your consumer's `tsconfig.json` (or `jsconfig.json`), set:
64
+
65
+ ```jsonc
66
+ {
67
+ "compilerOptions": {
68
+ "moduleResolution": "bundler"
69
+ }
70
+ }
71
+ ```
72
+
73
+ `"node16"` and `"nodenext"` also work. Without one of these, the `types` condition in this package's `exports` map is bypassed, types fall back to the `default` JS file, and editor features degrade.
74
+
75
+ ## Usage
76
+
77
+ Each primitive lives at its own subpath. There is no barrel `import { Logo } from '@archetypeai/ds-ui-svelte-labs'` - subpaths keep `layerchart` and the d3 packages out of bundles for consumers who never touch the chart primitives.
78
+
79
+ ```svelte
80
+ <script lang="ts">
81
+ import Logo from '@archetypeai/ds-ui-svelte-labs/primitives/logo'
82
+ import Menubar from '@archetypeai/ds-ui-svelte-labs/primitives/menubar'
83
+ import Slider from '@archetypeai/ds-ui-svelte-labs/primitives/slider'
84
+
85
+ let volume = $state(50)
86
+ </script>
87
+
88
+ <Menubar />
89
+ <Logo size="lg" />
90
+ <Slider type="single" bind:value={volume} max={100} />
91
+ ```
92
+
93
+ ## Per-primitive subpaths
94
+
95
+ | Primitive | Import path |
96
+ |---|---|
97
+ | AspectRatio | `@archetypeai/ds-ui-svelte-labs/primitives/aspect-ratio` |
98
+ | Chart | `@archetypeai/ds-ui-svelte-labs/primitives/chart` |
99
+ | Kbd | `@archetypeai/ds-ui-svelte-labs/primitives/kbd` |
100
+ | Logo | `@archetypeai/ds-ui-svelte-labs/primitives/logo` |
101
+ | Menubar | `@archetypeai/ds-ui-svelte-labs/primitives/menubar` |
102
+ | ScatterChart | `@archetypeai/ds-ui-svelte-labs/primitives/scatter-chart` |
103
+ | SensorChart | `@archetypeai/ds-ui-svelte-labs/primitives/sensor-chart` |
104
+ | Slider | `@archetypeai/ds-ui-svelte-labs/primitives/slider` |
105
+ | Switch | `@archetypeai/ds-ui-svelte-labs/primitives/switch` |
106
+ | Toggle | `@archetypeai/ds-ui-svelte-labs/primitives/toggle` |
107
+ | VideoPlayer | `@archetypeai/ds-ui-svelte-labs/primitives/video-player` |
108
+
109
+ Class-merging and element-ref type helpers re-export from console at `@archetypeai/ds-ui-svelte-labs/primitives/utils` (a single `cn`/`twMerge` instance exists in the tree), alongside the labs domain helpers (`healthTier`, `formatMMSS`, `clamp`).
110
+
111
+ ## Extending console primitives
112
+
113
+ Labs adapts console primitives without ever changing console, using this escape-hatch ladder (in order):
114
+
115
+ 1. `class` prop overrides on the console component
116
+ 2. `data-slot` attribute selectors in consumer CSS
117
+ 3. `tv({ extend })` on console's exported variant clusters
118
+ 4. (rare) a labs wrapper component
119
+
120
+ This document is the source for the package README (copied by `prepack`); the full design-system docs live in the repository's [readme](https://github.com/archetypeai/design-system).
@@ -0,0 +1,8 @@
1
+ <script lang="ts">
2
+ import { AspectRatio as AspectRatioPrimitive } from 'bits-ui';
3
+ import type { AspectRatioProps } from './types.js';
4
+
5
+ let { ref = $bindable(null), ...restProps }: AspectRatioProps = $props();
6
+ </script>
7
+
8
+ <AspectRatioPrimitive.Root bind:ref data-slot="aspect-ratio" {...restProps} />
@@ -0,0 +1,4 @@
1
+ import { AspectRatio as AspectRatioPrimitive } from 'bits-ui';
2
+ declare const AspectRatio: import("svelte").Component<AspectRatioPrimitive.RootProps, {}, "ref">;
3
+ type AspectRatio = ReturnType<typeof AspectRatio>;
4
+ export default AspectRatio;
@@ -0,0 +1,4 @@
1
+ import Root from './aspect-ratio.svelte';
2
+ export { type AspectRatioProps } from './types.js';
3
+ export { Root, Root as AspectRatio };
4
+ export default Root;
@@ -0,0 +1,6 @@
1
+ import Root from './aspect-ratio.svelte';
2
+ export {} from './types.js';
3
+ export { Root,
4
+ //
5
+ Root as AspectRatio };
6
+ export default Root;
@@ -0,0 +1,2 @@
1
+ import type { AspectRatio as AspectRatioPrimitive } from 'bits-ui';
2
+ export type AspectRatioProps = AspectRatioPrimitive.RootProps;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,36 @@
1
+ <script lang="ts">
2
+ import { cn } from '../utils.js';
3
+ import ChartStyle from './chart-style.svelte';
4
+ import { setChartContext } from './chart-utils.js';
5
+ import { chartContainerVariants, type ChartContainerProps } from './types.js';
6
+
7
+ const uid = $props.id();
8
+
9
+ let {
10
+ ref = $bindable(null),
11
+ id = uid,
12
+ class: className,
13
+ children,
14
+ config,
15
+ ...restProps
16
+ }: ChartContainerProps = $props();
17
+
18
+ let chartId = $derived(`chart-${id || uid.replace(/:/g, '')}`);
19
+
20
+ setChartContext({
21
+ get config() {
22
+ return config;
23
+ }
24
+ });
25
+ </script>
26
+
27
+ <div
28
+ bind:this={ref}
29
+ data-chart={chartId}
30
+ data-slot="chart"
31
+ class={cn(chartContainerVariants(), className)}
32
+ {...restProps}
33
+ >
34
+ <ChartStyle id={chartId} {config} />
35
+ {@render children?.()}
36
+ </div>
@@ -0,0 +1,4 @@
1
+ import { type ChartContainerProps } from './types.js';
2
+ declare const ChartContainer: import("svelte").Component<ChartContainerProps, {}, "ref">;
3
+ type ChartContainer = ReturnType<typeof ChartContainer>;
4
+ export default ChartContainer;
@@ -0,0 +1,37 @@
1
+ <script lang="ts">
2
+ import { THEMES, type ChartConfig } from './chart-utils.js';
3
+
4
+ let { id, config }: { id: string; config: ChartConfig } = $props();
5
+
6
+ const colorConfig = $derived(
7
+ config ? Object.entries(config).filter(([, config]) => config.theme || config.color) : null
8
+ );
9
+
10
+ const themeContents = $derived.by(() => {
11
+ if (!colorConfig || !colorConfig.length) return;
12
+
13
+ const themeContents = [];
14
+ for (let [_theme, prefix] of Object.entries(THEMES)) {
15
+ let content = `${prefix} [data-chart=${id}] {\n`;
16
+ const color = colorConfig.map(([key, itemConfig]) => {
17
+ const theme = _theme as keyof typeof itemConfig.theme;
18
+ const color = itemConfig.theme?.[theme] || itemConfig.color;
19
+ return color ? `\t--color-${key}: ${color};` : null;
20
+ });
21
+
22
+ content += color.join('\n') + '\n}';
23
+
24
+ themeContents.push(content);
25
+ }
26
+
27
+ return themeContents.join('\n');
28
+ });
29
+ </script>
30
+
31
+ {#if themeContents}
32
+ {#key id}
33
+ <svelte:element this={'style'}>
34
+ {themeContents}
35
+ </svelte:element>
36
+ {/key}
37
+ {/if}
@@ -0,0 +1,8 @@
1
+ import { type ChartConfig } from './chart-utils.js';
2
+ type $$ComponentProps = {
3
+ id: string;
4
+ config: ChartConfig;
5
+ };
6
+ declare const ChartStyle: import("svelte").Component<$$ComponentProps, {}, "">;
7
+ type ChartStyle = ReturnType<typeof ChartStyle>;
8
+ export default ChartStyle;
@@ -0,0 +1,136 @@
1
+ <script lang="ts">
2
+ import { cn } from '../utils.js';
3
+ import {
4
+ getPayloadConfigFromPayload,
5
+ getChartContext,
6
+ type TooltipPayload
7
+ } from './chart-utils.js';
8
+ import { chartTooltipVariants, type ChartTooltipProps } from './types.js';
9
+ import { getTooltipContext, Tooltip as TooltipPrimitive } from 'layerchart';
10
+
11
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
12
+ function defaultFormatter(value: any, _payload: TooltipPayload[]) {
13
+ return `${value}`;
14
+ }
15
+
16
+ let {
17
+ ref = $bindable(null),
18
+ class: className,
19
+ hideLabel = false,
20
+ indicator = 'dot',
21
+ hideIndicator = false,
22
+ labelKey,
23
+ label,
24
+ labelFormatter = defaultFormatter,
25
+ labelClassName,
26
+ formatter,
27
+ nameKey,
28
+ color,
29
+ ...restProps
30
+ }: ChartTooltipProps = $props();
31
+
32
+ const chart = getChartContext();
33
+ const tooltipCtx = getTooltipContext();
34
+
35
+ const formattedLabel = $derived.by(() => {
36
+ if (hideLabel || !tooltipCtx.payload?.length) return null;
37
+
38
+ const [item] = tooltipCtx.payload;
39
+ const key = labelKey ?? item?.label ?? item?.name ?? 'value';
40
+
41
+ const itemConfig = getPayloadConfigFromPayload(chart.config, item, key);
42
+
43
+ const value =
44
+ !labelKey && typeof label === 'string'
45
+ ? (chart.config[label]?.label ?? label)
46
+ : (itemConfig?.label ?? item.label);
47
+
48
+ if (value === undefined) return null;
49
+ if (!labelFormatter) return value;
50
+ return labelFormatter(value, tooltipCtx.payload);
51
+ });
52
+
53
+ const nestLabel = $derived(tooltipCtx.payload.length === 1 && indicator !== 'dot');
54
+ </script>
55
+
56
+ {#snippet TooltipLabel()}
57
+ {#if formattedLabel}
58
+ <div class={cn('font-medium', labelClassName)}>
59
+ {#if typeof formattedLabel === 'function'}
60
+ {@render formattedLabel()}
61
+ {:else}
62
+ {formattedLabel}
63
+ {/if}
64
+ </div>
65
+ {/if}
66
+ {/snippet}
67
+
68
+ <TooltipPrimitive.Root variant="none">
69
+ <div
70
+ bind:this={ref}
71
+ data-slot="chart-tooltip"
72
+ class={cn(chartTooltipVariants(), className)}
73
+ {...restProps}
74
+ >
75
+ {#if !nestLabel}
76
+ {@render TooltipLabel()}
77
+ {/if}
78
+ <div class="grid gap-1.5">
79
+ {#each tooltipCtx.payload as item, i (item.key + i)}
80
+ {@const key = `${nameKey || item.key || item.name || 'value'}`}
81
+ {@const itemConfig = getPayloadConfigFromPayload(chart.config, item, key)}
82
+ {@const indicatorColor = color || item.payload?.color || item.color}
83
+ <div
84
+ class={cn(
85
+ '[&>svg]:text-muted-foreground flex w-full flex-wrap items-stretch gap-2 [&>svg]:size-2.5',
86
+ indicator === 'dot' && 'items-center'
87
+ )}
88
+ >
89
+ {#if formatter && item.value !== undefined && item.name}
90
+ {@render formatter({
91
+ value: item.value,
92
+ name: item.name,
93
+ item,
94
+ index: i,
95
+ payload: tooltipCtx.payload
96
+ })}
97
+ {:else}
98
+ {#if itemConfig?.icon}
99
+ <itemConfig.icon />
100
+ {:else if !hideIndicator}
101
+ <div
102
+ style="--color-bg: {indicatorColor}; --color-border: {indicatorColor};"
103
+ class={cn('border-border shrink-0 rounded-[2px] bg-(--color-bg)', {
104
+ 'size-2.5': indicator === 'dot',
105
+ 'h-full w-1': indicator === 'line',
106
+ 'w-0 border-[1.5px] border-dashed bg-transparent': indicator === 'dashed',
107
+ 'my-0.5': nestLabel && indicator === 'dashed'
108
+ })}
109
+ ></div>
110
+ {/if}
111
+ <div
112
+ class={cn(
113
+ 'flex flex-1 shrink-0 justify-between leading-none',
114
+ nestLabel ? 'items-end' : 'items-center'
115
+ )}
116
+ >
117
+ <div class="grid gap-1.5">
118
+ {#if nestLabel}
119
+ {@render TooltipLabel()}
120
+ {/if}
121
+ <span class="text-muted-foreground">
122
+ {itemConfig?.label || item.name}
123
+ </span>
124
+ </div>
125
+ {#if item.value !== undefined}
126
+ <span class="text-foreground font-mono font-medium tabular-nums">
127
+ {item.value.toLocaleString()}
128
+ </span>
129
+ {/if}
130
+ </div>
131
+ {/if}
132
+ </div>
133
+ {/each}
134
+ </div>
135
+ </div>
136
+ </TooltipPrimitive.Root>
@@ -0,0 +1,4 @@
1
+ import { type ChartTooltipProps } from './types.js';
2
+ declare const ChartTooltip: import("svelte").Component<ChartTooltipProps, {}, "ref">;
3
+ type ChartTooltip = ReturnType<typeof ChartTooltip>;
4
+ export default ChartTooltip;
@@ -0,0 +1,45 @@
1
+ import type { Tooltip } from 'layerchart';
2
+ import { type Component, type ComponentProps, type Snippet } from 'svelte';
3
+ export declare const THEMES: {
4
+ readonly light: "";
5
+ readonly dark: ".dark";
6
+ };
7
+ export declare const CHART_COLORS: readonly ["var(--chart-1)", "var(--chart-2)", "var(--chart-3)", "var(--chart-4)", "var(--chart-5)"];
8
+ export type ChartConfig = {
9
+ [k in string]: {
10
+ label?: string;
11
+ icon?: Component;
12
+ } & ({
13
+ color?: string;
14
+ theme?: never;
15
+ } | {
16
+ color?: never;
17
+ theme: Record<keyof typeof THEMES, string>;
18
+ });
19
+ };
20
+ export type ChartSeries = {
21
+ key: string;
22
+ label?: string;
23
+ color?: string;
24
+ };
25
+ export type ChartAxis = 'both' | 'x' | 'y' | 'none';
26
+ export type ExtractSnippetParams<T> = T extends Snippet<[infer P]> ? P : never;
27
+ export type TooltipPayload = ExtractSnippetParams<ComponentProps<typeof Tooltip.Root>['children']>['payload'][number];
28
+ export declare function getPayloadConfigFromPayload(config: ChartConfig, payload: TooltipPayload, key: string): ({
29
+ label?: string;
30
+ icon?: Component;
31
+ } & ({
32
+ color?: string;
33
+ theme?: never;
34
+ } | {
35
+ color?: never;
36
+ theme: Record<keyof typeof THEMES, string>;
37
+ })) | undefined;
38
+ type ChartContextValue = {
39
+ config: ChartConfig;
40
+ };
41
+ export declare function setChartContext(value: ChartContextValue): ChartContextValue;
42
+ export declare function getChartContext(): ChartContextValue;
43
+ export declare function buildChartConfig(series: ChartSeries[]): ChartConfig;
44
+ export declare function slidingWindow<T>(data: T[], maxPoints?: number): T[];
45
+ export {};
@@ -0,0 +1,52 @@
1
+ import { getContext, setContext } from 'svelte';
2
+ // constants: themes for chart colors
3
+ export const THEMES = { light: '', dark: '.dark' };
4
+ // constants: chart colors
5
+ export const CHART_COLORS = [
6
+ 'var(--chart-1)',
7
+ 'var(--chart-2)',
8
+ 'var(--chart-3)',
9
+ 'var(--chart-4)',
10
+ 'var(--chart-5)'
11
+ ];
12
+ // utility: extracts item config from payload
13
+ export function getPayloadConfigFromPayload(config, payload, key) {
14
+ if (typeof payload !== 'object' || payload === null)
15
+ return undefined;
16
+ const payloadPayload = 'payload' in payload && typeof payload.payload === 'object' && payload.payload !== null
17
+ ? payload.payload
18
+ : undefined;
19
+ let configLabelKey = key;
20
+ if (payload.key === key) {
21
+ configLabelKey = payload.key;
22
+ }
23
+ else if (payload.name === key) {
24
+ configLabelKey = payload.name;
25
+ }
26
+ else if (key in payload && typeof payload[key] === 'string') {
27
+ configLabelKey = payload[key];
28
+ }
29
+ else if (payloadPayload !== undefined &&
30
+ key in payloadPayload &&
31
+ typeof payloadPayload[key] === 'string') {
32
+ configLabelKey = payloadPayload[key];
33
+ }
34
+ return configLabelKey in config ? config[configLabelKey] : config[key];
35
+ }
36
+ const chartContextKey = Symbol('chart-context');
37
+ // utility: sets chart context
38
+ export function setChartContext(value) {
39
+ return setContext(chartContextKey, value);
40
+ }
41
+ // utility: gets chart context
42
+ export function getChartContext() {
43
+ return getContext(chartContextKey);
44
+ }
45
+ // utility: builds chart config
46
+ export function buildChartConfig(series) {
47
+ return Object.fromEntries(series.map((s) => [s.key, { label: s.label, color: s.color }]));
48
+ }
49
+ // utility: creates a sliding window of data
50
+ export function slidingWindow(data, maxPoints) {
51
+ return maxPoints && data.length > maxPoints ? data.slice(-maxPoints) : data;
52
+ }
@@ -0,0 +1,7 @@
1
+ import ChartContainer from './chart-container.svelte';
2
+ import ChartTooltip from './chart-tooltip.svelte';
3
+ import ScatterTooltip from './scatter-tooltip.svelte';
4
+ export { getPayloadConfigFromPayload, type ChartAxis, type ChartConfig, type ChartSeries, type TooltipPayload } from './chart-utils.js';
5
+ export { chartContainerVariants, chartTooltipVariants, scatterTooltipVariants, type ChartContainerProps, type ChartTooltipIndicator, type ChartTooltipProps, type ScatterTooltipProps } from './types.js';
6
+ export { ChartContainer, ChartTooltip, ScatterTooltip, ChartContainer as Container, ChartTooltip as Tooltip };
7
+ export default ChartContainer;
@@ -0,0 +1,7 @@
1
+ import ChartContainer from './chart-container.svelte';
2
+ import ChartTooltip from './chart-tooltip.svelte';
3
+ import ScatterTooltip from './scatter-tooltip.svelte';
4
+ export { getPayloadConfigFromPayload } from './chart-utils.js';
5
+ export { chartContainerVariants, chartTooltipVariants, scatterTooltipVariants } from './types.js';
6
+ export { ChartContainer, ChartTooltip, ScatterTooltip, ChartContainer as Container, ChartTooltip as Tooltip };
7
+ export default ChartContainer;
@@ -0,0 +1,40 @@
1
+ <script lang="ts">
2
+ import { cn } from '../utils.js';
3
+ import { scatterTooltipVariants, type ScatterTooltipProps } from './types.js';
4
+ import { getTooltipContext, Tooltip } from 'layerchart';
5
+
6
+ let { class: className }: ScatterTooltipProps = $props();
7
+
8
+ const tooltipCtx = getTooltipContext();
9
+
10
+ // layerchart can provide data in different ways depending on chart type
11
+ const point = $derived.by(() => {
12
+ // try direct data property first
13
+ if (tooltipCtx.data?.x !== undefined) return tooltipCtx.data;
14
+ // try payload array (like other charts use)
15
+ if (tooltipCtx.payload?.[0]?.payload) return tooltipCtx.payload[0].payload;
16
+ if (tooltipCtx.payload?.[0]) return tooltipCtx.payload[0];
17
+ return null;
18
+ });
19
+ </script>
20
+
21
+ <Tooltip.Root variant="none">
22
+ <div data-slot="scatter-tooltip" class={cn(scatterTooltipVariants(), className)}>
23
+ {#if point}
24
+ <div class="flex items-center justify-between gap-4">
25
+ <span class="text-muted-foreground">x</span>
26
+ <span class="text-foreground font-mono font-medium tabular-nums"
27
+ >{point.x?.toFixed(3) ?? '–'}</span
28
+ >
29
+ </div>
30
+ <div class="flex items-center justify-between gap-4">
31
+ <span class="text-muted-foreground">y</span>
32
+ <span class="text-foreground font-mono font-medium tabular-nums"
33
+ >{point.y?.toFixed(3) ?? '–'}</span
34
+ >
35
+ </div>
36
+ {:else}
37
+ <span class="text-muted-foreground">no data</span>
38
+ {/if}
39
+ </div>
40
+ </Tooltip.Root>
@@ -0,0 +1,4 @@
1
+ import { type ScatterTooltipProps } from './types.js';
2
+ declare const ScatterTooltip: import("svelte").Component<ScatterTooltipProps, {}, "">;
3
+ type ScatterTooltip = ReturnType<typeof ScatterTooltip>;
4
+ export default ScatterTooltip;
@@ -0,0 +1,33 @@
1
+ import { type WithElementRef, type WithoutChildren } from '../utils.js';
2
+ import type { Snippet } from 'svelte';
3
+ import type { HTMLAttributes } from 'svelte/elements';
4
+ import type { ChartConfig, TooltipPayload } from './chart-utils.js';
5
+ export declare const chartContainerVariants: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, string[], {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, string[], unknown, unknown, undefined>>;
6
+ export declare const chartTooltipVariants: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "border-border/50 bg-background grid min-w-36 items-start gap-1.5 rounded-xs border px-2.5 py-1.5 text-xs shadow-xl", {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "border-border/50 bg-background grid min-w-36 items-start gap-1.5 rounded-xs border px-2.5 py-1.5 text-xs shadow-xl", unknown, unknown, undefined>>;
7
+ export declare const scatterTooltipVariants: import("tailwind-variants").TVReturnType<{} | {} | {}, undefined, "border-border/50 bg-background grid min-w-32 items-start gap-1.5 rounded-xs border px-2.5 py-1.5 text-xs shadow-xl", {} | {}, undefined, import("tailwind-variants").TVReturnType<unknown, undefined, "border-border/50 bg-background grid min-w-32 items-start gap-1.5 rounded-xs border px-2.5 py-1.5 text-xs shadow-xl", unknown, unknown, undefined>>;
8
+ export type ChartContainerProps = WithElementRef<HTMLAttributes<HTMLElement>> & {
9
+ config: ChartConfig;
10
+ };
11
+ export type ChartTooltipIndicator = 'line' | 'dot' | 'dashed';
12
+ export type ChartTooltipProps = WithoutChildren<WithElementRef<HTMLAttributes<HTMLDivElement>>> & {
13
+ hideLabel?: boolean;
14
+ label?: string;
15
+ indicator?: ChartTooltipIndicator;
16
+ nameKey?: string;
17
+ labelKey?: string;
18
+ hideIndicator?: boolean;
19
+ labelClassName?: string;
20
+ labelFormatter?: ((value: any, payload: TooltipPayload[]) => string | number | Snippet) | null;
21
+ formatter?: Snippet<[
22
+ {
23
+ value: unknown;
24
+ name: string;
25
+ item: TooltipPayload;
26
+ index: number;
27
+ payload: TooltipPayload[];
28
+ }
29
+ ]>;
30
+ };
31
+ export type ScatterTooltipProps = {
32
+ class?: string;
33
+ };
@@ -0,0 +1,45 @@
1
+ import {} from '../utils.js';
2
+ import { tv } from 'tailwind-variants';
3
+ export const chartContainerVariants = tv({
4
+ base: [
5
+ 'flex aspect-video justify-center overflow-visible text-xs',
6
+ // Overrides
7
+ //
8
+ // Stroke around dots/marks when hovering
9
+ '[&_.lc-highlight-point]:stroke-transparent',
10
+ // override the default stroke color of lines
11
+ '[&_.lc-line]:stroke-border/50',
12
+ // by default, layerchart shows a line intersecting the point when hovering, this hides that
13
+ '[&_.lc-highlight-line]:stroke-0',
14
+ // by default, when you hover a point on a stacked series chart, it will drop the opacity
15
+ // of the other series, this overrides that
16
+ '[&_.lc-area-path]:opacity-100 [&_.lc-highlight-line]:opacity-100 [&_.lc-highlight-point]:opacity-100 [&_.lc-spline-path]:opacity-100 [&_.lc-text]:text-xs [&_.lc-text-svg]:overflow-visible',
17
+ // We don't want the little tick lines between the axis labels and the chart, so we remove
18
+ // the stroke. The alternative is to manually disable `tickMarks` on the x/y axis of every
19
+ // chart.
20
+ '[&_.lc-axis-tick]:stroke-0',
21
+ // We don't want to display the rule on the x/y axis, as there is already going to be
22
+ // a grid line there and rule ends up overlapping the marks because it is rendered after
23
+ // the marks
24
+ '[&_.lc-rule-x-line:not(.lc-grid-x-rule)]:stroke-0 [&_.lc-rule-y-line:not(.lc-grid-y-rule)]:stroke-0',
25
+ '[&_.lc-grid-x-radial-line]:stroke-border [&_.lc-grid-x-radial-circle]:stroke-border',
26
+ '[&_.lc-grid-y-radial-line]:stroke-border [&_.lc-grid-y-radial-circle]:stroke-border',
27
+ // Legend adjustments
28
+ '[&_.lc-legend-swatch-button]:items-center [&_.lc-legend-swatch-button]:gap-1.5',
29
+ '[&_.lc-legend-swatch-group]:items-center [&_.lc-legend-swatch-group]:gap-4',
30
+ '[&_.lc-legend-swatch]:size-2.5 [&_.lc-legend-swatch]:rounded-[2px]',
31
+ // Labels
32
+ '[&_.lc-labels-text:not([fill])]:fill-foreground [&_text]:stroke-transparent',
33
+ // Tick labels on th x/y axes
34
+ '[&_.lc-axis-tick-label]:fill-muted-foreground [&_.lc-axis-tick-label]:font-normal',
35
+ '[&_.lc-tooltip-rects-g]:fill-transparent',
36
+ '[&_.lc-layout-svg-g]:fill-transparent',
37
+ '[&_.lc-root-container]:w-full'
38
+ ]
39
+ });
40
+ export const chartTooltipVariants = tv({
41
+ base: 'border-border/50 bg-background grid min-w-36 items-start gap-1.5 rounded-xs border px-2.5 py-1.5 text-xs shadow-xl'
42
+ });
43
+ export const scatterTooltipVariants = tv({
44
+ base: 'border-border/50 bg-background grid min-w-32 items-start gap-1.5 rounded-xs border px-2.5 py-1.5 text-xs shadow-xl'
45
+ });
@@ -0,0 +1,5 @@
1
+ import Root from './kbd.svelte';
2
+ import Group from './kbd-group.svelte';
3
+ export { kbdVariants, kbdGroupVariants, type KbdProps, type KbdGroupProps } from './types.js';
4
+ export { Root, Group, Root as Kbd, Group as KbdGroup };
5
+ export default Root;