Skip to content
Kappa
Button
@dicehub/kappav0.4.2

Button

Triggers an action or presents a link with consistent Kappa control styling.

Rotor study · Run 042Ready to submit
No action yet
<script setup>
import { ref } from "vue";
import { Button } from "@dicehub/kappa/components/button";

const message = ref("No action yet");
</script>

<template>
  <section class="run-panel">
    <div><span>Rotor study · Run 042</span><strong>Ready to submit</strong></div>
    <div class="actions">
      <Button @click="message = 'Draft saved'">Save draft</Button>
      <Button variant="primary" @click="message = 'Run submitted'">Run simulation</Button>
    </div>
    <output role="status" aria-live="polite">{{ message }}</output>
  </section>
</template>

Installation

Barrel

import { Button, LinkButton } from "@dicehub/kappa";

Granular

import { Button, LinkButton } from "@dicehub/kappa/components/button";

Usage

Use Button for actions and LinkButton for navigation. Button defaults to type="button", preventing accidental form submission.

<script setup>
import { Button } from "@dicehub/kappa/components/button";

function saveCase() {
  // Persist the current case.
}
</script>

<template>
  <Button variant="primary" @click="saveCase">Save case</Button>
</template>

Examples

Basic

The quiet secondary treatment is the default for dense technical workflows.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button>Save draft</Button>
</template>

Variants

Choose emphasis from the action’s meaning and local hierarchy. A view should rarely need more than one primary action.

Primary

Highest-emphasis action in the local context.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button variant="primary">Primary</Button>
</template>

Secondary

Quiet default action for dense workflows.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button variant="secondary">Secondary</Button>
</template>

Outline

Neutral action on the surrounding surface.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button variant="outline">Outline</Button>
</template>

Ghost

Lowest-emphasis toolbar or contextual action.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button variant="ghost">Ghost</Button>
</template>

Destructive

Primary irreversible or dangerous action.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button variant="destructive">Destructive</Button>
</template>

Secondary Destructive

Quiet destructive action with red text.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button variant="secondary-destructive">Secondary Destructive</Button>
</template>

Destructive Outline

Outlined destructive compatibility treatment.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button variant="destructive-outline">Destructive Outline</Button>
</template>

Success

Explicit approval or successful transition.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button variant="success">Success</Button>
</template>

Warning

Action that needs caution before continuing.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button variant="warning">Warning</Button>
</template>

Inline action styling; use LinkButton when it navigates.

Sizes

Use compact sizes in toolbars and data-dense controls; use base for standard forms.

xs
sm
base
lg
<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button size="xs">Extra small</Button>
  <Button size="sm">Small</Button>
  <Button size="base">Base</Button>
  <Button size="lg">Large</Button>
</template>

With Icons

These examples use @lucide/vue, but icon accepts any Vue component. Set iconPosition with logical values so placement follows the reading direction.

pnpm add @lucide/vue
<script setup>
import { ArrowRight, Plus } from "@lucide/vue";
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button :icon="Plus">New case</Button>
  <Button :icon="ArrowRight" icon-position="inline-end" variant="outline">Export</Button>
</template>

Icon-only

Use square or circle geometry and provide aria-label oraria-labelledby; the decorative icon is hidden from assistive technology.

<script setup>
import { Plus, RefreshCw } from "@lucide/vue";
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button :icon="Plus" shape="square" aria-label="Add case" />
  <Button :icon="RefreshCw" shape="circle" variant="ghost" aria-label="Refresh runs" />
</template>

Loading

Loading preserves the visible label, adds a spinner and aria-busy="true", and blocks duplicate activation.

0
<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button loading>Saving case</Button>
  <Button variant="primary" loading>Submitting run</Button>
</template>

Disabled

Disabled Button uses native disabled semantics. Disabled LinkButton renders a disabled native button so it cannot remain an apparently actionable anchor.

0
<script setup>
import { Button, LinkButton } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button disabled>Save case</Button>
  <LinkButton href="/runs/042" disabled>Open run</LinkButton>
</template>

Full Width

Use fullWidth for stacked mobile forms and narrow confirmation panels.

<script setup>
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <Button full-width variant="primary">Create project</Button>
</template>

LinkButton renders a real anchor. Use external for safe new-tab links andasChild to compose a router link without coupling Kappa to a router. The child owns its icon markup; when disabled, Kappa unwraps its label into a native disabled button.

Native Forms

Opt into native submit or reset behavior with the type prop.

Ready
<script setup>
import { ref } from "vue";
import { Button } from "@dicehub/kappa/components/button";

