first commit

This commit is contained in:
2026-05-29 08:20:56 +01:00
commit 949299f58d
6368 changed files with 527176 additions and 0 deletions

View File

@@ -0,0 +1,78 @@
# Field Variants (cva config)
## Purpose
`fieldVariants`, `fieldLabelVariants`, `fieldDescriptionVariants`, and `fieldErrorVariants` are the four cva (class-variance-authority) configurations powering the `<Field>` primitives. They are split from `field.tsx` into their own module so an ejected source copy under `npx shadcn@latest add @suaveplan/field` keeps the cva configurations in a dedicated file. Theme overrides flow through `useThemedVariants("Field" | "FieldLabel" | "FieldDescription" | "FieldError")`.
The container cva uses Tailwind's named-group selector (`group/field`) so the descendant `<FieldLabel>` instances can react to `data-invalid="true"` on the container without depending on direct-parent semantics.
## Features
- Container `flex flex-col gap-2` layout (NOT `space-y-*` per shadcn skill rule).
- `data-[invalid=true]:[&_label]:text-destructive` on the container — every descendant `<label>` (including nested `<FieldLabel>`) flips colour.
- `data-[disabled=true]:opacity-70` decay.
- `<FieldLabel>` cva inherits the destructive colour via `group-data-[invalid=true]/field:text-destructive`.
- `<FieldDescription>` muted via `text-sm text-muted-foreground`.
- `<FieldError>` destructive via `text-sm font-medium text-destructive`.
## Usage: Basic Example
```ts
import {
fieldVariants,
fieldLabelVariants,
fieldErrorVariants,
} from "@suaveplan/react-ui";
const containerCls = fieldVariants();
const labelCls = fieldLabelVariants();
const errorCls = fieldErrorVariants();
```
## Usage: Advanced Example
```ts
import { fieldVariants, cn } from "@suaveplan/react-ui";
export function CustomField({
invalid,
children,
}: {
invalid: boolean;
children: React.ReactNode;
}) {
return (
<div
data-invalid={invalid ? "true" : undefined}
className={cn(fieldVariants(), "rounded border p-2")}
>
{children}
</div>
);
}
```
## API Reference
### `fieldVariants(): string`
Returns the container classes — `group/field flex flex-col gap-2 …`.
### `fieldLabelVariants(): string`
Returns the label classes including the `group-data-[invalid=true]/field:text-destructive` selector.
### `fieldDescriptionVariants(): string`
Returns the muted helper-text classes.
### `fieldErrorVariants(): string`
Returns the destructive error-text classes.
## Implementation Notes
- The named group `group/field` is named (not the bare `group` class) so nested `<Field>` instances do not collide — Tailwind treats `group/field` as a distinct selector from a parent `group/section`.
- The container cva applies the destructive colour to ALL descendant `<label>` elements (`[&_label]:text-destructive`) so even a hand-rolled `<label>` inside `<Field>` picks up the colour without needing `<FieldLabel>`. This is intentional: consumers using the form library may render their own labels via `react-hook-form` field arrays.
- Per the shadcn skill rule, the cva NEVER uses `space-y-*` / `space-x-*` — `gap-*` flows the same in RTL.
- `<FieldError>` inherits the destructive colour directly (via `text-destructive`) rather than via the group selector so it always reads as an error even when `<Field invalid>` is not set (e.g. server-side error surfaces).