@picked/svelte 0.0.1-dev.1767922288295 → 0.0.1-dev.1767932013788
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.
- package/dist/form/form.svelte.d.ts +161 -10
- package/dist/form/form.svelte.ts +134 -56
- package/dist/hooks/action.d.ts +2 -0
- package/dist/hooks/action.js +1 -0
- package/dist/hooks/feature.d.ts +5 -0
- package/dist/hooks/feature.js +1 -0
- package/dist/hooks/index.d.ts +4 -0
- package/dist/hooks/index.js +1 -1
- package/dist/hooks/predicate.d.ts +3 -0
- package/dist/hooks/predicate.js +1 -0
- package/dist/hooks/step.d.ts +3 -21
- package/dist/hooks/step.js +1 -1
- package/package.json +2 -2
|
@@ -1,26 +1,177 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { FieldValue, ValidationError } from '@picked/client';
|
|
2
2
|
import { EventCallable, Store } from 'effector';
|
|
3
|
-
|
|
4
|
-
interface GetFormOptions {
|
|
3
|
+
type ExtractFieldIds<TFieldIds extends readonly string[]> = TFieldIds[number];
|
|
4
|
+
interface GetFormOptions<TFieldIds extends readonly string[]> {
|
|
5
5
|
id: string;
|
|
6
6
|
title: string;
|
|
7
|
-
|
|
7
|
+
fieldIds: TFieldIds;
|
|
8
8
|
}
|
|
9
|
-
type SuccessCallback = (options: {
|
|
10
|
-
data:
|
|
9
|
+
type SuccessCallback<TFieldIds extends string = string> = (options: {
|
|
10
|
+
data: Record<TFieldIds, FieldValue>;
|
|
11
11
|
stopNavigation: EventCallable<void>;
|
|
12
12
|
}) => void | Promise<void>;
|
|
13
13
|
type ErrorCallback = (errors: ValidationError[]) => void | Promise<void>;
|
|
14
|
-
type SubmitCallback = (data:
|
|
14
|
+
type SubmitCallback<TFieldIds extends string = string> = (data: Record<TFieldIds, FieldValue>) => Record<TFieldIds, FieldValue> | void | Promise<Record<TFieldIds, FieldValue> | void>;
|
|
15
15
|
type SubmitEventWithCurrentTarget = SubmitEvent & {
|
|
16
16
|
currentTarget: EventTarget & HTMLFormElement;
|
|
17
17
|
};
|
|
18
|
-
export declare function getForm({ id: formId, title,
|
|
18
|
+
export declare function getForm<const TFieldIds extends readonly string[]>({ id: formId, title, fieldIds, }: GetFormOptions<TFieldIds>): {
|
|
19
19
|
form: {
|
|
20
20
|
onsubmit: EventCallable<SubmitEventWithCurrentTarget>;
|
|
21
21
|
};
|
|
22
|
-
|
|
23
|
-
|
|
22
|
+
fields: Store<({
|
|
23
|
+
value: FieldValue | undefined;
|
|
24
|
+
type: "text";
|
|
25
|
+
multiple: false;
|
|
26
|
+
defaultValue?: string;
|
|
27
|
+
options?: {
|
|
28
|
+
id: string;
|
|
29
|
+
label: string;
|
|
30
|
+
description?: string;
|
|
31
|
+
value: string;
|
|
32
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
33
|
+
}[] | null;
|
|
34
|
+
id: string;
|
|
35
|
+
name: string;
|
|
36
|
+
label: string;
|
|
37
|
+
required: boolean;
|
|
38
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
39
|
+
placeholder?: string;
|
|
40
|
+
description?: string;
|
|
41
|
+
helpText?: string;
|
|
42
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
43
|
+
policies?: {
|
|
44
|
+
doNotTrackValue?: boolean;
|
|
45
|
+
doNotStoreValue?: boolean;
|
|
46
|
+
};
|
|
47
|
+
} | {
|
|
48
|
+
value: FieldValue | undefined;
|
|
49
|
+
type: "text";
|
|
50
|
+
multiple: true;
|
|
51
|
+
defaultValue?: string[];
|
|
52
|
+
options?: {
|
|
53
|
+
id: string;
|
|
54
|
+
label: string;
|
|
55
|
+
description?: string;
|
|
56
|
+
value: string;
|
|
57
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
58
|
+
}[] | null;
|
|
59
|
+
id: string;
|
|
60
|
+
name: string;
|
|
61
|
+
label: string;
|
|
62
|
+
required: boolean;
|
|
63
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
64
|
+
placeholder?: string;
|
|
65
|
+
description?: string;
|
|
66
|
+
helpText?: string;
|
|
67
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
68
|
+
policies?: {
|
|
69
|
+
doNotTrackValue?: boolean;
|
|
70
|
+
doNotStoreValue?: boolean;
|
|
71
|
+
};
|
|
72
|
+
} | {
|
|
73
|
+
value: FieldValue | undefined;
|
|
74
|
+
type: "number";
|
|
75
|
+
multiple: false;
|
|
76
|
+
defaultValue?: number;
|
|
77
|
+
options?: {
|
|
78
|
+
id: string;
|
|
79
|
+
label: string;
|
|
80
|
+
description?: string;
|
|
81
|
+
value: number;
|
|
82
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
83
|
+
}[] | null;
|
|
84
|
+
id: string;
|
|
85
|
+
name: string;
|
|
86
|
+
label: string;
|
|
87
|
+
required: boolean;
|
|
88
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
89
|
+
placeholder?: string;
|
|
90
|
+
description?: string;
|
|
91
|
+
helpText?: string;
|
|
92
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
93
|
+
policies?: {
|
|
94
|
+
doNotTrackValue?: boolean;
|
|
95
|
+
doNotStoreValue?: boolean;
|
|
96
|
+
};
|
|
97
|
+
} | {
|
|
98
|
+
value: FieldValue | undefined;
|
|
99
|
+
type: "number";
|
|
100
|
+
multiple: true;
|
|
101
|
+
defaultValue?: number[];
|
|
102
|
+
options?: {
|
|
103
|
+
id: string;
|
|
104
|
+
label: string;
|
|
105
|
+
description?: string;
|
|
106
|
+
value: number;
|
|
107
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
108
|
+
}[] | null;
|
|
109
|
+
id: string;
|
|
110
|
+
name: string;
|
|
111
|
+
label: string;
|
|
112
|
+
required: boolean;
|
|
113
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
114
|
+
placeholder?: string;
|
|
115
|
+
description?: string;
|
|
116
|
+
helpText?: string;
|
|
117
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
118
|
+
policies?: {
|
|
119
|
+
doNotTrackValue?: boolean;
|
|
120
|
+
doNotStoreValue?: boolean;
|
|
121
|
+
};
|
|
122
|
+
} | {
|
|
123
|
+
value: FieldValue | undefined;
|
|
124
|
+
type: "boolean";
|
|
125
|
+
multiple: false;
|
|
126
|
+
defaultValue?: boolean;
|
|
127
|
+
options?: {
|
|
128
|
+
id: string;
|
|
129
|
+
label: string;
|
|
130
|
+
description?: string;
|
|
131
|
+
value: boolean;
|
|
132
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
133
|
+
}[] | null;
|
|
134
|
+
id: string;
|
|
135
|
+
name: string;
|
|
136
|
+
label: string;
|
|
137
|
+
required: boolean;
|
|
138
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
139
|
+
placeholder?: string;
|
|
140
|
+
description?: string;
|
|
141
|
+
helpText?: string;
|
|
142
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
143
|
+
policies?: {
|
|
144
|
+
doNotTrackValue?: boolean;
|
|
145
|
+
doNotStoreValue?: boolean;
|
|
146
|
+
};
|
|
147
|
+
} | {
|
|
148
|
+
value: FieldValue | undefined;
|
|
149
|
+
type: "boolean";
|
|
150
|
+
multiple: true;
|
|
151
|
+
defaultValue?: boolean[];
|
|
152
|
+
options?: {
|
|
153
|
+
id: string;
|
|
154
|
+
label: string;
|
|
155
|
+
description?: string;
|
|
156
|
+
value: boolean;
|
|
157
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
158
|
+
}[] | null;
|
|
159
|
+
id: string;
|
|
160
|
+
name: string;
|
|
161
|
+
label: string;
|
|
162
|
+
required: boolean;
|
|
163
|
+
condition?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
164
|
+
placeholder?: string;
|
|
165
|
+
description?: string;
|
|
166
|
+
helpText?: string;
|
|
167
|
+
validation?: import('node_modules/@picked/client/dist/types/logic-engine').LogicRule;
|
|
168
|
+
policies?: {
|
|
169
|
+
doNotTrackValue?: boolean;
|
|
170
|
+
doNotStoreValue?: boolean;
|
|
171
|
+
};
|
|
172
|
+
})[]>;
|
|
173
|
+
onFormSubmit: (callback: SubmitCallback<ExtractFieldIds<TFieldIds>>) => void;
|
|
174
|
+
onFormSuccess: (callback: SuccessCallback<ExtractFieldIds<TFieldIds>>) => void;
|
|
24
175
|
onFormError: (callback: ErrorCallback) => void;
|
|
25
176
|
isFormSubmitting: import('effector').StoreWritable<boolean>;
|
|
26
177
|
};
|
package/dist/form/form.svelte.ts
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type {
|
|
2
|
-
CommitResponses,
|
|
3
2
|
ExperienceStep,
|
|
4
3
|
Field,
|
|
5
4
|
FieldValue,
|
|
6
5
|
ValidationError,
|
|
7
6
|
ExperienceInstance,
|
|
8
7
|
} from '@picked/client'
|
|
8
|
+
import { getStepFields } from '@picked/client'
|
|
9
9
|
import {
|
|
10
10
|
attach,
|
|
11
11
|
createEffect,
|
|
@@ -15,33 +15,39 @@ import {
|
|
|
15
15
|
split,
|
|
16
16
|
type EventCallable,
|
|
17
17
|
type Store,
|
|
18
|
+
combine,
|
|
18
19
|
} from 'effector'
|
|
19
|
-
import { getPicked, getExperience
|
|
20
|
+
import { getPicked, getExperience } from '../hooks'
|
|
20
21
|
|
|
21
22
|
interface Response {
|
|
22
23
|
questionId: Field['id']
|
|
23
24
|
value: FieldValue
|
|
24
25
|
}
|
|
25
26
|
|
|
26
|
-
|
|
27
|
+
// Extract field IDs from a readonly string array
|
|
28
|
+
type ExtractFieldIds<TFieldIds extends readonly string[]> = TFieldIds[number]
|
|
29
|
+
|
|
30
|
+
interface GetFormOptions<TFieldIds extends readonly string[]> {
|
|
27
31
|
id: string
|
|
28
32
|
title: string
|
|
29
|
-
|
|
33
|
+
fieldIds: TFieldIds
|
|
30
34
|
}
|
|
31
35
|
|
|
32
|
-
interface CommitResult {
|
|
33
|
-
data:
|
|
36
|
+
interface CommitResult<TFieldIds extends string = string> {
|
|
37
|
+
data: Record<TFieldIds, FieldValue>
|
|
34
38
|
errors: ValidationError[]
|
|
35
39
|
}
|
|
36
40
|
|
|
37
|
-
type SuccessCallback = (options: {
|
|
38
|
-
data:
|
|
41
|
+
type SuccessCallback<TFieldIds extends string = string> = (options: {
|
|
42
|
+
data: Record<TFieldIds, FieldValue>
|
|
39
43
|
stopNavigation: EventCallable<void>
|
|
40
44
|
}) => void | Promise<void>
|
|
45
|
+
|
|
41
46
|
type ErrorCallback = (errors: ValidationError[]) => void | Promise<void>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
47
|
+
|
|
48
|
+
type SubmitCallback<TFieldIds extends string = string> = (
|
|
49
|
+
data: Record<TFieldIds, FieldValue>,
|
|
50
|
+
) => Record<TFieldIds, FieldValue> | void | Promise<Record<TFieldIds, FieldValue> | void>
|
|
45
51
|
|
|
46
52
|
type SubmitEventWithCurrentTarget = SubmitEvent & { currentTarget: EventTarget & HTMLFormElement }
|
|
47
53
|
|
|
@@ -70,13 +76,67 @@ function createObserver<TCallback extends (...args: any[]) => any, TReturn = voi
|
|
|
70
76
|
return { executeFx, register }
|
|
71
77
|
}
|
|
72
78
|
|
|
73
|
-
export function getForm
|
|
79
|
+
export function getForm<const TFieldIds extends readonly string[]>({
|
|
80
|
+
id: formId,
|
|
81
|
+
title,
|
|
82
|
+
fieldIds,
|
|
83
|
+
}: GetFormOptions<TFieldIds>) {
|
|
84
|
+
type FieldId = ExtractFieldIds<TFieldIds>
|
|
74
85
|
const client = getPicked()
|
|
75
|
-
|
|
76
|
-
|
|
86
|
+
|
|
87
|
+
// Make experience and router context optional
|
|
88
|
+
let experienceInstance: ExperienceInstance | null = null
|
|
89
|
+
let stepStore: Store<ExperienceStep | null>
|
|
90
|
+
let goToNextStep: EventCallable<void> | null = null
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
experienceInstance = getExperience()
|
|
94
|
+
stepStore = experienceInstance.currentStepStore
|
|
95
|
+
goToNextStep = experienceInstance.goToNextStep
|
|
96
|
+
} catch {
|
|
97
|
+
// Not in experience context - create null store for standalone forms
|
|
98
|
+
stepStore = createStore<ExperienceStep | null>(null)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Create internal fields store
|
|
102
|
+
const fieldsStore = createStore<Field[]>([])
|
|
103
|
+
|
|
104
|
+
// Create fields with values store for UI
|
|
105
|
+
const fieldsWithValues = combine(
|
|
106
|
+
{
|
|
107
|
+
fields: fieldsStore,
|
|
108
|
+
responses: client.responses.listStore,
|
|
109
|
+
},
|
|
110
|
+
({ fields, responses }) => {
|
|
111
|
+
return fields.map((field) => {
|
|
112
|
+
const value = responses.find((r) => r.fieldId === field.id)?.value
|
|
113
|
+
return { ...field, value }
|
|
114
|
+
})
|
|
115
|
+
},
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
// Filter and evaluate fields based on fieldIds
|
|
119
|
+
const evaluateFieldsFx = attach({
|
|
120
|
+
source: client.fields.listStore,
|
|
121
|
+
effect: createEffect(async (allFields: Field[]) => {
|
|
122
|
+
const filteredFields = allFields.filter((field) =>
|
|
123
|
+
fieldIds.some((id) => id === field.id),
|
|
124
|
+
)
|
|
125
|
+
return await getStepFields(client, filteredFields)
|
|
126
|
+
}),
|
|
127
|
+
})
|
|
128
|
+
|
|
129
|
+
// Populate fields store when fields are evaluated
|
|
130
|
+
sample({
|
|
131
|
+
clock: evaluateFieldsFx.doneData,
|
|
132
|
+
target: fieldsStore,
|
|
133
|
+
})
|
|
134
|
+
|
|
135
|
+
// Auto-trigger field evaluation on form creation
|
|
136
|
+
evaluateFieldsFx()
|
|
77
137
|
|
|
78
138
|
const submitEvent = createEvent<SubmitEventWithCurrentTarget>()
|
|
79
|
-
const formSuccessEvent = createEvent<
|
|
139
|
+
const formSuccessEvent = createEvent<Record<FieldId, FieldValue>>()
|
|
80
140
|
const formErrorEvent = createEvent<ValidationError[]>()
|
|
81
141
|
const stopNavigationEvent = createEvent<void>()
|
|
82
142
|
const allCallbacksCompleteEvent = createEvent<void>()
|
|
@@ -88,7 +148,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
88
148
|
.on(submitEvent, () => false) // Reset to false on new submit
|
|
89
149
|
|
|
90
150
|
// Create observers for each callback type
|
|
91
|
-
const successObserver = createObserver<SuccessCallback
|
|
151
|
+
const successObserver = createObserver<SuccessCallback<FieldId>>(async (callbacks, options) => {
|
|
92
152
|
await Promise.all(callbacks.map((callback) => Promise.resolve(callback(options))))
|
|
93
153
|
})
|
|
94
154
|
|
|
@@ -96,7 +156,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
96
156
|
await Promise.all(callbacks.map((callback) => Promise.resolve(callback(errors))))
|
|
97
157
|
})
|
|
98
158
|
|
|
99
|
-
const submitObserver = createObserver<SubmitCallback,
|
|
159
|
+
const submitObserver = createObserver<SubmitCallback<FieldId>, Record<FieldId, FieldValue>>(
|
|
100
160
|
async (callbacks, data) => {
|
|
101
161
|
let transformedData = data
|
|
102
162
|
|
|
@@ -113,7 +173,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
113
173
|
},
|
|
114
174
|
)
|
|
115
175
|
|
|
116
|
-
const commitFx = createEffect(async (responses:
|
|
176
|
+
const commitFx = createEffect(async (responses: Record<FieldId, FieldValue>) => {
|
|
117
177
|
const result = await client.responses.commit(responses)
|
|
118
178
|
// Merge submitted data with validation result
|
|
119
179
|
return {
|
|
@@ -124,18 +184,28 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
124
184
|
|
|
125
185
|
const onSuccessFx = attach({
|
|
126
186
|
source: { step: stepStore },
|
|
127
|
-
mapParams: (commitResult: CommitResult
|
|
187
|
+
mapParams: (commitResult: CommitResult<FieldId>, source) => ({
|
|
128
188
|
step: source.step,
|
|
129
189
|
data: commitResult.data,
|
|
130
190
|
}),
|
|
131
191
|
effect: createEffect(
|
|
132
|
-
async ({
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
192
|
+
async ({
|
|
193
|
+
step,
|
|
194
|
+
data,
|
|
195
|
+
}: {
|
|
196
|
+
step: ExperienceStep | null
|
|
197
|
+
data: Record<FieldId, FieldValue>
|
|
198
|
+
}) => {
|
|
199
|
+
// Only fire events if in experience context
|
|
200
|
+
if (experienceInstance) {
|
|
201
|
+
client.eventBus({
|
|
202
|
+
type: 'form_submit_success',
|
|
203
|
+
form: { id: formId, title },
|
|
204
|
+
experience: experienceInstance,
|
|
205
|
+
step: step ?? undefined,
|
|
206
|
+
})
|
|
207
|
+
}
|
|
208
|
+
|
|
139
209
|
return data
|
|
140
210
|
},
|
|
141
211
|
),
|
|
@@ -143,28 +213,31 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
143
213
|
|
|
144
214
|
const onErrorFx = attach({
|
|
145
215
|
source: { step: stepStore },
|
|
146
|
-
mapParams: (commitResult: CommitResult
|
|
216
|
+
mapParams: (commitResult: CommitResult<FieldId>, source) => ({
|
|
147
217
|
step: source.step,
|
|
148
218
|
errors: commitResult.errors,
|
|
149
219
|
}),
|
|
150
220
|
effect: createEffect(
|
|
151
221
|
async ({ step, errors }: { step: ExperienceStep | null; errors: ValidationError[] }) => {
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
form: { id: formId, title },
|
|
155
|
-
exception: { reason: errors },
|
|
156
|
-
experience: experienceInstance,
|
|
157
|
-
step: step ?? undefined,
|
|
158
|
-
})
|
|
159
|
-
|
|
160
|
-
errors.forEach((exception) => {
|
|
222
|
+
// Only fire events if in experience context
|
|
223
|
+
if (experienceInstance) {
|
|
161
224
|
client.eventBus({
|
|
162
|
-
type: '
|
|
163
|
-
|
|
225
|
+
type: 'form_submit_error',
|
|
226
|
+
form: { id: formId, title },
|
|
227
|
+
exception: { reason: errors },
|
|
164
228
|
experience: experienceInstance,
|
|
165
229
|
step: step ?? undefined,
|
|
166
230
|
})
|
|
167
|
-
|
|
231
|
+
|
|
232
|
+
errors.forEach((exception) => {
|
|
233
|
+
client.eventBus({
|
|
234
|
+
type: 'field_validation_error',
|
|
235
|
+
exception: { reason: [exception] },
|
|
236
|
+
experience: experienceInstance,
|
|
237
|
+
step: step ?? undefined,
|
|
238
|
+
})
|
|
239
|
+
})
|
|
240
|
+
}
|
|
168
241
|
|
|
169
242
|
return errors
|
|
170
243
|
},
|
|
@@ -192,12 +265,15 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
192
265
|
title: string
|
|
193
266
|
step: ExperienceStep | null
|
|
194
267
|
}) => {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
268
|
+
// Only fire events if in experience context
|
|
269
|
+
if (experienceInstance) {
|
|
270
|
+
client.eventBus({
|
|
271
|
+
type: 'form_submit',
|
|
272
|
+
form: { id: formIdParam, title: titleParam },
|
|
273
|
+
experience: experienceInstance,
|
|
274
|
+
step: step ?? undefined,
|
|
275
|
+
})
|
|
276
|
+
}
|
|
201
277
|
},
|
|
202
278
|
),
|
|
203
279
|
})
|
|
@@ -205,10 +281,9 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
205
281
|
sample({
|
|
206
282
|
clock: submitEvent,
|
|
207
283
|
source: {
|
|
208
|
-
|
|
209
|
-
stepFields: fields,
|
|
284
|
+
stepFields: fieldsStore,
|
|
210
285
|
},
|
|
211
|
-
fn: ({ stepFields }, event) => {
|
|
286
|
+
fn: ({ stepFields }, event): Record<FieldId, FieldValue> => {
|
|
212
287
|
event.preventDefault()
|
|
213
288
|
|
|
214
289
|
const formData = new FormData(event.currentTarget)
|
|
@@ -244,7 +319,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
244
319
|
},
|
|
245
320
|
}
|
|
246
321
|
|
|
247
|
-
stepFields.forEach((field) => {
|
|
322
|
+
stepFields.forEach((field: Field) => {
|
|
248
323
|
let fieldEntries = formDataEntries.filter(([key]) => key === field.id)
|
|
249
324
|
|
|
250
325
|
if (fieldEntries.length === 0) {
|
|
@@ -341,13 +416,15 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
341
416
|
target: allCallbacksCompleteEvent,
|
|
342
417
|
})
|
|
343
418
|
|
|
344
|
-
// Check navigation after all callbacks complete
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
419
|
+
// Check navigation after all callbacks complete (only if in router context)
|
|
420
|
+
if (goToNextStep) {
|
|
421
|
+
sample({
|
|
422
|
+
clock: allCallbacksCompleteEvent,
|
|
423
|
+
source: stopNavigationStore,
|
|
424
|
+
filter: (stop) => !stop,
|
|
425
|
+
target: goToNextStep,
|
|
426
|
+
})
|
|
427
|
+
}
|
|
351
428
|
|
|
352
429
|
// Declarative event wiring for error flow
|
|
353
430
|
sample({
|
|
@@ -371,6 +448,7 @@ export function getForm({ id: formId, title, fields }: GetFormOptions) {
|
|
|
371
448
|
form: {
|
|
372
449
|
onsubmit: submitEvent,
|
|
373
450
|
},
|
|
451
|
+
fields: fieldsWithValues,
|
|
374
452
|
onFormSubmit: submitObserver.register,
|
|
375
453
|
onFormSuccess: successObserver.register,
|
|
376
454
|
onFormError: errorObserver.register,
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createStore as s,createEvent as f,attach as l,createEffect as u,sample as a}from"effector";import{getPicked as m}from"./client.js";function g(t){return m().actions.getEvokableAction(t)}function v(t){const c=g(t),o=s(void 0,{skipVoid:!1}),n=f(),r=l({source:c,mapParams:(e,i)=>i,effect:u(async e=>{if(e)return e()})});return a({clock:n,target:r}),a({clock:r.doneData,target:o}),n(),o}export{g as getAction,v as getActionResult};
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function getFeature(featureName: string): import('effector').Store<() => Promise<boolean | string | undefined>>;
|
|
2
|
+
export declare function getFeatureResult(featureName: string): import('effector').StoreWritable<{
|
|
3
|
+
id: string;
|
|
4
|
+
bucket: string | boolean;
|
|
5
|
+
} | undefined>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{createStore as i,createEvent as s,attach as f,createEffect as l,sample as o}from"effector";import{getPicked as v}from"./client.js";function d(t){return v().features.getEvokableFeature(t)}function m(t){const r=d(t),c=i(void 0,{skipVoid:!1}),a=s(),n=f({source:r,mapParams:(e,u)=>u,effect:l(async e=>await e())});return o({clock:a,target:n}),o({clock:n.doneData,fn:e=>{if(e!==void 0)return{id:t,bucket:e}},target:c}),a(),o({clock:r,target:a}),c}export{d as getFeature,m as getFeatureResult};
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
export { getPicked, getExperience } from './client';
|
|
2
2
|
export { getStep, setStepContext, type FieldWithValue } from './step';
|
|
3
3
|
export { getField } from './field';
|
|
4
|
+
export { getForm } from '../form';
|
|
5
|
+
export { getAction, getActionResult } from './action';
|
|
6
|
+
export { getFeature, getFeatureResult } from './feature';
|
|
7
|
+
export { getPredicate, getPredicateResult } from './predicate';
|
|
4
8
|
export { useUnit, getContextScope, setContextScope } from './stores';
|
|
5
9
|
export { createSessionStorageStore, createLocalStorageStore } from './storage.js';
|
|
6
10
|
export { getTrackRecommendationPresentEvent } from './events';
|
package/dist/hooks/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getExperience as r,getPicked as o}from"./client.js";import{getStep as c,setStepContext as
|
|
1
|
+
import{getExperience as r,getPicked as o}from"./client.js";import{getStep as c,setStepContext as g}from"./step.js";import{getField as m}from"./field.js";import{getForm as n}from"../form/form.svelte";import{getAction as s,getActionResult as i}from"./action.js";import{getFeature as S,getFeatureResult as d}from"./feature.js";import{getPredicate as P,getPredicateResult as C}from"./predicate.js";import{getContextScope as R,setContextScope as y,useUnit as k}from"./stores.js";import{createLocalStorageStore as A,createSessionStorageStore as E}from"./storage.js";import{getTrackRecommendationPresentEvent as v}from"./events.js";import{createQuery as Q,queryCache as T,queryPresets as U}from"./create-query/index.js";export{A as createLocalStorageStore,Q as createQuery,E as createSessionStorageStore,s as getAction,i as getActionResult,R as getContextScope,r as getExperience,S as getFeature,d as getFeatureResult,m as getField,n as getForm,o as getPicked,P as getPredicate,C as getPredicateResult,c as getStep,v as getTrackRecommendationPresentEvent,T as queryCache,U as queryPresets,y as setContextScope,g as setStepContext,k as useUnit};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import { Predicate } from '@picked/client';
|
|
2
|
+
export declare function getPredicate(predicateName: string): import('effector').Store<() => ReturnType<Predicate>>;
|
|
3
|
+
export declare function getPredicateResult(predicateName: string): import('effector').StoreWritable<string | boolean | string[] | undefined>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import"@picked/client";import{createStore as s,createEvent as d,attach as l,createEffect as f,sample as a}from"effector";import{getPicked as u}from"./client.js";function m(e){return u().predicates.getEvokablePredicate(e)}function v(e){const t=m(e),o=s(void 0,{skipVoid:!1}),r=d(),i=l({source:t,mapParams:(c,n)=>n,effect:f(async c=>{if(c)return await c()})});return a({clock:r,target:i}),a({clock:i.doneData,target:o}),r(),a({clock:t,target:r}),o}export{m as getPredicate,v as getPredicateResult};
|
package/dist/hooks/step.d.ts
CHANGED
|
@@ -1,30 +1,12 @@
|
|
|
1
1
|
import { Store } from 'effector';
|
|
2
|
-
import { ExperienceStep,
|
|
2
|
+
import { ExperienceStep, Response, Field } from '@picked/client';
|
|
3
3
|
import { getForm } from '../form';
|
|
4
4
|
export type FieldWithValue = Field & {
|
|
5
5
|
value: Response | undefined;
|
|
6
6
|
};
|
|
7
|
-
export interface StepContext {
|
|
7
|
+
export interface StepContext extends ReturnType<typeof getForm> {
|
|
8
8
|
step: Store<ExperienceStep>;
|
|
9
|
-
fields: Store<FieldWithValue[]>;
|
|
10
9
|
isActiveStep: Store<boolean>;
|
|
11
|
-
form: ReturnType<typeof getForm>;
|
|
12
10
|
}
|
|
13
|
-
export declare function getStep():
|
|
14
|
-
form: {
|
|
15
|
-
onsubmit: import('effector').EventCallable<SubmitEvent & {
|
|
16
|
-
currentTarget: EventTarget & HTMLFormElement;
|
|
17
|
-
}>;
|
|
18
|
-
};
|
|
19
|
-
onFormSubmit: (callback: (data: import('@picked/client').CommitResponses) => import('@picked/client').CommitResponses | void | Promise<import('@picked/client').CommitResponses | void>) => void;
|
|
20
|
-
onFormSuccess: (callback: (options: {
|
|
21
|
-
data: import('@picked/client').CommitResponses;
|
|
22
|
-
stopNavigation: import('effector').EventCallable<void>;
|
|
23
|
-
}) => void | Promise<void>) => void;
|
|
24
|
-
onFormError: (callback: (errors: import('@picked/client').ValidationError[]) => void | Promise<void>) => void;
|
|
25
|
-
isFormSubmitting: import('effector').StoreWritable<boolean>;
|
|
26
|
-
step: Store<ExperienceStep>;
|
|
27
|
-
fields: Store<FieldWithValue[]>;
|
|
28
|
-
isActiveStep: Store<boolean>;
|
|
29
|
-
};
|
|
11
|
+
export declare function getStep(): StepContext;
|
|
30
12
|
export declare function setStepContext(stepId: string): StepContext;
|
package/dist/hooks/step.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{getContext as
|
|
1
|
+
import{getContext as x,setContext as u}from"svelte";import{STEP_CONTEXT_KEY as n}from"../context.js";import{getStepRouter as a}from"../router/context.js";import{getForm as g}from"../form/form.svelte";import{getExperience as E}from"./client.js";function w(){return x(n)}function T(t){const i=E(),{activeStep:c}=a(),m=c.map(e=>(e==null?void 0:e.id)===t),o=i.treeStore.map(e=>{const r=e.steps.find(s=>s.id===t);if(!r)throw new Error(`Step with id "${t}" not found in the experience tree.`);return r}),{label:p,fieldIds:f}=o.getState(),S=g({id:`${t}`,title:p||t,fieldIds:f});return u(n,{step:o,isActiveStep:m,...S})}export{w as getStep,T as setStepContext};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@picked/svelte",
|
|
3
|
-
"version": "0.0.1-dev.
|
|
3
|
+
"version": "0.0.1-dev.1767932013788",
|
|
4
4
|
"dependencies": {
|
|
5
5
|
"d3": "^7.9.0"
|
|
6
6
|
},
|
|
@@ -75,7 +75,7 @@
|
|
|
75
75
|
],
|
|
76
76
|
"module": "./dist/index.js",
|
|
77
77
|
"peerDependencies": {
|
|
78
|
-
"@picked/client": "0.0.1-dev.
|
|
78
|
+
"@picked/client": "0.0.1-dev.1767932013788",
|
|
79
79
|
"effector": "^23.3.0",
|
|
80
80
|
"svelte": "^5.34.3"
|
|
81
81
|
},
|