# Frameworks

Classes on HTML work everywhere. Here is how to wire them into common stacks.

## Any stack

MIAN is markup plus classes, so there is nothing framework-specific to install. The only rule: if your framework renders content after load, `mian.js` notices on its own (it watches the DOM), and you can also call `Mian.init(element)`.

## React / Next.js

```
class="hl-c">// app/layout.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
  return (
    <html lang=class="hl-s">"en" data-noodle=class="hl-s">"lamian">
      <head><link rel=class="hl-s">"stylesheet" href=class="hl-s">"https:class="hl-c">//mian.ro/dist/mian.css" /></head>
      <body>{children}<Script src=class="hl-s">"https:class="hl-c">//mian.ro/dist/mian.js" strategy=class="hl-s">"afterInteractive" /></body>
    </html>
  );
}

class="hl-c">// anywhere
<button className=class="hl-s">"mn-btn mn-btn-outline">Cancel</button>
```

Use `className`. Listen for MIAN events with `addEventListener` in an effect: they are ordinary DOM CustomEvents such as `mn:change`.

## Vue / Nuxt

```
<template>
  <div class="mn-tabs">
    <div class="mn-tab-list" aria-label="Settings">
      <button class="mn-tab" aria-selected="true">General</button>
      <button class="mn-tab">Billing</button>
    </div>
    <div class="mn-tab-panel">…</div>
    <div class="mn-tab-panel">…</div>
  </div>
</template>
```

## Laravel, WordPress, plain PHP

```
<button class="mn-btn <?= $danger ? 'mn-danger' : '' ?>" type="submit">
  <?= htmlspecialchars($label) ?>
</button>
```

## Events

Interactive components emit bubbling CustomEvents prefixed `mn:`:

- mn:change: Tabs, toggle group, combobox.

- mn:select: Dropdown menu, command palette (cancelable).

- mn:open · mn:close: Modal and drawer.

- mn:complete: OTP input.

- mn:remove · mn:dismiss: Chip and alert (cancelable).

- mn:theme: Noodle or mode changed.

Source: https://mian.ro/docs/frameworks
