# @colletdev/react

React 18+ wrappers for the Collet component library. Typed props, ref forwarding, and idiomatic event callbacks over 48 Rust/WASM Custom Elements.

## Install

```bash
npm install @colletdev/react @colletdev/core
```

## Quick Start

```tsx
import { init } from '@colletdev/react';
import { Button, TextInput } from '@colletdev/react';

await init(); // once, at app startup

function App() {
  return (
    <>
      <Button variant="filled" label="Save" intent="primary" onClick={() => save()} />
      <TextInput label="Email" kind="email" onInput={(e) => setEmail(e.detail.value)} />
    </>
  );
}
```

## Features

- **Typed props** -- union-literal types for variant, intent, size, and all other enums
- **Event callbacks** -- `onClick`, `onInput`, `onChange`, etc. with typed `CustomEvent` `detail`
- **Ref types** -- `ButtonRef`, `TextInputRef`, `DialogRef`, etc. for imperative access (`.open()`, `.close()`, `.focus()`)
- **Structured data** -- `SelectOption[]`, `TableColumn[]`, `AccordionItem[]` and other complex prop types are fully typed
- **Markdown** -- `useMarkdown(content)` hook renders GFM to sanitized HTML via WASM
- **Streaming** -- `useMarkdownStream()` for token-by-token rendering with cursor animation

## Markdown

```tsx
import { useMarkdown } from '@colletdev/react';

function Docs({ content }: { content: string }) {
  const html = useMarkdown(content);
  return <div dangerouslySetInnerHTML={{ __html: html }} />;
}
```

## Event Pattern

Event callbacks use standard React naming (`onChange`, `onClick`, `onInput`, etc.) and receive typed `CustomEvent` objects:

```tsx
<Select
  label="Country"
  options={countries}
  onChange={(e) => setCountry(e.detail.value)}
/>
```

## API Reference

See [@colletdev/docs](https://www.npmjs.com/package/@colletdev/docs) for the full props/events reference and framework guides.

## License

MIT -- [github.com/Danrozen87/collet](https://github.com/Danrozen87/collet)
