@classic-homes/charts-svelte 0.1.38 → 0.3.0

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 (66) hide show
  1. package/dist/lib/components/base/ChartContainer.svelte +175 -9
  2. package/dist/lib/components/base/ChartContainer.svelte.d.ts +26 -0
  3. package/dist/lib/components/base/ChartDataTable.svelte +59 -0
  4. package/dist/lib/components/base/ChartDataTable.svelte.d.ts +15 -0
  5. package/dist/lib/components/base/ChartEmpty.svelte +1 -0
  6. package/dist/lib/components/base/ChartLegend.svelte +59 -0
  7. package/dist/lib/components/base/ChartLegend.svelte.d.ts +10 -0
  8. package/dist/lib/components/base/ChartSkeleton.svelte +7 -2
  9. package/dist/lib/components/base/ChartSkeleton.svelte.d.ts +2 -0
  10. package/dist/lib/components/base/index.d.ts +6 -0
  11. package/dist/lib/components/base/index.js +2 -0
  12. package/dist/lib/components/core/AreaChart.svelte +204 -92
  13. package/dist/lib/components/core/AreaChart.svelte.d.ts +2 -1
  14. package/dist/lib/components/core/BarChart.svelte +202 -74
  15. package/dist/lib/components/core/BarChart.svelte.d.ts +2 -1
  16. package/dist/lib/components/core/DonutChart.svelte +189 -100
  17. package/dist/lib/components/core/DonutChart.svelte.d.ts +2 -1
  18. package/dist/lib/components/core/LineChart.svelte +195 -97
  19. package/dist/lib/components/core/LineChart.svelte.d.ts +2 -1
  20. package/dist/lib/components/core/PieChart.svelte +137 -56
  21. package/dist/lib/components/core/PieChart.svelte.d.ts +2 -1
  22. package/dist/lib/components/core/ScatterChart.svelte +167 -95
  23. package/dist/lib/components/core/ScatterChart.svelte.d.ts +2 -1
  24. package/dist/lib/components/extended/CandlestickChart.svelte +106 -61
  25. package/dist/lib/components/extended/FunnelChart.svelte +139 -56
  26. package/dist/lib/components/extended/FunnelChart.svelte.d.ts +2 -1
  27. package/dist/lib/components/extended/GaugeChart.svelte +111 -39
  28. package/dist/lib/components/extended/HeatmapChart.svelte +107 -58
  29. package/dist/lib/components/extended/RadarChart.svelte +111 -37
  30. package/dist/lib/components/extended/RadarChart.svelte.d.ts +2 -1
  31. package/dist/lib/components/extended/SankeyChart.svelte +99 -40
  32. package/dist/lib/components/extended/TreemapChart.svelte +118 -45
  33. package/dist/lib/components/index.d.ts +2 -1
  34. package/dist/lib/components/index.js +3 -1
  35. package/dist/lib/components/report/BoxPlotChart.svelte +253 -0
  36. package/dist/lib/components/report/BoxPlotChart.svelte.d.ts +7 -0
  37. package/dist/lib/components/report/BulletChart.svelte +231 -0
  38. package/dist/lib/components/report/BulletChart.svelte.d.ts +7 -0
  39. package/dist/lib/components/report/ComboChart.svelte +327 -0
  40. package/dist/lib/components/report/ComboChart.svelte.d.ts +8 -0
  41. package/dist/lib/components/report/DotPlotChart.svelte +325 -0
  42. package/dist/lib/components/report/DotPlotChart.svelte.d.ts +8 -0
  43. package/dist/lib/components/report/HistogramChart.svelte +226 -0
  44. package/dist/lib/components/report/HistogramChart.svelte.d.ts +7 -0
  45. package/dist/lib/components/report/Sparkline.svelte +181 -0
  46. package/dist/lib/components/report/Sparkline.svelte.d.ts +4 -0
  47. package/dist/lib/components/report/StatCard.svelte +146 -0
  48. package/dist/lib/components/report/StatCard.svelte.d.ts +4 -0
  49. package/dist/lib/components/report/StatGroup.svelte +35 -0
  50. package/dist/lib/components/report/StatGroup.svelte.d.ts +12 -0
  51. package/dist/lib/components/report/WaterfallChart.svelte +271 -0
  52. package/dist/lib/components/report/WaterfallChart.svelte.d.ts +7 -0
  53. package/dist/lib/components/report/index.d.ts +12 -0
  54. package/dist/lib/components/report/index.js +9 -0
  55. package/dist/lib/composables/index.d.ts +2 -1
  56. package/dist/lib/composables/index.js +2 -1
  57. package/dist/lib/composables/useChart.svelte.d.ts +34 -0
  58. package/dist/lib/composables/useChart.svelte.js +121 -9
  59. package/dist/lib/composables/useChartLegend.svelte.d.ts +37 -0
  60. package/dist/lib/composables/useChartLegend.svelte.js +54 -0
  61. package/dist/lib/composables/useChartTheme.svelte.js +14 -11
  62. package/dist/lib/events.d.ts +15 -0
  63. package/dist/lib/events.js +56 -0
  64. package/dist/lib/index.d.ts +4 -3
  65. package/dist/lib/index.js +7 -3
  66. package/package.json +10 -4
