import { Button, Container, Flex, Text } from "@radix-ui/themes" import { createFileRoute } from "@tanstack/react-router" import { Console, Effect, Schema } from "effect" import { Component, Form, MutationForm, View } from "effect-view" import { TextFieldFormInputView } from "@/lib/form/TextFieldFormInputView" import { runtime } from "@/runtime" const RegisterSchema = Schema.Struct({ email: Schema.String.check( Schema.isPattern(/^[^\s@]+@[^\s@]+\.[^\s@]+$/, { message: "Enter a valid email address", }), ), password: Schema.String.check( Schema.isMinLength(5, { message: "Password must be at least 5 characters long", }), ), }) const RegisterRouteComponent = Component.make("RegisterRouteView")(function*() { yield* Component.useOnMount(() => Effect.gen(function*() { yield* Effect.addFinalizer(() => Console.log("Form route unmounted")) yield* Console.log("Form route mounted") })) const [form, emailField, passwordField] = yield* Component.useOnMount(() => Effect.gen(function*() { const form = yield* MutationForm.make({ schema: RegisterSchema, initialEncodedValue: { email: "", password: "" }, f: ([value]) => Effect.log(`Registered ${value.email}`), }).pipe( MutationForm.run, ) const emailField = Form.focusObjectOn(form, "email") const passwordField = Form.focusObjectOn(form, "password") return [form, emailField, passwordField] as const })) const [canCommit, isCommitting] = yield* View.useAll([ form.canCommit, form.isCommitting, ]) const TextFieldFormInput = yield* TextFieldFormInputView.use const runPromise = yield* Component.useRunPromise() return (
{ event.preventDefault() void runPromise(form.submit) }}>
A MutationForm validates local input, then submits it.
) }).pipe( Component.withContext(runtime.context), ) export const Route = createFileRoute("/form")({ component: RegisterRouteComponent, })