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

This commit is contained in:
Julien Valverdé
2025-12-01 20:38:54 +01:00
parent 1accd657e0
commit 92a13efabc
4 changed files with 24 additions and 26 deletions

View File

@@ -26,7 +26,7 @@ extends Pipeable.Pipeable {
readonly debounce: Option.Option<Duration.DurationInput> readonly debounce: Option.Option<Duration.DurationInput>
readonly value: Subscribable.Subscribable<Option.Option<A>> readonly value: Subscribable.Subscribable<Option.Option<A>>
readonly encodedValue: Subscribable.Subscribable<I> readonly encodedValue: SubscriptionRef.SubscriptionRef<I>
readonly error: Subscribable.Subscribable<Option.Option<ParseResult.ParseError>> readonly error: Subscribable.Subscribable<Option.Option<ParseResult.ParseError>>
readonly validationFiber: Subscribable.Subscribable<Option.Option<Fiber.Fiber<A, ParseResult.ParseError>>> readonly validationFiber: Subscribable.Subscribable<Option.Option<Fiber.Fiber<A, ParseResult.ParseError>>>

View File

@@ -29,9 +29,9 @@ export class TextFieldFormInput extends Component.makeUntraced("TextFieldFormInp
: { optional: false, ...yield* Form.useInput(props.field, props) } : { optional: false, ...yield* Form.useInput(props.field, props) }
const [issues, isValidating, isSubmitting] = yield* Subscribable.useSubscribables([ const [issues, isValidating, isSubmitting] = yield* Subscribable.useSubscribables([
props.field.issuesSubscribable, props.field.issues,
props.field.isValidatingSubscribable, props.field.isValidating,
props.field.isSubmittingSubscribable, props.field.isSubmitting,
]) ])
return ( return (

View File

@@ -54,7 +54,7 @@ class RegisterForm extends Effect.Service<RegisterForm>()("RegisterForm", {
), ),
initialEncodedValue: { email: "", password: "", birth: Option.none() }, initialEncodedValue: { email: "", password: "", birth: Option.none() },
onSubmit: Effect.fnUntraced(function*(v) { f: Effect.fnUntraced(function*([v]) {
yield* Effect.sleep("500 millis") yield* Effect.sleep("500 millis")
return yield* Schema.decode(RegisterFormSubmitSchema)(v) return yield* Schema.decode(RegisterFormSubmitSchema)(v)
}), }),
@@ -65,8 +65,8 @@ class RegisterForm extends Effect.Service<RegisterForm>()("RegisterForm", {
class RegisterFormView extends Component.makeUntraced("RegisterFormView")(function*() { class RegisterFormView extends Component.makeUntraced("RegisterFormView")(function*() {
const form = yield* RegisterForm const form = yield* RegisterForm
const [canSubmit, submitResult] = yield* Subscribable.useSubscribables([ const [canSubmit, submitResult] = yield* Subscribable.useSubscribables([
form.canSubmitSubscribable, form.canSubmit,
form.submitResultRef, form.mutation.result,
]) ])
const runPromise = yield* Component.useRunPromise() const runPromise = yield* Component.useRunPromise()
@@ -82,21 +82,21 @@ class RegisterFormView extends Component.makeUntraced("RegisterFormView")(functi
<Container width="300"> <Container width="300">
<form onSubmit={e => { <form onSubmit={e => {
e.preventDefault() e.preventDefault()
void runPromise(Form.submit(form)) void runPromise(form.submit)
}}> }}>
<Flex direction="column" gap="2"> <Flex direction="column" gap="2">
<TextFieldFormInputFC <TextFieldFormInputFC
field={yield* Form.field(form, ["email"])} field={yield* form.field(["email"])}
/> />
<TextFieldFormInputFC <TextFieldFormInputFC
field={yield* Form.field(form, ["password"])} field={yield* form.field(["password"])}
/> />
<TextFieldFormInputFC <TextFieldFormInputFC
optional optional
type="datetime-local" type="datetime-local"
field={yield* Form.field(form, ["birth"])} field={yield* form.field(["birth"])}
defaultValue="" defaultValue=""
/> />

View File

@@ -54,17 +54,15 @@ export class Todo extends Component.makeUntraced("Todo")(function*(props: TodoPr
Match.exhaustive, Match.exhaustive,
) )
), ),
onSubmit: function(todo) { f: ([todo, form]) => Match.value(props).pipe(
return Match.value(props).pipe(
Match.tag("new", () => Ref.update(state.ref, Chunk.prepend(todo)).pipe( Match.tag("new", () => Ref.update(state.ref, Chunk.prepend(todo)).pipe(
Effect.andThen(makeTodo), Effect.andThen(makeTodo),
Effect.andThen(Schema.encode(TodoFormSchema)), Effect.andThen(Schema.encode(TodoFormSchema)),
Effect.andThen(v => Ref.set(this.encodedValueRef, v)), Effect.andThen(v => Ref.set(form.encodedValue, v)),
)), )),
Match.tag("edit", ({ id }) => Ref.set(state.getElementRef(id), todo)), Match.tag("edit", ({ id }) => Ref.set(state.getElementRef(id), todo)),
Match.exhaustive, Match.exhaustive,
) ),
},
autosubmit: props._tag === "edit", autosubmit: props._tag === "edit",
debounce: "250 millis", debounce: "250 millis",
}) })
@@ -72,15 +70,15 @@ export class Todo extends Component.makeUntraced("Todo")(function*(props: TodoPr
return [ return [
indexRef, indexRef,
form, form,
yield* Form.field(form, ["content"]), yield* form.field(["content"]),
yield* Form.field(form, ["completedAt"]), yield* form.field(["completedAt"]),
] as const ] as const
}), [props._tag, props._tag === "edit" ? props.id : undefined]) }), [props._tag, props._tag === "edit" ? props.id : undefined])
const [index, size, canSubmit] = yield* Subscribable.useSubscribables([ const [index, size, canSubmit] = yield* Subscribable.useSubscribables([
indexRef, indexRef,
state.sizeSubscribable, state.sizeSubscribable,
form.canSubmitSubscribable, form.canSubmit,
]) ])
const runSync = yield* Component.useRunSync() const runSync = yield* Component.useRunSync()
@@ -103,7 +101,7 @@ export class Todo extends Component.makeUntraced("Todo")(function*(props: TodoPr
/> />
{props._tag === "new" && {props._tag === "new" &&
<Button disabled={!canSubmit} onClick={() => void runPromise(Form.submit(form))}> <Button disabled={!canSubmit} onClick={() => void runPromise(form.submit)}>
Add Add
</Button> </Button>
} }