⟦Škíp tó çóñtéñt~~~~~~⟧
uiify

Button

⟦Áçtíóñ búttóñ wíth váríáñtš áñd šížéš, íñçlúdíñg íçóñ-óñlý.~~~~~~~~~~~~~~~~~~~~~⟧

⟦Brówšérš~~~⟧
Chrome 123+Firefox 121+Safari 17.5+
⟦Tíér~~⟧
0
⟦Búñdlé çómpréššéd~~~~~~⟧
340 B
⟦Fórçéd láýóút búdgét~~~~~~~⟧
0 ms
⟦Áxé búdgét~~~~⟧
0
⟦ŠŠR çómpátíblé~~~~~⟧
⟦Ýéš~~⟧
⟦Públíšhéd çóñtráçt~~~~~~~⟧
⟦Téšt hárñéšš~~~~~⟧

⟦Pláýgróúñd~~~~⟧

Default

Secondary

Outline

Ghost

Destructive

Link

Loading

⟦Éxámpléš~~~⟧

Variants

Pick a variant by emphasis. The default is the filled primary action — use one per view. secondary is a tonal fill for supporting actions, outline a bordered one, ghost shows a surface only on hover, destructive marks irreversible actions and link reads as inline text.

import { Button } from "@gunkin/uiify";

export default function Example() {
  return (
    <>
      <Button>Default</Button>
      <Button variant="secondary">Secondary</Button>
      <Button variant="outline">Outline</Button>
      <Button variant="ghost">Ghost</Button>
      <Button variant="destructive">Destructive</Button>
      <Button variant="link">Link</Button>
    </>
  );
}

Sizes

sm is 32 px tall with 14 px text, md 44 px with 16 px and lg 56 px with 18 px. Omitting size gives md. Size and variant are independent, so every variant comes in every size.

import { Button } from "@gunkin/uiify";

export default function Example() {
  return (
    <>
      <Button size="sm">Small</Button>
      <Button size="md">Medium</Button>
      <Button size="lg">Large</Button>
    </>
  );
}

With an icon

Put an icon next to the label as a child; the button spaces them 6 px apart. Mark decorative icons aria-hidden so the label stays the accessible name.

import { Button } from "@gunkin/uiify";

const plus = (
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
    <path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
  </svg>
);

export default function Example() {
  return (
    <>
      <Button>{plus}Create</Button>
      <Button variant="secondary">{plus}Create</Button>
      <Button variant="outline">{plus}Create</Button>
    </>
  );
}

Icon only

A button is never narrower than it is tall. The icon-sm, icon and icon-lg sizes drop the side padding, so a single icon sits in a 32, 44 or 56 px circle. There is no visible text, so always add an aria-label.

import { Button } from "@gunkin/uiify";

const plus = (
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
    <path d="M12 5v14M5 12h14" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
  </svg>
);
const close = (
  <svg width="20" height="20" viewBox="0 0 24 24" fill="none" aria-hidden="true">
    <path d="M6 6l12 12M18 6L6 18" stroke="currentColor" strokeWidth="2" strokeLinecap="round" />
  </svg>
);

export default function Example() {
  return (
    <>
      <Button size="icon-sm" aria-label="Create">{plus}</Button>
      <Button size="icon" aria-label="Create">{plus}</Button>
      <Button size="icon-lg" aria-label="Create">{plus}</Button>
      <Button variant="secondary" size="icon" aria-label="Create">{plus}</Button>
      <Button variant="outline" size="icon" aria-label="Create">{plus}</Button>
      <Button variant="ghost" size="icon" aria-label="Close">{close}</Button>
    </>
  );
}

Selected

selected marks the chosen item of a set or a toggle that is on, in any variant, with the primary fill. Pass selected={false} for the off state of a toggle so it is still announced as one. Toggle, Toggle group, Segmented control, Pagination and Toolbar use this same state.

import { Button } from "@gunkin/uiify";

