selva-shared 0.8.4 → 0.8.5

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.
@@ -32,6 +32,9 @@
32
32
  footerComponentProps?: () => Record<string, unknown>;
33
33
  footerItemId?: string;
34
34
  footerItemPriority?: number;
35
+ // Callback to expose the loadValues function to the parent
36
+ // Usage: bind:loadValues={myLoadFn} or onReady={({ loadValues }) => ...}
37
+ onReady?: (api: { loadValues: (values: Record<string, unknown>) => void }) => void;
35
38
  // Snippets for custom layout
36
39
  header?: Snippet;
37
40
  children?: Snippet<[{ errors: string[]; warnings: string[] }]>;
@@ -53,7 +56,8 @@
53
56
  footerItemId = 'footer-item',
54
57
  footerItemPriority = 0,
55
58
  header,
56
- children
59
+ children,
60
+ onReady
57
61
  }: Props = $props();
58
62
 
59
63
  // ── Helpers ──────────────────────────────────────────────────────────────────
@@ -118,6 +122,19 @@
118
122
  computeThrottle.trigger($state.snapshot(values));
119
123
  }
120
124
 
125
+ function loadValues(incoming: Record<string, unknown>) {
126
+ Object.assign(values, incoming);
127
+ if (schema?.instanceSolve !== false) {
128
+ performSolve();
129
+ } else {
130
+ hasPendingChanges = true;
131
+ }
132
+ }
133
+
134
+ $effect(() => {
135
+ onReady?.({ loadValues });
136
+ });
137
+
121
138
  // ── Definition switching ─────────────────────────────────────────────────────
122
139
  let previousDefinitionKey = $state('');
123
140
  let isInitialLoad = $state(true);
