# @42/vue

Vue 3 wrappers for [`@42/core`](../core) headless controllers.

Every non‑presentational `@42/core` controller gets a thin Vue component whose
**props mirror the controller options** and whose **events mirror the controller
events** (re‑emitted with the original `CustomEvent.detail` as payload). The
controller is mounted on the component's root element; you provide the markup in
the default slot.

The wrappers are generated from `packages/core/manifest.json` — see
[Regenerating](#regenerating).

## Install

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

`vue` (`>=3.3`) and `@42/core` are peer dependencies.

## `useC42` composable

The low‑level building block. Bind any `@42/core` controller to an element:

```vue
<script setup lang="ts">
import { ref } from 'vue';
import { Accordion } from '@42/core/accordion';
import { useC42 } from '@42/vue';
import '@42/core/accordion/style.css';

const multiple = ref(true);
// Pass a getter so option changes stay reactive.
const el = useC42(Accordion, () => ({ multiple: multiple.value }));
</script>

<template>
  <div :ref="el">
    <div data-c42-accordion-item data-value="a">
      <button data-c42-accordion-trigger>Title</button>
      <div data-c42-accordion-panel>Content</div>
    </div>
  </div>
</template>
```

- The controller is instantiated in `onMounted` (SSR‑safe — nothing runs on the
  server) and destroyed in `onUnmounted`.
- When the reactive options change, the controller's `update()` is called if it
  exists; otherwise the instance is destroyed and re‑created.

## Generated components

Each controller also ships as a ready‑made component. Props are the controller
options; listen to controller events with `@`:

```vue
<script setup lang="ts">
import { Accordion } from '@42/vue';
import '@42/core/accordion/style.css';

function onChange(detail: { value: string[] }) {
  console.log('open panels:', detail.value);
}
</script>

<template>
  <Accordion :multiple="true" @accordion:change="onChange">
    <div data-c42-accordion-item data-value="a">
      <button data-c42-accordion-trigger>Title</button>
      <div data-c42-accordion-panel>Content</div>
    </div>
  </Accordion>
</template>
```

> Note: component names follow the underlying controller class, so a few differ
> from the manifest id — `choice` → `Checkbox`, `toast` → `Toaster`.

## Regenerating

After the core manifest changes, regenerate the wrappers:

```bash
node scripts/generate-wrappers.mjs
# or
npm run generate
```

This rewrites `src/components/*.ts`, `src/components/index.ts` and
`src/index.ts`. Do not edit the generated files by hand.

## Build

```bash
npm run build
```

## License

MIT © [Laravel42](https://laravel42.com)
