Files
effect-view/packages/example-next/src/routes/form.tsx
T
Julien Valverdé 31d87ffcab
Lint / lint (push) Successful in 38s
Fix
2026-07-19 04:00:46 +02:00

64 lines
2.3 KiB
TypeScript

import { Button, Container, Flex, Text, TextField } from "@radix-ui/themes"
import { createFileRoute } from "@tanstack/react-router"
import { Effect, Schema } from "effect"
import { Component, Form, MutationForm, View } from "effect-fc-next"
import { runtime } from "@/runtime"
const RegisterSchema = Schema.Struct({
email: Schema.String,
password: Schema.String,
})
const RegisterRouteComponent = Component.make("RegisterRouteView")(function*() {
const form = yield* Component.useOnMount(() => MutationForm.service({
schema: RegisterSchema,
initialEncodedValue: { email: "", password: "" },
f: ([value]) => Effect.log(`Registered ${value.email}`),
}))
const emailField = yield* Form.useInput(
Form.focusObjectOn(form, "email"),
)
const passwordField = yield* Form.useInput(
Form.focusObjectOn(form, "password"),
)
const [canCommit, isCommitting] = yield* View.useAll([
form.canCommit,
form.isCommitting,
])
const runPromise = yield* Component.useRunPromise()
return (
<Container width="300">
<form onSubmit={(event) => {
event.preventDefault()
void runPromise(form.submit)
}}>
<Flex direction="column" gap="2">
<TextField.Root
value={emailField.value}
onChange={event => emailField.setValue(event.currentTarget.value)}
placeholder="Email"
/>
<TextField.Root
value={passwordField.value}
onChange={event => passwordField.setValue(event.currentTarget.value)}
placeholder="Password"
type="password"
/>
<Button disabled={!canCommit || isCommitting}>
{isCommitting ? "Submitting…" : "Submit"}
</Button>
</Flex>
</form>
<Text size="2">A MutationForm validates local input, then submits it.</Text>
</Container>
)
}).pipe(
Component.withRuntime(runtime.context),
)
export const Route = createFileRoute("/form")({
component: RegisterRouteComponent,
})