@@ -1,14 +1,31 @@
1
1
  <script lang="ts">
2
2
  import type { Snippet } from 'svelte';
3
+ import {
4
+ chartFilename,
5
+ downloadCsv,
6
+ downloadFile,
7
+ type ChartDataTable as ChartDataTableData,
8
+ type ChartExportConfig,
9
+ type ChartLegendPosition,
10
+ } from '@classic-homes/charts-core';
3
11
  import { cn } from '../../utils.js';
4
12
  import ChartSkeleton from './ChartSkeleton.svelte';
5
13
  import ChartError from './ChartError.svelte';
6
14
  import ChartEmpty from './ChartEmpty.svelte';
15
+ import ChartDataTable from './ChartDataTable.svelte';
7
16
 
8
17
  interface Props {
9
18
  title: string;
10
19
  description?: string;
11
20
  height?: number | string;
21
+ /** Minimum height in pixels */
22
+ minHeight?: number;
23
+ /** Maximum height in pixels */
24
+ maxHeight?: number;
25
+ /**
26
+ * Loading. With no data yet this shows a skeleton; over an existing chart
27
+ * it dims the chart instead, keeping its zoom and legend state.
28
+ */
12
29
  loading?: boolean;
13
30
  error?: string | null;
14
31
  empty?: boolean;
@@ -16,6 +33,23 @@
16
33
  onRetry?: () => void;
17
34
  class?: string;
18
35
  wrapperClass?: string;
36
+ /**
37
+ * Custom legend, rendered beside the chart rather than inside the
38
+ * `role="img"` element so its controls stay accessible
39
+ */
40
+ legend?: Snippet;
41
+ /** Where the custom legend sits (defaults to 'bottom') */
42
+ legendPosition?: ChartLegendPosition;
43
+ /** The chart's data as a table, for screen readers, "Show data" and CSV export */
44
+ dataTable?: ChartDataTableData;
45
+ /** 'sr-only' renders the table for screen readers, true adds a visible toggle */
46
+ showDataTable?: boolean | 'sr-only';
47
+ /** Formats values in the data table */
48
+ format?: (value: number) => string;
49
+ /** Show download buttons */
50
+ exportable?: boolean | ChartExportConfig;
51
+ /** Renders the chart to an image data URL, for the PNG download */
52
+ exportImage?: () => string | null;
19
53
  children: Snippet;
20
54
  }
21
55
 
@@ -23,6 +57,8 @@
23
57
  title,
24
58
  description,
25
59
  height = 400,
