UI components

Headless, shadcn-vue style components for Vue 3 + Nuxt 3/4. Each component ships as its own independently-versioned package — install only what you need. Fully typed, themed via CSS variables, dark-mode out of the box.

Components

  • ATelInput — international phone input. Built on reka-ui and vaul-vue. Country auto-detect, libphonenumber-js validation, responsive popover/drawer picker, VeeValidate + Zod integration.
  • ASkeleton — auto-generating skeleton loader. First paint mirrors the slot's HTML structure; second load replays a pixel-aligned shape captured from the real DOM. Public composable + primitives for crafting custom skeleton flows.

Theming

Every design token is a CSS variable prefixed --ak-ui-. Override any of them globally on :root, scoped to a wrapper class, or inline — components pick up the change at runtime via the cascade. Portaled popover / drawer content inherits.

css
/* Per-tenant override — applies to anything inside .tenant-acme */
.tenant-acme {
  --ak-ui-popover: 220 70% 8%;
  --ak-ui-accent: 220 50% 30%;
  --ak-ui-ring: 220 100% 65%;
}
vue
<div class="tenant-acme">
  <ATelInput v-model:phone="phone" v-model:country="country" />
</div>

Values are HSL triplets — no hsl(…) wrapper — because the Tailwind tokens compose them via hsl(var(--ak-ui-…)).

Tokens

VariableUsed for
--ak-ui-background / *-foregroundPage background + text
--ak-ui-popover / *-foregroundPopover surfaces + their text
--ak-ui-muted / *-foregroundHint text, search bar bg, country trigger bg
--ak-ui-accent / *-foregroundList hover + selected row
--ak-ui-destructiveError ring + warning icon
--ak-ui-border / --ak-ui-inputOuter border + inner dividers
--ak-ui-ringFocus ring (the visual "brand")
--ak-ui-radiusBorder radius (no Tailwind token — used directly)

Live theming recipes (brand-only, day/night, multi-tenant, server-driven, state-specific) live on the ATelInput page.

License

MIT © alikhalilll