const message = ref("Ready");
</script>

<template>
  <form aria-label="Case action form" @submit.prevent="message = 'Submitted'" @reset="message = 'Reset'">
    <input name="case" value="Rotor study" />
    <Button type="submit">Submit</Button>
    <Button type="reset" variant="ghost">Reset</Button>
  <output role="status" aria-live="polite">{{ message }}</output>
  </form>
</template>

Right-to-left

Logical icon positions preserve the intended leading and trailing relationships in RTL.

<script setup>
import { ArrowLeft, Plus } from "@lucide/vue";
import { Button } from "@dicehub/kappa/components/button";
</script>

<template>
  <div dir="rtl">
    <Button :icon="Plus">حالة جديدة</Button>
    <Button :icon="ArrowLeft" icon-position="inline-end" variant="outline">تصدير</Button>
  </div>
</template>

Accessibility

  • Use Button for actions and LinkButton for navigation; styling does not replace semantics.
  • Icon-only controls need a concise accessible name describing the action.
  • Loading retains its label, exposes aria-busy, and prevents repeated activation.
  • Do not use only color to distinguish destructive, warning, success, or disabled actions.
  • Keep visible focus indicators. Native buttons activate with Enter and Space; links activate with Enter.
  • A title supplements a concise label; it is not a replacement for an accessible name.

API Reference

Button

Renders a native button and forwards native attributes, ARIA properties, classes, and listeners.

PropTypeDefaultDescription
variantButtonVariant"secondary"Visual and semantic treatment.
size"xs" | "sm" | "base" | "lg""base"Control height, spacing, and icon scale.
shape"base" | "square" | "circle""base"Standard text control or icon-only geometry.
type"button" | "submit" | "reset""button"Native button behavior, including form submission and reset.
loadingbooleanfalseShows a spinner, sets aria-busy, and prevents activation.
disabledbooleanfalseDisables native activation and focus.
fullWidthbooleanfalseFills the available inline size.
iconComponent—Decorative icon rendered beside the label.
iconPropsRecord<string, unknown>—Attributes forwarded to the icon component.
iconPosition"inline-start" | "inline-end""inline-start"Logical icon placement that follows text direction.
titlestring | number—Native advisory text; not a replacement for an accessible name.

Renders an anchor when enabled, a disabled button when unavailable, or merges onto one semantic child when composed.

PropTypeDefaultDescription
hrefstring | undefined—Native anchor destination; omit only when asChild supplies navigation.
externalbooleanfalseOpens in a new tab with a safe rel value.
disabledbooleanfalseRenders a disabled native button so navigation and activation are unavailable.
asChildbooleanfalseMerges styling and attributes onto one child link, such as RouterLink.
iconComponent—Decorates native links. With asChild, render the icon inside the child instead.
iconPropsRecord<string, unknown>—Attributes forwarded to the native-link icon component.
iconPosition"inline-start" | "inline-end""inline-start"Logical native-link icon placement.
titlestring | number—Native advisory text; not a replacement for an accessible name.
variant / size / shape / fullWidthButton styling propsshared defaultsShares Button geometry and visual variants.

Variant Reference

VariantPurpose
primaryHighest-emphasis action in the local context.
secondaryQuiet default action for dense workflows.
outlineNeutral action on the surrounding surface.
ghostLowest-emphasis toolbar or contextual action.
destructivePrimary irreversible or dangerous action.
secondary-destructiveQuiet destructive action with red text.
destructive-outlineOutlined destructive compatibility treatment.
successExplicit approval or successful transition.
warningAction that needs caution before continuing.
linkInline action styling; use LinkButton when it navigates.

Exports

ExportDescription
ButtonNative action button with complete visual and async states.
LinkButtonAnchor and router-link composition with Button styling.
BUTTON_VARIANTS / BUTTON_SIZES / BUTTON_SHAPESReadonly visual option lists.
BUTTON_ICON_POSITIONS / BUTTON_TYPESReadonly logical icon-position and native-type lists.
BUTTON_DEFAULT_*Public variant, size, shape, icon-position, and type defaults.
isButton*Runtime guards for every public option union.
resolveButton*Runtime default resolvers for every public option union.
ButtonProps / ButtonSlots / LinkButtonProps / LinkButtonSlotsPublic Vue contracts.
ButtonVisualPropsVisual props shared by Button and LinkButton.
ButtonVariant / ButtonSize / ButtonShape / ButtonIconPosition / ButtonTypePublic option unions.