Button
This library is a work-in-progress. We are releasing it early to gather feedback, but it is not ready for production.
The Button component provides a versatile, accessible button foundation with multiple variants, sizes, and shapes.
Examples
Live Preview
Rounded Variants
Shapes
Bordered
Sizes
Icons Small
Icons Only
To create an accessible icon-only button, wrap the icon component with a <ag-button> element and provide an accessible label using the VisuallyHidden component.
This ensures screen reader users understand the button's action without a visible text label. Ensure you also provide a clear title attribute for mouse users who hover over the icon.
Icons
Grouped
Miscellaneous
Full Width
Use the full-width attribute to make buttons expand to 100% of their container width.
Disabled States - Filled Buttons
Disabled buttons maintain their color identity using lighter background and text tokens. Each variant shows its tonal identity while clearly indicating the inactive state.
Disabled States - Bordered Buttons
Bordered buttons use opacity when disabled, maintaining visual consistency.
State Comparison - Normal vs Disabled
Side-by-side comparison of normal and disabled states for each variant.
State Comparison - Bordered Normal vs Disabled
CSS Parts Customization
Customize button appearance using CSS Shadow Parts without breaking encapsulation.
View Vue Code
<template>
<section>
<div class="mbe4">
<VueButton
class="mie2"
title="Default"
>
Default
</VueButton>
</div>
<!-- Rounded -->
<div class="mbe2">
<h2>Rounded Variants</h2>
</div>
<div class="stacked-mobile mbe4">
<VueButton
shape="rounded"
title="Default"
>Default</VueButton>
<VueButton
shape="rounded"
variant="primary"
title="Primary"
>Primary</VueButton>
<VueButton
shape="rounded"
variant="secondary"
title="Secondary"
>Secondary</VueButton>
<VueButton
shape="rounded"
variant="success"
title="Success"
>Success</VueButton>
<VueButton
shape="rounded"
variant="warning"
title="Warning"
>Warning</VueButton>
<VueButton
shape="rounded"
variant="danger"
title="Danger"
>Danger</VueButton>
<VueButton
shape="rounded"
variant="monochrome"
title="Monochrome"
>Monochrome</VueButton>
</div>
<!-- Shapes -->
<div class="mbe2">
<h2>Shapes</h2>
</div>
<div class="stacked-mobile mbe4">
<VueButton
shape="rounded"
variant="primary"
:bordered="true"
title="Rounded Button"
>Rounded</VueButton>
<VueButton
shape="capsule"
variant="success"
:bordered="true"
title="Capsule Button"
>Capsule</VueButton>
<VueButton
shape="circle"
:bordered="true"
title="Circle Button"
>C</VueButton>
<VueButton
shape="square"
variant="secondary"
:bordered="true"
title="Square Button"
>S</VueButton>
<VueButton
shape="rounded-square"
:bordered="true"
variant="danger"
title="Rounded Square Button"
>RS</VueButton>
</div>
<!-- Bordered -->
<div class="mbe2">
<h2>Bordered</h2>
</div>
<div class="stacked-mobile mbe4">
<VueButton
:bordered="true"
shape="rounded"
title="Default"
>Default</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="primary"
title="Primary"
>Primary</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="secondary"
title="Secondary"
>Secondary</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="success"
title="Success"
>Success</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="warning"
title="Warning"
>Warning</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="danger"
title="Danger"
>Danger</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="monochrome"
title="Monochrome"
>Monochrome</VueButton>
</div>
<!-- Sizes -->
<div class="mbe2">
<h2>Sizes</h2>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
:bordered="true"
size="x-sm"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
:bordered="true"
size="sm"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
:bordered="true"
size="md"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
:bordered="true"
size="lg"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
:bordered="true"
size="xl"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
variant="primary"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
variant="primary"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
variant="primary"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
variant="primary"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
variant="primary"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
variant="primary"
:bordered="true"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
variant="primary"
:bordered="true"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
variant="primary"
:bordered="true"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
variant="primary"
:bordered="true"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
variant="primary"
:bordered="true"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
variant="success"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
variant="success"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
variant="success"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
variant="success"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
variant="success"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
variant="success"
:bordered="true"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
variant="success"
:bordered="true"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
variant="success"
:bordered="true"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
variant="success"
:bordered="true"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
variant="success"
:bordered="true"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
variant="warning"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
variant="warning"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
variant="warning"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
variant="warning"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
variant="warning"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
variant="warning"
:bordered="true"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
variant="warning"
:bordered="true"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
variant="warning"
:bordered="true"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
variant="warning"
:bordered="true"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
variant="warning"
:bordered="true"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
variant="danger"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
variant="danger"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
variant="danger"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
variant="danger"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
variant="danger"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
bordered
variant="danger"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
:bordered="true"
variant="danger"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
:bordered="true"
variant="danger"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
:bordered="true"
variant="danger"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
:bordered="true"
variant="danger"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
variant="monochrome"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
variant="monochrome"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
variant="monochrome"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
variant="monochrome"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
variant="monochrome"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<div class="stacked-mobile mbe4">
<VueButton
size="x-sm"
bordered
variant="monochrome"
shape="rounded"
title="Extra Small"
>Extra Small</VueButton>
<VueButton
size="sm"
:bordered="true"
variant="monochrome"
shape="rounded"
title="Small"
>Small</VueButton>
<VueButton
size="md"
:bordered="true"
variant="monochrome"
shape="rounded"
title="Medium"
>Medium</VueButton>
<VueButton
size="lg"
:bordered="true"
variant="monochrome"
shape="rounded"
title="Large"
>Large</VueButton>
<VueButton
size="xl"
:bordered="true"
variant="monochrome"
shape="rounded"
title="Extra Large"
>Extra Large</VueButton>
</div>
<!-- Icons -->
<!-- Icons Small -->
<div class="mbe2">
<h2>Icons Small</h2>
</div>
<div class="stacked-mobile mbe4">
<div
class="flex-inline"
role="group"
aria-label="Framework selection"
>
<VueButton
variant="primary"
size="sm"
shape="rounded"
class="mie2"
title="Invite Members"
>
<VueIcon size="16" :no-fill="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
</VueIcon>
<span class="mis1 mie2">Invite Members</span>
</VueButton>
<VueButton
variant="primary"
size="sm"
shape="rounded"
:bordered="true"
class="mis1 mie2"
title="Create New"
>
<VueIcon size="16" :no-fill="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 5v14m-7-7h14"/>
</svg>
</VueIcon>
<span>Create New</span>
</VueButton>
<VueButton
variant="danger"
size="sm"
shape="rounded"
title="Record"
>
<VueIcon size="16" :no-fill="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 1a3 3 0 003 3v8a3 3 0 11-6 0V4a3 3 0 003-3zM19 10v2a7 7 0 01-14 0v-2M12 19v4m-4 0h8"/>
</svg>
</VueIcon>
<span>Record</span>
</VueButton>
</div>
</div>
<!-- Icons Only -->
<div class="mbe2">
<h2>Icons Only</h2>
<p>To create an accessible icon-only button, wrap the icon component with a <code><ag-button></code> element and provide an accessible label using the <code>VisuallyHidden</code> component.</p>
<p>This ensures screen reader users understand the button's action without a visible text label. Ensure you also provide a clear <code>title</code> attribute for mouse users who hover over the icon.</p>
</div>
<div class="stacked-mobile mbe4">
<div
class="flex-inline"
role="group"
aria-label="Framework selection"
>
<VueButton
variant="primary"
size="sm"
shape="rounded"
title="Invite Members"
class="mie2"
>
<VueIcon size="16" :no-fill="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
</VueIcon>
<VueVisuallyHidden>Invite Members</VueVisuallyHidden>
</VueButton>
</div>
</div>
<!-- Icons -->
<div class="mbe2">
<h2>Icons</h2>
</div>
<div class="stacked-mobile mbe4">
<div
class="flex-inline"
role="group"
aria-label="Framework selection"
>
<VueButton
variant="primary"
shape="rounded"
title="Invite Members"
class="mie2"
>
<VueIcon size="18" :no-fill="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
</VueIcon>
<span class="mis1 mie2">Invite Members</span>
</VueButton>
<VueButton
variant="primary"
shape="rounded"
title="Create new"
:bordered="true"
class="mis1 mie2"
>
<VueIcon size="18" :no-fill="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 5v14m-7-7h14"/>
</svg>
</VueIcon>
<span>Create New</span>
</VueButton>
<VueButton
variant="danger"
title="Record"
shape="rounded"
>
<VueIcon size="18" :no-fill="true">
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 1a3 3 0 003 3v8a3 3 0 11-6 0V4a3 3 0 003-3zM19 10v2a7 7 0 01-14 0v-2M12 19v4m-4 0h8"/>
</svg>
</VueIcon>
<span>Record</span>
</VueButton>
</div>
</div>
<!-- Grouped -->
<div class="mbe2">
<h2>Grouped</h2>
</div>
<div class="stacked-mobile mbe4">
<div
class="flex-inline"
role="group"
aria-label="Framework selection"
>
<VueButton
grouped
title="React"
:bordered="true"
variant="secondary"
>React</VueButton>
<VueButton
grouped
title="Vue"
:bordered="true"
variant="secondary"
>Vue</VueButton>
<VueButton
grouped
title="Svelte"
:bordered="true"
variant="secondary"
>Svelte</VueButton>
<VueButton
grouped
title="Lit"
:bordered="true"
variant="secondary"
>Lit</VueButton>
</div>
</div>
<div class="stacked-mobile mbe4">
<div
class="flex-inline"
role="group"
aria-label="Framework selection"
>
<VueButton
grouped
title="React"
:bordered="true"
variant="primary"
>React</VueButton>
<VueButton
grouped
title="Vue"
:bordered="true"
variant="primary"
>Vue</VueButton>
<VueButton
grouped
title="Svelte"
:bordered="true"
variant="primary"
>Svelte</VueButton>
<VueButton
grouped
title="Lit"
:bordered="true"
variant="primary"
>Lit</VueButton>
</div>
</div>
<div class="stacked-mobile mbe4">
<div
class="flex-inline"
role="group"
aria-label="Framework selection"
>
<VueButton
grouped
title="React"
:bordered="true"
variant="monochrome"
>React</VueButton>
<VueButton
grouped
title="Vue"
:bordered="true"
variant="monochrome"
>Vue</VueButton>
<VueButton
grouped
title="Svelte"
:bordered="true"
variant="monochrome"
>Svelte</VueButton>
<VueButton
grouped
title="Lit"
:bordered="true"
variant="monochrome"
>Lit</VueButton>
</div>
</div>
<!-- Misc -->
<div class="mbe2">
<h2>Miscellaneous</h2>
</div>
<div class="stacked-mobile mbe4">
<VueButton
ghost
title="Ghost button"
class="mie2"
>Ghost</VueButton>
<VueButton
link
title="button link"
class="mie2"
>Link</VueButton>
<VueButton
type="submit"
bordered
title="submit button"
shape="rounded"
variant="primary"
class="mie2"
>Submit</VueButton>
<VueButton
title="toggle button"
:toggle="true"
class="mie2"
>Toggle</VueButton>
<VueButton
title="example disabled button"
disabled
class="mie2"
>Disabled</VueButton>
</div>
<!-- Full Width -->
<div class="mbe2">
<h2>Full Width</h2>
<p style="color: var(--ag-text-secondary); font-size: 0.875rem;">
Use the <code>full-width</code> attribute to make buttons expand to 100% of their container width.
</p>
</div>
<div class="mbe4">
<VueButton
:full-width="true"
variant="primary"
shape="rounded"
title="Full Width Primary"
>Full Width Primary</VueButton>
</div>
<div class="mbe4">
<VueButton
:full-width="true"
variant="monochrome"
shape="rounded"
title="Full Width Monochrome"
>Full Width Monochrome</VueButton>
</div>
<div class="mbe4">
<VueButton
:full-width="true"
:bordered="true"
variant="success"
shape="rounded"
title="Full Width Bordered Success"
>Full Width Bordered Success</VueButton>
</div>
<!-- Disabled States - Comprehensive -->
<div class="mbe2">
<h2>Disabled States - Filled Buttons</h2>
<p style="color: var(--ag-text-secondary); font-size: 0.875rem;">
Disabled buttons maintain their color identity using lighter background and text tokens.
Each variant shows its tonal identity while clearly indicating the inactive state.
</p>
</div>
<div class="stacked-mobile mbe4">
<VueButton
shape="rounded"
title="Default Disabled"
disabled
>Default</VueButton>
<VueButton
shape="rounded"
variant="primary"
title="Primary Disabled"
disabled
>Primary</VueButton>
<VueButton
shape="rounded"
variant="secondary"
title="Secondary Disabled"
disabled
>Secondary</VueButton>
<VueButton
shape="rounded"
variant="success"
title="Success Disabled"
disabled
>Success</VueButton>
<VueButton
shape="rounded"
variant="warning"
title="Warning Disabled"
disabled
>Warning</VueButton>
<VueButton
shape="rounded"
variant="danger"
title="Danger Disabled"
disabled
>Danger</VueButton>
<VueButton
shape="rounded"
variant="monochrome"
title="Monochrome Disabled"
disabled
>Monochrome</VueButton>
</div>
<div class="mbe2">
<h2>Disabled States - Bordered Buttons</h2>
<p style="color: var(--ag-text-secondary); font-size: 0.875rem;">
Bordered buttons use opacity when disabled, maintaining visual consistency.
</p>
</div>
<div class="stacked-mobile mbe4">
<VueButton
:bordered="true"
shape="rounded"
title="Default Bordered Disabled"
disabled
>Default</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="primary"
title="Primary Bordered Disabled"
disabled
>Primary</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="secondary"
title="Secondary Bordered Disabled"
disabled
>Secondary</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="success"
title="Success Bordered Disabled"
disabled
>Success</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="warning"
title="Warning Bordered Disabled"
disabled
>Warning</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="danger"
title="Danger Bordered Disabled"
disabled
>Danger</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="monochrome"
title="Monochrome Bordered Disabled"
disabled
>Monochrome</VueButton>
</div>
<div class="mbe2">
<h2>State Comparison - Normal vs Disabled</h2>
<p style="color: var(--ag-text-secondary); font-size: 0.875rem;">
Side-by-side comparison of normal and disabled states for each variant.
</p>
</div>
<div class="mbe4">
<div class="stacked-mobile mbe2">
<VueButton
shape="rounded"
variant="primary"
title="Primary Normal"
>Primary Normal</VueButton>
<VueButton
shape="rounded"
variant="primary"
title="Primary Disabled"
disabled
>Primary Disabled</VueButton>
</div>
<div class="stacked-mobile mbe2">
<VueButton
shape="rounded"
variant="success"
title="Success Normal"
>Success Normal</VueButton>
<VueButton
shape="rounded"
variant="success"
title="Success Disabled"
disabled
>Success Disabled</VueButton>
</div>
<div class="stacked-mobile mbe2">
<VueButton
shape="rounded"
variant="warning"
title="Warning Normal"
>Warning Normal</VueButton>
<VueButton
shape="rounded"
variant="warning"
title="Warning Disabled"
disabled
>Warning Disabled</VueButton>
</div>
<div class="stacked-mobile mbe2">
<VueButton
shape="rounded"
variant="danger"
title="Danger Normal"
>Danger Normal</VueButton>
<VueButton
shape="rounded"
variant="danger"
title="Danger Disabled"
disabled
>Danger Disabled</VueButton>
</div>
</div>
<div class="mbe2">
<h2>State Comparison - Bordered Normal vs Disabled</h2>
</div>
<div class="mbe4">
<div class="stacked-mobile mbe2">
<VueButton
:bordered="true"
shape="rounded"
variant="primary"
title="Primary Bordered Normal"
>Primary Normal</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="primary"
title="Primary Bordered Disabled"
disabled
>Primary Disabled</VueButton>
</div>
<div class="stacked-mobile mbe2">
<VueButton
:bordered="true"
shape="rounded"
variant="success"
title="Success Bordered Normal"
>Success Normal</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="success"
title="Success Bordered Disabled"
disabled
>Success Disabled</VueButton>
</div>
<div class="stacked-mobile mbe2">
<VueButton
:bordered="true"
shape="rounded"
variant="warning"
title="Warning Bordered Normal"
>Warning Normal</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="warning"
title="Warning Bordered Disabled"
disabled
>Warning Disabled</VueButton>
</div>
<div class="stacked-mobile mbe2">
<VueButton
:bordered="true"
shape="rounded"
variant="danger"
title="Danger Bordered Normal"
>Danger Normal</VueButton>
<VueButton
:bordered="true"
shape="rounded"
variant="danger"
title="Danger Bordered Disabled"
disabled
>Danger Disabled</VueButton>
</div>
</div>
<!-- CSS Parts Customization -->
<div class="mbe4">
<h2>CSS Parts Customization</h2>
<p
class="mbe2"
style="color: var(--ag-text-secondary); font-size: 0.875rem;"
>
Customize button appearance using CSS Shadow Parts without breaking encapsulation.
</p>
</div>
<div class="stacked-mobile mbe4">
<VueButton
title="Gradient Button"
class="custom-gradient-button mie3"
>
Gradient Button
</VueButton>
</div>
</section>
</template>
<script>
import VueButton from "agnosticui-core/button/vue";
import { VueVisuallyHidden } from "agnosticui-core/visually-hidden/vue";
import { VueIcon } from "agnosticui-core/icon/vue";
export default {
name: "ButtonExamples",
components: {
VueButton,
VueVisuallyHidden,
VueIcon,
},
};
</script>
<style scoped>
/* CSS Parts customization examples */
/* Gradient button style */
.custom-gradient-button::part(ag-button) {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
padding: 1rem 2rem;
border-radius: 50px;
border: none;
box-shadow: 0 8px 16px rgba(102, 126, 234, 0.4);
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
transition: all 0.3s ease;
}
.custom-gradient-button::part(ag-button):hover {
transform: translateY(-2px);
box-shadow: 0 10px 20px rgba(102, 126, 234, 0.6);
}
</style>
Live Preview
View Lit / Web Component Code
import { LitElement, html } from 'lit';
import 'agnosticui-core/button';
import 'agnosticui-core/icon';
export class ButtonLitExamples extends LitElement {
// Render in light DOM to access global utility classes
createRenderRoot() {
return this;
}
render() {
return html`
<section>
<!-- Default -->
<div class="mbe4">
<ag-button class="mie2" title="Default">Default</ag-button>
</div>
<!-- Rounded Variants -->
<div class="mbe2">
<h2>Rounded Variants</h2>
</div>
<div class="stacked-mobile mbe4">
<ag-button shape="rounded" title="Default">Default</ag-button>
<ag-button shape="rounded" variant="primary" title="Primary">Primary</ag-button>
<ag-button shape="rounded" variant="secondary" title="Secondary">Secondary</ag-button>
<ag-button shape="rounded" variant="success" title="Success">Success</ag-button>
<ag-button shape="rounded" variant="warning" title="Warning">Warning</ag-button>
<ag-button shape="rounded" variant="danger" title="Danger">Danger</ag-button>
<ag-button shape="rounded" variant="monochrome" title="Monochrome">Monochrome</ag-button>
</div>
<!-- Shapes -->
<div class="mbe2">
<h2>Shapes</h2>
</div>
<div class="stacked-mobile mbe4">
<ag-button shape="rounded" variant="primary" bordered title="Rounded Button">Rounded</ag-button>
<ag-button shape="capsule" variant="success" bordered title="Capsule Button">Capsule</ag-button>
<ag-button shape="circle" bordered title="Circle Button">C</ag-button>
<ag-button shape="square" variant="secondary" bordered title="Square Button">S</ag-button>
<ag-button shape="rounded-square" bordered variant="danger" title="Rounded Square Button">RS</ag-button>
</div>
<!-- Bordered -->
<div class="mbe2">
<h2>Bordered</h2>
</div>
<div class="stacked-mobile mbe4">
<ag-button bordered shape="rounded" title="Default">Default</ag-button>
<ag-button bordered shape="rounded" variant="primary" title="Primary">Primary</ag-button>
<ag-button bordered shape="rounded" variant="secondary" title="Secondary">Secondary</ag-button>
<ag-button bordered shape="rounded" variant="success" title="Success">Success</ag-button>
<ag-button bordered shape="rounded" variant="warning" title="Warning">Warning</ag-button>
<ag-button bordered shape="rounded" variant="danger" title="Danger">Danger</ag-button>
<ag-button bordered shape="rounded" variant="monochrome" title="Monochrome">Monochrome</ag-button>
</div>
<!-- Sizes -->
<div class="mbe2">
<h2>Sizes</h2>
</div>
<!-- Default sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Bordered sizes -->
<div class="stacked-mobile mbe4">
<ag-button bordered size="x-sm" shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button bordered size="sm" shape="rounded" title="Small">Small</ag-button>
<ag-button bordered size="md" shape="rounded" title="Medium">Medium</ag-button>
<ag-button bordered size="lg" shape="rounded" title="Large">Large</ag-button>
<ag-button bordered size="xl" shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Primary sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" variant="primary" shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" variant="primary" shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" variant="primary" shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" variant="primary" shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" variant="primary" shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Primary bordered sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" variant="primary" bordered shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" variant="primary" bordered shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" variant="primary" bordered shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" variant="primary" bordered shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" variant="primary" bordered shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Success sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" variant="success" shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" variant="success" shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" variant="success" shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" variant="success" shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" variant="success" shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Success bordered sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" variant="success" bordered shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" variant="success" bordered shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" variant="success" bordered shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" variant="success" bordered shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" variant="success" bordered shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Warning sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" variant="warning" shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" variant="warning" shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" variant="warning" shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" variant="warning" shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" variant="warning" shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Warning bordered sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" variant="warning" bordered shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" variant="warning" bordered shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" variant="warning" bordered shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" variant="warning" bordered shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" variant="warning" bordered shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Danger sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" variant="danger" shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" variant="danger" shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" variant="danger" shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" variant="danger" shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" variant="danger" shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Danger bordered sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" bordered variant="danger" shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" bordered variant="danger" shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" bordered variant="danger" shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" bordered variant="danger" shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" bordered variant="danger" shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Monochrome sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" variant="monochrome" shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" variant="monochrome" shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" variant="monochrome" shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" variant="monochrome" shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" variant="monochrome" shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Monochrome bordered sizes -->
<div class="stacked-mobile mbe4">
<ag-button size="x-sm" bordered variant="monochrome" shape="rounded" title="Extra Small">Extra Small</ag-button>
<ag-button size="sm" bordered variant="monochrome" shape="rounded" title="Small">Small</ag-button>
<ag-button size="md" bordered variant="monochrome" shape="rounded" title="Medium">Medium</ag-button>
<ag-button size="lg" bordered variant="monochrome" shape="rounded" title="Large">Large</ag-button>
<ag-button size="xl" bordered variant="monochrome" shape="rounded" title="Extra Large">Extra Large</ag-button>
</div>
<!-- Icons Small -->
<div class="mbe2">
<h2>Icons Small</h2>
</div>
<div class="stacked-mobile mbe4">
<div class="flex-inline" role="group" aria-label="Framework selection">
<ag-button variant="primary" size="sm" shape="rounded" class="mie2" title="Invite Members">
<ag-icon size="16" no-fill>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
</ag-icon>
<span class="mis1 mie2">Invite Members</span>
</ag-button>
<ag-button variant="primary" size="sm" shape="rounded" bordered class="mis1 mie2" title="Create New">
<ag-icon size="16" no-fill>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 5v14m-7-7h14"/>
</svg>
</ag-icon>
<span>Create New</span>
</ag-button>
<ag-button variant="danger" size="sm" shape="rounded" title="Record">
<ag-icon size="16" no-fill>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 1a3 3 0 003 3v8a3 3 0 11-6 0V4a3 3 0 003-3zM19 10v2a7 7 0 01-14 0v-2M12 19v4m-4 0h8"/>
</svg>
</ag-icon>
<span>Record</span>
</ag-button>
</div>
</div>
<!-- Icons Only -->
<div class="mbe2">
<h2>Icons Only</h2>
<p>To create an accessible icon-only button, provide an accessible label using the <code>aria-label</code> attribute. This ensures screen reader users understand the button's action without a visible text label. Ensure you also provide a clear <code>title</code> attribute for mouse users who hover over the icon.</p>
</div>
<div class="stacked-mobile mbe4">
<div class="flex-inline" role="group" aria-label="Framework selection">
<ag-button variant="primary" size="sm" shape="rounded" title="Invite Members" aria-label="Invite Members" class="mie2">
<ag-icon size="16" no-fill>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
</ag-icon>
</ag-button>
</div>
</div>
<!-- Icons -->
<div class="mbe2">
<h2>Icons</h2>
</div>
<div class="stacked-mobile mbe4">
<div class="flex-inline" role="group" aria-label="Framework selection">
<ag-button variant="primary" shape="rounded" title="Invite Members" class="mie2">
<ag-icon size="18" no-fill>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"/>
</svg>
</ag-icon>
<span class="mis1 mie2">Invite Members</span>
</ag-button>
<ag-button variant="primary" shape="rounded" title="Create new" bordered class="mis1 mie2">
<ag-icon size="18" no-fill>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 5v14m-7-7h14"/>
</svg>
</ag-icon>
<span>Create New</span>
</ag-button>
<ag-button variant="danger" title="Record" shape="rounded">
<ag-icon size="18" no-fill>
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" aria-hidden="true">
<path d="M12 1a3 3 0 003 3v8a3 3 0 11-6 0V4a3 3 0 003-3zM19 10v2a7 7 0 01-14 0v-2M12 19v4m-4 0h8"/>
</svg>
</ag-icon>
<span>Record</span>
</ag-button>
</div>
</div>
<!-- Grouped -->
<div class="mbe2">
<h2>Grouped</h2>
</div>
<div class="stacked-mobile mbe4">
<div class="flex-inline" role="group" aria-label="Framework selection">
<ag-button grouped title="React" bordered variant="secondary">React</ag-button>
<ag-button grouped title="Vue" bordered variant="secondary">Vue</ag-button>
<ag-button grouped title="Svelte" bordered variant="secondary">Svelte</ag-button>
<ag-button grouped title="Lit" bordered variant="secondary">Lit</ag-button>
</div>
</div>
<div class="stacked-mobile mbe4">
<div class="flex-inline" role="group" aria-label="Framework selection">
<ag-button grouped title="React" bordered variant="primary">React</ag-button>
<ag-button grouped title="Vue" bordered variant="primary">Vue</ag-button>
<ag-button grouped title="Svelte" bordered variant="primary">Svelte</ag-button>
<ag-button grouped title="Lit" bordered variant="primary">Lit</ag-button>
</div>
</div>
<div class="stacked-mobile mbe4">
<div class="flex-inline" role="group" aria-label="Framework selection">
<ag-button grouped title="React" bordered variant="monochrome">React</ag-button>
<ag-button grouped title="Vue" bordered variant="monochrome">Vue</ag-button>
<ag-button grouped title="Svelte" bordered variant="monochrome">Svelte</ag-button>
<ag-button grouped title="Lit" bordered variant="monochrome">Lit</ag-button>
</div>
</div>
<!-- Miscellaneous -->
<div class="mbe2">
<h2>Miscellaneous</h2>
</div>
<div class="stacked-mobile mbe4">
<ag-button ghost title="Ghost button" class="mie2">Ghost</ag-button>
<ag-button link title="button link" class="mie2">Link</ag-button>
<ag-button type="submit" bordered title="submit button" shape="rounded" variant="primary" class="mie2">Submit</ag-button>
<ag-button title="toggle button" toggle class="mie2">Toggle</ag-button>
<ag-button title="example disabled button" disabled class="mie2">Disabled</ag-button>
</div>
<!-- CSS Parts Customization -->
<div class="mbe4">
<h2>CSS Parts Customization</h2>
<p class="mbe2" style="color: var(--ag-text-secondary); font-size: 0.875rem;">
Customize button appearance using CSS Shadow Parts without breaking encapsulation.
</p>
</div>
<div class="stacked-mobile mbe4">
<ag-button title="Gradient Button" class="custom-gradient-button mie3">
Gradient Button
</ag-button>
</div>
</section>
`;
}
}
// Register the custom element
customElements.define('button-lit-examples', ButtonLitExamples);
Interactive Preview: Click the "Open in StackBlitz" button below to see this example running live in an interactive playground.
View React Code
import { useState } from "react";
import { ReactButton } from "agnosticui-core/button/react";
import { ReactIcon } from "agnosticui-core/icon/react";
import { ReactVisuallyHidden } from "agnosticui-core/visually-hidden/react";
export default function ButtonReactExamples() {
const [isPressed, setIsPressed] = useState(false);
const handleToggle = (event) => {
setIsPressed(event.detail.pressed);
console.log("Button toggled:", event.detail.pressed);
};
return (
<section>
{/* Default */}
<div className="mbe4">
<ReactButton className="mie2" title="Default">
Default
</ReactButton>
</div>
{/* Rounded Variants */}
<div className="mbe2">
<h2>Rounded Variants</h2>
</div>
<div className="stacked-mobile mbe4">
<ReactButton shape="rounded" title="Default">
Default
</ReactButton>
<ReactButton shape="rounded" variant="primary" title="Primary">
Primary
</ReactButton>
<ReactButton shape="rounded" variant="secondary" title="Secondary">
Secondary
</ReactButton>
<ReactButton shape="rounded" variant="success" title="Success">
Success
</ReactButton>
<ReactButton shape="rounded" variant="warning" title="Warning">
Warning
</ReactButton>
<ReactButton shape="rounded" variant="danger" title="Danger">
Danger
</ReactButton>
<ReactButton shape="rounded" variant="monochrome" title="Monochrome">
Monochrome
</ReactButton>
</div>
{/* Shapes */}
<div className="mbe2">
<h2>Shapes</h2>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
shape="rounded"
variant="primary"
bordered
title="Rounded Button"
>
Rounded
</ReactButton>
<ReactButton
shape="capsule"
variant="success"
bordered
title="Capsule Button"
>
Capsule
</ReactButton>
<ReactButton shape="circle" bordered title="Circle Button">
C
</ReactButton>
<ReactButton
shape="square"
variant="secondary"
bordered
title="Square Button"
>
S
</ReactButton>
<ReactButton
shape="rounded-square"
bordered
variant="danger"
title="Rounded Square Button"
>
RS
</ReactButton>
</div>
{/* Bordered */}
<div className="mbe2">
<h2>Bordered</h2>
</div>
<div className="stacked-mobile mbe4">
<ReactButton bordered shape="rounded" title="Default">
Default
</ReactButton>
<ReactButton bordered shape="rounded" variant="primary" title="Primary">
Primary
</ReactButton>
<ReactButton
bordered
shape="rounded"
variant="secondary"
title="Secondary"
>
Secondary
</ReactButton>
<ReactButton bordered shape="rounded" variant="success" title="Success">
Success
</ReactButton>
<ReactButton bordered shape="rounded" variant="warning" title="Warning">
Warning
</ReactButton>
<ReactButton bordered shape="rounded" variant="danger" title="Danger">
Danger
</ReactButton>
<ReactButton
bordered
shape="rounded"
variant="monochrome"
title="Monochrome"
>
Monochrome
</ReactButton>
</div>
{/* Sizes */}
<div className="mbe2">
<h2>Sizes</h2>
</div>
<div className="stacked-mobile mbe4">
<ReactButton size="x-sm" shape="rounded" title="Extra Small">
Extra Small
</ReactButton>
<ReactButton size="sm" shape="rounded" title="Small">
Small
</ReactButton>
<ReactButton size="md" shape="rounded" title="Medium">
Medium
</ReactButton>
<ReactButton size="lg" shape="rounded" title="Large">
Large
</ReactButton>
<ReactButton size="xl" shape="rounded" title="Extra Large">
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton bordered size="x-sm" shape="rounded" title="Extra Small">
Extra Small
</ReactButton>
<ReactButton bordered size="sm" shape="rounded" title="Small">
Small
</ReactButton>
<ReactButton bordered size="md" shape="rounded" title="Medium">
Medium
</ReactButton>
<ReactButton bordered size="lg" shape="rounded" title="Large">
Large
</ReactButton>
<ReactButton bordered size="xl" shape="rounded" title="Extra Large">
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
size="x-sm"
variant="primary"
shape="rounded"
title="Extra Small"
>
Extra Small
</ReactButton>
<ReactButton size="sm" variant="primary" shape="rounded" title="Small">
Small
</ReactButton>
<ReactButton size="md" variant="primary" shape="rounded" title="Medium">
Medium
</ReactButton>
<ReactButton size="lg" variant="primary" shape="rounded" title="Large">
Large
</ReactButton>
<ReactButton
size="xl"
variant="primary"
shape="rounded"
title="Extra Large"
>
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
size="x-sm"
variant="primary"
bordered
shape="rounded"
title="Extra Small"
>
Extra Small
</ReactButton>
<ReactButton
size="sm"
variant="primary"
bordered
shape="rounded"
title="Small"
>
Small
</ReactButton>
<ReactButton
size="md"
variant="primary"
bordered
shape="rounded"
title="Medium"
>
Medium
</ReactButton>
<ReactButton
size="lg"
variant="primary"
bordered
shape="rounded"
title="Large"
>
Large
</ReactButton>
<ReactButton
size="xl"
variant="primary"
bordered
shape="rounded"
title="Extra Large"
>
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
size="x-sm"
variant="success"
shape="rounded"
title="Extra Small"
>
Extra Small
</ReactButton>
<ReactButton size="sm" variant="success" shape="rounded" title="Small">
Small
</ReactButton>
<ReactButton size="md" variant="success" shape="rounded" title="Medium">
Medium
</ReactButton>
<ReactButton size="lg" variant="success" shape="rounded" title="Large">
Large
</ReactButton>
<ReactButton
size="xl"
variant="success"
shape="rounded"
title="Extra Large"
>
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
size="x-sm"
variant="success"
bordered
shape="rounded"
title="Extra Small"
>
Extra Small
</ReactButton>
<ReactButton
size="sm"
variant="success"
bordered
shape="rounded"
title="Small"
>
Small
</ReactButton>
<ReactButton
size="md"
variant="success"
bordered
shape="rounded"
title="Medium"
>
Medium
</ReactButton>
<ReactButton
size="lg"
variant="success"
bordered
shape="rounded"
title="Large"
>
Large
</ReactButton>
<ReactButton
size="xl"
variant="success"
bordered
shape="rounded"
title="Extra Large"
>
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
size="x-sm"
variant="warning"
shape="rounded"
title="Extra Small"
>
Extra Small
</ReactButton>
<ReactButton size="sm" variant="warning" shape="rounded" title="Small">
Small
</ReactButton>
<ReactButton size="md" variant="warning" shape="rounded" title="Medium">
Medium
</ReactButton>
<ReactButton size="lg" variant="warning" shape="rounded" title="Large">
Large
</ReactButton>
<ReactButton
size="xl"
variant="warning"
shape="rounded"
title="Extra Large"
>
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
size="x-sm"
variant="warning"
bordered
shape="rounded"
title="Extra Small"
>
Extra Small
</ReactButton>
<ReactButton
size="sm"
variant="warning"
bordered
shape="rounded"
title="Small"
>
Small
</ReactButton>
<ReactButton
size="md"
variant="warning"
bordered
shape="rounded"
title="Medium"
>
Medium
</ReactButton>
<ReactButton
size="lg"
variant="warning"
bordered
shape="rounded"
title="Large"
>
Large
</ReactButton>
<ReactButton
size="xl"
variant="warning"
bordered
shape="rounded"
title="Extra Large"
>
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
size="x-sm"
variant="danger"
shape="rounded"
title="Extra Small"
>
Extra Small
</ReactButton>
<ReactButton size="sm" variant="danger" shape="rounded" title="Small">
Small
</ReactButton>
<ReactButton size="md" variant="danger" shape="rounded" title="Medium">
Medium
</ReactButton>
<ReactButton size="lg" variant="danger" shape="rounded" title="Large">
Large
</ReactButton>
<ReactButton
size="xl"
variant="danger"
shape="rounded"
title="Extra Large"
>
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
size="x-sm"
bordered
variant="danger"
shape="rounded"
title="Extra Small"
>
Extra Small
</ReactButton>
<ReactButton
size="sm"
bordered
variant="danger"
shape="rounded"
title="Small"
>
Small
</ReactButton>
<ReactButton
size="md"
bordered
variant="danger"
shape="rounded"
title="Medium"
>
Medium
</ReactButton>
<ReactButton
size="lg"
bordered
variant="danger"
shape="rounded"
title="Large"
>
Large
</ReactButton>
<ReactButton
size="xl"
bordered
variant="danger"
shape="rounded"
title="Extra Large"
>
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
size="x-sm"
variant="monochrome"
shape="rounded"
title="Extra Small"
>
Extra Small
</ReactButton>
<ReactButton
size="sm"
variant="monochrome"
shape="rounded"
title="Small"
>
Small
</ReactButton>
<ReactButton
size="md"
variant="monochrome"
shape="rounded"
title="Medium"
>
Medium
</ReactButton>
<ReactButton
size="lg"
variant="monochrome"
shape="rounded"
title="Large"
>
Large
</ReactButton>
<ReactButton
size="xl"
variant="monochrome"
shape="rounded"
title="Extra Large"
>
Extra Large
</ReactButton>
</div>
<div className="stacked-mobile mbe4">
<ReactButton
size="x-sm"
bordered
variant="monochrome"
shape="rounded"
title="Extra Small"
>
Extra Small
</ReactButton>
<ReactButton
size="sm"
bordered
variant="monochrome"
shape="rounded"
title="Small"
>
Small
</ReactButton>
<ReactButton
size="md"
bordered
variant="monochrome"
shape="rounded"
title="Medium"
>
Medium
</ReactButton>
<ReactButton
size="lg"
bordered
variant="monochrome"
shape="rounded"
title="Large"
>
Large
</ReactButton>
<ReactButton
size="xl"
bordered
variant="monochrome"
shape="rounded"
title="Extra Large"
>
Extra Large
</ReactButton>
</div>
{/* Icons Small */}
<div className="mbe2">
<h2>Icons Small</h2>
</div>
<div className="stacked-mobile mbe4">
<div
className="flex-inline"
role="group"
aria-label="Framework selection"
>
<ReactButton
variant="primary"
size="sm"
shape="rounded"
className="mie2"
title="Invite Members"
>
<ReactIcon size="16" noFill>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
aria-hidden="true"
>
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
</ReactIcon>
<span className="mis1 mie2">Invite Members</span>
</ReactButton>
<ReactButton
variant="primary"
size="sm"
shape="rounded"
bordered
className="mis1 mie2"
title="Create New"
>
<ReactIcon size="16" noFill>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
aria-hidden="true"
>
<path d="M12 5v14m-7-7h14" />
</svg>
</ReactIcon>
<span>Create New</span>
</ReactButton>
<ReactButton variant="danger" size="sm" shape="rounded" title="Record">
<ReactIcon size="16" noFill>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
aria-hidden="true"
>
<path d="M12 1a3 3 0 003 3v8a3 3 0 11-6 0V4a3 3 0 003-3zM19 10v2a7 7 0 01-14 0v-2M12 19v4m-4 0h8" />
</svg>
</ReactIcon>
<span>Record</span>
</ReactButton>
</div>
</div>
{/* Icons Only */}
<div className="mbe2">
<h2>Icons Only</h2>
<p>
To create an accessible icon-only button, wrap the icon component with
a <code><ReactButton></code> element and provide an accessible
label using the <code>ReactVisuallyHidden</code> component.
</p>
<p>
This ensures screen reader users understand the button's action
without a visible text label. Ensure you also provide a clear{" "}
<code>title</code> attribute for mouse users who hover over the icon.
</p>
</div>
<div className="stacked-mobile mbe4">
<div
className="flex-inline"
role="group"
aria-label="Framework selection"
>
<ReactButton
variant="primary"
size="sm"
shape="rounded"
title="Invite Members"
className="mie2"
>
<ReactIcon size="16" noFill>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
aria-hidden="true"
>
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
</ReactIcon>
<ReactVisuallyHidden>Invite Members</ReactVisuallyHidden>
</ReactButton>
</div>
</div>
{/* Icons */}
<div className="mbe2">
<h2>Icons</h2>
</div>
<div className="stacked-mobile mbe4">
<div
className="flex-inline"
role="group"
aria-label="Framework selection"
>
<ReactButton
variant="primary"
shape="rounded"
title="Invite Members"
className="mie2"
>
<ReactIcon size="18" noFill>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
aria-hidden="true"
>
<path d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" />
</svg>
</ReactIcon>
<span className="mis1 mie2">Invite Members</span>
</ReactButton>
<ReactButton
variant="primary"
shape="rounded"
title="Create new"
bordered
className="mis1 mie2"
>
<ReactIcon size="18" noFill>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
aria-hidden="true"
>
<path d="M12 5v14m-7-7h14" />
</svg>
</ReactIcon>
<span>Create New</span>
</ReactButton>
<ReactButton variant="danger" title="Record" shape="rounded">
<ReactIcon size="18" noFill>
<svg
viewBox="0 0 24 24"
fill="none"
stroke="currentColor"
strokeWidth="2"
aria-hidden="true"
>
<path d="M12 1a3 3 0 003 3v8a3 3 0 11-6 0V4a3 3 0 003-3zM19 10v2a7 7 0 01-14 0v-2M12 19v4m-4 0h8" />
</svg>
</ReactIcon>
<span>Record</span>
</ReactButton>
</div>
</div>
{/* Grouped */}
<div className="mbe2">
<h2>Grouped</h2>
</div>
<div className="stacked-mobile mbe4">
<div
className="flex-inline"
role="group"
aria-label="Framework selection"
>
<ReactButton grouped title="React" bordered variant="secondary">
React
</ReactButton>
<ReactButton grouped title="Vue" bordered variant="secondary">
Vue
</ReactButton>
<ReactButton grouped title="Svelte" bordered variant="secondary">
Svelte
</ReactButton>
<ReactButton grouped title="Lit" bordered variant="secondary">
Lit
</ReactButton>
</div>
</div>
<div className="stacked-mobile mbe4">
<div
className="flex-inline"
role="group"
aria-label="Framework selection"
>
<ReactButton grouped title="React" bordered variant="primary">
React
</ReactButton>
<ReactButton grouped title="Vue" bordered variant="primary">
Vue
</ReactButton>
<ReactButton grouped title="Svelte" bordered variant="primary">
Svelte
</ReactButton>
<ReactButton grouped title="Lit" bordered variant="primary">
Lit
</ReactButton>
</div>
</div>
<div className="stacked-mobile mbe4">
<div
className="flex-inline"
role="group"
aria-label="Framework selection"
>
<ReactButton grouped title="React" bordered variant="monochrome">
React
</ReactButton>
<ReactButton grouped title="Vue" bordered variant="monochrome">
Vue
</ReactButton>
<ReactButton grouped title="Svelte" bordered variant="monochrome">
Svelte
</ReactButton>
<ReactButton grouped title="Lit" bordered variant="monochrome">
Lit
</ReactButton>
</div>
</div>
{/* Miscellaneous */}
<div className="mbe2">
<h2>Miscellaneous</h2>
</div>
<div className="stacked-mobile mbe4">
<ReactButton ghost title="Ghost button" className="mie2">
Ghost
</ReactButton>
<ReactButton link title="button link" className="mie2">
Link
</ReactButton>
<ReactButton
type="submit"
bordered
title="submit button"
shape="rounded"
variant="primary"
className="mie2"
>
Submit
</ReactButton>
<ReactButton
title="toggle button"
toggle
pressed={isPressed}
onToggle={handleToggle}
className="mie2"
>
Toggle
</ReactButton>
<ReactButton title="example disabled button" disabled className="mie2">
Disabled
</ReactButton>
</div>
{/* CSS Parts Customization */}
<div className="mbe4">
<h2>CSS Parts Customization</h2>
<p
className="mbe2"
style={{ color: "var(--ag-text-secondary)", fontSize: "0.875rem" }}
>
Customize button appearance using CSS Shadow Parts without breaking
encapsulation.
</p>
</div>
<div className="stacked-mobile mbe4">
<ReactButton title="Gradient Button" className="custom-gradient-button mie3">
Gradient Button
</ReactButton>
</div>
</section>
);
}
Usage
TIP
The framework examples below import AgnosticUI as an npm package. Alternatively, you can use the CLI for complete control, AI/LLM visibility, and full code ownership:
npx ag init --framework FRAMEWORK # react, vue, lit, svelte, etc.
npx ag add ButtonThe CLI copies source code directly into your project, giving you full visibility and control. After running npx ag add, you'll receive exact import instructions.
Vue
<template>
<section>
<VueButton>Click me</VueButton>
<VueButton variant="primary">Primary</VueButton>
<VueButton variant="success">Success</VueButton>
<VueButton variant="danger">Danger</VueButton>
<VueButton variant="monochrome">Monochrome</VueButton>
<VueButton size="sm">Small</VueButton>
<VueButton size="lg">Large</VueButton>
<VueButton shape="rounded">Rounded</VueButton>
<VueButton shape="capsule">Capsule</VueButton>
<VueButton shape="circle">C</VueButton>
<VueButton bordered variant="primary">Bordered</VueButton>
<VueButton ghost variant="primary">Ghost</VueButton>
<VueButton link>Link Style</VueButton>
<VueButton disabled>Disabled</VueButton>
<VueButton loading>Loading</VueButton>
<VueButton
toggle
:pressed="isPressed"
@toggle="handleToggle"
>Toggle Me</VueButton>
<VueButton type="submit" variant="primary">Submit</VueButton>
</section>
</template>
<script>
import VueButton from "agnosticui-core/button/vue";
export default {
name: "ButtonExample",
components: { VueButton },
data() {
return {
isPressed: false,
};
},
methods: {
handleToggle(event) {
this.isPressed = event.pressed;
console.log("Button toggled:", event.pressed);
},
},
};
</script>React
import { useState } from 'react';
import { ReactButton } from 'agnosticui-core/button/react';
export default function ButtonExample() {
const [isPressed, setIsPressed] = useState(false);
const handleToggle = (event: CustomEvent) => {
setIsPressed(event.detail.pressed);
console.log("Button toggled:", event.detail.pressed);
};
return (
<section>
<ReactButton>Click me</ReactButton>
<ReactButton variant="primary">Primary</ReactButton>
<ReactButton variant="success">Success</ReactButton>
<ReactButton variant="danger">Danger</ReactButton>
<ReactButton variant="monochrome">Monochrome</ReactButton>
<ReactButton size="sm">Small</ReactButton>
<ReactButton size="lg">Large</ReactButton>
<ReactButton shape="rounded">Rounded</ReactButton>
<ReactButton shape="capsule">Capsule</ReactButton>
<ReactButton shape="circle">C</ReactButton>
<ReactButton bordered variant="primary">Bordered</ReactButton>
<ReactButton ghost variant="primary">Ghost</ReactButton>
<ReactButton link>Link Style</ReactButton>
<ReactButton disabled>Disabled</ReactButton>
<ReactButton loading>Loading</ReactButton>
<ReactButton
toggle
pressed={isPressed}
onToggle={handleToggle}
>
Toggle Me
</ReactButton>
<ReactButton type="submit" variant="primary">Submit</ReactButton>
</section>
);
}Lit (Web Components)
import { LitElement, html, css } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import 'agnosticui-core/button';
@customElement('button-example')
export class ButtonExample extends LitElement {
@state() private isPressed = false;
static styles = css`
:host {
display: block;
}
section {
display: flex;
flex-wrap: wrap;
gap: 0.5rem;
}
`;
firstUpdated() {
// Set up event listener for toggle button in the shadow DOM
const toggleButton = this.shadowRoot?.querySelector('#toggle-button');
toggleButton?.addEventListener('toggle', (event: Event) => {
const customEvent = event as CustomEvent;
this.isPressed = customEvent.detail.pressed;
console.log('Button toggled:', this.isPressed);
});
}
render() {
return html`
<section>
<ag-button>Click me</ag-button>
<ag-button variant="primary">Primary</ag-button>
<ag-button variant="success">Success</ag-button>
<ag-button variant="danger">Danger</ag-button>
<ag-button variant="monochrome">Monochrome</ag-button>
<ag-button size="sm">Small</ag-button>
<ag-button size="lg">Large</ag-button>
<ag-button shape="rounded">Rounded</ag-button>
<ag-button shape="capsule">Capsule</ag-button>
<ag-button shape="circle">C</ag-button>
<ag-button bordered variant="primary">Bordered</ag-button>
<ag-button ghost variant="primary">Ghost</ag-button>
<ag-button link>Link Style</ag-button>
<ag-button disabled>Disabled</ag-button>
<ag-button loading>Loading</ag-button>
<ag-button id="toggle-button" toggle>Toggle Me</ag-button>
<ag-button type="submit" variant="primary">Submit</ag-button>
</section>
`;
}
}Note: When using button components within a custom element's shadow DOM, set up event listeners in the component's lifecycle (e.g., firstUpdated()) rather than using DOMContentLoaded, as document.querySelector() cannot access elements inside shadow DOM. Use this.shadowRoot.querySelector() instead.
Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | 'primary' | 'secondary' | 'success' | 'warning' | 'danger' | '' | '' | Visual color variant |
size | 'x-sm' | 'sm' | 'md' | 'lg' | 'xl' | 'md' | Size of the button |
shape | 'capsule' | 'rounded' | 'circle' | 'square' | 'rounded-square' | '' | '' | Shape variant |
bordered | boolean | false | Outline style with transparent background |
ghost | boolean | false | Minimal style with transparent background |
link | boolean | false | Text link style with underline on hover |
grouped | boolean | false | Style for buttons in a group (removes inner borders) |
fullWidth | boolean | false | Makes button take 100% width of container |
type | 'button' | 'submit' | 'reset' | 'button' | HTML button type |
disabled | boolean | false | Disabled state |
loading | boolean | false | Loading/busy state (disables interaction) |
toggle | boolean | false | Enable toggle button mode |
pressed | boolean | false | Pressed state for toggle buttons |
ariaLabel | string | '' | Accessible label (use when button has no text) |
Events
| Event | Framework | Detail | Description |
|---|---|---|---|
click | Vue: @clickReact: onClickLit: @click | MouseEvent | Fired when the button is clicked. |
focus | Vue: @focusReact: onFocusLit: @focus | FocusEvent | Fired when the button receives focus. |
blur | Vue: @blurReact: onBlurLit: @blur | FocusEvent | Fired when the button loses focus. |
toggle | Vue: @toggleReact: onToggleLit: @toggle | { pressed: boolean } | Emitted when a toggle button is clicked (only when the toggle prop is true). |
Note: Standard button events (click, focus, blur) work uniformly across all frameworks. The toggle event is custom and only fires when the toggle prop is true, providing { pressed: boolean } in its detail.
Accessibility
The Button component implements the WAI-ARIA Button pattern:
- Uses semantic
<button>element - Full keyboard support (Space/Enter activation via browser defaults)
- Proper ARIA states:
aria-disabledfor disabled statearia-busyfor loading statearia-pressedfor toggle buttons
- Focus management with clear visual indicators
- Accessible name via button text content or
ariaLabelprop
Toggle Buttons
Toggle buttons follow the WAI-ARIA Toggle Button pattern:
- Set
toggleprop to enable toggle mode aria-pressedcommunicates state to assistive technologies- Visual and programmatic state synchronization
Variant Guide
Color Variants
- primary - Primary action (blue)
- secondary - Secondary action (neutral)
- success - Positive action (green)
- warning - Warning action (yellow)
- danger - Destructive action (red)
Style Variants
- bordered - Outline style, fills on hover
- ghost - Minimal padding, transparent background
- link - Text link appearance with underline
Shape Variants
- rounded - Rounded corners
- capsule - Fully rounded ends (pill shape)
- circle - Perfect circle (for icons/single characters)
- square - Sharp corners, equal width/height
- rounded-square - Rounded corners, equal width/height
Disabled States
Disabled buttons maintain their color identity while providing clear visual affordance that they are inactive:
- Filled buttons use lighter background and text tokens specific to each variant
- Bordered buttons use opacity to dim both border and text
- Ghost/Link buttons use opacity to indicate disabled state
- All disabled buttons show a
not-allowedcursor on hover
Each color variant (primary, success, warning, danger, secondary, monochrome) maintains its tonal identity in the disabled state, making it easy to understand what action would be available when the button becomes enabled.
Accessibility: Disabled buttons maintain appropriate contrast ratios between foreground and background colors by using design tokens specifically created for disabled states.
Grouped Buttons
Use the grouped prop to create connected button groups:
Vue
<div class="flex-inline" role="group" aria-label="Actions">
<VueButton grouped bordered>Edit</VueButton>
<VueButton grouped bordered>Delete</VueButton>
<VueButton grouped bordered>Share</VueButton>
</div>React
<div className="flex-inline" role="group" aria-label="Actions">
<ReactButton grouped bordered>Edit</ReactButton>
<ReactButton grouped bordered>Delete</ReactButton>
<ReactButton grouped bordered>Share</ReactButton>
</div>Lit (Web Components)
<div class="flex-inline" role="group" aria-label="Actions">
<ag-button grouped bordered>Edit</ag-button>
<ag-button grouped bordered>Delete</ag-button>
<ag-button grouped bordered>Share</ag-button>
</div>Form Integration
Buttons integrate seamlessly with forms using the type prop:
Vue
<form @submit.prevent="handleSubmit">
<VueButton type="submit" variant="primary">Submit</VueButton>
<VueButton type="reset">Reset</VueButton>
<VueButton type="button" @click="cancel">Cancel</VueButton>
</form>React
<form onSubmit={(e) => { e.preventDefault(); handleSubmit(); }}>
<ReactButton type="submit" variant="primary">Submit</ReactButton>
<ReactButton type="reset">Reset</ReactButton>
<ReactButton type="button" onClick={cancel}>Cancel</ReactButton>
</form>Lit (Web Components)
<form id="myForm">
<ag-button type="submit" variant="primary">Submit</ag-button>
<ag-button type="reset">Reset</ag-button>
<ag-button type="button" id="cancel-button">Cancel</ag-button>
</form>
<script type="module">
document.getElementById("myForm")?.addEventListener("submit", (e) => {
e.preventDefault();
handleSubmit();
});
document.getElementById("cancel-button")?.addEventListener("click", cancel);
</script>Button Types
- submit - Submits the form
- reset - Resets form fields to defaults
- button - No default behavior (use with click handlers)
CSS Shadow Parts
Shadow Parts allow you to style internal elements of the button from outside the shadow DOM using the ::part() CSS selector.
| Part | Description |
|---|---|
ag-button | The internal <button> element |
Customization Example
ag-button::part(ag-button) {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border-radius: 50px;
padding: 1rem 2rem;
font-weight: 700;
text-transform: uppercase;
letter-spacing: 0.05em;
box-shadow: 0 4px 15px rgba(102, 126, 234, 0.4);
transition: all 0.3s ease;
}
ag-button::part(ag-button):hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(102, 126, 234, 0.6);
}