import { Form } from '@base-ui/react/form'; import { useState } from 'react'; import { Button } from '#/components/atoms/button.jsx'; import { Notice } from '#/components/atoms/notice.jsx'; import { cn } from '#/lib/utils.js'; /** * The form frame. Fields validate through native constraint attributes, so * an invalid submit is blocked by the browser in the browser's own words; * values are read off the element with FormData, never mirrored into state. * The submit handler's rejection becomes the root error. */ export function FormShell({ className, submitLabel, onSubmit, onSucceed, children, ...props }) { const [error, setError] = useState(''); const [busy, setBusy] = useState(false); return (
{ event.preventDefault(); const form = event.currentTarget; const values = Object.fromEntries(new FormData(form)); setError(''); setBusy(true); try { await onSubmit(values); form.reset(); onSucceed?.(); } catch (err) { setError(err instanceof Error ? err.message : String(err)); } finally { setBusy(false); } }} {...props} > {children} {error && {error}}
); }