Skip to content

@vibe-labs/design-vue-buttons

Vue 3 button components for the Vibe Design System. Polymorphic rendering, custom color cascading, and full accessibility.

Installation

ts
import { VibeButton, VibeButtonGroup } from "@vibe-labs/design-vue-buttons";

Requires the CSS layer from @vibe-labs/design-components-buttons.

Components

VibeButton

Polymorphic button with variant styling, loading state, and custom color support.

Usage

vue
<!-- Basic variants -->
<VibeButton>Primary</VibeButton>
<VibeButton variant="secondary">Secondary</VibeButton>
<VibeButton variant="ghost">Ghost</VibeButton>
<VibeButton variant="danger">Delete</VibeButton>
<VibeButton variant="link">Learn more</VibeButton>

<!-- Sizes -->
<VibeButton size="sm">Small</VibeButton>
<VibeButton size="md">Medium</VibeButton>
<VibeButton size="lg">Large</VibeButton>

<!-- Shapes -->
<VibeButton shape="circle" icon aria-label="Play">
  <PlayIcon />
</VibeButton>

<!-- Loading -->
<VibeButton :loading="isSubmitting">Save</VibeButton>

<!-- Full width -->
<VibeButton full>Continue</VibeButton>

<!-- Icon button (square aspect ratio) -->
<VibeButton icon aria-label="Settings">
  <SettingsIcon />
</VibeButton>

<!-- Custom color (cascades through all accent-derived tokens) -->
<VibeButton color="#e91e63">Pink Button</VibeButton>

<!-- Render as a link -->
<VibeButton as="a" href="/dashboard">Go to Dashboard</VibeButton>

<!-- Render as a router-link -->
<VibeButton :as="RouterLink" :to="{ name: 'settings' }">Settings</VibeButton>

<!-- Submit button -->
<VibeButton type="submit">Submit Form</VibeButton>

<!-- Disabled -->
<VibeButton disabled>Can't touch this</VibeButton>

Props

PropTypeDefaultDescription
variantButtonVariant"primary"primary · secondary · ghost · danger · link
sizeButtonSize"md"sm · md · lg
shapeButtonShape"default"default · circle (full radius + hover/active scale)
loadingbooleanfalseShows spinner, disables interaction
fullbooleanfalseFull width
iconbooleanfalseSquare aspect ratio for icon-only buttons
disabledbooleanfalseDisabled state
colorstringCustom accent color (cascades via --color-accent)
asstring | Component"button"Polymorphic element/component
type"button" | "submit" | "reset""button"Native button type (only for <button>)

Events

EventPayloadDescription
clickMouseEventClick handler (prevented when disabled/loading)

Slots

SlotDescription
defaultButton content (text, icons, etc.)

Shape: Circle

Circle buttons are commonly used for play controls, FABs, and tile overlays. The circle shape applies border-radius: var(--radius-full) with a subtle hover scale(1.1) and active scale(1.05). Combine with icon for a perfect circle:

vue
<VibeButton shape="circle" icon variant="primary" aria-label="Play">
  <PlayIcon />
</VibeButton>

Custom Color Cascade

The color prop sets --color-accent locally on the button element. Since variant tokens like --btn-primary-bg are defined as var(--color-accent) in the component token layer, they automatically resolve to the custom color — no per-variant overrides needed. Hover and active states are derived using color-mix().

Accessibility

  • Native disabled for <button> elements, aria-disabled for others
  • aria-busy="true" during loading state
  • tabindex="-1" on disabled non-button elements
  • Click prevented when disabled or loading

VibeButtonGroup

Groups buttons with shared border radius handling and overlap.

Usage

vue
<VibeButtonGroup label="Actions">
  <VibeButton variant="secondary">Left</VibeButton>
  <VibeButton variant="secondary">Center</VibeButton>
  <VibeButton variant="secondary">Right</VibeButton>
</VibeButtonGroup>

<!-- As toolbar -->
<VibeButtonGroup role="toolbar" label="Text formatting">
  <VibeButton icon><BoldIcon /></VibeButton>
  <VibeButton icon><ItalicIcon /></VibeButton>
  <VibeButton icon><UnderlineIcon /></VibeButton>
</VibeButtonGroup>

Props

PropTypeDefaultDescription
role"group" | "toolbar""group"ARIA role
labelstringAccessible group label

Dependencies

PackagePurpose
@vibe-labs/design-components-buttonsCSS tokens + generated styles

Build

bash
npm run build

Built with Vite + vite-plugin-dts. Outputs ES module with TypeScript declarations.