60
+ minHeight,
61
+ maxHeight,
26
62
  loading,
27
63
  error,
28
64
  empty,
@@ -30,6 +66,13 @@
30
66
  onRetry,
31
67
  class: className,
32
68
  wrapperClass,
69
+ legend,
70
+ legendPosition = 'bottom',
71
+ dataTable,
72
+ showDataTable = 'sr-only',
73
+ format,
74
+ exportable,
75
+ exportImage,
33
76
  children,
34
77
  }: Props = $props();
35
78
 
@@ -38,27 +81,150 @@
38
81
 
39
82
  const heightStyle = $derived(typeof height === 'number' ? `${height}px` : height);
40
83
  const descriptionId = $derived(description ? `${uid}-desc` : undefined);
84
+ const tableId = `${uid}-table`;
85
+
86
+ // The legend's DOM order follows its visual position
87
+ const side = $derived(legendPosition === 'left' || legendPosition === 'right');
88
+ const leading = $derived(legendPosition === 'top' || legendPosition === 'left');
89
+
90
+ const exportConfig = $derived<ChartExportConfig | undefined>(
91
+ exportable ? (exportable === true ? {} : exportable) : undefined
92
+ );
93
+ const canExportImage = $derived(!!exportConfig && exportConfig.image !== false && !!exportImage);
94
+ const canExportCsv = $derived(!!exportConfig && exportConfig.csv !== false && !!dataTable);
95
+ const filename = $derived(exportConfig?.filename ?? chartFilename(title));
96
+
97
+ // A hidden table of thousands of rows (a dense scatter or heatmap) costs
98
+ // more than it helps; "Show data" and CSV export still offer the data
99
+ const SR_TABLE_MAX_ROWS = 500;
100
+
101
+ let tableOpen = $state(false);
102
+ const toggleTable = $derived(showDataTable === true && !!dataTable);
103
+ const toolbar = $derived(canExportImage || canExportCsv || toggleTable);
104
+ const framed = $derived(!!legend || toolbar);
105
+
106
+ function downloadImage() {
107
+ const url = exportImage?.();
108
+ if (url) downloadFile(url, `${filename}.png`);
109
+ }
110
+
111
+ function downloadData() {
112
+ if (dataTable) downloadCsv(dataTable, filename);
113
+ }
114
+
115
+ const buttonClass =
116
+ 'rounded-md px-2 py-1 text-xs font-medium text-muted-foreground hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring';
41
117
  </script>
42
118
 
