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

This commit is contained in:
Julien Valverdé
2025-10-02 15:43:40 +02:00
parent 4c253fcfe8
commit 3456440e1e
5 changed files with 122 additions and 52 deletions

View File

@@ -1,7 +1,6 @@
import { Callout, Flex, Spinner, TextField } from "@radix-ui/themes"
import { Array, Option } from "effect"
import { Component, Form } from "effect-fc"
import { useSubscribables } from "effect-fc/Hooks"
import { Component, Form, Hooks } from "effect-fc"
export interface TextFieldFormInputProps
@@ -9,38 +8,42 @@ extends TextField.RootProps, Form.useInput.Options {
readonly field: Form.FormField<any, string>
}
export class TextFieldFormInput extends Component.makeUntraced("TextFieldFormInput")(function*(props: TextFieldFormInputProps) {
const { value, setValue } = yield* Form.useInput(props.field, props)
const [issues, isValidating, isSubmitting] = yield* useSubscribables(
props.field.issuesSubscribable,
props.field.isValidatingSubscribable,
props.field.isSubmittingSubscribable,
)
export class TextFieldFormInput extends Component.makeUntraced("TextFieldFormInput")(
function*(props: TextFieldFormInputProps) {
const { value, setValue } = yield* Form.useInput(props.field, props)
const [issues, isValidating, isSubmitting] = yield* Hooks.useSubscribables(
props.field.issuesSubscribable,
props.field.isValidatingSubscribable,
props.field.isSubmittingSubscribable,
)
return (
<Flex direction="column" gap="1">
<TextField.Root
value={value}
onChange={e => setValue(e.target.value)}
disabled={isSubmitting}
{...props}
>
{isValidating &&
<TextField.Slot side="right">
<Spinner />
</TextField.Slot>
}
</TextField.Root>
return (
<Flex direction="column" gap="1">
<TextField.Root
value={value}
onChange={e => setValue(e.target.value)}
disabled={isSubmitting}
{...props}
>
{isValidating &&
<TextField.Slot side="right">
<Spinner />
</TextField.Slot>
}
{Option.match(Array.head(issues), {
onSome: issue => (
<Callout.Root>
<Callout.Text>{issue.message}</Callout.Text>
</Callout.Root>
),
{props.children}
</TextField.Root>
onNone: () => <></>,
})}
</Flex>
)
}) {}
{Option.match(Array.head(issues), {
onSome: issue => (
<Callout.Root>
<Callout.Text>{issue.message}</Callout.Text>
</Callout.Root>
),
onNone: () => <></>,
})}
</Flex>
)
}
) {}