@freereportjs/svelte 0.8.0 → 0.9.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.
@@ -1,63 +1,67 @@
1
- <script lang="ts">
2
- import { createViewer, type Report, type Viewer } from '@freereportjs/core';
3
- import { untrack } from 'svelte';
4
- import { FILL, FRAME, type FreeReportViewerProps } from './types.js';
5
-
6
- /**
7
- * Toolbar, parameter panel and paged report. `definition`, `data`, `params` and `zoom` update the viewer
8
- * in place; other props recreate it. Callbacks are read when called.
9
- */
10
- let { class: className = '', style = '', ...props }: FreeReportViewerProps = $props();
11
- let host: HTMLDivElement;
12
- let viewer = $state.raw<Viewer | null>(null);
13
- let applied: Pick<FreeReportViewerProps, 'definition' | 'data' | 'params' | 'zoom'> = { definition: undefined! };
14
-
15
- /** The viewer (null before mount); with `bind:this`. */
16
- export function getViewer(): Viewer | null {
17
- return viewer;
18
- }
19
- /** The report the viewer shows (null before mount). */
20
- export function getReport(): Report | null {
21
- return viewer?.report ?? null;
22
- }
23
-
24
- const key = $derived(JSON.stringify([props.lang, props.toolbar, props.licenseKey, props.pdfSecurity, props.fileName, !!props.fetchData]));
25
-
26
- // create on mount, recreate when a creation-only prop changes
27
- $effect(() => {
28
- void key;
29
- const v = untrack(() => {
30
- applied = { definition: props.definition, data: props.data, params: props.params, zoom: props.zoom };
31
- return createViewer(host, {
32
- ...applied, lang: props.lang, toolbar: props.toolbar, licenseKey: props.licenseKey, pdfSecurity: props.pdfSecurity,
33
- fileName: props.fileName,
34
- onOutput: e => props.onOutput?.(e),
35
- fetchData: props.fetchData && (params => props.fetchData!(params)),
36
- });
37
- });
38
- viewer = v;
39
- untrack(() => props.onReady?.(v));
40
- return () => {
41
- v.destroy();
42
- viewer = null;
43
- };
44
- });
45
-
46
- $effect(() => {
47
- const { definition, data, params, zoom } = props;
48
- const v = viewer;
49
- if (!v) return;
50
- untrack(() => {
51
- const a = applied;
52
- if (zoom !== a.zoom) v.setZoom((a.zoom = zoom) ?? 'width');
53
- // definition + data together are laid out once
54
- let dirty = false;
55
- if (definition !== a.definition) { v.report.setDefinition((a.definition = definition)); dirty = true; }
56
- if (data !== a.data) { v.report.setData((a.data = data) ?? {}); dirty = true; }
57
- if (params !== a.params) void v.setParams((a.params = params) ?? {});
58
- else if (dirty) void v.refresh();
59
- });
60
- });
61
- </script>
62
-
63
- <div class={className} style={FRAME + style}><div bind:this={host} style={FILL}></div></div>
1
+ <script lang="ts">
2
+ import { createViewer, type Report, type Viewer } from '@freereportjs/core';
3
+ import { untrack } from 'svelte';
4
+ import { FILL, FRAME, type FreeReportViewerProps } from './types.js';
5
+
6
+ /**
7
+ * Toolbar, parameter panel and paged report. `definition`, `data`, `params` and `zoom` update the viewer
8
+ * in place; other props recreate it. Callbacks are read when called.
9
+ */
10
+ let { class: className = '', style = '', ...props }: FreeReportViewerProps = $props();
11
+ let host: HTMLDivElement;
12
+ let viewer = $state.raw<Viewer | null>(null);
13
+ let applied: Pick<FreeReportViewerProps, 'definition' | 'data' | 'params' | 'zoom'> = { definition: undefined! };
14
+
15
+ /** The viewer (null before mount); with `bind:this`. */
16
+ export function getViewer(): Viewer | null {
17
+ return viewer;
18
+ }
19
+ /** The report the viewer shows (null before mount). */
20
+ export function getReport(): Report | null {
21
+ return viewer?.report ?? null;
22
+ }
23
+
24
+ const key = $derived(JSON.stringify([props.lang, props.toolbar, props.licenseKey, props.pdfSecurity, props.fileName, !!props.fetchData]));
25
+
26
+ // create on mount, recreate when a creation-only prop changes
27
+ $effect(() => {
28
+ void key;
29
+ const v = untrack(() => {
30
+ applied = { definition: props.definition, data: props.data, params: props.params, zoom: props.zoom };
31
+ return createViewer(host, {
32
+ ...applied, lang: props.lang, toolbar: props.toolbar, licenseKey: props.licenseKey, pdfSecurity: props.pdfSecurity,
33
+ fileName: props.fileName,
34
+ onOutput: e => props.onOutput?.(e),
35
+ onReady: e => props.onRendered?.(e),
36
+ onParamsSubmit: p => props.onParamsSubmit?.(p),
37
+ onPageChange: (n, total) => props.onPageChange?.(n, total),
38
+ onError: (err, during) => props.onError?.(err, during),
39
+ fetchData: props.fetchData && (params => props.fetchData!(params)),
40
+ });
41
+ });
42
+ viewer = v;
43
+ untrack(() => props.onReady?.(v));
44
+ return () => {
45
+ v.destroy();
46
+ viewer = null;
47
+ };
48
+ });
49
+
50
+ $effect(() => {
51
+ const { definition, data, params, zoom } = props;
52
+ const v = viewer;
53
+ if (!v) return;
54
+ untrack(() => {
55
+ const a = applied;
56
+ if (zoom !== a.zoom) v.setZoom((a.zoom = zoom) ?? 'width');
57
+ // definition + data together are laid out once
58
+ let dirty = false;
59
+ if (definition !== a.definition) { v.report.setDefinition((a.definition = definition)); dirty = true; }
60
+ if (data !== a.data) { v.report.setData((a.data = data) ?? {}); dirty = true; }
61
+ if (params !== a.params) void v.setParams((a.params = params) ?? {});
62
+ else if (dirty) void v.refresh();
63
+ });
64
+ });
65
+ </script>
66
+
67
+ <div class={className} style={FRAME + style}><div bind:this={host} style={FILL}></div></div>
package/dist/types.d.ts CHANGED
@@ -15,6 +15,11 @@ export interface FreeReportViewerProps {
15
15
  fetchData?: ViewerOptions['fetchData'];
16
16
  /** Called with the viewer each time one is created. */
17
17
  onReady?: (viewer: Viewer) => void;
18
+ /** After every run: { pages, rows, ms, params } (the core viewer's onReady). */
19
+ onRendered?: ViewerOptions['onReady'];
20
+ onParamsSubmit?: ViewerOptions['onParamsSubmit'];
21
+ onPageChange?: ViewerOptions['onPageChange'];
22
+ onError?: ViewerOptions['onError'];
18
23
  class?: string;
19
24
  /** Extra inline style for the frame (default: height 100%, min-height 480px). */
20
25
  style?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@freereportjs/svelte",
3
- "version": "0.8.0",
3
+ "version": "0.9.0",
4
4
  "description": "Svelte 5 components for FreeReport, the web reporting engine: report viewer and banded report designer (free for personal use).",
5
5
  "license": "SEE LICENSE IN LICENSE",
6
6
  "type": "module",
@@ -19,7 +19,7 @@
19
19
  "LICENSE"
20
20
  ],
21
21
  "peerDependencies": {
22
- "@freereportjs/core": "^0.8.0",
22
+ "@freereportjs/core": "^0.9.0",
23
23
  "svelte": "^5.0.0"
24
24
  },
25
25
  "keywords": [
@@ -36,7 +36,7 @@
36
36
  "access": "public"
37
37
  },
38
38
  "devDependencies": {
39
- "@freereportjs/core": "^0.8.0",
39
+ "@freereportjs/core": "^0.9.0",
40
40
  "@sveltejs/package": "^3.0.0",
41
41
  "@sveltejs/vite-plugin-svelte": "^7.3.1",
42
42
  "jsdom": "^30.1.2",