@opendata-ai/openchart-svelte 8.0.0-rc.2 → 8.0.0-rc.21

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 (42) hide show
  1. package/dist/Chart.svelte +4 -0
  2. package/dist/Chart.svelte.d.ts +1 -0
  3. package/dist/Chart.svelte.d.ts.map +1 -1
  4. package/dist/GeoMap.svelte +8 -10
  5. package/dist/GeoMap.svelte.d.ts +3 -7
  6. package/dist/GeoMap.svelte.d.ts.map +1 -1
  7. package/dist/Graph.svelte +135 -12
  8. package/dist/Graph.svelte.d.ts +56 -3
  9. package/dist/Graph.svelte.d.ts.map +1 -1
  10. package/dist/__tests__/Graph.test.js +50 -0
  11. package/dist/composables/useGraph.svelte.d.ts +66 -9
  12. package/dist/composables/useGraph.svelte.d.ts.map +1 -1
  13. package/dist/composables/useGraph.svelte.js +48 -8
  14. package/dist/styles.css +1 -1
  15. package/dist/styles.css.map +1 -1
  16. package/package.json +5 -6
  17. package/src/BarList.svelte +0 -95
  18. package/src/Chart.svelte +0 -192
  19. package/src/ChartStory.svelte +0 -116
  20. package/src/DataTable.svelte +0 -132
  21. package/src/GeoMap.svelte +0 -91
  22. package/src/Graph.svelte +0 -119
  23. package/src/Sankey.svelte +0 -94
  24. package/src/ThemeProvider.svelte +0 -27
  25. package/src/TileMap.svelte +0 -112
  26. package/src/Visualization.svelte +0 -54
  27. package/src/__tests__/Chart.test.ts +0 -134
  28. package/src/__tests__/ChartStory.test.ts +0 -64
  29. package/src/__tests__/ChartStoryHarness.svelte +0 -13
  30. package/src/__tests__/DataTable.test.ts +0 -126
  31. package/src/__tests__/Graph.test.ts +0 -130
  32. package/src/__tests__/ThemeContext.test.ts +0 -106
  33. package/src/__tests__/composables.test.ts +0 -101
  34. package/src/__tests__/useTableState.test.ts +0 -134
  35. package/src/composables/useChart.svelte.ts +0 -108
  36. package/src/composables/useDarkMode.svelte.ts +0 -51
  37. package/src/composables/useGraph.svelte.ts +0 -115
  38. package/src/composables/useTable.svelte.ts +0 -85
  39. package/src/composables/useTableState.svelte.ts +0 -78
  40. package/src/context.ts +0 -35
  41. package/src/index.ts +0 -100
  42. package/src/types.ts +0 -149