@@ -17,6 +17,9 @@ interface Props {
17
17
  footerComponentProps?: () => Record<string, unknown>;
18
18
  footerItemId?: string;
19
19
  footerItemPriority?: number;
20
+ onReady?: (api: {
21
+ loadValues: (values: Record<string, unknown>) => void;
22
+ }) => void;
20
23
  header?: Snippet;
21
24
  children?: Snippet<[{
22
25
  errors: string[];
@@ -1,5 +1,5 @@
1
- import { onMount, onDestroy } from 'svelte';
2
- import { useFooter } from '../contexts/footerContext.svelte';
1
+ import { getContext, onMount, onDestroy } from 'svelte';
2
+ import { FOOTER_CONTEXT_KEY } from '../contexts/footerContext.svelte';
3
3
  /**
4
4
  * Register a footer item component that reactively updates its props.
5
5
  * The `getProps` function is called on every render, so returning reactive state
@@ -16,13 +16,15 @@ import { useFooter } from '../contexts/footerContext.svelte';
16
16
  */
17
17
  export function useFooterItem(id, component, getProps, position = 'left', priority = 0, onClick) {
18
18
  onMount(() => {
19
- const footer = useFooter();
20
- footer.register(id, component, getProps, position, priority, onClick);
19
+ const store = getContext(FOOTER_CONTEXT_KEY);
20
+ if (!store || !component)
21
+ return;
22
+ store.register(id, component, getProps, position, priority, onClick);
21
23
  });
22
24
  onDestroy(() => {
23
25
  try {
24
- const footer = useFooter();
25
- footer.unregister(id);
26
+ const store = getContext(FOOTER_CONTEXT_KEY);
27
+ store?.unregister(id);
26
28
  }
27
29
  catch {
28
30
  // Context may not exist during SSR cleanup — safe to ignore
@@ -13,5 +13,6 @@ export interface FooterStore {
13
13
  register(id: string, component: any, getProps: () => Record<string, any>, position?: 'left' | 'right', priority?: number, onClick?: () => void): void;
14
14
  unregister(id: string): void;
15
15
  }
16
+ export declare const FOOTER_CONTEXT_KEY: unique symbol;
16
17
  export declare function initializeFooterContext(): FooterStore;
17
18
  export declare function useFooter(): FooterStore;
@@ -1,6 +1,6 @@
1
1
  import { getContext, setContext } from 'svelte';
2
2
  import { SvelteMap } from 'svelte/reactivity';
3
- const FOOTER_CONTEXT_KEY = Symbol('footer-context');
3
+ export const FOOTER_CONTEXT_KEY = Symbol('footer-context');
4
4
  export function initializeFooterContext() {
5
5
  const items = new SvelteMap();
6
6
  const store = {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "selva-shared",
3
- "version": "0.8.4",
3
+ "version": "0.8.5",
4
4
  "description": "Shared UI components and utilities for Selva applications",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -32,6 +32,9 @@
32
32
  footerComponentProps?: () => Record<string, unknown>;
33
33
  footerItemId?: string;
34
34
  footerItemPriority?: number;
35
+ // Callback to expose the loadValues function to the parent
36
+ // Usage: bind:loadValues={myLoadFn} or onReady={({ loadValues }) => ...}
37
+ onReady?: (api: { loadValues: (values: Record<string, unknown>) => void }) => void;
35
38
  // Snippets for custom layout
36
39
  header?: Snippet;
37
40
  children?: Snippet<[{ errors: string[]; warnings: string[] }]>;
@@ -53,7 +56,8 @@
53
56
  footerItemId = 'footer-item',
54
57
  footerItemPriority = 0,
55
58
  header,
56
- children
59
+ children,
60
+ onReady
57
61
  }: Props = $props();
58
62
 
59
63
  // ── Helpers ──────────────────────────────────────────────────────────────────
@@ -118,6 +122,19 @@
118
122
  computeThrottle.trigger($state.snapshot(values));
119
123
  }
120
124
 
125
+ function loadValues(incoming: Record<string, unknown>) {
126
+ Object.assign(values, incoming);
127
+ if (schema?.instanceSolve !== false) {
128
+ performSolve();
129
+ } else {
130
+ hasPendingChanges = true;
131
+ }
132
+ }
133
+
134
+ $effect(() => {
135
+ onReady?.({ loadValues });
136
+ });
137
+
121
138
  // ── Definition switching ─────────────────────────────────────────────────────
122
139
  let previousDefinitionKey = $state('');
123
140
  let isInitialLoad = $state(true);
@@ -1,5 +1,5 @@
1
- import { onMount, onDestroy } from 'svelte';
2
- import { useFooter } from '$lib/contexts/footerContext.svelte';
1
+ import { getContext, onMount, onDestroy } from 'svelte';
2
+ import { type FooterStore, FOOTER_CONTEXT_KEY } from '$lib/contexts/footerContext.svelte';
3
3
 
4
4
  /**
5
5
  * Register a footer item component that reactively updates its props.
@@ -24,14 +24,15 @@ export function useFooterItem(
24
24
  onClick?: () => void
25
25
  ) {
26
26
  onMount(() => {
27
- const footer = useFooter();
28
- footer.register(id, component, getProps, position, priority, onClick);
27
+ const store = getContext<FooterStore | undefined>(FOOTER_CONTEXT_KEY);
28
+ if (!store || !component) return;
29
+ store.register(id, component, getProps, position, priority, onClick);
29
30
  });
30
31
 
31
32
  onDestroy(() => {
32
33
  try {
33
- const footer = useFooter();
34
- footer.unregister(id);
34
+ const store = getContext<FooterStore | undefined>(FOOTER_CONTEXT_KEY);
35
+ store?.unregister(id);
35
36
  } catch {
36
37
  // Context may not exist during SSR cleanup — safe to ignore
37
38
  }
@@ -24,7 +24,7 @@ export interface FooterStore {
24
24
  unregister(id: string): void;
25
25
  }
26
26
 
27
- const FOOTER_CONTEXT_KEY = Symbol('footer-context');
27
+ export const FOOTER_CONTEXT_KEY = Symbol('footer-context');
28
28
 
29
29
  export function initializeFooterContext(): FooterStore {
30
30
  const items = new SvelteMap<string, FooterItem>();