43
- {#if loading}
44
- <ChartSkeleton {height} class={wrapperClass} />
45
- {:else if error}
46
- <ChartError message={error} {height} {onRetry} class={wrapperClass} />
47
- {:else if empty}
48
- <ChartEmpty message={emptyMessage} {height} class={wrapperClass} />
49
- {:else}
119
+ {#snippet chart(chartClass: string)}
50
120
  <div
51
121
  role="img"
52
122
  aria-label={title}
53
123
  aria-describedby={descriptionId}
124
+ aria-busy={loading || undefined}
54
125
  data-testid="chart-container"
55
- class={cn('rounded-lg border border-border bg-card', wrapperClass)}
126
+ class={cn('relative', chartClass)}
56
127
  >
57
128
  {#if description}
58
129
  <span id={descriptionId} class="sr-only">{description}</span>
59
130
  {/if}
60
- <div class={cn('h-full w-full', className)} style:height={heightStyle}>
131
+ <div
132
+ class={cn('h-full w-full', className)}
133
+ style:height={heightStyle}
134
+ style:min-height={minHeight !== undefined ? `${minHeight}px` : undefined}
135
+ style:max-height={maxHeight !== undefined ? `${maxHeight}px` : undefined}
136
+ >
61
137
  {@render children()}
62
138
  </div>
139
+ {#if loading}
140
+ <div
141
+ data-testid="chart-loading-overlay"
142
+ class="absolute inset-0 flex items-center justify-center rounded-lg bg-card/60"
143
+ >
144
+ <span
145
+ class="h-6 w-6 animate-spin rounded-full border-2 border-muted-foreground/30 border-t-muted-foreground motion-reduce:animate-none"
146
+ ></span>
147
+ </div>
148
+ {/if}
149
+ </div>
150
+ {/snippet}
151
+
152
+ {#snippet legendArea(content: Snippet)}
153
+ <div
154
+ data-testid="chart-legend"
155
+ class={cn('flex shrink-0 p-2', side ? 'items-center' : 'justify-center')}
156
+ >
157
+ {@render content()}
158
+ </div>
159
+ {/snippet}
160
+
161
+ {#snippet srTable()}
162
+ {#if dataTable && showDataTable === 'sr-only' && dataTable.rows.length <= SR_TABLE_MAX_ROWS}
163
+ <ChartDataTable table={dataTable} caption={`${title} data`} {format} srOnly />
164
+ {/if}
165
+ {/snippet}
166
+
167
+ {#if loading && empty}
168
+ <ChartSkeleton {height} label={`Loading ${title}`} class={wrapperClass} />
169
+ {:else if error}
170
+ <ChartError message={error} {height} {onRetry} class={wrapperClass} />
171
+ {:else if empty}
172
+ <ChartEmpty message={emptyMessage} {height} class={wrapperClass} />
173
+ {:else if framed}
174
+ <div
175
+ data-testid="chart-frame"
176
+ class={cn('flex flex-col rounded-lg border border-border bg-card', wrapperClass)}
177
+ >
178
+ {#if toolbar}
179
+ <div data-testid="chart-toolbar" class="flex justify-end gap-1 px-2 pt-2 print:hidden">
180
+ {#if toggleTable}
181
+ <button
182
+ type="button"
183
+ class={buttonClass}
184
+ aria-expanded={tableOpen}
185
+ aria-controls={tableId}
186
+ onclick={() => (tableOpen = !tableOpen)}
187
+ >
188
+ {tableOpen ? 'Hide data' : 'Show data'}
189
+ </button>
190
+ {/if}
191
+ {#if canExportImage}
192
+ <button
193
+ type="button"
194
+ class={buttonClass}
195
+ aria-label={`Download ${title} as PNG`}
196
+ onclick={downloadImage}
197
+ >
198
+ PNG
199
+ </button>
200
+ {/if}
201
+ {#if canExportCsv}
202
+ <button
203
+ type="button"
204
+ class={buttonClass}
205
+ aria-label={`Download ${title} data as CSV`}
206
+ onclick={downloadData}
207
+ >
208
+ CSV
209
+ </button>
210
+ {/if}
211
+ </div>
212
+ {/if}
213
+ <div class={cn('flex min-h-0 flex-1', side ? 'flex-row' : 'flex-col')}>
214
+ {#if legend && leading}{@render legendArea(legend)}{/if}
215
+ {@render chart('min-h-0 min-w-0 flex-1')}
216
+ {#if legend && !leading}{@render legendArea(legend)}{/if}
217
+ </div>
218
+ {#if toggleTable && dataTable}
219
+ <div id={tableId} hidden={!tableOpen} class="border-t border-border p-2">
220
+ {#if tableOpen}
221
+ <ChartDataTable table={dataTable} caption={`${title} data`} {format} />
222
+ {/if}
223
+ </div>
224
+ {/if}
225
+ {@render srTable()}
63
226
  </div>
227
+ {:else}
228
+ {@render chart(cn('rounded-lg border border-border bg-card', wrapperClass))}
229
+ {@render srTable()}
64
230
  {/if}
@@ -1,8 +1,17 @@
1
1
  import type { Snippet } from 'svelte';
2
+ import { type ChartDataTable as ChartDataTableData, type ChartExportConfig, type ChartLegendPosition } from '@classic-homes/charts-core';
2
3
  interface Props {
3
4
  title: string;
4
5
  description?: string;
5
6
  height?: number | string;
7
+ /** Minimum height in pixels */
8
+ minHeight?: number;
9
+ /** Maximum height in pixels */
10
+ maxHeight?: number;
11
+ /**
12
+ * Loading. With no data yet this shows a skeleton; over an existing chart
13
+ * it dims the chart instead, keeping its zoom and legend state.
14
+ */
6
15
  loading?: boolean;
7
16
  error?: string | null;
8
17
  empty?: boolean;
@@ -10,6 +19,23 @@ interface Props {
10
19
  onRetry?: () => void;
11
20
  class?: string;
12
21
  wrapperClass?: string;
22
+ /**
23
+ * Custom legend, rendered beside the chart rather than inside the
24
+ * `role="img"` element so its controls stay accessible
25
+ */
26
+ legend?: Snippet;
27
+ /** Where the custom legend sits (defaults to 'bottom') */
28
+ legendPosition?: ChartLegendPosition;
29
+ /** The chart's data as a table, for screen readers, "Show data" and CSV export */
30
+ dataTable?: ChartDataTableData;
31
+ /** 'sr-only' renders the table for screen readers, true adds a visible toggle */
32
+ showDataTable?: boolean | 'sr-only';
33
+ /** Formats values in the data table */
34
+ format?: (value: number) => string;
35
+ /** Show download buttons */
36
+ exportable?: boolean | ChartExportConfig;
37
+ /** Renders the chart to an image data URL, for the PNG download */
38
+ exportImage?: () => string | null;
13
39
  children: Snippet;
14
40
  }
15
41
  declare const ChartContainer: import("svelte").Component<Props, {}, "">;
@@ -0,0 +1,59 @@
1
+ <script lang="ts">
2
+ import { formatTableCell, type ChartDataTable } from '@classic-homes/charts-core';
3
+ import { cn } from '../../utils.js';
4
+
5
+ interface Props {
6
+ /** Table contents */
7
+ table: ChartDataTable;
8
+ /** Caption naming the chart the data belongs to */
9
+ caption: string;
10
+ /** Formats 'value' columns */
11
+ format?: (value: number) => string;
12
+ /** Hide visually, leaving the table to screen readers */
13
+ srOnly?: boolean;
14
+ class?: string;
15
+ }
16
+
17
+ let { table, caption, format, srOnly = false, class: className }: Props = $props();
18
+ </script>
19
+
20
+ <div
21
+ data-testid="chart-data-table"
22
+ class={cn(srOnly ? 'sr-only' : 'max-h-80 overflow-auto', className)}
23
+ >
24
+ <table class="w-full border-collapse text-sm">
25
+ <caption class={srOnly ? undefined : 'sr-only'}>{caption}</caption>
26
+ <thead>
27
+ <tr>
28
+ {#each table.headers as header, column (column)}
29
+ <th
30
+ scope="col"
31
+ class={cn(
32
+ 'sticky top-0 border-b border-border bg-card px-3 py-2 font-medium text-muted-foreground',
33
+ column === 0 ? 'text-left' : 'text-right'
34
+ )}
35
+ >
36
+ {header}
37
+ </th>
38
+ {/each}
39
+ </tr>
40
+ </thead>
41
+ <tbody>
42
+ {#each table.rows as row, rowIndex (rowIndex)}
43
+ <tr class="border-b border-border last:border-0">
44
+ {#each row as cell, column (column)}
45
+ {#if column === 0}
46
+ <th scope="row" class="px-3 py-1.5 text-left font-normal text-foreground">
47
+ {formatTableCell(table, cell, column, format)}
48
+ </th>
49
+ {:else}
50
+ <td class="px-3 py-1.5 text-right tabular-nums text-foreground">
51
+ {formatTableCell(table, cell, column, format)}
52
+ </td>
53
+ {/if}
54
+ {/each}
55
+ </tr>
56
+ {/each}
57
+ </tbody>
58
+ </table>
59
+ </div>
@@ -0,0 +1,15 @@
1
+ import { type ChartDataTable } from '@classic-homes/charts-core';
2
+ interface Props {
3
+ /** Table contents */
4
+ table: ChartDataTable;
5
+ /** Caption naming the chart the data belongs to */
6
+ caption: string;
7
+ /** Formats 'value' columns */
8
+ format?: (value: number) => string;
9
+ /** Hide visually, leaving the table to screen readers */
10
+ srOnly?: boolean;
11
+ class?: string;
12
+ }
13
+ declare const ChartDataTable: import("svelte").Component<Props, {}, "">;
14
+ type ChartDataTable = ReturnType<typeof ChartDataTable>;
15
+ export default ChartDataTable;
@@ -14,6 +14,7 @@
14
14
 
15
15
  <div
16
16
  data-testid="chart-empty"
17
+ role="status"
17
18
  class={cn(
18
19
  'flex flex-col items-center justify-center rounded-lg border border-border bg-muted/50',
19
20
  className
@@ -0,0 +1,59 @@
1
+ <script lang="ts">
2
+ import type { LegendRenderProps } from '@classic-homes/charts-core';
3
+ import { cn } from '../../utils.js';
4
+
5
+ interface Props
6
+ extends
7
+ Pick<LegendRenderProps, 'items' | 'toggle'>,
8
+ Partial<Omit<LegendRenderProps, 'items' | 'toggle'>> {
9
+ /** Lay items out in a column (defaults to vertical for left/right positions) */
10
+ orientation?: 'horizontal' | 'vertical';
11
+ /** Additional classes for the list */
12
+ class?: string;
13
+ }
14
+
15
+ let {
16
+ items,
17
+ toggle,
18
+ position = 'bottom',
19
+ chartTitle,
20
+ orientation,
21
+ class: className,
22
+ }: Props = $props();
23
+
24
+ const vertical = $derived(
25
+ (orientation ?? (position === 'left' || position === 'right' ? 'vertical' : 'horizontal')) ===
26
+ 'vertical'
27
+ );
28
+ </script>
29
+
30
+ <!--
31
+ Accessible HTML legend for use with a chart's `renderLegend` snippet. Each
32
+ item is a toggle button that shows or hides its series.
33
+ -->
34
+ <ul
35
+ aria-label={chartTitle ? `${chartTitle} legend` : 'Chart legend'}
36
+ class={cn('flex gap-1 text-sm', vertical ? 'flex-col' : 'flex-wrap justify-center', className)}
37
+ >
38
+ {#each items as item (item.name)}
39
+ <li>
40
+ <button
41
+ type="button"
42
+ aria-pressed={item.visible}
43
+ onclick={() => toggle(item.name)}
44
+ class={cn(
45
+ 'inline-flex items-center gap-2 rounded-md px-2 py-1 text-left hover:bg-accent hover:text-accent-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring',
46
+ item.visible ? 'text-foreground' : 'text-muted-foreground line-through'
47
+ )}
48
+ >
49
+ <span
50
+ aria-hidden="true"
51
+ class="h-3 w-3 shrink-0 rounded-sm"
52
+ style:background-color={item.color}
53
+ style:opacity={item.visible ? 1 : 0.35}
54
+ ></span>
55
+ {item.name}
56
+ </button>
57
+ </li>
58
+ {/each}
59
+ </ul>
@@ -0,0 +1,10 @@
1
+ import type { LegendRenderProps } from '@classic-homes/charts-core';
2
+ interface Props extends Pick<LegendRenderProps, 'items' | 'toggle'>, Partial<Omit<LegendRenderProps, 'items' | 'toggle'>> {
3
+ /** Lay items out in a column (defaults to vertical for left/right positions) */
4
+ orientation?: 'horizontal' | 'vertical';
5
+ /** Additional classes for the list */
6
+ class?: string;
7
+ }
8
+ declare const ChartLegend: import("svelte").Component<Props, {}, "">;
9
+ type ChartLegend = ReturnType<typeof ChartLegend>;
10
+ export default ChartLegend;
@@ -3,20 +3,25 @@
3
3
 
4
4
  interface Props {
5
5
  height?: number | string;
6
+ /** Accessible name announced while loading (defaults to 'Loading chart') */
7
+ label?: string;
6
8
  class?: string;
7
9
  }
8
10
 
9
- let { height = 400, class: className }: Props = $props();
11
+ let { height = 400, label = 'Loading chart', class: className }: Props = $props();
10
12
 
11
13
  const heightStyle = $derived(typeof height === 'number' ? `${height}px` : height);
12
14
  </script>
13
15
 
14
16
  <div
15
17
  data-testid="chart-skeleton"
18
+ role="status"
19
+ aria-busy="true"
20
+ aria-label={label}
16
21
  class={cn('animate-pulse rounded-lg border border-border bg-muted', className)}
17
22
  style:height={heightStyle}
18
23
  >
19
- <div class="flex h-full flex-col p-4">
24
+ <div class="flex h-full flex-col p-4" aria-hidden="true">
20
25
  <!-- Title skeleton -->
21
26
  <div class="mb-4 h-5 w-1/3 rounded bg-muted-foreground/20"></div>
22
27
 
@@ -1,5 +1,7 @@
1
1
  interface Props {
2
2
  height?: number | string;
3
+ /** Accessible name announced while loading (defaults to 'Loading chart') */
4
+ label?: string;
3
5
  class?: string;
4
6
  }
5
7
  declare const ChartSkeleton: import("svelte").Component<Props, {}, "">;
@@ -2,12 +2,18 @@ export { default as ChartContainer } from './ChartContainer.svelte';
2
2
  export { default as ChartSkeleton } from './ChartSkeleton.svelte';
3
3
  export { default as ChartError } from './ChartError.svelte';
4
4
  export { default as ChartEmpty } from './ChartEmpty.svelte';
5
+ export { default as ChartLegend } from './ChartLegend.svelte';
6
+ export { default as ChartDataTable } from './ChartDataTable.svelte';
5
7
  import type { ComponentProps } from 'svelte';
6
8
  import type ChartContainer from './ChartContainer.svelte';
7
9
  import type ChartSkeleton from './ChartSkeleton.svelte';
8
10
  import type ChartError from './ChartError.svelte';
9
11
  import type ChartEmpty from './ChartEmpty.svelte';
12
+ import type ChartLegend from './ChartLegend.svelte';
13
+ import type ChartDataTable from './ChartDataTable.svelte';
10
14
  export type ChartContainerProps = ComponentProps<typeof ChartContainer>;
11
15
  export type ChartSkeletonProps = ComponentProps<typeof ChartSkeleton>;
12
16
  export type ChartErrorProps = ComponentProps<typeof ChartError>;
13
17
  export type ChartEmptyProps = ComponentProps<typeof ChartEmpty>;
18
+ export type ChartLegendProps = ComponentProps<typeof ChartLegend>;
19
+ export type ChartDataTableProps = ComponentProps<typeof ChartDataTable>;
@@ -2,3 +2,5 @@ export { default as ChartContainer } from './ChartContainer.svelte';
2
2
  export { default as ChartSkeleton } from './ChartSkeleton.svelte';
3
3
  export { default as ChartError } from './ChartError.svelte';
4
4
  export { default as ChartEmpty } from './ChartEmpty.svelte';
5
+ export { default as ChartLegend } from './ChartLegend.svelte';
6
+ export { default as ChartDataTable } from './ChartDataTable.svelte';