@opendata-ai/openchart-svelte 2.0.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/README.md +94 -0
  2. package/dist/Chart.svelte +132 -0
  3. package/dist/Chart.svelte.d.ts +20 -0
  4. package/dist/Chart.svelte.d.ts.map +1 -0
  5. package/dist/DataTable.svelte +132 -0
  6. package/dist/DataTable.svelte.d.ts +19 -0
  7. package/dist/DataTable.svelte.d.ts.map +1 -0
  8. package/dist/Graph.svelte +119 -0
  9. package/dist/Graph.svelte.d.ts +22 -0
  10. package/dist/Graph.svelte.d.ts.map +1 -0
  11. package/dist/ThemeProvider.svelte +27 -0
  12. package/dist/ThemeProvider.svelte.d.ts +11 -0
  13. package/dist/ThemeProvider.svelte.d.ts.map +1 -0
  14. package/dist/Visualization.svelte +35 -0
  15. package/dist/Visualization.svelte.d.ts +12 -0
  16. package/dist/Visualization.svelte.d.ts.map +1 -0
  17. package/dist/__tests__/Chart.test.js +108 -0
  18. package/dist/__tests__/DataTable.test.js +101 -0
  19. package/dist/__tests__/Graph.test.js +104 -0
  20. package/dist/__tests__/ThemeContext.test.js +89 -0
  21. package/dist/__tests__/composables.test.js +84 -0
  22. package/dist/__tests__/useTableState.test.js +105 -0
  23. package/dist/composables/useChart.svelte.d.ts +41 -0
  24. package/dist/composables/useChart.svelte.d.ts.map +1 -0
  25. package/dist/composables/useChart.svelte.js +73 -0
  26. package/dist/composables/useDarkMode.svelte.d.ts +15 -0
  27. package/dist/composables/useDarkMode.svelte.d.ts.map +1 -0
  28. package/dist/composables/useDarkMode.svelte.js +47 -0
  29. package/dist/composables/useGraph.svelte.d.ts +53 -0
  30. package/dist/composables/useGraph.svelte.d.ts.map +1 -0
  31. package/dist/composables/useGraph.svelte.js +67 -0
  32. package/dist/composables/useTable.svelte.d.ts +30 -0
  33. package/dist/composables/useTable.svelte.d.ts.map +1 -0
  34. package/dist/composables/useTable.svelte.js +59 -0
  35. package/dist/composables/useTableState.svelte.d.ts +45 -0
  36. package/dist/composables/useTableState.svelte.d.ts.map +1 -0
  37. package/dist/composables/useTableState.svelte.js +58 -0
  38. package/dist/context.d.ts +21 -0
  39. package/dist/context.d.ts.map +1 -0
  40. package/dist/context.js +28 -0
  41. package/dist/index.d.ts +25 -0
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +21 -0
  44. package/dist/types.d.ts +60 -0
  45. package/dist/types.d.ts.map +1 -0
  46. package/dist/types.js +7 -0
  47. package/package.json +65 -0
  48. package/src/Chart.svelte +132 -0
  49. package/src/DataTable.svelte +132 -0
  50. package/src/Graph.svelte +119 -0
  51. package/src/ThemeProvider.svelte +27 -0
  52. package/src/Visualization.svelte +35 -0
  53. package/src/__tests__/Chart.test.ts +134 -0
  54. package/src/__tests__/DataTable.test.ts +126 -0
  55. package/src/__tests__/Graph.test.ts +130 -0
  56. package/src/__tests__/ThemeContext.test.ts +106 -0
  57. package/src/__tests__/composables.test.ts +101 -0
  58. package/src/__tests__/useTableState.test.ts +134 -0
  59. package/src/composables/useChart.svelte.ts +108 -0
  60. package/src/composables/useDarkMode.svelte.ts +51 -0
  61. package/src/composables/useGraph.svelte.ts +115 -0
  62. package/src/composables/useTable.svelte.ts +85 -0
  63. package/src/composables/useTableState.svelte.ts +78 -0
  64. package/src/context.ts +35 -0
  65. package/src/index.ts +46 -0
  66. package/src/types.ts +78 -0
