Files
temetro/.agents/skills/coss/references/primitives/form.md
T
Khalid Abdi 929bec8f31 feat: AI-added records save with placeholders + "Added by AI" provenance
Stop blocking AI imports/proposals on missing non-critical fields. Records
the chat agent drafts now save with safe placeholders, auto-generated file
numbers, and a source="ai" marker that surfaces an "Added by AI" badge so a
clinician can review/edit them later.

Backend:
- add `source` (manual|ai) column to patients/appointments/prescriptions
  (migration 0014) + canonical types, services, validation schemas
- relax patient/appointment validation: empty file number allowed, demographic
  + type/provider/initials fall back to placeholders (initials derived from name)
- patients.generateFileNumber() auto-assigns an MRN when one is missing
- proposeAppointment accepts a name when no file number resolves; AI commits +
  /api/ai/import stamp source="ai"

Frontend:
- `source` on Appointment/Patient/Prescription types; AI commits send source="ai"
- reusable <AiBadge> shown on the Patients table/detail and prescriptions list

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-14 19:27:17 +03:00

2.9 KiB

coss Form

When to use

  • Structured form validation and submission flows.
  • Forms with field-level labels, descriptions, and errors.
  • Integrations with external form libraries (for example React Hook Form / TanStack Form).

Install

npx shadcn@latest add @coss/form

Manual deps:

npm install @base-ui/react zod

Canonical imports

import {
  Field,
  FieldDescription,
  FieldError,
  FieldLabel,
} from "@/components/ui/field"
import { Form } from "@/components/ui/form"
import { Input } from "@/components/ui/input"

Minimal pattern

<Form onSubmit={(e) => {/* handle submit */}}>
  <Field>
    <FieldLabel>Email</FieldLabel>
    <Input name="email" type="email" required />
    <FieldDescription>Used for account updates</FieldDescription>
    <FieldError>Please enter a valid email.</FieldError>
  </Field>
</Form>

Patterns from coss particles

  • Form usage in particles is intentionally lightweight; use the Base UI forms handbook patterns below for deeper validation/library integrations.
  • Dialog / sheet / drawer: Header outside the form; Form className="contents" wraps panel + footer only (p-dialog-1, p-sheet-1, p-sheet-2, p-drawer-10, p-drawer-12).

Patterns from coss/Base UI forms

  • Submission mode: use onSubmit for native FormData handling; use onFormSubmit when you want parsed form values object from Base UI Form.
  • Field naming: set name on each field/control flow so values are included in submission.
  • Accessible names: prefer visible labels (FieldLabel, SelectLabel, etc.); use aria-label only when no visible label exists.
  • Grouped controls: for radio/checkbox groups or multi-control sections, use fieldset-style grouping (Fieldset + Field.Item) instead of ad-hoc wrappers.
  • Validation rendering: pair constraints/custom validation with FieldError; keep error output semantically tied to the same field.
  • Textarea integration: use coss Textarea directly inside Field; it already integrates with Base UI field control semantics, so FieldControl render={...} is not required for standard textarea usage.
  • External library integration: when using RHF/TanStack, forward refs/input refs to the underlying control and map invalid/touched/dirty state into Field.

Common pitfalls

  • Using Form without field-level structure (Field, label, error).
  • Missing control name (field not present in form submission payload).
  • Missing input type and button type.
  • Showing validation messages without matching invalid semantics.
  • Using grouped checkboxes/radios without proper group legend/structure.
  • Not forwarding refs in RHF/TanStack integration, which breaks focus-on-error behavior.

Useful particle references

  • p-form-1 (basic integration)
  • p-form-2 (zod usage)

Further reading

  • Base UI Forms handbook: https://base-ui.com/react/handbook/forms.md