mirror of
https://github.com/temetro/temetro.git
synced 2026-08-30 20:39:06 +00:00
929bec8f31
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>
174 lines
5.0 KiB
Markdown
174 lines
5.0 KiB
Markdown
# coss vs shadcn/Radix assumptions
|
|
|
|
Use this guide when adapting snippets that were originally written with shadcn/Radix mental models.
|
|
|
|
## Core idea
|
|
|
|
coss is close to shadcn ergonomically, but its primitives and composition model are aligned to Base UI patterns.
|
|
|
|
## High-impact differences
|
|
|
|
- Do not assume every shadcn pattern translates 1:1.
|
|
- Verify trigger and popup composition from coss docs before coding.
|
|
- Apply `asChild` -> `render` only on coss parts that explicitly support `render`.
|
|
- Prefer coss component names and exports as documented (`DialogPopup`, `MenuPopup`, `SelectPopup`, etc.).
|
|
- Some legacy aliases may exist, but primary coss names should be preferred in new examples.
|
|
- Prefer styled coss exports by default (for example `Slider`, `SliderValue`) and use `*Primitive` only for advanced/custom composition.
|
|
- When only Base UI helpers are needed (`useRender`, `mergeProps`, `CSPProvider`, `DirectionProvider`), prefer `@coss/ui/base-ui/*` re-exports over direct `@base-ui/react` dependency.
|
|
- For Select migration, replace children-only option derivation with an `items`-first pattern where possible, then map options consistently in `SelectPopup`.
|
|
- For OTP fields, migrate off the `input-otp` package to coss `@coss/otp-field`: rename components (`OTPField`, `OTPFieldInput`, `OTPFieldSeparator`), use `length` and `onValueChange`, and drop `InputOTPGroup` / slot `index` (see example below).
|
|
|
|
## Practical migration examples
|
|
|
|
Use these snippets as fast conversion templates when migrating shadcn/Radix code.
|
|
|
|
### Composition: `asChild` -> `render`
|
|
|
|
```tsx
|
|
// shadcn/Radix
|
|
<DialogTrigger asChild>
|
|
<Button variant="outline">Open</Button>
|
|
</DialogTrigger>
|
|
```
|
|
|
|
```tsx
|
|
// coss/Base UI
|
|
<DialogTrigger render={<Button variant="outline" />}>Open</DialogTrigger>
|
|
```
|
|
|
|
### Menu actions: `onSelect` -> `onClick`
|
|
|
|
```tsx
|
|
// shadcn/Radix
|
|
<DropdownMenuItem onSelect={handleOpen}>Open</DropdownMenuItem>
|
|
```
|
|
|
|
```tsx
|
|
// coss/Base UI
|
|
<MenuItem onClick={handleOpen}>Open</MenuItem>
|
|
```
|
|
|
|
### Select: `items`-first + placeholder on `SelectValue`
|
|
|
|
```tsx
|
|
// shadcn/Radix
|
|
<Select>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Select a framework" />
|
|
</SelectTrigger>
|
|
<SelectContent>
|
|
<SelectItem value="next">Next.js</SelectItem>
|
|
<SelectItem value="vite">Vite</SelectItem>
|
|
</SelectContent>
|
|
</Select>
|
|
```
|
|
|
|
```tsx
|
|
// coss/Base UI
|
|
const items = [
|
|
{ label: "Next.js", value: "next" },
|
|
{ label: "Vite", value: "vite" },
|
|
];
|
|
|
|
<Select items={items}>
|
|
<SelectTrigger>
|
|
<SelectValue placeholder="Select a framework" />
|
|
</SelectTrigger>
|
|
<SelectPopup alignItemWithTrigger={false}>
|
|
{items.map((item) => (
|
|
<SelectItem key={item.value} value={item.value}>
|
|
{item.label}
|
|
</SelectItem>
|
|
))}
|
|
</SelectPopup>
|
|
</Select>
|
|
```
|
|
|
|
### Toggle Group: `type` -> `multiple`
|
|
|
|
```tsx
|
|
// shadcn/Radix
|
|
<ToggleGroup type="single" defaultValue="daily">
|
|
<ToggleGroupItem value="daily">Daily</ToggleGroupItem>
|
|
<ToggleGroupItem value="weekly">Weekly</ToggleGroupItem>
|
|
</ToggleGroup>
|
|
```
|
|
|
|
```tsx
|
|
// coss/Base UI
|
|
<ToggleGroup defaultValue={["daily"]}>
|
|
<ToggleGroupItem value="daily">Daily</ToggleGroupItem>
|
|
<ToggleGroupItem value="weekly">Weekly</ToggleGroupItem>
|
|
</ToggleGroup>
|
|
```
|
|
|
|
### Slider: scalar single-value usage in coss
|
|
|
|
```tsx
|
|
// shadcn/Radix
|
|
<Slider defaultValue={[50]} max={100} step={1} />
|
|
```
|
|
|
|
```tsx
|
|
// coss/Base UI
|
|
<Slider defaultValue={50} max={100} step={1} />
|
|
```
|
|
|
|
### Accordion: `type/collapsible` -> coss defaults
|
|
|
|
```tsx
|
|
// shadcn/Radix
|
|
<Accordion type="single" collapsible defaultValue="item-1">
|
|
<AccordionItem value="item-1">...</AccordionItem>
|
|
</Accordion>
|
|
```
|
|
|
|
```tsx
|
|
// coss/Base UI
|
|
<Accordion defaultValue={["item-1"]}>
|
|
<AccordionItem value="item-1">...</AccordionItem>
|
|
</Accordion>
|
|
```
|
|
|
|
### OTP Field: `input-otp` package → `@coss/otp-field`
|
|
|
|
coss wraps [Base UI OTP Field](https://base-ui.com/react/components/otp-field) (`OTPFieldPreview`). Remove the `input-otp` dependency and align with the new names and root props.
|
|
|
|
```tsx
|
|
// shadcn / input-otp
|
|
<InputOTP maxLength={6} value={value} onChange={setValue}>
|
|
<InputOTPGroup>
|
|
<InputOTPSlot index={0} />
|
|
<InputOTPSlot index={1} />
|
|
</InputOTPGroup>
|
|
</InputOTP>
|
|
```
|
|
|
|
```tsx
|
|
// coss
|
|
<OTPField length={6} value={value} onValueChange={setValue}>
|
|
<OTPFieldInput aria-label="Character 1 of 6" />
|
|
<OTPFieldInput aria-label="Character 2 of 6" />
|
|
</OTPField>
|
|
```
|
|
|
|
- `InputOTPGroup` is not used; optional `size="lg"` lives on `OTPField`.
|
|
- Render one `OTPFieldInput` per character in order; do not pass `index`.
|
|
|
|
## Migration checklist
|
|
|
|
1. Confirm the exact coss imports from docs.
|
|
2. Confirm child structure requirements (trigger/header/panel/footer/items/groups).
|
|
3. Confirm prop names and semantics from the coss docs page.
|
|
4. Validate with at least one coss particle example.
|
|
|
|
## Per-component migration notes
|
|
|
|
For the full component registry, see `../component-registry.md`.
|
|
|
|
## Anti-patterns
|
|
|
|
- Copy/paste shadcn examples and only change import path.
|
|
- Using undocumented props because they exist in other ecosystems.
|
|
- Omitting required subcomponents in overlays/forms because the source snippet did.
|