Skip to content

Button

A Vue UI kit component for Baklava's bl-button component with enhanced features and full TypeScript support.

Basic Button

Use the Button component with the variant prop for different styles.

Click me
vue
<template>
  <BvButton variant="primary" @click="handleClick">Click me</BvButton>
</template>

<script setup>
import { BvButton } from "@baklavue/ui";

const handleClick = () => {
  console.log("Button clicked!");
};
</script>

Variants

The Button component supports four variants: primary, secondary and tertiary

PrimarySecondaryTertiary
vue
<template>
  <BvButton variant="primary">Primary</BvButton>
  <BvButton variant="secondary">Secondary</BvButton>
  <BvButton variant="tertiary">Tertiary</BvButton>
</template>

<script setup>
import { BvButton } from "@baklavue/ui";
</script>

Kinds

The Button component supports multiple kinds: default, neutral, success, danger, and custom (with color overrides).

DefaultNeutralSuccessDangerCustom
vue
<template>
  <BvButton kind="default" variant="primary">Default</BvButton>
  <BvButton kind="neutral" variant="primary">Neutral</BvButton>
  <BvButton kind="success" variant="primary">Success</BvButton>
  <BvButton kind="danger" variant="primary">Danger</BvButton>
  <BvButton kind="custom" variant="primary" :custom-class="{ color: '#8b5cf6', highlightColor: '#7c3aed' }">Custom</BvButton>
</template>

<script setup>
import { BvButton } from "@baklavue/ui";
</script>

Sizes

The Button component supports three sizes: small, medium, and large.

SmallMediumLarge
vue
<template>
  <BvButton size="small">Small</BvButton>
  <BvButton size="medium">Medium</BvButton>
  <BvButton size="large">Large</BvButton>
</template>

<script setup>
import { BvButton } from "@baklavue/ui";
</script>

Loading State

Use the loading prop to show a loading indicator. Bind it to your async submit handler.

Submit
vue
<template>
  <BvButton :loading="isLoading" @click="handleClick">Submit</BvButton>
</template>

<script setup>
import { ref } from "vue";
import { BvButton } from "@baklavue/ui";

const isLoading = ref(false);

const handleClick = async () => {
  isLoading.value = true;
  await new Promise((resolve) => setTimeout(resolve, 2000));
  isLoading.value = false;
};
</script>

Disabled State

Use the disabled prop to prevent user interaction.

Disabled Button
vue
<template>
  <BvButton :disabled="true">Disabled Button</BvButton>
</template>

<script setup>
import { BvButton } from "@baklavue/ui";
</script>

Provide an href prop to render the button as a link (anchor tag).

Go to About
vue
<template>
  <BvButton href="/about" variant="primary">Go to About</BvButton>
</template>

<script setup>
import { BvButton } from "@baklavue/ui";
</script>

With Icon

Add an icon using the icon prop. Use a valid icon name from Baklava icons.

Icon
vue
<template>
  <BvButton icon="info">Icon</BvButton>
</template>

<script setup>
import { BvButton } from "@baklavue/ui";
</script>

Props

PropTypeDefaultDescription
variantButtonVariant'primary'Button style variant (primary, secondary, tertiary)
kindButtonKind'default'Button kind (default, neutral, success, danger, custom)
sizeButtonSize'medium'Button size (small, medium, large)
labelstringundefinedButton label text
loadingLabelstring'...'Label shown during loading state
loadingbooleanundefinedLoading state
disabledbooleanundefinedDisabled state
hrefstringundefinedLink URL (renders as anchor tag)
targetTargetTypeundefinedLink target attribute
iconBaklavaIconundefinedIcon name from Baklava icons
typestring'button'Button type (button, submit, reset)
autofocusbooleanundefinedAutofocus attribute
customClassCustomClassundefinedCustom color overrides for custom kind

Events

EventPayloadDescription
clickCustomEvent<MouseEvent>Emitted when button is clicked

Slots

SlotPropsDescription
default-Button content (overrides label prop if provided)

Types

typescript
import type { ButtonProps } from "@baklavue/ui";

// ButtonVariant: "primary" | "secondary" | "tertiary"
// ButtonKind: "default" | "neutral" | "success" | "danger" | "custom"
// ButtonSize: "small" | "medium" | "large"

interface ButtonProps {
  variant?: ButtonVariant;
  kind?: ButtonKind;
  size?: ButtonSize;
  label?: string;
  loadingLabel?: string;
  loading?: boolean;
  disabled?: boolean;
  href?: string;
  target?: "_self" | "_blank" | "_parent" | "_top";
  icon?: string;
  type?: "button" | "submit" | "reset";
  autofocus?: boolean;
  customClass?: {
    color?: string;
    highlightColor?: string;
  };
}

Examples

Form Submit Button

Combine with form inputs and use type="submit" with loading state for async form submission.

Submit
vue
<template>
  <form @submit.prevent="handleSubmit">
    <BvInput v-model="email" label="Email" />
    <BvButton type="submit" :loading="isSubmitting">Submit</BvButton>
  </form>
</template>

<script setup>
import { ref } from "vue";
import { BvButton, BvInput } from "@baklavue/ui";

const email = ref("");
const isSubmitting = ref(false);

const handleSubmit = async () => {
  isSubmitting.value = true;
  await new Promise((resolve) => setTimeout(resolve, 1000));
  isSubmitting.value = false;
};
</script>

Button Group

Group related buttons together with flex layout.

SaveCancelDelete
vue
<template>
  <div style="display: flex; gap: 0.5rem">
    <BvButton variant="primary">Save</BvButton>
    <BvButton variant="secondary">Cancel</BvButton>
    <BvButton variant="tertiary">Delete</BvButton>
  </div>
</template>

<script setup>
import { BvButton } from "@baklavue/ui";
</script>

Usage Notes

  • Label vs Default Slot: Use the label prop for simple text buttons. Use the #default slot when you need custom content (e.g. icons, formatted text, or multiple elements).

  • Loading State: Set loading to true during async operations. The button shows a spinner and is non-clickable while loading. Use loadingLabel to customize the accessibility text.

  • Link vs Button: When href is provided, the component renders an <a> tag instead of <button>. Use target for external links (e.g. _blank).

  • Accessibility: The component follows Baklava's accessibility guidelines and includes proper ARIA attributes for screen readers.

  • Styling: The component uses Baklava's default styling. Custom colors can be applied through the customClass prop when using kind="custom", or by overriding component styles.