# Reusability & Composition

> Source: https://design.nanatec.co.ke/guides/reusability/
> Consume Nana components through attributes, slots, and events — theme once, reuse everywhere.

Nana components are designed to be consumed through one stable contract —
attributes, slots, and events — and themed through design tokens, CSS variables,
and `::part()`. Stay on that surface and the same component drops into any
screen, in any framework, with no forking and no shadow-DOM hacks.

## How it flows

Tokens flow in, the component exposes a public API, your app composes it — and
you theme once at the edges.

```
  design tokens            component (public API)            your app
 ┌──────────────┐        ┌───────────────────────────┐      ┌──────────────┐
 │ --nana-color │        │  attributes  variant/size │      │  <nana-card> │
 │ --nana-space │  ───▶  │  slots       header/body  │ ───▶ │   <nana-…/>  │
 │ --nana-radius│        │  events      nana-change  │      │  </nana-card>│
 └──────────────┘        └───────────────────────────┘      └──────────────┘
        ▲                    ▲ style via ::part / CSS vars        │
        └────────────────────┴─── theme once, reuse everywhere ──┘
```

## 1 · One component, many uses (attributes)

Behaviour and appearance are props. No variant means no new component, no
copy-paste, no custom CSS.

```html
<nana-button variant="primary">Primary</nana-button>
<nana-button variant="secondary">Secondary</nana-button>
<nana-button variant="ghost">Ghost</nana-button>
<nana-button variant="danger" size="sm">Delete</nana-button>
<nana-button variant="primary" loading>Saving…</nana-button>
```

## 2 · Compose with slots

Structure comes from slotted children, so you assemble layouts from primitives
instead of reaching inside them.

```html
<nana-card>
  <nana-card-header>
    <nana-card-title>Monthly statement</nana-card-title>
    <nana-card-description>June 2026</nana-card-description>
  </nana-card-header>
  <nana-card-content>
    Your balance increased by 4.2%.
  </nana-card-content>
</nana-card>
```

## 3 · Theme once, reuse everywhere

Restyle through the three supported layers below — never by targeting shadow-DOM
internals directly. A token change re-skins every instance at once.

```css
:root {
  --nana-color-primary-600: #0f1f1d;
  --nana-radius-md: 8px;
}
nana-table { --nana-table-pad-x: 1rem; --nana-table-pad-y: .5rem; }
nana-dialog::part(panel) { box-shadow: 0 20px 60px rgb(0 0 0 / .2); }
```

## 4 · Reusable icon registry

The icon set is a shared registry: register a glyph once and every `<nana-icon>`
can use it by name. The bundled glyphs are code-split — they load on demand, so
apps that register only their own icons never ship the full set.

```ts
import { registerIcons } from "@nana-tec/ui-components";
registerIcons({
  github: { viewBox: "0 0 24 24", paths: ["M12 .5C5.37.5 …"] },
});
```

## 5 · Stay clean

If you find yourself writing `!important` or piercing the shadow DOM, there's
almost always a prop, slot, or part for it.

```html
<nana-icon name="settings" size="sm"></nana-icon>
<nana-button variant="ghost" size="sm" icon-only>
  <nana-icon name="more_vert"></nana-icon>
</nana-button>
```

```html
<nana-icon name="settings" class="!w-[16px] !h-[16px]"></nana-icon>
```

| Need | Reach for | Not |
|---|---|---|
| Different look / state | `variant`, `size`, `loading` attributes | Cloning the component |
| Custom structure | Slots (`header` / `body` / `footer`) | Wrapper divs around internals |
| Brand colours / spacing | Design tokens + documented CSS vars | `!important` overrides |
| Style an internal part | `::part()` | Piercing the shadow DOM |
| A new glyph | `registerIcon()` once, reuse by name | Inline one-off SVGs everywhere |
