effector-final-form
Advanced tools
Comparing version 0.4.0 to 0.5.0
@@ -1,10 +0,7 @@ | ||
import type { FormApi as FFFormApi } from 'final-form'; | ||
import type { createFields } from './createFields'; | ||
import type { Store } from 'effector'; | ||
import type { FormApi as FFFormApi, FieldState as FFFieldState } from 'final-form'; | ||
import type { createFormState } from './createFormState'; | ||
import type { FormSubscription } from './types'; | ||
import type { FormSubscription, ValidationResult } from './types'; | ||
declare const createApi: <FormValues, T extends FormSubscription>(config: { | ||
finalForm: FFFormApi<FormValues, Partial<FormValues>>; | ||
fieldsApi: { | ||
update: import("effector").Event<import("final-form").FieldState<FormValues[keyof FormValues]>>; | ||
}; | ||
formStateApi: { | ||
@@ -29,18 +26,22 @@ update: import("effector").Event<Omit<Pick<Omit<import("final-form").FormState<FormValues, Partial<FormValues>>, "active" | "errors" | "modified" | "submitErrors" | "touched" | "visited"> & { | ||
}; | ||
revalidateFx: () => void; | ||
}) => { | ||
blurFx: import("effector").Effect<keyof FormValues, void, Error>; | ||
changeFx: import("effector").Effect<{ | ||
name: keyof FormValues; | ||
value?: FormValues[keyof FormValues] | undefined; | ||
}, void, Error>; | ||
focusFx: import("effector").Effect<keyof FormValues, void, Error>; | ||
initialize: import("effector").Effect<Partial<FormValues> | ((values: FormValues) => Partial<FormValues>), void, Error>; | ||
pauseValidation: import("effector").Effect<void, void, Error>; | ||
registerField: import("effector").Effect<{ | ||
registerField: <P, T_1 extends readonly (keyof import("final-form").FieldSubscription)[] = readonly (keyof import("final-form").FieldSubscription)[]>({ name, subscribeOn, config, initialValue, validate, }: { | ||
name: keyof FormValues; | ||
subscribeOn: readonly (keyof import("final-form").FieldSubscription)[]; | ||
config?: import("final-form").FieldConfig<FormValues[keyof FormValues]> | undefined; | ||
}, void, Error>; | ||
subscribeOn: T_1; | ||
initialValue?: P | Store<P> | undefined; | ||
validate?: ((value?: P | undefined) => ValidationResult) | undefined; | ||
config?: Omit<import("final-form").FieldConfig<FormValues[keyof FormValues]>, "initialValue" | "getValidator"> | undefined; | ||
}) => { | ||
api: { | ||
blurFx: import("effector").Effect<void, void, Error>; | ||
changeFx: import("effector").Effect<void | FormValues[keyof FormValues] | undefined, void, Error>; | ||
focusFx: import("effector").Effect<void, void, Error>; | ||
resetState: import("effector").Effect<void, void, Error>; | ||
setValidationFn: (fn: Required<((value?: P | undefined) => ValidationResult) | undefined>) => void; | ||
}; | ||
$state: Store<Pick<FFFieldState<P>, "value" | T_1[number]>>; | ||
}; | ||
reset: import("effector").Effect<void | Partial<FormValues> | undefined, void, Error>; | ||
resetFieldState: import("effector").Effect<keyof FormValues, void, Error>; | ||
restart: import("effector").Effect<void | Partial<FormValues> | undefined, void, Error>; | ||
@@ -47,0 +48,0 @@ resumeValidation: import("effector").Effect<void, void, Error>; |
import type { Config as FFConfig } from 'final-form'; | ||
import type { FormSubscription } from './types'; | ||
declare const createForm: <FormValues, T extends FormSubscription>(config: Omit<FFConfig<FormValues, Partial<FormValues>>, "debug"> & { | ||
declare const createForm: <FormValues extends {}, T extends FormSubscription = FormSubscription>(config: Omit<FFConfig<FormValues, Partial<FormValues>>, "initialValues" | "validate" | "debug"> & { | ||
subscribeOn: T; | ||
@@ -8,19 +8,24 @@ }) => { | ||
revalidateFx: import("effector").Effect<void, void, Error>; | ||
setSubmitFn: (fn: (params: FormValues) => void | import("final-form").SubmissionErrors | Promise<void | import("final-form").SubmissionErrors>) => void; | ||
setValidationFn: (fn: (params: FormValues) => import("final-form").ValidationErrors | Promise<import("final-form").ValidationErrors>) => void; | ||
blurFx: import("effector").Effect<keyof FormValues, void, Error>; | ||
changeFx: import("effector").Effect<{ | ||
name: keyof FormValues; | ||
value?: FormValues[keyof FormValues] | undefined; | ||
}, void, Error>; | ||
focusFx: import("effector").Effect<keyof FormValues, void, Error>; | ||
initialize: import("effector").Effect<Partial<FormValues> | ((values: FormValues) => Partial<FormValues>), void, Error>; | ||
setSubmitFn: { | ||
(handler: (params: FormValues) => void | import("final-form").SubmissionErrors | Promise<void | import("final-form").SubmissionErrors>): import("effector").Effect<FormValues, void | import("final-form").SubmissionErrors, Error>; | ||
getCurrent(): (params: FormValues) => Promise<void | import("final-form").SubmissionErrors>; | ||
}; | ||
pauseValidation: import("effector").Effect<void, void, Error>; | ||
registerField: import("effector").Effect<{ | ||
registerField: <P, T_1 extends readonly (keyof import("final-form").FieldSubscription)[] = readonly (keyof import("final-form").FieldSubscription)[]>({ name, subscribeOn, config, initialValue, validate, }: { | ||
name: keyof FormValues; | ||
subscribeOn: readonly (keyof import("final-form").FieldSubscription)[]; | ||
config?: import("final-form").FieldConfig<FormValues[keyof FormValues]> | undefined; | ||
}, void, Error>; | ||
subscribeOn: T_1; | ||
initialValue?: P | import("effector").Store<P> | undefined; | ||
validate?: ((value?: P | undefined) => any) | undefined; | ||
config?: Omit<import("final-form").FieldConfig<FormValues[keyof FormValues]>, "initialValue" | "getValidator"> | undefined; | ||
}) => { | ||
api: { | ||
blurFx: import("effector").Effect<void, void, Error>; | ||
changeFx: import("effector").Effect<void | FormValues[keyof FormValues] | undefined, void, Error>; | ||
focusFx: import("effector").Effect<void, void, Error>; | ||
resetState: import("effector").Effect<void, void, Error>; | ||
setValidationFn: (fn: Required<((value?: P | undefined) => any) | undefined>) => void; | ||
}; | ||
$state: import("effector").Store<Pick<import("final-form").FieldState<P>, "value" | T_1[number]>>; | ||
}; | ||
reset: import("effector").Effect<void | Partial<FormValues> | undefined, void, Error>; | ||
resetFieldState: import("effector").Effect<keyof FormValues, void, Error>; | ||
restart: import("effector").Effect<void | Partial<FormValues> | undefined, void, Error>; | ||
@@ -30,3 +35,2 @@ resumeValidation: import("effector").Effect<void, void, Error>; | ||
}; | ||
$fields: import("effector").Store<{ [T_1 in keyof FormValues]: import("final-form").FieldState<FormValues[keyof FormValues]>; }>; | ||
$formState: import("effector").Store<Pick<Omit<import("final-form").FormState<FormValues, Partial<FormValues>>, "active" | "errors" | "modified" | "submitErrors" | "touched" | "visited"> & { | ||
@@ -48,4 +52,3 @@ active: Exclude<keyof FormValues, undefined> | null; | ||
}>; | ||
$registeredFields: import("effector").Store<[] | (keyof FormValues)[]>; | ||
}; | ||
export { createForm }; |
@@ -1,4 +0,4 @@ | ||
import { createEffect as l, createEvent as F, createStore as O, sample as E, is as P } from "effector"; | ||
import { fieldSubscriptionItems as h, formSubscriptionItems as x, createForm as $ } from "final-form"; | ||
function S(e) { | ||
import { createEffect as u, is as H, createEvent as g, createStore as h, sample as R } from "effector"; | ||
import { fieldSubscriptionItems as $, formSubscriptionItems as z, createForm as D } from "final-form"; | ||
function _(e) { | ||
if (e === null) | ||
@@ -13,8 +13,8 @@ return "Null"; | ||
} | ||
const b = (e) => { | ||
const v = (e) => { | ||
const t = e.__proto__.toString(); | ||
return ["Error", "TypeError"].includes(t) ? [t, e.message] : []; | ||
}, V = (e) => e.toDateString ? [!0, e.getTime()] : [!1], y = (e) => e.constructor !== RegExp ? [!1] : [!0, e.toString()], g = (e, t) => { | ||
const r = S(e); | ||
if (r !== S(t)) | ||
}, N = (e) => e.toDateString ? [!0, e.getTime()] : [!1], O = (e) => e.constructor !== RegExp ? [!1] : [!0, e.toString()], S = (e, t) => { | ||
const r = _(e); | ||
if (r !== _(t)) | ||
return !1; | ||
@@ -30,101 +30,117 @@ if (r === "Function") | ||
if (r === "Array") { | ||
const o = Array.from(e), u = Array.from(t); | ||
return o.toString() !== u.toString() ? !1 : o.every((f, p) => f === u[p] || g(f, u[p])); | ||
const s = Array.from(e), c = Array.from(t); | ||
return s.toString() !== c.toString() ? !1 : s.every((p, f) => p === c[f] || S(p, c[f])); | ||
} | ||
const s = y(e), n = y(t); | ||
if (s[0]) | ||
return n[0] ? s[1] === n[1] : !1; | ||
const n = O(e), o = O(t); | ||
if (n[0]) | ||
return o[0] ? n[1] === o[1] : !1; | ||
if (o[0]) | ||
return !1; | ||
const c = V(e), i = V(t); | ||
if (c[0]) | ||
return i[0] ? c[1] === i[1] : !1; | ||
const l = N(e), a = N(t); | ||
if (l[0]) | ||
return a[0] ? l[1] === a[1] : !1; | ||
if (a[0]) | ||
return !1; | ||
const i = v(e), d = v(t); | ||
if (i[0]) | ||
return !1; | ||
const a = b(e), d = b(t); | ||
if (a[0]) | ||
return d[0] ? a[0] === d[0] && a[1] === d[1] : !1; | ||
return d[0] ? i[0] === d[0] && i[1] === d[1] : !1; | ||
if (r === "Object") { | ||
const o = Object.keys(e); | ||
return o.length !== Object.keys(t).length ? !1 : o.every((u) => { | ||
const f = e[u], p = t[u]; | ||
return f === p || g(f, p); | ||
const s = Object.keys(e); | ||
return s.length !== Object.keys(t).length ? !1 : s.every((c) => { | ||
const p = e[c], f = t[c]; | ||
return p === f || S(p, f); | ||
}); | ||
} | ||
return !1; | ||
}, v = (e) => e == null, k = (e, t) => ( | ||
}, A = (e) => e == null, j = (e, t) => ( | ||
// @ts-expect-error | ||
v(t) ? {} : e.reduce( | ||
(r, s) => Object.prototype.hasOwnProperty.call(t, s) ? { ...r, [s]: t[s] } : r, | ||
A(t) ? {} : e.reduce( | ||
(r, n) => Object.prototype.hasOwnProperty.call(t, n) ? { ...r, [n]: t[n] } : r, | ||
{} | ||
) | ||
), A = (e, t) => e.reduce((r, s) => ({ ...r, [s]: t.includes(s) }), {}), _ = (e, t) => !g(e, t), z = (e) => { | ||
const { finalForm: t, fieldsApi: r, formStateApi: s } = e, n = ({ name: o, value: u }) => t.change(o, u), c = ({ | ||
name: o, | ||
subscribeOn: u, | ||
config: f | ||
), x = (e, t) => e.reduce((r, n) => ({ ...r, [n]: t.includes(n) }), {}), T = (e, t) => !S(e, t), q = (e) => { | ||
}, w = (e) => { | ||
const { finalForm: t, formStateApi: r, revalidateFx: n } = e, o = (s) => (c) => t.change(s, c), l = ({ | ||
name: s, | ||
subscribeOn: c, | ||
config: p = {}, | ||
initialValue: f, | ||
validate: E | ||
}) => { | ||
t.registerField( | ||
o, | ||
r.update, | ||
A(h, [...u, "value"]), | ||
f | ||
); | ||
const F = u(E ?? q), P = { | ||
...p, | ||
initialValue: H.store(f) ? f.getState() : f, | ||
getValidator: (m) => F | ||
}, b = g(); | ||
t.batch(() => { | ||
t.registerField( | ||
s, | ||
b, | ||
x($, [...c, "value"]), | ||
// @ts-expect-error | ||
P | ||
), n(); | ||
}); | ||
const k = j([...c, "value"], t.getFieldState(s)), V = h(k); | ||
R({ | ||
clock: b.filterMap(({ blur: m, change: I, focus: M, ...y }) => y.name === s ? y : void 0), | ||
target: V | ||
}); | ||
const C = o(s); | ||
return { api: { | ||
blurFx: u(() => { | ||
t.blur(s); | ||
}), | ||
changeFx: u(C), | ||
focusFx: u(() => { | ||
t.focus(s); | ||
}), | ||
resetState: u(() => { | ||
t.resetFieldState(s); | ||
}), | ||
setValidationFn: (m) => { | ||
F.use(m), n(); | ||
} | ||
}, $state: V }; | ||
}, a = () => { | ||
t.pauseValidation(), r.setValidationPaused(!0); | ||
}, i = () => { | ||
t.pauseValidation(), s.setValidationPaused(!0); | ||
}, a = () => { | ||
t.resumeValidation(), s.setValidationPaused(!1); | ||
t.resumeValidation(), r.setValidationPaused(!1); | ||
}; | ||
return { | ||
blurFx: l(t.blur), | ||
changeFx: l(n), | ||
focusFx: l(t.focus), | ||
initialize: l(t.initialize), | ||
pauseValidation: l(i), | ||
registerField: l(c), | ||
reset: l(t.reset), | ||
resetFieldState: l(t.resetFieldState), | ||
restart: l(t.restart), | ||
resumeValidation: l(a), | ||
submitFx: l(t.submit) | ||
pauseValidation: u(a), | ||
// form api | ||
registerField: l, | ||
// form api | ||
reset: u(t.reset), | ||
// form api | ||
restart: u(t.restart), | ||
// form api | ||
resumeValidation: u(i), | ||
// form api | ||
submitFx: u(t.submit) | ||
// form api | ||
}; | ||
}, H = (e) => { | ||
const t = { | ||
update: F() | ||
}, r = O( | ||
// @ts-expect-error | ||
{}, | ||
{ updateFilter: _ } | ||
), s = r.map((n) => Object.keys(n)); | ||
return E({ | ||
clock: t.update, | ||
source: r, | ||
fn: (n, c) => ({ ...n, [c.name]: c }), | ||
target: r | ||
}), { $fields: r, fieldsApi: t, $registeredFields: s }; | ||
}, R = (e) => { | ||
const { finalForm: t, subscribeOn: r } = e, s = k([...r, "isValidationPaused"], { | ||
}, U = (e) => { | ||
const { finalForm: t, subscribeOn: r } = e, n = j([...r, "isValidationPaused"], { | ||
...t.getState(), | ||
isValidationPaused: !1 | ||
}), n = { | ||
update: F(), | ||
setValidationPaused: F() | ||
}, c = O(s, { | ||
updateFilter: _ | ||
}).on(n.update, (i, a) => Object.assign({}, i, a)).on(n.setValidationPaused, (i, a) => Object.assign({}, i, { isValidationPaused: a })); | ||
return t.subscribe((i) => { | ||
const a = r.reduce((d, o) => v(i[o]) ? { ...d, [o]: null } : d, i); | ||
n.update(a); | ||
}, A(x, r)), { $formState: c, formStateApi: n }; | ||
}, D = () => { | ||
}, U = (e) => { | ||
const { subscribeOn: t, ...r } = e, s = P.store(e.initialValues) ? e.initialValues.getState() : e.initialValues, n = l(r.validate ?? D), c = l(r.onSubmit), i = $({ | ||
}), o = { | ||
update: g(), | ||
setValidationPaused: g() | ||
}, l = h(n, { | ||
updateFilter: T | ||
}).on(o.update, (a, i) => Object.assign({}, a, i)).on(o.setValidationPaused, (a, i) => Object.assign({}, a, { isValidationPaused: i })); | ||
return t.subscribe((a) => { | ||
const i = r.reduce((d, s) => A(a[s]) ? { ...d, [s]: null } : d, a); | ||
o.update(i); | ||
}, x(z, r)), { $formState: l, formStateApi: o }; | ||
}, K = (e) => { | ||
const { subscribeOn: t, ...r } = e, n = u(r.onSubmit), o = D({ | ||
...r, | ||
initialValues: s, | ||
validate: n, | ||
onSubmit: async (m) => { | ||
onSubmit: async (s) => { | ||
try { | ||
return await c(m); | ||
} catch (j) { | ||
return j; | ||
return await n(s); | ||
} catch (c) { | ||
return c; | ||
} | ||
@@ -136,26 +152,19 @@ }, | ||
} | ||
}), a = l(() => { | ||
i.mutators.__update__(); | ||
}), { $fields: d, $registeredFields: o, fieldsApi: u } = H(), { $formState: f, formStateApi: p } = R({ | ||
finalForm: i, | ||
}), l = u(() => { | ||
o.mutators.__update__(); | ||
}), { $formState: a, formStateApi: i } = U({ | ||
finalForm: o, | ||
subscribeOn: t | ||
}), N = z({ finalForm: i, fieldsApi: u, formStateApi: p }); | ||
return a(), { | ||
}); | ||
return { | ||
api: { | ||
...N, | ||
revalidateFx: a, | ||
setSubmitFn: (m) => { | ||
c.use(m); | ||
}, | ||
setValidationFn: (m) => { | ||
n.use(m), a(); | ||
} | ||
...w({ finalForm: o, formStateApi: i, revalidateFx: l }), | ||
revalidateFx: l, | ||
setSubmitFn: n.use | ||
}, | ||
$fields: d, | ||
$formState: f, | ||
$registeredFields: o | ||
$formState: a | ||
}; | ||
}; | ||
export { | ||
U as createForm | ||
K as createForm | ||
}; |
@@ -10,2 +10,3 @@ import type { FormSubscription as FFFormSubscription } from 'final-form'; | ||
type FormSubscription = readonly (keyof FFFormSubscription)[]; | ||
export type { FormSubscription, Pick, Nil }; | ||
type ValidationResult = any | undefined | Promise<any> | Promise<undefined>; | ||
export type { FormSubscription, Pick, Nil, ValidationResult }; |
{ | ||
"name": "effector-final-form", | ||
"version": "0.4.0", | ||
"version": "0.5.0", | ||
"description": "☄️ Effector bindings for Final Form", | ||
@@ -5,0 +5,0 @@ "license": "MIT", |
@@ -54,3 +54,3 @@ # effector-final-form | ||
test('', async () => { | ||
const { $formState, $fields, api } = createForm({ | ||
const { $formState, api } = createForm<{ firstName: string }>({ | ||
onSubmit: async (f) => { | ||
@@ -61,19 +61,19 @@ await sleep(1000); | ||
}, | ||
validate: (f) => (f.firstName === '' ? { firstName: 'Can not be empty' } : undefined), | ||
initialValues: { firstName: '' }, | ||
subscribeOn: ['values', 'errors', 'submitting', 'submitSucceeded', 'submitFailed', 'submitErrors'], | ||
}); | ||
await api.registerField({ | ||
const field = api.registerField({ | ||
name: 'firstName', | ||
subscribeOn: ['value', 'error', 'initial'], | ||
initialValue: '', | ||
validate: (v) => (v === '' ? 'Can not be empty' : undefined), | ||
}); | ||
api.changeFx({ name: 'firstName', value: '' }); | ||
field.api.changeFx(''); | ||
await waitForExpect(() => { | ||
expect($fields.getState().firstName.error).toBe('Can not be empty'); | ||
expect(field.$state.getState().error).toBe('Can not be empty'); | ||
}); | ||
expect($fields.getState().firstName.initial).toBe(''); | ||
expect($fields.getState().firstName.value).toBe(''); | ||
expect(field.$state.getState().initial).toBe(''); | ||
expect(field.$state.getState().value).toBe(''); | ||
@@ -88,7 +88,7 @@ expect($formState.getState().errors).toStrictEqual({ firstName: 'Can not be empty' }); | ||
{ | ||
await api.changeFx({ name: 'firstName', value: 'Incorrect' }); | ||
await field.api.changeFx('Incorrect'); | ||
await waitForExpect(() => { | ||
expect($fields.getState().firstName.error).toBe(undefined); | ||
expect($fields.getState().firstName.value).toBe('Incorrect'); | ||
expect(field.$state.getState().error).toBe(undefined); | ||
expect(field.$state.getState().value).toBe('Incorrect'); | ||
expect($formState.getState().errors).toStrictEqual({}); | ||
@@ -115,6 +115,6 @@ }); | ||
{ | ||
await api.changeFx({ name: 'firstName', value: 'John' }); | ||
await field.api.changeFx('John'); | ||
expect($fields.getState().firstName.error).toBe(undefined); | ||
expect($fields.getState().firstName.value).toBe('John'); | ||
expect(field.$state.getState().error).toBe(undefined); | ||
expect(field.$state.getState().value).toBe('John'); | ||
expect($formState.getState().errors).toStrictEqual({}); | ||
@@ -121,0 +121,0 @@ |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
348
23088
12