Primitives
02

Button

The button primitive. Two independent axes: variant decides how the colour is applied — a fill (primary), a ring (secondary), a bare label with a control-sized box (ghost) or without one (text) — and tone decides which colour, from the same twelve-step scales the badges and alerts read. Forwards every native button attribute.

plain markup — no library on the page
rendered by aura-react
rendered by aura-vue
rendered by aura-svelte
built from aura-angular's own class helpers

Code

index.html
<div class="aura-stack" style="--aura-dir:column;--aura-gap:var(--space-4);">
  <div class="aura-group" style="--aura-gap:var(--space-3);">
    <button type="button" class="aura-btn aura-btn--primary">Primary</button>
    <button type="button" class="aura-btn aura-btn--secondary">Secondary</button>
    <button type="button" class="aura-btn aura-btn--ghost">Ghost</button>
    <button type="button" class="aura-btn aura-btn--text">Text</button>
    <button type="button" class="aura-btn aura-btn--primary" disabled>Disabled</button>
    <button type="button" class="aura-btn aura-btn--primary aura-btn--loading" disabled aria-busy="true">Saving</button>
  </div>
  <div class="aura-group" style="--aura-gap:var(--space-3);">
    <button type="button" class="aura-btn aura-btn--primary aura-btn--danger">Delete</button>
    <button type="button" class="aura-btn aura-btn--secondary aura-btn--danger">Delete</button>
    <button type="button" class="aura-btn aura-btn--text aura-btn--danger">Delete</button>
    <button type="button" class="aura-btn aura-btn--primary aura-btn--warning">Archive</button>
    <button type="button" class="aura-btn aura-btn--primary aura-btn--success">Approve</button>
  </div>
</div>
Demo.tsx
import { Button, Group, Stack } from '@ilomee/aura-react';

/**
 * Two rows because there are two axes. The first varies `variant` at one tone, the second
 * varies `tone` — and shows the same tone under three variants, which is the part a props
 * table cannot say: "Delete" is the same red whether it is the main button or the last word
 * in a row.
 */
export default function Demo() {
  return (
    <Stack gap={4}>
      <Group>
        <Button variant="primary">Primary</Button>
        <Button variant="secondary">Secondary</Button>
        <Button variant="ghost">Ghost</Button>
        <Button variant="text">Text</Button>
        <Button variant="primary" disabled>
          Disabled
        </Button>
        <Button variant="primary" loading>
          Saving
        </Button>
      </Group>
      <Group>
        <Button variant="primary" tone="danger">
          Delete
        </Button>
        <Button variant="secondary" tone="danger">
          Delete
        </Button>
        <Button variant="text" tone="danger">
          Delete
        </Button>
        <Button variant="primary" tone="warning">
          Archive
        </Button>
        <Button variant="primary" tone="success">
          Approve
        </Button>
      </Group>
    </Stack>
  );
}
Demo.vue
<script setup lang="ts">
import { Button } from '@ilomee/aura-vue';
</script>

<template>
  <Button variant="primary" @click="save">Save</Button>
  <Button variant="ghost">Cancel</Button>
  <Button variant="text" tone="danger" @click="remove">Delete</Button>
</template>

Renders type="button"; override it through attribute fallthrough.

Demo.svelte
<script lang="ts">
  import { Button } from '@ilomee/aura-svelte';
</script>

<Button variant="primary" onclick={save}>Save</Button>
<Button variant="ghost">Cancel</Button>
<Button variant="text" tone="danger" onclick={remove}>Delete</Button>

Used as button[auraButton].

demo.component.ts
import { AuraButton } from '@ilomee/aura-angular';

@Component({
  standalone: true,
  imports: [AuraButton],
  template: `
    <button auraButton variant="primary" (click)="save()">Save</button>
    <button auraButton variant="ghost">Cancel</button>
    <button auraButton variant="text" tone="danger" (click)="remove()">Delete</button>
  `,
})
export class DemoComponent {}

Props

