The preview needs JavaScript. The code is in the Code tab.
<template>
<div>
<Button>Primary</Button>
<Button tone="neutral" emphasis="outline">Neutral</Button>
</div>
</template>
Installation
npx @pixelscriptio/tessera add Buttonpnpm exec tessera add Buttonyarn tessera add Buttonbunx @pixelscriptio/tessera add Button- Works with Tessera 0.9.0 or newer.
Copy and paste the code into your project
Put it in
system/components.system/components/Button.tess <contract> { "name": "Button", "role": "button", "description": "Triggers an action. Press it with a mouse, a finger, Enter or Space.", "since": "0.1.0", "parts": ["root", "icon", "label"], "variants": { "tone": ["primary", "neutral", "danger"], // first value is the default "size": ["sm", "md", "lg"], "emphasis": ["solid", "outline", "ghost"] }, "states": ["hover", "focus-visible", "pressed", "disabled"], "behavior": "press", "slots": { "default": "label content", "icon": "optional leading icon" }, "events": { "press": "fired on click, Enter, or Space, with { source: 'pointer' | 'keyboard' | 'virtual' }" }, "preview": { "slots": { "default": "Save changes" } } } </contract> <script> const { disabled, type } = props({ disabled: false, type: 'button' }) </script> <template> <button class="root" :type="type" :disabled="disabled" @press="emit('press', $event)"> <span class="icon"><slot name="icon" /></span> <span class="label"><slot /></span> </button> </template> <style> .root { display: inline-flex; align-items: center; justify-content: center; gap: $space.2; padding: $space.2 $space.4; border: 1px solid transparent; border-radius: $radius.md; background: $color.action.primary.bg; color: $color.action.primary.fg; cursor: pointer; transition-duration: $motion.duration.fast; &:hover { background: $color.action.primary.bg-hover; } &:focus-visible { outline: 2px solid $color.focus.ring; outline-offset: 2px; } &:disabled, &[aria-disabled='true'] { opacity: $opacity.disabled; cursor: not-allowed; } &[data-size='sm'] { padding: $space.1 $space.2; } &[data-size='lg'] { padding: $space.3 $space.6; } &[data-tone='neutral'] { background: $color.surface.raised; color: $color.text.default; } &[data-tone='neutral']:hover { background: $color.surface.hover; } &[data-tone='danger'] { background: $color.action.danger.bg; color: $color.action.danger.fg; } &[data-tone='danger']:hover { background: $color.action.danger.bg-hover; } &[data-emphasis='outline'], &[data-emphasis='ghost'] { background: transparent; color: $color.action.primary.text; } &[data-emphasis='outline'] { border-color: currentColor; } &[data-emphasis='outline'][data-tone='neutral'], &[data-emphasis='ghost'][data-tone='neutral'] { color: $color.text.default; } &[data-emphasis='outline'][data-tone='danger'], &[data-emphasis='ghost'][data-tone='danger'] { color: $color.action.danger.text; } &[data-emphasis='outline']:hover, &[data-emphasis='ghost']:hover { background: $color.surface.raised; } } .icon { display: inline-flex; } .icon:empty { display: none; } </style>Check your design tokens
Your design system needs these.
tessera addreports the ones that are missing; by hand, runnpx @pixelscriptio/tessera check.color.action.danger.bgcolor.action.danger.bg-hovercolor.action.danger.fgcolor.action.danger.textcolor.action.primary.bgcolor.action.primary.bg-hovercolor.action.primary.fgcolor.action.primary.textcolor.focus.ringcolor.surface.hovercolor.surface.raisedcolor.text.defaultmotion.duration.fastopacity.disabledradius.mdspace.1space.2space.3space.4space.6
Usage
Using Button
Use a button for an action, and a Link to go somewhere.
- Say what happens: "Save changes", not "OK".
- One primary button per view.
- It is a plain button. Set
type="submit"for the button that sends a Form.
The preview needs JavaScript. The code is in the Code tab.
<template>
<div>
<Button>Primary</Button>
<Button tone="neutral" emphasis="outline">Neutral</Button>
</div>
</template>
API reference
Variants
| Variant | Values |
|---|---|
tone | primary default neutral danger |
size | sm default md lg |
emphasis | solid default outline ghost |
Slots
| Slot | Content |
|---|---|
default | label content |
icon | optional leading icon |
Events
| Event | When |
|---|---|
press | fired on click, Enter, or Space, with { source: 'pointer' | 'keyboard' | 'virtual' } |
Anatomy
| Role | button |
| Behavior | press |
| Parts | root icon label |
| States | hover focus-visible pressed disabled |
| Since | 0.1.0 |
Design tokens it uses
Your design system needs these. tessera add checks that it has them, and can add the ones it lacks.
color.action.danger.bg color.action.danger.bg-hover color.action.danger.fg color.action.danger.text color.action.primary.bg color.action.primary.bg-hover color.action.primary.fg color.action.primary.text color.focus.ring color.surface.hover color.surface.raised color.text.default motion.duration.fast opacity.disabled radius.md space.1 space.2 space.3 space.4 space.6
Checksum
9205bc828f63b9642398a6cd3ddc4250f0bbd00ca6a96a89f8ac2db0532f333f