# GNexus UI Kit — AI Agent Reference

When working on a Vue project that depends on `gnexus-ui-kit`, **always use the official Vue adapter components** instead of writing raw HTML/CSS markup. This document is the single source of truth for which components exist and when to use them.

## Golden Rule

> Prefer `gnexus-ui-kit/vue` components. Do not recreate modal, drawer, tab, toast, form, button, or table markup manually unless the adapter does not expose the needed component yet.

## Required Setup (once per app)

```js
import "gnexus-ui-kit/dist/css/kit.css";
import "gnexus-ui-kit/dist/assets/fonts/phosphor-icons/src/css/icons.css";
```

## Import Pattern

Named imports (preferred):

```js
import { GnButton, GnInput, GnModal } from "gnexus-ui-kit/vue";
```

Global registration:

```js
import { GnexusUiVue } from "gnexus-ui-kit/vue";
app.use(GnexusUiVue);
```

## Icon Naming

All icon props **must** use the `ph-` prefix. Phosphor Icons are the only supported icon set.

```js
// Correct
icon="ph-house"
icon="ph-plus"
icon="ph-bold ph-spinner"   // multiple classes allowed

// Wrong — will trigger a dev warning and may not render
icon="house"
icon="plus"
```

## Component Catalog

| Need | Component | Props you will use |
|------|-----------|-------------------|
| Button | `GnButton` | `variant`, `size`, `icon`, `loading`, `disabled` |
| Icon-only button | `GnIconButton` | `icon`, `label` |
| Status label | `GnBadge` | `variant`, `outline` |
| Message block | `GnAlert` | `variant` |
| Card / panel | `GnCard` | `title` (slot), `footer` (slot) |
| Page title bar | `GnPageHeader` | `kicker`, `title`, `subtitle`, `meta`, `actions` (slot) |
| Text field | `GnInput` | `v-model`, `label`, `icon`, `state`, `help` |
| Textarea | `GnTextarea` | `v-model`, `label`, `state`, `help` |
| Select dropdown | `GnSelect` | `v-model`, `label`, `options` |
| Checkbox | `GnCheckbox` | `v-model`, `label`, `disabled` |
| Toggle switch | `GnSwitch` | `v-model`, `label`, `disabled` |
| Radio | `GnRadio` / `GnRadioGroup` | `v-model`, `options` |
| Range slider | `GnRange` | `v-model`, `label`, `min`, `max` |
| File upload | `GnFileUpload` | `v-model`, `badge`, `multiple`, `accept` |
| Searchable select | `GnCombobox` | `v-model`, `label`, `options`, `placeholder` |
| Tabs | `GnTabs` | `v-model`, `items` |
| Router tabs | `GnRouterTabs` | `items` (with `to`), `activeMatch` |
| Accordion | `GnAccordion` | `items`, `v-model`, `multiple` |
| Modal dialog | `GnModal` | `v-model:open`, `title`, `closeOnBackdrop` |
| Side drawer | `GnDrawer` | `v-model:open`, `title`, `position` |
| Toasts | `GnToastProvider` + `useToast` | Wrap app once; call `toast.success({ title, text })` |
| Confirm dialog | `GnConfirmDialog` | `v-model:open`, `title`, `message`, `confirmVariant` |
| Table | `GnTable` | `columns`, `rows`, `caption`, `emptyText` |
| Toolbar | `GnToolbar` | `title`, `meta`, `actions` (slot) |
| Input group | `GnInputGroup` | `addon` (slot), `action` (slot) |
| Search field | `GnSearchField` | `v-model` |
| Pagination | `GnPagination` | `page`, `total-pages` |
| Empty state | `GnEmptyState` | `title`, `text`, `icon`, `actions` (slot) |
| Skeleton loader | `GnSkeleton` | — |
| Key-value list | `GnDescriptionList` | `items` |
| Progress bar | `GnProgress` | `value`, `label`, `animated` |
| Usage meter card | `GnUsageMeter` | `value`, `label`, `max` |
| Staged progress | `GnProgressStages` | `items` |
| Wizard steps | `GnSteps` | `items`, `current` |
| Chip / tag | `GnChip` | `variant`, `selected`, `removable` |
| Chip group | `GnChipGroup` | — |
| Avatar | `GnAvatar` | `initials`, `icon`, `image`, `size`, `status` |
| Identity row | `GnIdentity` | `title`, `meta`, `avatar` props |
| Avatar stack | `GnAvatarStack` | `items` |
| Timeline | `GnTimeline` | `items` |
| Activity log | `GnActivityLog` | `items` |
| Basic list | `GnList` | `items` |
| Definition list | `GnDefinitionList` | `items` |
| Action list | `GnActionList` | `items` |
| Loader / spinner | `GnLoader` | — |
| Status card | `GnStatusCard` | `variant`, `title`, `meta` |
| Metric card | `GnMetricCard` | `title`, `value`, `trend` |
| Action card | `GnActionCard` | `title`, `text`, `actions` (slot) |
| Dropdown menu | `GnDropdown` | `items`, `label`, `variant` |
| Popover panel | `GnPopover` | `title`, `text`, `label` |
| Tooltip | `GnTooltip` | `text` |
| Navigation list | `GnNavList` | `items` |
| App shell | `GnNavigationShell` | `brand`, `items`, `current`, `footerLeft`, `footerRight` |

## Variants

Use only these variant names:

```
primary, secondary, accent, success, warning, danger, error, info
```

`danger` and `error` render the same color in most components.

## What NOT to do

- Do **not** copy raw modal markup from demo partials into Vue apps.
- Do **not** call `GNexusUIKit.Modals.create()` from Vue components.
- Do **not** call `GNexusUIKit.Overlays.init()` or `GNexusUIKit.NavigationShell.init()` in Vue projects.
- Do **not** run `Accordion.init()` or `Tabs.init()` inside Vue components.
- Do **not** use the legacy `advancedSelect()` helper in Vue; use `GnCombobox`.
- Do **not** use `InputPatterns.init()` for Vue file upload previews; use `GnFileUpload`.
- Do **not** invent new variant names.
- Do **not** duplicate GNexus CSS in scoped `<style>` blocks.
- Do **not** write `class="btn btn-primary"` when `GnButton` exists.

## Acceptable Raw Markup

Raw classes are only acceptable for layout wrappers and content that has **no Vue adapter yet**:

```html
<div class="form-grid">...</div>
<div class="demo-actions">...</div>
```

For any interactive component, add or extend the adapter first.

## Slot Conventions

- `GnTabs` uses tab ids as slot names: `<template #overview>...</template>`
- `GnTable` uses `cell-${column.key}`: `<template #cell-status="{ value }"><GnBadge>{{ value }}</GnBadge></template>`
- `GnModal` uses `default`, `title`, `footer`, and `actions` (actions receives `{ close }`)

## Behavior Contracts

- `GnModal` and `GnDrawer` handle Escape, focus return, and Tab trapping automatically.
- `GnToastProvider` shows one toast at a time: a new toast replaces the previous one.
- `GnCombobox` owns combobox/listbox ARIA and keyboard navigation.
- `GnFileUpload` owns preview object URLs and cleans them up on remove/unmount.

## Verification

Before claiming Vue adapter compatibility in this repo, run:

```bash
npm run build
npm run test:vue-adapter
```
