Button
One size, five statuses, three variants. Icons go in as children, a loading state keeps the width.
One skill, every component.
Install
The button is part of the boilerplate skill, with every other component on this site. Install it in your project's folder; it works in Claude Code, Codex, Cursor and other agents. Already done? Skip ahead. More in the Introduction.
npx skills add frontendsupply/skills --skill boilerplateAsk
Then ask for it in your own words, or run the command. The skill reads your project's style first and writes the component in it. If the project has no button yet:
/boilerplate add buttonIf it already has one, the skill rebuilds it on this pattern and keeps its look, its names and every place that uses it working:
/boilerplate refactor buttonEither way it ends by proving that only the look changed: a script checks every behavior class and slot is still there.
Emphasis and meaning.
Variants and statuses
variant is emphasis: solid for the one action a view is for, outline for the rest, ghost where a border would be noise. status is meaning: information, success, warning, danger. Each status sets four colors and every variant reads them, so all fifteen combinations work.
Children, not props.
Icons
Put an icon before the text, after it, or alone with an aria-label. The button wraps its text in a label, so it can tell the three apart: the icon side gets 2px less padding, which balances the icon's own whitespace, and an icon alone makes the button square.
Nothing moves.
Loading
Set loading and a spinner takes the content's place. The width doesn't change, even when the label does: the button holds the width it had before it started loading, so the buttons and text around it stay where they are. A second press does nothing.
Disabled
disabled dims the button. When a disabled button has to stay reachable, say for a tooltip that explains why it's disabled, add focusableWhenDisabled.
What lines up.
Alignment
The button at its real size, with the lines its parts share. Hover a line to see what sits on it: one height for every button side by side, one center line for icons and labels, an icon alone centered in a square. The dashed lines show the padding, 2px less on the icon's side, which evens out the icon's own whitespace. A part a pixel off would show as a line of its own.