Getting Started

Usage

Learn the core patterns for using Akaza UI components.

The slots API

Akaza UI exposes component state through Vue scoped slots.

<script setup lang="ts">
import { Collapsible } from 'akaza-ui'
</script>

<template>
  <Collapsible :ui="{ trigger: 'px-4 py-3 hover:bg-neutral-50' }">
    <template #trigger="{ isOpen }">
      <span>Advanced settings</span>
    </template>

    <template #icon="{ isOpen }">
      <svg :class="{ 'rotate-180': isOpen }" .../>
    </template>

    <template #content>
      <p>Hidden until the trigger is activated.</p>
    </template>
  </Collapsible>
</template>

Bind scoped slot actions to native event handlers. This preserves the originating event for event details and focus restoration:

<template #trigger="{ toggle }">
  <button @click="toggle">Open</button>
</template>

Calling toggle() is appropriate for programmatic actions. For a native handler, prefer @click="toggle" over @click="() => toggle()".

The ui prop

Most components accept a ui prop to inject CSS classes onto root and internal elements. Each key targets a named structural part:

<Accordion
  :items="items"
  :ui="{
    item: 'border-b border-neutral-200',
    trigger: 'px-4 py-3 font-medium hover:bg-neutral-50',
    content: 'px-4 pb-4 text-sm text-neutral-600',
  }"
/>

Use plain class for the root of single-root components. Use ui.root when styling root alongside internal parts. For multi-root or teleported components such as Dialog, AlertDialog, and Drawer, use named ui keys like overlay and content.

The available keys for each component are listed in that component's UI Options table. Exact CSS classes and data attributes are listed in Styling Hooks.

v-model

Components with open/close or value state support v-model:

<script setup lang="ts">
import { ref } from 'vue'
import { Dialog } from 'akaza-ui'

const open = ref(false)
</script>

<template>
  <Dialog v-model="open">
    <template #trigger="{ toggle }">
      <button @click="toggle">Open dialog</button>
    </template>
    <template #body>Dialog content here.</template>
  </Dialog>
</template>

Programmatic control

Components that manage open state expose open, close, and toggle via defineExpose. Access them with a template ref:

<script setup lang="ts">
import { ref } from 'vue'
import { Dialog } from 'akaza-ui'

const dialog = ref()

function showConfirmation() {
  dialog.value?.open()
}
</script>

<template>
  <Dialog ref="dialog">
    <template #body>Are you sure?</template>
    <template #footer="{ close }">
      <button @click="close">Dismiss</button>
    </template>
  </Dialog>

  <button @click="showConfirmation">Show confirmation</button>
</template>

Items-based API

List components (Tabs, Menu, RadioGroup, CheckboxGroup, Accordion) accept an items or options array. Named slots render per-item content:

<script setup lang="ts">
import { ref } from 'vue'
import { Tabs } from 'akaza-ui'

const active = ref('account')
const items = [
  { value: 'account', label: 'Account' },
  { value: 'security', label: 'Security' },
]
</script>

<template>
  <Tabs v-model="active" :items="items" aria-label="Settings">
    <template #panel-account>Account settings…</template>
    <template #panel-security>Security settings…</template>
  </Tabs>
</template>

Listening to events

Components emit typed events for state changes. The first argument is the next value. The second argument is details with reason, optional event, and cancel() for cancelable changes:

<Accordion
  :items="items"
  @value-change="(value, details) => {
    if (details.reason === 'trigger') console.log('opened:', value)
  }"
/>
<Dialog
  @open-change="(open) => analytics.track(open ? 'dialog_open' : 'dialog_close')"
/>

Each component's documentation lists its events in the Emits table.

Input modalities and accessibility

Interactive primitives are designed for keyboard, mouse, pen, and touch input:

  • Native controls keep their browser keyboard, pointer, touch, and form behavior.
  • Composite controls implement their WAI-ARIA keyboard pattern alongside click or tap interaction.
  • Pointer-driven controls use Pointer Events so mouse, pen, and touch share one behavior path.
  • Hover-triggered content also has a focus path. Hover must never be the only way to reach essential information.
  • Tooltips are supplementary labels and are not a reliable place for essential touch content. Use visible text or a Popover when touch users must access the content.
  • Akaza UI is headless, so the consumer controls visual target size. Give tap targets enough space for the interface's audience and device.

The package browser suite covers Chromium, Firefox, WebKit, Android-style touch, iPhone-style touch, and serious or critical axe violations.