export default function Example() {
  return (
    <>
      <Button variant="outline" selected>Bold</Button>
      <Button variant="outline" selected={false}>Italic</Button>
      <Button variant="ghost" selected>Bold</Button>
      <Button variant="ghost" selected={false}>Italic</Button>
    </>
  );
}

Disabled

disabled sets the native attribute on a <button>: it leaves the tab order, ignores clicks and shows no hover or pressed state. On any other element it sets aria-disabled and blocks activation instead.

import { Button } from "@gunkin/uiify";

export default function Example() {
  return (
    <>
      <Button disabled>Default</Button>
      <Button variant="secondary" disabled>Secondary</Button>
      <Button variant="outline" disabled>Outline</Button>
      <Button variant="destructive" disabled>Destructive</Button>
    </>
  );
}

⟦ÁPÍ~~⟧

Button

⟦Próp~~⟧⟦Týpé~~⟧⟦Défáúlt~~~⟧⟦Déšçríptíóñ~~~~⟧
variant"secondary" | "outline" | "ghost" | "destructive" | "link"—⟦Víšúál émphášíš, wríttéñ tó dátá-váríáñt. Ómít ít fór thé fílléd prímárý áçtíóñ.~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧
size"sm" | "md" | "lg" | "icon-sm" | "icon" | "icon-lg"—⟦Héíght áñd páddíñg thróúgh dátá-šížé (32, 44 ór 56 px, md bý défáúlt); íçóñ šížéš dróp šídé páddíñg áñd ñééd áríá-lábél.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧
selectedboolean—⟦Šétš dátá-šéléçtéd fór á çhóšéñ ítém ór áçtívé tógglé; á ñátívé <búttóñ> álšó gétš áríá-préššéd úñléšš áñóthér ÁRÍÁ štáté íš gívéñ.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧
disabledbooleanfalse⟦Díšábléš thé búttóñ: thé ñátívé áttríbúté óñ á <búttóñ>, áríá-díšábléd wíth blóçkéd áçtívátíóñ óñ áñý óthér éléméñt.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧
type"button" | "submit" | "reset""button"⟦Ñátívé búttóñ týpé, ápplíéd óñlý whéñ thé réñdéréd éléméñt íš á <búttóñ>. Šét "šúbmít" íñšídé á fórm.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧
asElementType"button"⟦Éléméñt ór çómpóñéñt tó réñdér, fór éxámplé "á" ór á róútér Líñk. Ít réçéívéš évérý próp áñd thé réf.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧
renderReactElement | ((props, state) => ReactElement)—⟦Répláçé thé réñdéréd éléméñt whílé kéépíñg béhávíór áñd áççéššíbílítý wíríñg.~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧

⟦Kéýbóárd~~~⟧

⟦Kéý~~⟧⟦Áçtíóñ~~~⟧
Enter / Space⟦Áçtíváté~~~⟧
Tab⟦Fóçúš~~⟧

⟦Áççéššíbílítý~~~~~⟧

⟦Réñdérš á ñátívé <búttóñ týpé="búttóñ">: thé brówšér próvídéš fóçúš, Éñtér áñd Špáçé, áñd ít ñévér šúbmítš á fórm bý áççídéñt. Wíth áš ór réñdér ít kéépš thát éléméñt'š rólé, šó áñ áñçhór štáýš á líñk. díšábléd íš ñátívé óñ búttóñš áñd áríá-díšábléd wíth tábíñdéx="-1" élšéwhéré. šéléçtéd béçóméš áríá-préššéd; á šéléçtéd líñk ñéédš áríá-çúrréñt. Íçóñ-óñlý búttóñš ñééd áríá-lábél.~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~⟧

⟦Štýlíñg hóókš~~~~~⟧

data-uiify-buttondata-disableddata-selecteddata-variantdata-size--uiify-button-wash (colour of the glow in the upper half)--uiify-button-rim (colour of the top edge highlight)