chadtmiller.com/pds.js
An atproto PDS in JavaScript, for Cloudflare Workers and Node
0
0
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 (
<Form
// Base UI defaults to noValidate; the browser's gate goes back on
noValidate={false}
className={cn('flex flex-col gap-4', className)}
onSubmit={async (event) => {
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 && <Notice variant="error">{error}</Notice>}
<Button type="submit" size="block" disabled={busy}>
{submitLabel}
</Button>
</Form>
);
}