Fix
All checks were successful
Lint / lint (push) Successful in 12s

This commit is contained in:
Julien Valverdé
2025-09-28 19:16:33 +02:00
parent 3eaa250c28
commit ef042ed4b1
2 changed files with 48 additions and 44 deletions

View File

@@ -155,54 +155,55 @@ const run = <A, I, R, SA, SE, SR>(self: Form<A, I, R, SA, SE, SR>) => Stream.run
) )
export const field: { export const field = <A, I, R, SA, SE, SR, const P extends PropertyPath.Paths<NoInfer<I>>>(
<A, I, R, SA, SE, SR, const P extends PropertyPath.Paths<NoInfer<I>>>(
self: Form<A, I, R, SA, SE, SR>,
path: P,
): Effect.Effect<FormField<PropertyPath.ValueFromPath<A, P>, PropertyPath.ValueFromPath<I, P>>>
} = Effect.fnUntraced(function* <A, I, R, SA, SE, SR, const P extends PropertyPath.Paths<NoInfer<I>>>(
self: Form<A, I, R, SA, SE, SR>, self: Form<A, I, R, SA, SE, SR>,
path: P, path: P,
) { ): FormField<PropertyPath.ValueFromPath<A, P>, PropertyPath.ValueFromPath<I, P>> => new FormFieldImpl(
return new FormFieldImpl( pipe(
pipe( Option.match({
(v: Option.Option<A>) => Option.match(v, { onSome: (v: A) => Option.map(PropertyPath.get(v, path), Option.some),
onSome: PropertyPath.get(path), onNone: () => Option.some(Option.none()),
onNone: () => Option.none(), }),
}), filter => SubscribableInternal.make({
filter => SubscribableInternal.make({ get: Effect.flatMap(self.valueRef, filter),
get: Effect.flatMap(self.valueRef, filter), get changes() { return Stream.flatMap(self.valueRef.changes, filter) },
get changes() { return Stream.flatMap(self.valueRef.changes, filter) }, }),
}), ),
),
SubscriptionSubRef.makeFromPath(self.encodedValueRef, path), SubscriptionSubRef.makeFromPath(self.encodedValueRef, path),
pipe( pipe(
Option.match({ Option.match({
onSome: (v: ParseResult.ParseError) => Effect.andThen( onSome: (v: ParseResult.ParseError) => Effect.andThen(
ParseResult.ArrayFormatter.formatError(v), ParseResult.ArrayFormatter.formatError(v),
Array.filter(issue => PropertyPath.equivalence(issue.path, path)), Array.filter(issue => PropertyPath.equivalence(issue.path, path)),
), ),
onNone: () => Effect.succeed([]), onNone: () => Effect.succeed([]),
}), }),
filter => SubscribableInternal.make({ filter => SubscribableInternal.make({
get: Effect.flatMap(self.errorRef.get, filter), get: Effect.flatMap(self.errorRef.get, filter),
get changes() { return Stream.flatMap(self.errorRef.changes, filter) }, get changes() { return Stream.flatMap(self.errorRef.changes, filter) },
}), }),
), ),
self.isValidatingRef, self.isValidatingRef,
pipe( pipe(
AsyncData.isLoading, AsyncData.isLoading,
filter => SubscribableInternal.make({ filter => SubscribableInternal.make({
get: Effect.map(self.submitStateRef, filter), get: Effect.map(self.submitStateRef, filter),
get changes() { return Stream.map(self.submitStateRef.changes, filter) }, get changes() { return Stream.map(self.submitStateRef.changes, filter) },
}), }),
), ),
) )
})
export const useField = <A, I, R, SA, SE, SR, const P extends PropertyPath.Paths<NoInfer<I>>>(
self: Form<A, I, R, SA, SE, SR>,
path: P,
): FormField<PropertyPath.ValueFromPath<A, P>, PropertyPath.ValueFromPath<I, P>> => React.useMemo(
() => field(self, path),
[self, ...path],
)
export namespace useInput { export namespace useInput {

View File

@@ -25,13 +25,16 @@ class RegisterForm extends Effect.Service<RegisterForm>()("RegisterForm", {
scoped: Form.service({ scoped: Form.service({
schema: RegisterFormSchema, schema: RegisterFormSchema,
initialEncodedValue: { email: "", password: "" }, initialEncodedValue: { email: "", password: "" },
submit: () => Effect.void,
}) })
}) {} }) {}
class RegisterPage extends Component.makeUntraced("RegisterPage")(function*() { class RegisterPage extends Component.makeUntraced("RegisterPage")(function*() {
const form = yield* RegisterForm const form = yield* RegisterForm
const emailInput = yield* Form.useInput(form, ["email"], { debounce: "200 millis" }) const emailField = Form.useField(form, ["email"])
const passwordInput = yield* Form.useInput(form, ["password"], { debounce: "200 millis" }) const passwordField = Form.useField(form, ["password"])
const emailInput = yield* Form.useInput(emailField, { debounce: "200 millis" })
const passwordInput = yield* Form.useInput(passwordField, { debounce: "200 millis" })
const [canSubmit] = yield* useSubscribables(form.canSubmitSubscribable) const [canSubmit] = yield* useSubscribables(form.canSubmitSubscribable)