Plain markup has no props — the classes below are the whole API. The four packages do nothing more than set these same classes for you.
NameTypeDefaultNotes
variant'primary' | 'secondary' | 'ghost' | 'text''secondary'How the colour is applied. text also drops the control height, which is what a button at the end of a dense list row needs and ghost does not give it.
size'sm' | 'md' | 'lg''md'Three heights, from the --control-h-* tokens the field controls read — so a button beside an input is the same height as the input.
tone'default' | 'accent' | 'success' | 'warning' | 'danger' | 'info''default'Colour, independent of variant: variant says filled / outlined / bare, tone says which colour. A destructive action is tone="danger" whether it is the main button on the screen or the last word in a list row.
loadingbooleanfalseWork is in flight: the button goes disabled and aria-busy, and grows a spinner before its label. Beside the words rather than replacing them, so the button does not change width at the moment it stops being clickable.
type'button' | 'submit' | 'reset''button'
…ButtonHTMLAttributesattrsButtonHTMLAttributes<HTMLButtonElement>Forwarded to the button.
NameTypeDefaultNotes
variant'primary' | 'secondary' | 'ghost' | 'text''secondary'
size'sm' | 'md' | 'lg''md'
tone'default' | 'accent' | 'success' | 'warning' | 'danger' | 'info''default'Colour, independent of variant: variant says filled / outlined / bare, tone says which colour. A destructive action is tone="danger" whether it is the main button on the screen or the last word in a list row.
loadingbooleanfalseWork is in flight: the button goes disabled and aria-busy, and grows a spinner before its label. Beside the words rather than replacing them, so the button does not change width at the moment it stops being clickable.
defaultslotSlot
NameTypeDefaultNotes
variant'primary' | 'secondary' | 'ghost' | 'text''secondary'
size'sm' | 'md' | 'lg''md'
tone'default' | 'accent' | 'success' | 'warning' | 'danger' | 'info''default'Colour, independent of variant: variant says filled / outlined / bare, tone says which colour. A destructive action is tone="danger" whether it is the main button on the screen or the last word in a list row.
childrenslotSnippet
…restattrsHTMLButtonAttributes
NameTypeDefaultNotes
variant'primary' | 'secondary' | 'ghost' | 'text''secondary'
size'sm' | 'md' | 'lg''md'
tone'default' | 'accent' | 'success' | 'warning' | 'danger' | 'info''default'Colour, independent of variant: variant says filled / outlined / bare, tone says which colour. A destructive action is tone="danger" whether it is the main button on the screen or the last word in a list row.
loadingbooleanfalseWork is in flight: the button goes disabled and aria-busy, and grows a spinner before its label. Beside the words rather than replacing them, so the button does not change width at the moment it stops being clickable.

Emitted classes

Every framework emits the same classes — that is what makes the four libraries look identical. You can use them directly, without any component library.

ClassRoleNotes
.aura-btnbaseRequired. A modifier does nothing without it.
.aura-btn--primarymodifier
.aura-btn--secondarymodifier
.aura-btn--ghostmodifier
.aura-btn--textmodifier
.aura-btn--smmodifier
.aura-btn--lgmodifier
.aura-btn--loadingmodifier
.aura-btn--accentmodifier
.aura-btn--successmodifier
.aura-btn--warningmodifier
.aura-btn--dangermodifier
.aura-btn--infomodifier

Tokens and rules

components.css
height
var(--control-h) · sm var(--control-h-sm) · lg var(--control-h-lg)
padding
0 18px · sm 0 12px · lg 0 24px · literal
radius
var(--r2)
font
700 14px var(--font)
primary
var(--gradient) · #fff · var(--shadow-2)
secondary
var(--surface) · var(--border) · var(--shadow-1)
ghost
transparent · var(--text-muted)
text
height auto · padding 0 · underline on hover
tone fill
var(--<tone>-solid) · hover var(--<tone>-solid-hover)
tone ring
var(--<tone>-border)
tone ink
var(--<tone>-text) · over a fill: derived from its oklch lightness
tone wash
var(--<tone>-bg-hover)
hover
translateY(-1px) · brightness(1.05), untoned only
disabled
var(--opacity-disabled)
spinner
1em · currentColor · ::before · aura-spin 1s