# @42-components

Headless UI component library in vanilla TypeScript, with optional theme.

## Packages

| Package | Description |
| --- | --- |
| `@42/core` | Framework-agnostic headless controllers (subpath exports per component). |
| `@42/styles` | Optional theme (CSS custom properties, dark mode included). |

## Components

Grouped by what you are trying to do. Full per-component reference (markup,
options, events) lives in [`docs/llm/reference/`](docs/llm/reference/); complex
components have a deep dive in [`docs/llm/`](docs/llm/).

| Category | Use it when… | Reference |
| --- | --- | --- |
| Inputs & Forms | you capture data from the user | [inputs.md](docs/llm/reference/inputs.md) |
| Overlays | you need a transient layer above content | [overlays.md](docs/llm/reference/overlays.md) |
| Navigation | you move around or structure a flow | [navigation.md](docs/llm/reference/navigation.md) |
| Data & Collections | you display or manipulate sets of data | [data.md](docs/llm/reference/data.md) |
| Media | you show images or people | [media.md](docs/llm/reference/media.md) |
| Feedback & Status | you communicate state, progress or an action | [feedback.md](docs/llm/reference/feedback.md) |
| Disclosure & Layout | you show or hide regions of content | [disclosure.md](docs/llm/reference/disclosure.md) |
| Presentational (CSS-only) | you just need styles, no controller | [presentational.md](docs/llm/reference/presentational.md) |

## Development

```bash
pnpm install
pnpm test            # vitest (jsdom)
pnpm build           # build all publishable packages
pnpm storybook       # run Storybook (HTML + Vite)
```

## Usage

```bash
npm install @42/core @42/styles
```

```html
<div data-c42-accordion>
  <div data-c42-accordion-item data-value="a">
    <button data-c42-accordion-trigger>Title</button>
    <div data-c42-accordion-panel>Content</div>
  </div>
</div>
```

```ts
import { Accordion } from '@42/core/accordion';
import '@42/styles/accordion.css'; // optional theme

const acc = new Accordion(document.querySelector('[data-c42-accordion]')!, { multiple: false });
acc.on('accordion:change', (e) => console.log(e.detail.value));
```

### Form validation

The `Form` controller turns native inputs into a validated, accessible form
(ARIA wiring, error states, typed events) without imposing styles:

```html
<form data-c42-form>
  <div data-c42-field>
    <label for="email">Email</label>
    <input id="email" name="email" type="email" data-c42-validate="required email" />
    <span data-c42-field-error hidden></span>
  </div>
  <button type="submit">Sign up</button>
</form>
```

```ts
import { Form } from '@42/core/form';
import '@42/styles/form.css'; // optional theme

const form = new Form(document.querySelector('[data-c42-form]')!, { mode: 'blur' });
form.on('form:submit', (e) => console.log(e.detail.values)); // only fires when valid
form.on('form:invalid', (e) => console.log(e.detail.errors));
```

See [`docs/llm/form.md`](docs/llm/form.md) for rules, options and recipes.

## Theming

Import `@42/styles` for the complete theme. Customize by overriding primitives:

```css
:root {
  --c42-primary-500: #0ea5e9;
  --c42-primary-600: #0284c7;
}
```

Dark mode activates automatically via `prefers-color-scheme` or with `data-theme="dark"` on `<html>`.

The full theme also applies a thin, subtle global scrollbar (tunable via
`--c42-scrollbar-size` / `--c42-scrollbar-thumb` / `--c42-scrollbar-thumb-hover`,
or import `@42/styles/scrollbar.css` standalone).

## AI agents

See [`LLM.md`](LLM.md) for the complete component reference optimized for AI consumption.
