Skip to content

Button

Experimental Alpha

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

Vue
Lit
React
Live Preview
Default

Rounded Variants

DefaultPrimarySecondarySuccessWarningDangerMonochrome

Shapes

RoundedCapsuleCSRS

Bordered

DefaultPrimarySecondarySuccessWarningDangerMonochrome

Sizes

Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large
Extra SmallSmallMediumLargeExtra Large

Icons Small

Invite MembersCreate NewRecord

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.

Invite Members

Icons

Invite MembersCreate NewRecord

Grouped

ReactVueSvelteLit
ReactVueSvelteLit
ReactVueSvelteLit

Miscellaneous

GhostLinkSubmitToggleDisabled

CSS Parts Customization

Customize button appearance using CSS Shadow Parts without breaking encapsulation.

Gradient Button
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>&lt;ag-button&gt;</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>

    <!-- 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>&lt;ReactButton&gt;</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>
  );
}
Open in StackBlitz

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:

bash
npx ag init --framework FRAMEWORK # react, vue, lit, svelte, etc.
npx ag add Button

The 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
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
tsx
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)
typescript
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

PropTypeDefaultDescription
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
borderedbooleanfalseOutline style with transparent background
ghostbooleanfalseMinimal style with transparent background
linkbooleanfalseText link style with underline on hover
groupedbooleanfalseStyle for buttons in a group (removes inner borders)
type'button' | 'submit' | 'reset''button'HTML button type
disabledbooleanfalseDisabled state
loadingbooleanfalseLoading/busy state (disables interaction)
togglebooleanfalseEnable toggle button mode
pressedbooleanfalsePressed state for toggle buttons
ariaLabelstring''Accessible label (use when button has no text)

Events

EventFrameworkDetailDescription
clickVue: @click
React: onClick
Lit: @click
MouseEventFired when the button is clicked.
focusVue: @focus
React: onFocus
Lit: @focus
FocusEventFired when the button receives focus.
blurVue: @blur
React: onBlur
Lit: @blur
FocusEventFired when the button loses focus.
toggleVue: @toggle
React: onToggle
Lit: @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-disabled for disabled state
    • aria-busy for loading state
    • aria-pressed for toggle buttons
  • Focus management with clear visual indicators
  • Accessible name via button text content or ariaLabel prop

Toggle Buttons

Toggle buttons follow the WAI-ARIA Toggle Button pattern:

  • Set toggle prop to enable toggle mode
  • aria-pressed communicates 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

Grouped Buttons

Use the grouped prop to create connected button groups:

Vue
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
tsx
<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)
html
<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
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
tsx
<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)
html
<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.

PartDescription
ag-buttonThe internal <button> element

Customization Example

css
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);
}