Button

Material Design 3 button component with multiple variants and sizes

Button

Buttons allow users to take actions with a single tap. @duskmoon-dev/core provides a complete set of Material Design 3 button variants.

Basic Usage

Basic Button

Variants

Filled Buttons

Filled buttons have the most visual impact and should be used for primary actions.

Filled Buttons

Outlined Buttons

Outlined buttons are medium-emphasis buttons. They’re used for important but not primary actions.

Outlined Buttons

Text Buttons

Text buttons are used for low-priority actions, such as “Cancel” or “Learn More”.

Text Buttons

Tonal Buttons

Tonal buttons use the theme’s container colors for a subtle but noticeable effect.

Tonal Buttons

Semantic Colors

Use semantic colors for user feedback:

Semantic Color Buttons

Semantic colors work with all variants:

Semantic Colors with Variants

Sizes

Three sizes are available:

Button Sizes

Icon Buttons

Buttons with Icons

Add icons alongside text:

Buttons with Icons

Icon-Only Buttons

For compact interfaces, use icon-only buttons:

Icon-Only Buttons

States

Disabled State

Disabled buttons are non-interactive:

Disabled Buttons

Loading State

Use the btn-loading class to show a loading spinner. The text is hidden and a spinner appears in its place:

Loading Buttons

The loading state can be combined with any button variant and size:

Loading Button Sizes

Block Buttons

Full-width buttons:

Block Button

Button Groups

Group related buttons together:

Button Group

Best Practices

Visual Hierarchy

Use button variants to create clear visual hierarchy:

  1. Primary action: btn-primary (filled)
  2. Secondary action: btn-outlined or btn-tonal
  3. Tertiary action: btn-text

Visual Hierarchy Example

Accessibility

  • Always provide meaningful button text or aria-label for icon buttons
  • Use semantic HTML <button> elements
  • Ensure sufficient color contrast
  • Support keyboard navigation (built-in)

Accessible Icon Button

Touch Targets

Ensure buttons are large enough for touch interfaces (minimum 44×44px):

Responsive Button for Touch

Framework Examples

React

interface ButtonProps {
  variant?: 'primary' | 'outlined' | 'text' | 'tonal';
  size?: 'sm' | 'md' | 'lg';
  children: React.ReactNode;
  onClick?: () => void;
}

export function Button({ variant = 'primary', size = 'md', children, ...props }: ButtonProps) {
  return (
    <button className={`btn btn-${variant} btn-${size}`} {...props}>
      {children}
    </button>
  );
}

// Usage
<Button variant="primary" onClick={() => console.log('clicked')}>
  Click Me
</Button>

Vue

<template>
  <button :class="`btn btn-${variant} btn-${size}`" v-bind="$attrs">
    <slot />
  </button>
</template>

<script setup>
defineProps({
  variant: {
    type: String,
    default: 'primary'
  },
  size: {
    type: String,
    default: 'md'
  }
})
</script>

<!-- Usage -->
<Button variant="primary" @click="handleClick">
  Click Me
</Button>

API Reference

Class Names

ClassDescription
.btnBase button styles (required)
.btn-primaryPrimary filled button (default)
.btn-secondarySecondary filled button
.btn-tertiaryTertiary filled button
.btn-outlinedOutlined button variant
.btn-textText button variant
.btn-tonalTonal button variant
.btn-successSuccess semantic color
.btn-errorError semantic color
.btn-warningWarning semantic color
.btn-infoInfo semantic color
.btn-smSmall size
.btn-mdMedium size (default)
.btn-lgLarge size
.btn-iconIcon-only button
.btn-icon-smSmall icon button
.btn-icon-lgLarge icon button
.btn-blockFull-width button
.btn-loadingLoading state with spinner
.btn-circleCircular button (1:1 aspect ratio)
.btn-squareSquare button (1:1 aspect ratio)

Combinations

You can combine classes for different effects:

Class Combinations

  • Badge - Notification indicators
  • Card - Container with actions
  • Input - Form inputs

See Also