@@ -1,51 +0,0 @@
1
- /**
2
- * useDarkMode: resolve a DarkMode preference to a boolean.
3
- *
4
- * - "force" -> true
5
- * - "off" -> false
6
- * - "auto" -> matches system preference (reactive to changes)
7
- *
8
- * Uses .svelte.ts extension so runes ($state, $effect) work outside
9
- * .svelte components.
10
- */
11
-
12
- import type { DarkMode } from '@opendata-ai/openchart-core';
13
-
14
- export function useDarkMode(mode: () => DarkMode | undefined) {
15
- let isDark = $state(resolveInitial(mode()));
16
-
17
- $effect(() => {
18
- const m = mode();
19
- if (m !== 'auto') {
20
- isDark = m === 'force';
21
- return;
22
- }
23
- if (typeof window === 'undefined' || !window.matchMedia) {
24
- isDark = false;
25
- return;
26
- }
27
- const mq = window.matchMedia('(prefers-color-scheme: dark)');
28
- isDark = mq.matches;
29
- const handler = (e: MediaQueryListEvent) => {
30
- isDark = e.matches;
31
- };
32
- mq.addEventListener('change', handler);
33
- return () => mq.removeEventListener('change', handler);
34
- });
35
-
36
- return {
37
- get isDark() {
38
- return isDark;
39
- },
40
- };
41
- }
42
-
43
- function resolveInitial(mode?: DarkMode): boolean {
44
- if (mode === 'force') return true;
45
- if (mode === 'off' || mode === undefined) return false;
46
- // "auto"
47
- if (typeof window !== 'undefined' && window.matchMedia) {
48
- return window.matchMedia('(prefers-color-scheme: dark)').matches;
49
- }
50
- return false;
51
- }
@@ -1,115 +0,0 @@
1
- /**
2
- * useGraph: composable for imperative graph control.
3
- *
4
- * Returns a Svelte action and exposes graph methods (search, zoom, select)
5
- * for programmatic control of the graph instance.
6
- *
7
- * Usage:
8
- * ```svelte
9
- * <script>
10
- * const { action, search, zoomToFit } = useGraph(spec);
11
- * </script>
12
- * <div use:action></div>
13
- * ```
14
- *
15
- * Uses .svelte.ts extension so runes ($state, $effect) work outside
16
- * .svelte components.
17
- */
18
-
19
- import type { GraphSpec } from '@opendata-ai/openchart-core';
20
- import {
21
- createGraph,
22
- type GraphInstance,
23
- type GraphMountOptions,
24
- } from '@opendata-ai/openchart-vanilla';
25
-
26
- export interface UseGraphOptions {
27
- /** Theme overrides. */
28
- theme?: GraphMountOptions['theme'];
29
- /** Dark mode setting. */
30
- darkMode?: GraphMountOptions['darkMode'];
31
- /** Node click handler. */
32
- onNodeClick?: GraphMountOptions['onNodeClick'];
33
- /** Node double-click handler. */
34
- onNodeDoubleClick?: GraphMountOptions['onNodeDoubleClick'];
35
- /** Selection change handler. */
36
- onSelectionChange?: GraphMountOptions['onSelectionChange'];
37
- /** Enable responsive resizing. Defaults to true. */
38
- responsive?: boolean;
39
- }
40
-
41
- export interface UseGraphReturn {
42
- /** Svelte action to attach to a container div. */
43
- action: (node: HTMLElement) => { destroy: () => void };
44
- /** Search for nodes matching a query string. */
45
- search: (query: string) => void;
46
- /** Clear the current search. */
47
- clearSearch: () => void;
48
- /** Zoom to fit all nodes in view. */
49
- zoomToFit: () => void;
50
- /** Zoom and center on a specific node. */
51
- zoomToNode: (nodeId: string) => void;
52
- /** Select a node by id. */
53
- selectNode: (nodeId: string) => void;
54
- /** Get the currently selected node ids. */
55
- getSelectedNodes: () => string[];
56
- }
57
-
58
- export function useGraph(
59
- spec: () => GraphSpec,
60
- options?: () => UseGraphOptions | undefined,
61
- ): UseGraphReturn {
62
- let instance = $state<GraphInstance | null>(null);
63
-
64
- function action(node: HTMLElement) {
65
- $effect(() => {
66
- const currentSpec = spec();
67
- const opts = options?.();
68
-
69
- const mountOpts: GraphMountOptions = {
70
- theme: opts?.theme,
71
- darkMode: opts?.darkMode,
72
- onNodeClick: opts?.onNodeClick,
73
- onNodeDoubleClick: opts?.onNodeDoubleClick,
74
- onSelectionChange: opts?.onSelectionChange,
75
- responsive: opts?.responsive ?? true,
76
- };
77
-
78
- const graph = createGraph(node, currentSpec, mountOpts);
79
- instance = graph;
80
-
81
- return () => {
82
- graph.destroy();
83
- instance = null;
84
- };
85
- });
86
-
87
- return {
88
- destroy() {
89
- // $effect cleanup handles teardown
90
- },
91
- };
92
- }
93
-
94
- return {
95
- action,
96
- search(query: string) {
97
- instance?.search(query);
98
- },
99
- clearSearch() {
100
- instance?.clearSearch();
101
- },
102
- zoomToFit() {
103
- instance?.zoomToFit();
104
- },
105
- zoomToNode(nodeId: string) {
106
- instance?.zoomToNode(nodeId);
107
- },
108
- selectNode(nodeId: string) {
109
- instance?.selectNode(nodeId);
110
- },
111
- getSelectedNodes(): string[] {
112
- return instance?.getSelectedNodes() ?? [];
113
- },
114
- };
115
- }
@@ -1,85 +0,0 @@
1
- /**
2
- * useTable: composable for manual table lifecycle control.
3
- *
4
- * Returns a Svelte action and exposes the table instance and current state.
5
- *
6
- * Usage:
7
- * ```svelte
8
- * <script>
9
- * const { action, table, state } = useTable(spec);
10
- * </script>
11
- * <div use:action></div>
12
- * ```
13
- *
14
- * Uses .svelte.ts extension so runes ($state, $effect) work outside
15
- * .svelte components.
16
- */
17
-
18
- import type { TableSpec } from '@opendata-ai/openchart-core';
19
- import {
20
- createTable,
21
- type TableInstance,
22
- type TableMountOptions,
23
- type TableState,
24
- } from '@opendata-ai/openchart-vanilla';
25
-
26
- export interface UseTableReturn {
27
- /** Svelte action to attach to a container div. */
28
- action: (node: HTMLElement) => { destroy: () => void };
29
- /** The table instance (null until mounted). */
30
- readonly table: TableInstance | null;
31
- /** The current table state (sort, search, page). */
32
- readonly state: TableState;
33
- }
34
-
35
- export function useTable(
36
- spec: () => TableSpec,
37
- options?: () => TableMountOptions | undefined,
38
- ): UseTableReturn {
39
- let table = $state<TableInstance | null>(null);
40
- let state = $state<TableState>({
41
- sort: null,
42
- search: '',
43
- page: 0,
44
- });
45
-
46
- function action(node: HTMLElement) {
47
- $effect(() => {
48
- const currentSpec = spec();
49
- const opts = options?.();
50
-
51
- const mountOpts: TableMountOptions = {
52
- ...opts,
53
- onStateChange: (newState) => {
54
- state = newState;
55
- opts?.onStateChange?.(newState);
56
- },
57
- };
58
-
59
- const instance = createTable(node, currentSpec, mountOpts);
60
- table = instance;
61
- state = instance.getState();
62
-
63
- return () => {
64
- instance.destroy();
65
- table = null;
66
- };
67
- });
68
-
69
- return {
70
- destroy() {
71
- // $effect cleanup handles teardown
72
- },
73
- };
74
- }
75
-
76
- return {
77
- action,
78
- get table() {
79
- return table;
80
- },
81
- get state() {
82
- return state;
83
- },
84
- };
85
- }
@@ -1,78 +0,0 @@
1
- /**
2
- * useTableState: managed state for controlled table usage.
3
- *
4
- * Provides individual sort/search/page state with setters and a
5
- * resetState function to return to initial values.
6
- *
7
- * Uses .svelte.ts extension so runes ($state) work outside
8
- * .svelte components.
9
- */
10
-
11
- import type { SortState } from '@opendata-ai/openchart-core';
12
-
13
- export interface UseTableStateOptions {
14
- sort?: SortState | null;
15
- search?: string;
16
- page?: number;
17
- }
18
-
19
- export interface UseTableStateReturn {
20
- readonly sort: SortState | null;
21
- setSort: (sort: SortState | null) => void;
22
- readonly search: string;
23
- setSearch: (query: string) => void;
24
- readonly page: number;
25
- setPage: (page: number) => void;
26
- resetState: () => void;
27
- }
28
-
29
- /**
30
- * Composable for managing table state (sort, search, page).
31
- *
32
- * Usage:
33
- * ```svelte
34
- * <script>
35
- * const state = useTableState();
36
- * </script>
37
- * <DataTable
38
- * spec={spec}
39
- * sort={state.sort}
40
- * search={state.search}
41
- * page={state.page}
42
- * onsortchange={state.setSort}
43
- * onsearchchange={state.setSearch}
44
- * onpagechange={state.setPage}
45
- * />
46
- * ```
47
- */
48
- export function useTableState(initialState?: UseTableStateOptions): UseTableStateReturn {
49
- let sort = $state<SortState | null>(initialState?.sort ?? null);
50
- let search = $state(initialState?.search ?? '');
51
- let page = $state(initialState?.page ?? 0);
52
-
53
- return {
54
- get sort() {
55
- return sort;
56
- },
57
- setSort(newSort: SortState | null) {
58
- sort = newSort;
59
- },
60
- get search() {
61
- return search;
62
- },
63
- setSearch(query: string) {
64
- search = query;
65
- },
66
- get page() {
67
- return page;
68
- },
69
- setPage(newPage: number) {
70
- page = newPage;
71
- },
72
- resetState() {
73
- sort = initialState?.sort ?? null;
74
- search = initialState?.search ?? '';
75
- page = initialState?.page ?? 0;
76
- },
77
- };
78
- }
package/src/context.ts DELETED
@@ -1,35 +0,0 @@
1
- /**
2
- * Theme context: provides a theme and dark mode preference to all
3
- * descendant Chart, DataTable, and Graph components without prop drilling.
4
- *
5
- * Context values are getter functions so reads from children stay reactive
6
- * when the parent's props change.
7
- */
8
-
9
- import type { DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';
10
- import { getContext, setContext } from 'svelte';
11
-
12
- /** @internal Context key for theme (exported for test use). */
13
- export const THEME_KEY = Symbol('oc-theme');
14
- /** @internal Context key for dark mode (exported for test use). */
15
- export const DARK_MODE_KEY = Symbol('oc-dark-mode');
16
-
17
- /** Set the theme context for descendant components. */
18
- export function setVizTheme(theme: () => ThemeConfig | undefined): void {
19
- setContext(THEME_KEY, theme);
20
- }
21
-
22
- /** Read the current theme from the nearest VizThemeProvider. */
23
- export function getVizTheme(): (() => ThemeConfig | undefined) | undefined {
24
- return getContext<(() => ThemeConfig | undefined) | undefined>(THEME_KEY);
25
- }
26
-
27
- /** Set the dark mode context for descendant components. */
28
- export function setVizDarkMode(darkMode: () => DarkMode | undefined): void {
29
- setContext(DARK_MODE_KEY, darkMode);
30
- }
31
-
32
- /** Read the current dark mode preference from the nearest VizThemeProvider. */
33
- export function getVizDarkMode(): (() => DarkMode | undefined) | undefined {
34
- return getContext<(() => DarkMode | undefined) | undefined>(DARK_MODE_KEY);
35
- }
package/src/index.ts DELETED
@@ -1,100 +0,0 @@
1
- /**
2
- * @opendata-ai/openchart-svelte
3
- *
4
- * Svelte 5 adapter for openchart. Provides <Chart />, <DataTable />,
5
- * and <Graph /> components that wrap the vanilla adapter with Svelte
6
- * lifecycle management using runes.
7
- *
8
- * Re-exports the full core type system and utilities so Svelte consumers
9
- * only need a single @opendata-ai/openchart-svelte dependency.
10
- */
11
-
12
- // ---------------------------------------------------------------------------
13
- // Core: full type system, theme, colors, locale, accessibility, helpers
14
- // ---------------------------------------------------------------------------
15
-
16
- export * from '@opendata-ai/openchart-core';
17
-
18
- // ---------------------------------------------------------------------------
19
- // Vanilla: export utilities (SVG/PNG/JPG/CSV)
20
- // ---------------------------------------------------------------------------
21
-
22
- export type { JPGExportOptions, PNGExportOptions } from '@opendata-ai/openchart-vanilla';
23
- export { exportCSV, exportJPG, exportPNG, exportSVG } from '@opendata-ai/openchart-vanilla';
24
-
25
- // ---------------------------------------------------------------------------
26
- // Engine: compile API and types not covered by core
27
- // ---------------------------------------------------------------------------
28
-
29
- export type {
30
- ChartRenderer,
31
- CompiledGraphEdge,
32
- CompiledGraphNode,
33
- CompileResult,
34
- GraphCompilation,
35
- NormalizedBarListSpec,
36
- NormalizedChartSpec,
37
- NormalizedChrome,
38
- NormalizedGraphSpec,
39
- NormalizedMapSpec,
40
- NormalizedSankeySpec,
41
- NormalizedSpec,
42
- NormalizedTableSpec,
43
- SimulationConfig,
44
- ValidationError,
45
- ValidationErrorCode,
46
- ValidationResult,
47
- } from '@opendata-ai/openchart-engine';
48
- export {
49
- clearRenderers,
50
- compile,
51
- compileBarList,
52
- compileChart,
53
- compileGraph,
54
- compileMap,
55
- compileSankey,
56
- compileTable,
57
- getChartRenderer,
58
- normalizeSpec,
59
- registerChartRenderer,
60
- validateSpec,
61
- } from '@opendata-ai/openchart-engine';
62
- export { default as BarList } from './BarList.svelte';
63
- // Components
64
- export { default as Chart } from './Chart.svelte';
65
- // Scrollytelling
66
- export { default as ChartStory } from './ChartStory.svelte';
67
- export type { UseChartOptions, UseChartReturn } from './composables/useChart.svelte.js';
68
- export { useChart } from './composables/useChart.svelte.js';
69
- // Composables
70
- export { useDarkMode } from './composables/useDarkMode.svelte.js';
71
- export type { UseGraphOptions, UseGraphReturn } from './composables/useGraph.svelte.js';
72
- export { useGraph } from './composables/useGraph.svelte.js';
73
- export type { UseTableReturn } from './composables/useTable.svelte.js';
74
- export { useTable } from './composables/useTable.svelte.js';
75
- export type {
76
- UseTableStateOptions,
77
- UseTableStateReturn,
78
- } from './composables/useTableState.svelte.js';
79
- export { useTableState } from './composables/useTableState.svelte.js';
80
- // Context
81
- export { getVizDarkMode, getVizTheme, setVizDarkMode, setVizTheme } from './context.js';
82
- export { default as DataTable } from './DataTable.svelte';
83
- export { default as GeoMap } from './GeoMap.svelte';
84
- export { default as Graph } from './Graph.svelte';
85
- export { default as Sankey } from './Sankey.svelte';
86
- export { default as VizThemeProvider } from './ThemeProvider.svelte';
87
- export { default as TileMap } from './TileMap.svelte';
88
- // Component prop types
89
- export type {
90
- BarListProps,
91
- ChartProps,
92
- DataTableProps,
93
- GraphProps,
94
- MapProps,
95
- SankeyProps,
96
- TileMapProps,
97
- VisualizationProps,
98
- VizThemeProviderProps,
99
- } from './types.js';
100
- export { default as Visualization } from './Visualization.svelte';
package/src/types.ts DELETED
@@ -1,149 +0,0 @@
1
- /**
2
- * Exported prop types for Svelte components.
3
- *
4
- * These mirror the inline types used in each component's $props() destructuring
5
- * and provide named exports for downstream typing.
6
- */
7
-
8
- import type {
9
- Annotation,
10
- AnnotationOffset,
11
- BarListSpec,
12
- ChartSpec,
13
- DarkMode,
14
- ElementEdit,
15
- GraphSpec,
16
- LayerSpec,
17
- MapSpec,
18
- MarkEvent,
19
- SankeySpec,
20
- SortState,
21
- TableSpec,
22
- TextAnnotation,
23
- ThemeConfig,
24
- TileMapSpec,
25
- VizSpec,
26
- } from '@opendata-ai/openchart-core';
27
- import type { Snippet } from 'svelte';
28
-
29
- export interface ChartProps {
30
- spec: ChartSpec | LayerSpec | GraphSpec;
31
- theme?: ThemeConfig;
32
- darkMode?: DarkMode;
33
- onmarkclick?: (event: MarkEvent) => void;
34
- onmarkhover?: (event: MarkEvent) => void;
35
- onmarkleave?: () => void;
36
- onlegendtoggle?: (series: string, visible: boolean) => void;
37
- onannotationclick?: (annotation: Annotation, event: MouseEvent) => void;
38
- onannotationedit?: (annotation: TextAnnotation, offset: AnnotationOffset) => void;
39
- onedit?: (edit: ElementEdit) => void;
40
- ondatapointclick?: (data: Record<string, unknown>) => void;
41
- class?: string;
42
- style?: string;
43
- }
44
-
45
- export interface DataTableProps {
46
- spec: TableSpec;
47
- theme?: ThemeConfig;
48
- darkMode?: DarkMode;
49
- onrowclick?: (row: Record<string, unknown>) => void;
50
- onsortchange?: (sort: SortState | null) => void;
51
- onsearchchange?: (query: string) => void;
52
- onpagechange?: (page: number) => void;
53
- sort?: SortState | null;
54
- search?: string;
55
- page?: number;
56
- class?: string;
57
- style?: string;
58
- }
59
-
60
- export interface GraphProps {
61
- spec: GraphSpec;
62
- theme?: ThemeConfig;
63
- darkMode?: DarkMode;
64
- onnodeclick?: (node: Record<string, unknown>) => void;
65
- onnodedoubleclick?: (node: Record<string, unknown>) => void;
66
- onselectionchange?: (nodeIds: string[]) => void;
67
- class?: string;
68
- style?: string;
69
- }
70
-
71
- export interface SankeyProps {
72
- spec: SankeySpec;
73
- theme?: ThemeConfig;
74
- darkMode?: DarkMode;
75
- onnodeclick?: (node: Record<string, unknown>) => void;
76
- onlinkclick?: (link: Record<string, unknown>) => void;
77
- onnodehover?: (node: Record<string, unknown> | null) => void;
78
- onlinkhover?: (link: Record<string, unknown> | null) => void;
79
- class?: string;
80
- style?: string;
81
- }
82
-
83
- export interface MapFeatureEvent {
84
- id: string | number;
85
- name?: string;
86
- data: Record<string, unknown> | null;
87
- }
88
-
89
- export interface MapProps {
90
- spec: MapSpec;
91
- theme?: ThemeConfig;
92
- darkMode?: DarkMode;
93
- onmarkclick?: (event: MapFeatureEvent) => void;
94
- onmarkhover?: (event: MapFeatureEvent) => void;
95
- class?: string;
96
- style?: string;
97
- }
98
-
99
- export interface TileMapProps {
100
- spec: TileMapSpec;
101
- theme?: ThemeConfig;
102
- darkMode?: DarkMode;
103
- ontileclick?: (tile: {
104
- stateCode: string;
105
- stateName: string;
106
- value: number | null;
107
- data: Record<string, unknown>;
108
- }) => void;
109
- ontilehover?: (
110
- tile: {
111
- stateCode: string;
112
- stateName: string;
113
- value: number | null;
114
- data: Record<string, unknown>;
115
- } | null,
116
- ) => void;
117
- class?: string;
118
- style?: string;
119
- }
120
-
121
- export interface BarListProps {
122
- spec: BarListSpec;
123
- theme?: ThemeConfig;
124
- darkMode?: DarkMode;
125
- onrowclick?: (row: { label: string; value: number; data: Record<string, unknown> }) => void;
126
- onrowhover?: (
127
- row: {
128
- label: string;
129
- value: number;
130
- data: Record<string, unknown>;
131
- } | null,
132
- ) => void;
133
- class?: string;
134
- style?: string;
135
- }
136
-
137
- export interface VisualizationProps {
138
- spec: VizSpec;
139
- theme?: ThemeConfig;
140
- darkMode?: DarkMode;
141
- class?: string;
142
- style?: string;
143
- }
144
-
145
- export interface VizThemeProviderProps {
146
- theme: ThemeConfig | undefined;
147
- darkMode?: DarkMode;
148
- children: Snippet;
149
- }