@@ -0,0 +1,73 @@
1
+ /**
2
+ * useChart: composable for manual chart lifecycle control.
3
+ *
4
+ * Returns a Svelte action function for use with `use:chart` directive
5
+ * and exposes the chart instance and compiled layout.
6
+ *
7
+ * Usage:
8
+ * ```svelte
9
+ * <script>
10
+ * const { action, chart, layout } = useChart(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
+ import { createChart } from '@opendata-ai/openchart-vanilla';
19
+ import { untrack } from 'svelte';
20
+ export function useChart(spec, options) {
21
+ let chart = $state(null);
22
+ let layout = $state(null);
23
+ function action(node) {
24
+ let prevSpec = '';
25
+ // Effect 1: Mount/recreate on option changes
26
+ $effect(() => {
27
+ const opts = options?.();
28
+ const mountOpts = {
29
+ theme: opts?.theme,
30
+ darkMode: opts?.darkMode,
31
+ onDataPointClick: opts?.onDataPointClick,
32
+ responsive: opts?.responsive ?? true,
33
+ };
34
+ // Read spec without tracking
35
+ const currentSpec = untrack(() => spec());
36
+ const instance = createChart(node, currentSpec, mountOpts);
37
+ chart = instance;
38
+ layout = instance.layout;
39
+ prevSpec = JSON.stringify(currentSpec);
40
+ return () => {
41
+ instance.destroy();
42
+ chart = null;
43
+ layout = null;
44
+ };
45
+ });
46
+ // Effect 2: Update on spec change
47
+ $effect(() => {
48
+ const currentSpec = spec();
49
+ if (!chart)
50
+ return;
51
+ const specString = JSON.stringify(currentSpec);
52
+ if (specString !== prevSpec) {
53
+ prevSpec = specString;
54
+ chart.update(currentSpec);
55
+ layout = chart.layout;
56
+ }
57
+ });
58
+ return {
59
+ destroy() {
60
+ // $effect cleanup handles teardown
61
+ },
62
+ };
63
+ }
64
+ return {
65
+ action,
66
+ get chart() {
67
+ return chart;
68
+ },
69
+ get layout() {
70
+ return layout;
71
+ },
72
+ };
73
+ }
@@ -0,0 +1,15 @@
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
+ import type { DarkMode } from '@opendata-ai/openchart-core';
12
+ export declare function useDarkMode(mode: () => DarkMode | undefined): {
13
+ readonly isDark: boolean;
14
+ };
15
+ //# sourceMappingURL=useDarkMode.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDarkMode.svelte.d.ts","sourceRoot":"","sources":["../../src/composables/useDarkMode.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AAE5D,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,QAAQ,GAAG,SAAS;;EA2B3D"}
@@ -0,0 +1,47 @@
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
+ export function useDarkMode(mode) {
12
+ let isDark = $state(resolveInitial(mode()));
13
+ $effect(() => {
14
+ const m = mode();
15
+ if (m !== 'auto') {
16
+ isDark = m === 'force';
17
+ return;
18
+ }
19
+ if (typeof window === 'undefined' || !window.matchMedia) {
20
+ isDark = false;
21
+ return;
22
+ }
23
+ const mq = window.matchMedia('(prefers-color-scheme: dark)');
24
+ isDark = mq.matches;
25
+ const handler = (e) => {
26
+ isDark = e.matches;
27
+ };
28
+ mq.addEventListener('change', handler);
29
+ return () => mq.removeEventListener('change', handler);
30
+ });
31
+ return {
32
+ get isDark() {
33
+ return isDark;
34
+ },
35
+ };
36
+ }
37
+ function resolveInitial(mode) {
38
+ if (mode === 'force')
39
+ return true;
40
+ if (mode === 'off' || mode === undefined)
41
+ return false;
42
+ // "auto"
43
+ if (typeof window !== 'undefined' && window.matchMedia) {
44
+ return window.matchMedia('(prefers-color-scheme: dark)').matches;
45
+ }
46
+ return false;
47
+ }
@@ -0,0 +1,53 @@
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
+ import type { GraphSpec } from '@opendata-ai/openchart-core';
19
+ import { type GraphMountOptions } from '@opendata-ai/openchart-vanilla';
20
+ export interface UseGraphOptions {
21
+ /** Theme overrides. */
22
+ theme?: GraphMountOptions['theme'];
23
+ /** Dark mode setting. */
24
+ darkMode?: GraphMountOptions['darkMode'];
25
+ /** Node click handler. */
26
+ onNodeClick?: GraphMountOptions['onNodeClick'];
27
+ /** Node double-click handler. */
28
+ onNodeDoubleClick?: GraphMountOptions['onNodeDoubleClick'];
29
+ /** Selection change handler. */
30
+ onSelectionChange?: GraphMountOptions['onSelectionChange'];
31
+ /** Enable responsive resizing. Defaults to true. */
32
+ responsive?: boolean;
33
+ }
34
+ export interface UseGraphReturn {
35
+ /** Svelte action to attach to a container div. */
36
+ action: (node: HTMLElement) => {
37
+ destroy: () => void;
38
+ };
39
+ /** Search for nodes matching a query string. */
40
+ search: (query: string) => void;
41
+ /** Clear the current search. */
42
+ clearSearch: () => void;
43
+ /** Zoom to fit all nodes in view. */
44
+ zoomToFit: () => void;
45
+ /** Zoom and center on a specific node. */
46
+ zoomToNode: (nodeId: string) => void;
47
+ /** Select a node by id. */
48
+ selectNode: (nodeId: string) => void;
49
+ /** Get the currently selected node ids. */
50
+ getSelectedNodes: () => string[];
51
+ }
52
+ export declare function useGraph(spec: () => GraphSpec, options?: () => UseGraphOptions | undefined): UseGraphReturn;
53
+ //# sourceMappingURL=useGraph.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useGraph.svelte.d.ts","sourceRoot":"","sources":["../../src/composables/useGraph.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,eAAe;IAC9B,uBAAuB;IACvB,KAAK,CAAC,EAAE,iBAAiB,CAAC,OAAO,CAAC,CAAC;IACnC,yBAAyB;IACzB,QAAQ,CAAC,EAAE,iBAAiB,CAAC,UAAU,CAAC,CAAC;IACzC,0BAA0B;IAC1B,WAAW,CAAC,EAAE,iBAAiB,CAAC,aAAa,CAAC,CAAC;IAC/C,iCAAiC;IACjC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;IAC3D,gCAAgC;IAChC,iBAAiB,CAAC,EAAE,iBAAiB,CAAC,mBAAmB,CAAC,CAAC;IAC3D,oDAAoD;IACpD,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,MAAM,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK;QAAE,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;IACvD,gDAAgD;IAChD,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,gCAAgC;IAChC,WAAW,EAAE,MAAM,IAAI,CAAC;IACxB,qCAAqC;IACrC,SAAS,EAAE,MAAM,IAAI,CAAC;IACtB,0CAA0C;IAC1C,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,2BAA2B;IAC3B,UAAU,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,2CAA2C;IAC3C,gBAAgB,EAAE,MAAM,MAAM,EAAE,CAAC;CAClC;AAED,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,SAAS,EACrB,OAAO,CAAC,EAAE,MAAM,eAAe,GAAG,SAAS,GAC1C,cAAc,CAsDhB"}
@@ -0,0 +1,67 @@
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
+ import { createGraph, } from '@opendata-ai/openchart-vanilla';
19
+ export function useGraph(spec, options) {
20
+ let instance = $state(null);
21
+ function action(node) {
22
+ $effect(() => {
23
+ const currentSpec = spec();
24
+ const opts = options?.();
25
+ const mountOpts = {
26
+ theme: opts?.theme,
27
+ darkMode: opts?.darkMode,
28
+ onNodeClick: opts?.onNodeClick,
29
+ onNodeDoubleClick: opts?.onNodeDoubleClick,
30
+ onSelectionChange: opts?.onSelectionChange,
31
+ responsive: opts?.responsive ?? true,
32
+ };
33
+ const graph = createGraph(node, currentSpec, mountOpts);
34
+ instance = graph;
35
+ return () => {
36
+ graph.destroy();
37
+ instance = null;
38
+ };
39
+ });
40
+ return {
41
+ destroy() {
42
+ // $effect cleanup handles teardown
43
+ },
44
+ };
45
+ }
46
+ return {
47
+ action,
48
+ search(query) {
49
+ instance?.search(query);
50
+ },
51
+ clearSearch() {
52
+ instance?.clearSearch();
53
+ },
54
+ zoomToFit() {
55
+ instance?.zoomToFit();
56
+ },
57
+ zoomToNode(nodeId) {
58
+ instance?.zoomToNode(nodeId);
59
+ },
60
+ selectNode(nodeId) {
61
+ instance?.selectNode(nodeId);
62
+ },
63
+ getSelectedNodes() {
64
+ return instance?.getSelectedNodes() ?? [];
65
+ },
66
+ };
67
+ }
@@ -0,0 +1,30 @@
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
+ import type { TableSpec } from '@opendata-ai/openchart-core';
18
+ import { type TableInstance, type TableMountOptions, type TableState } from '@opendata-ai/openchart-vanilla';
19
+ export interface UseTableReturn {
20
+ /** Svelte action to attach to a container div. */
21
+ action: (node: HTMLElement) => {
22
+ destroy: () => void;
23
+ };
24
+ /** The table instance (null until mounted). */
25
+ readonly table: TableInstance | null;
26
+ /** The current table state (sort, search, page). */
27
+ readonly state: TableState;
28
+ }
29
+ export declare function useTable(spec: () => TableSpec, options?: () => TableMountOptions | undefined): UseTableReturn;
30
+ //# sourceMappingURL=useTable.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTable.svelte.d.ts","sourceRoot":"","sources":["../../src/composables/useTable.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAC7D,OAAO,EAEL,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,UAAU,EAChB,MAAM,gCAAgC,CAAC;AAExC,MAAM,WAAW,cAAc;IAC7B,kDAAkD;IAClD,MAAM,EAAE,CAAC,IAAI,EAAE,WAAW,KAAK;QAAE,OAAO,EAAE,MAAM,IAAI,CAAA;KAAE,CAAC;IACvD,+CAA+C;IAC/C,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,oDAAoD;IACpD,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAC;CAC5B;AAED,wBAAgB,QAAQ,CACtB,IAAI,EAAE,MAAM,SAAS,EACrB,OAAO,CAAC,EAAE,MAAM,iBAAiB,GAAG,SAAS,GAC5C,cAAc,CA+ChB"}
@@ -0,0 +1,59 @@
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
+ import { createTable, } from '@opendata-ai/openchart-vanilla';
18
+ export function useTable(spec, options) {
19
+ let table = $state(null);
20
+ let state = $state({
21
+ sort: null,
22
+ search: '',
23
+ page: 0,
24
+ });
25
+ function action(node) {
26
+ $effect(() => {
27
+ const currentSpec = spec();
28
+ const opts = options?.();
29
+ const mountOpts = {
30
+ ...opts,
31
+ onStateChange: (newState) => {
32
+ state = newState;
33
+ opts?.onStateChange?.(newState);
34
+ },
35
+ };
36
+ const instance = createTable(node, currentSpec, mountOpts);
37
+ table = instance;
38
+ state = instance.getState();
39
+ return () => {
40
+ instance.destroy();
41
+ table = null;
42
+ };
43
+ });
44
+ return {
45
+ destroy() {
46
+ // $effect cleanup handles teardown
47
+ },
48
+ };
49
+ }
50
+ return {
51
+ action,
52
+ get table() {
53
+ return table;
54
+ },
55
+ get state() {
56
+ return state;
57
+ },
58
+ };
59
+ }
@@ -0,0 +1,45 @@
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
+ import type { SortState } from '@opendata-ai/openchart-core';
11
+ export interface UseTableStateOptions {
12
+ sort?: SortState | null;
13
+ search?: string;
14
+ page?: number;
15
+ }
16
+ export interface UseTableStateReturn {
17
+ readonly sort: SortState | null;
18
+ setSort: (sort: SortState | null) => void;
19
+ readonly search: string;
20
+ setSearch: (query: string) => void;
21
+ readonly page: number;
22
+ setPage: (page: number) => void;
23
+ resetState: () => void;
24
+ }
25
+ /**
26
+ * Composable for managing table state (sort, search, page).
27
+ *
28
+ * Usage:
29
+ * ```svelte
30
+ * <script>
31
+ * const state = useTableState();
32
+ * </script>
33
+ * <DataTable
34
+ * spec={spec}
35
+ * sort={state.sort}
36
+ * search={state.search}
37
+ * page={state.page}
38
+ * onsortchange={state.setSort}
39
+ * onsearchchange={state.setSearch}
40
+ * onpagechange={state.setPage}
41
+ * />
42
+ * ```
43
+ */
44
+ export declare function useTableState(initialState?: UseTableStateOptions): UseTableStateReturn;
45
+ //# sourceMappingURL=useTableState.svelte.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useTableState.svelte.d.ts","sourceRoot":"","sources":["../../src/composables/useTableState.svelte.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AAE7D,MAAM,WAAW,oBAAoB;IACnC,IAAI,CAAC,EAAE,SAAS,GAAG,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,CAAC;IAChC,OAAO,EAAE,CAAC,IAAI,EAAE,SAAS,GAAG,IAAI,KAAK,IAAI,CAAC;IAC1C,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,OAAO,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAChC,UAAU,EAAE,MAAM,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,aAAa,CAAC,YAAY,CAAC,EAAE,oBAAoB,GAAG,mBAAmB,CA8BtF"}
@@ -0,0 +1,58 @@
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
+ * Composable for managing table state (sort, search, page).
12
+ *
13
+ * Usage:
14
+ * ```svelte
15
+ * <script>
16
+ * const state = useTableState();
17
+ * </script>
18
+ * <DataTable
19
+ * spec={spec}
20
+ * sort={state.sort}
21
+ * search={state.search}
22
+ * page={state.page}
23
+ * onsortchange={state.setSort}
24
+ * onsearchchange={state.setSearch}
25
+ * onpagechange={state.setPage}
26
+ * />
27
+ * ```
28
+ */
29
+ export function useTableState(initialState) {
30
+ let sort = $state(initialState?.sort ?? null);
31
+ let search = $state(initialState?.search ?? '');
32
+ let page = $state(initialState?.page ?? 0);
33
+ return {
34
+ get sort() {
35
+ return sort;
36
+ },
37
+ setSort(newSort) {
38
+ sort = newSort;
39
+ },
40
+ get search() {
41
+ return search;
42
+ },
43
+ setSearch(query) {
44
+ search = query;
45
+ },
46
+ get page() {
47
+ return page;
48
+ },
49
+ setPage(newPage) {
50
+ page = newPage;
51
+ },
52
+ resetState() {
53
+ sort = initialState?.sort ?? null;
54
+ search = initialState?.search ?? '';
55
+ page = initialState?.page ?? 0;
56
+ },
57
+ };
58
+ }
@@ -0,0 +1,21 @@
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
+ import type { DarkMode, ThemeConfig } from '@opendata-ai/openchart-core';
9
+ /** @internal Context key for theme (exported for test use). */
10
+ export declare const THEME_KEY: unique symbol;
11
+ /** @internal Context key for dark mode (exported for test use). */
12
+ export declare const DARK_MODE_KEY: unique symbol;
13
+ /** Set the theme context for descendant components. */
14
+ export declare function setVizTheme(theme: () => ThemeConfig | undefined): void;
15
+ /** Read the current theme from the nearest VizThemeProvider. */
16
+ export declare function getVizTheme(): (() => ThemeConfig | undefined) | undefined;
17
+ /** Set the dark mode context for descendant components. */
18
+ export declare function setVizDarkMode(darkMode: () => DarkMode | undefined): void;
19
+ /** Read the current dark mode preference from the nearest VizThemeProvider. */
20
+ export declare function getVizDarkMode(): (() => DarkMode | undefined) | undefined;
21
+ //# sourceMappingURL=context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../src/context.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,QAAQ,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAGzE,+DAA+D;AAC/D,eAAO,MAAM,SAAS,eAAsB,CAAC;AAC7C,mEAAmE;AACnE,eAAO,MAAM,aAAa,eAA0B,CAAC;AAErD,uDAAuD;AACvD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,WAAW,GAAG,SAAS,GAAG,IAAI,CAEtE;AAED,gEAAgE;AAChE,wBAAgB,WAAW,IAAI,CAAC,MAAM,WAAW,GAAG,SAAS,CAAC,GAAG,SAAS,CAEzE;AAED,2DAA2D;AAC3D,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,QAAQ,GAAG,SAAS,GAAG,IAAI,CAEzE;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,IAAI,CAAC,MAAM,QAAQ,GAAG,SAAS,CAAC,GAAG,SAAS,CAEzE"}
@@ -0,0 +1,28 @@
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
+ import { getContext, setContext } from 'svelte';
9
+ /** @internal Context key for theme (exported for test use). */
10
+ export const THEME_KEY = Symbol('viz-theme');
11
+ /** @internal Context key for dark mode (exported for test use). */
12
+ export const DARK_MODE_KEY = Symbol('viz-dark-mode');
13
+ /** Set the theme context for descendant components. */
14
+ export function setVizTheme(theme) {
15
+ setContext(THEME_KEY, theme);
16
+ }
17
+ /** Read the current theme from the nearest VizThemeProvider. */
18
+ export function getVizTheme() {
19
+ return getContext(THEME_KEY);
20
+ }
21
+ /** Set the dark mode context for descendant components. */
22
+ export function setVizDarkMode(darkMode) {
23
+ setContext(DARK_MODE_KEY, darkMode);
24
+ }
25
+ /** Read the current dark mode preference from the nearest VizThemeProvider. */
26
+ export function getVizDarkMode() {
27
+ return getContext(DARK_MODE_KEY);
28
+ }
@@ -0,0 +1,25 @@
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
+ export type { ChartLayout, ChartSpec, CompileOptions, TableLayout, TableSpec, VizSpec, } from '@opendata-ai/openchart-engine';
9
+ export { default as Chart } from './Chart.svelte';
10
+ export type { UseChartOptions, UseChartReturn } from './composables/useChart.svelte.js';
11
+ export { useChart } from './composables/useChart.svelte.js';
12
+ export { useDarkMode } from './composables/useDarkMode.svelte.js';
13
+ export type { UseGraphOptions, UseGraphReturn } from './composables/useGraph.svelte.js';
14
+ export { useGraph } from './composables/useGraph.svelte.js';
15
+ export type { UseTableReturn } from './composables/useTable.svelte.js';
16
+ export { useTable } from './composables/useTable.svelte.js';
17
+ export type { UseTableStateOptions, UseTableStateReturn, } from './composables/useTableState.svelte.js';
18
+ export { useTableState } from './composables/useTableState.svelte.js';
19
+ export { getVizDarkMode, getVizTheme, setVizDarkMode, setVizTheme } from './context.js';
20
+ export { default as DataTable } from './DataTable.svelte';
21
+ export { default as Graph } from './Graph.svelte';
22
+ export { default as VizThemeProvider } from './ThemeProvider.svelte';
23
+ export type { ChartProps, DataTableProps, GraphProps, VisualizationProps, VizThemeProviderProps, } from './types.js';
24
+ export { default as Visualization } from './Visualization.svelte';
25
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAGH,YAAY,EACV,WAAW,EACX,SAAS,EACT,cAAc,EACd,WAAW,EACX,SAAS,EACT,OAAO,GACR,MAAM,+BAA+B,CAAC;AAEvC,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAE5D,OAAO,EAAE,WAAW,EAAE,MAAM,qCAAqC,CAAC;AAClE,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACxF,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAC5D,YAAY,EAAE,cAAc,EAAE,MAAM,kCAAkC,CAAC;AACvE,OAAO,EAAE,QAAQ,EAAE,MAAM,kCAAkC,CAAC;AAC5D,YAAY,EACV,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,uCAAuC,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,uCAAuC,CAAC;AAEtE,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACxF,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,KAAK,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAErE,YAAY,EACV,UAAU,EACV,cAAc,EACd,UAAU,EACV,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,21 @@
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
+ // Components
9
+ export { default as Chart } from './Chart.svelte';
10
+ export { useChart } from './composables/useChart.svelte.js';
11
+ // Composables
12
+ export { useDarkMode } from './composables/useDarkMode.svelte.js';
13
+ export { useGraph } from './composables/useGraph.svelte.js';
14
+ export { useTable } from './composables/useTable.svelte.js';
15
+ export { useTableState } from './composables/useTableState.svelte.js';
16
+ // Context
17
+ export { getVizDarkMode, getVizTheme, setVizDarkMode, setVizTheme } from './context.js';
18
+ export { default as DataTable } from './DataTable.svelte';
19
+ export { default as Graph } from './Graph.svelte';
20
+ export { default as VizThemeProvider } from './ThemeProvider.svelte';
21
+ export { default as Visualization } from './Visualization.svelte';
@@ -0,0 +1,60 @@
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
+ import type { Annotation, AnnotationOffset, ChartSpec, DarkMode, ElementEdit, GraphSpec, MarkEvent, SortState, TableSpec, TextAnnotation, ThemeConfig, VizSpec } from '@opendata-ai/openchart-core';
8
+ import type { Snippet } from 'svelte';
9
+ export interface ChartProps {
10
+ spec: ChartSpec | GraphSpec;
11
+ theme?: ThemeConfig;
12
+ darkMode?: DarkMode;
13
+ onmarkclick?: (event: MarkEvent) => void;
14
+ onmarkhover?: (event: MarkEvent) => void;
15
+ onmarkleave?: () => void;
16
+ onlegendtoggle?: (series: string, visible: boolean) => void;
17
+ onannotationclick?: (annotation: Annotation, event: MouseEvent) => void;
18
+ onannotationedit?: (annotation: TextAnnotation, offset: AnnotationOffset) => void;
19
+ onedit?: (edit: ElementEdit) => void;
20
+ ondatapointclick?: (data: Record<string, unknown>) => void;
21
+ class?: string;
22
+ style?: string;
23
+ }
24
+ export interface DataTableProps {
25
+ spec: TableSpec;
26
+ theme?: ThemeConfig;
27
+ darkMode?: DarkMode;
28
+ onrowclick?: (row: Record<string, unknown>) => void;
29
+ onsortchange?: (sort: SortState | null) => void;
30
+ onsearchchange?: (query: string) => void;
31
+ onpagechange?: (page: number) => void;
32
+ sort?: SortState | null;
33
+ search?: string;
34
+ page?: number;
35
+ class?: string;
36
+ style?: string;
37
+ }
38
+ export interface GraphProps {
39
+ spec: GraphSpec;
40
+ theme?: ThemeConfig;
41
+ darkMode?: DarkMode;
42
+ onnodeclick?: (node: Record<string, unknown>) => void;
43
+ onnodedoubleclick?: (node: Record<string, unknown>) => void;
44
+ onselectionchange?: (nodeIds: string[]) => void;
45
+ class?: string;
46
+ style?: string;
47
+ }
48
+ export interface VisualizationProps {
49
+ spec: VizSpec;
50
+ theme?: ThemeConfig;
51
+ darkMode?: DarkMode;
52
+ class?: string;
53
+ style?: string;
54
+ }
55
+ export interface VizThemeProviderProps {
56
+ theme: ThemeConfig | undefined;
57
+ darkMode?: DarkMode;
58
+ children: Snippet;
59
+ }
60
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,7 @@
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
+ export {};