@picked/svelte 0.0.69 → 0.0.70-next.1

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.
@@ -0,0 +1,30 @@
1
+ <script lang="ts">
2
+ // Test-only harness. `createForm` registers option callbacks with `$effect`,
3
+ // which requires a real component instance — mounting this is how the callback
4
+ // lifecycle (registration on mount, teardown on unmount) gets exercised.
5
+ import { untrack } from 'svelte'
6
+ import type { Store } from 'effector'
7
+ import { createForm, type FormCallbackOptions } from '../create-form.svelte'
8
+
9
+ interface HarnessProps {
10
+ formId: string
11
+ title: Store<string>
12
+ fieldKeys: Store<string[]>
13
+ options?: FormCallbackOptions
14
+ imperativeCallback?: () => void
15
+ }
16
+
17
+ const { formId, title, fieldKeys, options, imperativeCallback }: HarnessProps = $props()
18
+
19
+ // Props are read once, at init, on purpose: the harness is mounted with fixed
20
+ // props to exercise registration and teardown, and `createForm` itself is an
21
+ // init-time call. `untrack` states that intent rather than suppressing the
22
+ // state_referenced_locally warning.
23
+ untrack(() => {
24
+ const instance = createForm(formId, title, fieldKeys, options)
25
+
26
+ if (imperativeCallback) {
27
+ instance.form.onSuccess(imperativeCallback)
28
+ }
29
+ })
30
+ </script>
@@ -1 +1 @@
1
- import{getExperience as e,getPicked as t}from"../hooks/client.js";import{createForm as n}from"@picked/client/form";import*as r from"svelte/internal/client";function i(i,a,o){let s=n({client:t(),experienceInstance:e()},i,a,o);return{...s,form:{...s.form,props:{...s.form.props,onsubmit:e=>s.form.props.onsubmit(e)},onBeforeSubmit:e=>{r.user_effect(()=>s.form.onBeforeSubmit(e))},onSuccess:e=>{r.user_effect(()=>s.form.onSuccess(e))},onError:e=>{r.user_effect(()=>s.form.onError(e))}}}}export{i as createForm};
1
+ import{getExperience as e,getPicked as t}from"../hooks/client.js";import{createForm as n}from"@picked/client/form";import*as r from"svelte/internal/client";function i(i,a,o,s){let c=n({client:t(),experienceInstance:e()},i,a,o);if(s?.onBeforeSubmit){let e=s.onBeforeSubmit;r.user_effect(()=>c.form.onBeforeSubmit(e))}if(s?.onSuccess){let e=s.onSuccess;r.user_effect(()=>c.form.onSuccess(e))}if(s?.onError){let e=s.onError;r.user_effect(()=>c.form.onError(e))}return{...c,form:{...c.form,props:{...c.form.props,onsubmit:e=>c.form.props.onsubmit(e)},onBeforeSubmit:e=>{r.user_effect(()=>c.form.onBeforeSubmit(e))},onSuccess:e=>{r.user_effect(()=>c.form.onSuccess(e))},onError:e=>{r.user_effect(()=>c.form.onError(e))}}}}export{i as createForm};
@@ -1,6 +1,6 @@
1
1
  import { Store } from 'effector';
2
- import { FormInstance as CoreFormInstance, ErrorCallback, SubmitCallback, SubmitEventWithCurrentTarget, SuccessCallback } from '@picked/client/form';
3
- export type { FormField } from '@picked/client/form';
2
+ import { FormInstance as CoreFormInstance, ErrorCallback, FormCallbackOptions, SubmitCallback, SubmitEventWithCurrentTarget, SuccessCallback } from '@picked/client/form';
3
+ export type { FormField, FormCallbackOptions } from '@picked/client/form';
4
4
  /**
5
5
  * Svelte FormInstance — identical to core but callback registration returns void
6
6
  * (cleanup is handled automatically via $effect, not by the consumer).
@@ -28,10 +28,12 @@ export interface FormInstance<TFieldKeys extends string = string> extends Omit<C
28
28
  * @param {string} formId - Unique identifier for this form instance.
29
29
  * @param {Store<string>} title - Reactive store holding the form/step title.
30
30
  * @param {Store<string[]>} fieldKeys - Reactive store of field keys that belong to this form.
31
+ * @param {FormCallbackOptions} [options] - Submit callback slots, registered once for the component's lifetime.
31
32
  * @returns {FormInstance} A form instance with reactive field stores, submission handlers, and callback registration.
32
33
  * @example
33
34
  * ```ts
34
- * const { form, fields } = createForm('lead-capture', $title, $fieldKeys)
35
+ * const { form, fields } = createForm('lead-capture', $title, $fieldKeys, { onSuccess })
35
36
  * ```
37
+ * @design-parity Mirrors `useForm`'s options argument in `@picked/react`.
36
38
  */
37
- export declare function createForm(formId: string, title: Store<string>, fieldKeys: Store<string[]>): FormInstance;
39
+ export declare function createForm(formId: string, title: Store<string>, fieldKeys: Store<string[]>, options?: FormCallbackOptions): FormInstance;
@@ -1,2 +1,3 @@
1
- export type { FormField } from '@picked/client/form';
1
+ /** @file Public surface of `@picked/svelte/form`. */
2
+ export type { FormField, FormCallbackOptions } from '@picked/client/form';
2
3
  export { getForm } from './get-form';
@@ -1,6 +1,6 @@
1
1
  import { Store } from 'effector';
2
2
  import { Content, ExperienceStep } from '@picked/client';
3
- import { FormInstance, FormField } from '../form/create-form.svelte';
3
+ import { FormCallbackOptions, FormInstance, FormField } from '../form/create-form.svelte';
4
4
  export interface StepContext extends FormInstance {
5
5
  step: Store<ExperienceStep>;
6
6
  /** Directly accessible fields with current response values — usable without a form. */
@@ -26,17 +26,29 @@ export interface StepContext extends FormInstance {
26
26
  * Creates and sets step context in the Svelte context tree.
27
27
  *
28
28
  * @param {string} stepKey - The step key.
29
+ * @param {FormCallbackOptions} [options] - Submit callback slots for the step's form.
29
30
  * @returns {StepContext} The created step context.
30
- * @example setStepContext('step-1')
31
+ * @example setStepContext('step-1', { onSuccess: ({ data }) => track(data) })
31
32
  */
32
- export declare function setStepContext(stepKey: string): StepContext;
33
+ export declare function setStepContext(stepKey: string, options?: FormCallbackOptions): StepContext;
33
34
  /**
34
35
  * Retrieves the step context from the Svelte context tree.
35
36
  *
37
+ * Passing `options` registers those callbacks for the calling component's
38
+ * lifetime. It is sugar over `form.onSuccess(cb)` and friends, which already
39
+ * manage their own teardown via `$effect` — the value is symmetry with
40
+ * `useStep(options)` in `@picked/react`, where the options form is what makes
41
+ * render-body registration safe.
42
+ *
43
+ * Must be called during component initialisation, like any other rune-backed
44
+ * helper.
45
+ *
46
+ * @param {FormCallbackOptions} [options] - Submit callback slots for this component.
36
47
  * @returns {StepContext} The current step context.
37
- * @example getStep()
48
+ * @example const { form, fields } = getStep({ onSuccess: ({ data }) => track(data) })
49
+ * @design-parity Mirrors `useStep(options)` in `@picked/react`.
38
50
  */
39
- export declare function getStep(): StepContext;
51
+ export declare function getStep(options?: FormCallbackOptions): StepContext;
40
52
  /**
41
53
  * Returns a Svelte/Effector store that yields the current step's resolved CMS content
42
54
  * data, or `null` when no content is registered for the step's `layoutContentId`.
@@ -1 +1 @@
1
- import{STEP_CONTEXT_KEY as e}from"../context.js";import{getExperience as t,getPicked as n}from"./client.js";import{getStepRouter as r}from"../router/context.js";import{getContext as i,setContext as a}from"svelte";import{combine as o}from"effector";import{createForm as s}from"../form/create-form.svelte";function c(t){let i=n(),{activeStep:c}=r(),l=c.map(e=>e?.key===t),u=i.steps.listStore.map(e=>e.find(e=>e.key===t)??{id:t,key:t,name:``,fieldKeys:[]}),d=s(t,u.map(e=>e.name),u.map(e=>e.fieldKeys)),f=o(u,i.contents.indexStore,(e,t)=>e.layoutContentId?t[e.layoutContentId]??null:null,{skipVoid:!1});return a(e,{step:u,layoutContentStore:f,content:f.map(e=>e?.data??null,{skipVoid:!1}),isActive:l,isActiveStep:l,...d})}function l(){return i(e)}function u(){let t=i(e);return t?t.content:d().map(e=>e?.data??null,{skipVoid:!1})}function d(){let e=t(),r=n();return o(e.treeStore,r.contents.indexStore,(e,t)=>{let n=e.steps.find(e=>e.layoutContentId);return n?.layoutContentId?t[n.layoutContentId]??null:null})}export{l as getStep,u as getStepContent,c as setStepContext};
1
+ import{STEP_CONTEXT_KEY as e}from"../context.js";import{getExperience as t,getPicked as n}from"./client.js";import{getStepRouter as r}from"../router/context.js";import{getContext as i,setContext as a}from"svelte";import{combine as o}from"effector";import{createForm as s}from"../form/create-form.svelte";function c(t,i){let c=n(),{activeStep:l}=r(),u=l.map(e=>e?.key===t),d=c.steps.listStore.map(e=>e.find(e=>e.key===t)??{id:t,key:t,name:``,fieldKeys:[]}),f=s(t,d.map(e=>e.name),d.map(e=>e.fieldKeys),i),p=o(d,c.contents.indexStore,(e,t)=>e.layoutContentId?t[e.layoutContentId]??null:null,{skipVoid:!1});return a(e,{step:d,layoutContentStore:p,content:p.map(e=>e?.data??null,{skipVoid:!1}),isActive:u,isActiveStep:u,...f})}function l(t){let n=i(e);return t?.onBeforeSubmit&&n.form.onBeforeSubmit(t.onBeforeSubmit),t?.onSuccess&&n.form.onSuccess(t.onSuccess),t?.onError&&n.form.onError(t.onError),n}function u(){let t=i(e);return t?t.content:d().map(e=>e?.data??null,{skipVoid:!1})}function d(){let e=t(),r=n();return o(e.treeStore,r.contents.indexStore,(e,t)=>{let n=e.steps.find(e=>e.layoutContentId);return n?.layoutContentId?t[n.layoutContentId]??null:null})}export{l as getStep,u as getStepContent,c as setStepContext};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@picked/svelte",
3
- "version": "0.0.69",
3
+ "version": "0.0.70-next.1",
4
4
  "dependencies": {
5
5
  "d3": "^7.9.0"
6
6
  },
@@ -106,7 +106,7 @@
106
106
  },
107
107
  "module": "./dist/index.js",
108
108
  "peerDependencies": {
109
- "@picked/client": "0.0.69",
109
+ "@picked/client": "0.0.70-next.1",
110
110
  "effector": "^23.3.0",
111
111
  "svelte": "^5.46.4"
112
112
  },