Button
The Button primitive — 6 variants × 4 sizes. Mirrors the shadcn/ui Button surface so muscle memory translates 1:1. Used inside ShadNG components and freely composable in your own UI.
Preview — variants
<ai-button>Default</ai-button>
<ai-button variant="destructive">Destructive</ai-button>
<ai-button variant="outline">Outline</ai-button>
<ai-button variant="secondary">Secondary</ai-button>
<ai-button variant="ghost">Ghost</ai-button>
<ai-button variant="link">Link</ai-button>Preview — sizes
<ai-button size="sm">Small</ai-button>
<ai-button>Default</ai-button>
<ai-button size="lg">Large</ai-button>
<ai-button size="icon" variant="outline" ariaLabel="Search">
<svg><!-- icon --></svg>
</ai-button>
<ai-button [disabled]="true">Disabled</ai-button>Installation
bash
npm install @shadng/coreUsage
typescript
import { Component } from '@angular/core';
import { Button } from '@shadng/core';
@Component({
selector: 'app-search-bar',
imports: [Button],
template: `
<ai-button
variant="default"
size="default"
(pressedChange)="onClick()"
>
Search
</ai-button>
<ai-button
variant="destructive"
(pressedChange)="onDelete()"
>
Delete
</ai-button>
<ai-button
variant="outline"
size="icon"
ariaLabel="Toggle theme"
[pressed]="isDark()"
(pressedChange)="toggleTheme()"
>
<svg><!-- icon --></svg>
</ai-button>
`,
})
export class SearchBar {
onClick() { /* ... */ }
onDelete() { /* ... */ }
}API — Inputs
| Name | Type | Default | Description |
|---|---|---|---|
| variant | 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost' | 'link' | 'default' | Visual treatment. |
| size | 'default' | 'sm' | 'lg' | 'icon' | 'default' | Size class. Use icon for icon-only buttons (square). |
| type | 'button' | 'submit' | 'reset' | 'button' | Native button type. Stays as button by default to avoid accidental form submissions. |
| disabled | boolean | false | Disable the button. |
| pressed | boolean | null | null | Toggle state. null means not a toggle (no aria-pressed emitted). |
| ariaLabel | string | '' | Accessible name. Required for icon-only buttons. |
| title | string | '' | Native HTML title tooltip. |
API — Outputs
| Name | Type | Description |
|---|---|---|
| pressedChange | MouseEvent | Fires on click. Carries the native MouseEvent in case modifier keys matter. |
Variants
| Name | Type | Description |
|---|---|---|
| default | variant | Primary CTA. Solid background using --primary. |
| destructive | variant | Dangerous actions (delete, remove). Uses --destructive. |
| outline | variant | Bordered, transparent fill. Secondary actions where presence is needed but not bold. |
| secondary | variant | Soft alternative to default. Uses --secondary. |
| ghost | variant | No background at rest, accent on hover. Use in toolbars or compact layouts. |
| link | variant | Renders like an underlined link. Use for inline navigation actions. |
Sizes
| Name | Type | Description |
|---|---|---|
| default | size | 36px high (h-9), text-sm. The standard for most buttons. |
| sm | size | 32px high (h-8), text-xs. Compact rows. |
| lg | size | 40px high (h-10). Heroes and primary CTAs. |
| icon | size | 36px square. Icon-only buttons. Pair with ariaLabel. |
Accessibility
- Native
<button>under the hood — full keyboard support out of the box (Tab, Enter, Space). ariaLabelrecommended for icon-only buttons (sizeicon) — required by AT for context.pressedinput togglesaria-pressedfor toggle-button semantics (null = not a toggle).- Focus ring uses the
--ringsemantic token, with offset against--background. - Touch targets:
default/icon= 36px,sm= 32px,lg= 40px — meets WCAG 2.2 SC 2.5.8.
Theming
Semantic tokens consumed per variant:
- default —
--primary/--primary-foreground - destructive —
--destructive/--destructive-foreground - outline —
--input(border) +--background+ hover--accent - secondary —
--secondary/--secondary-foreground - ghost — transparent + hover
--accent - link —
--primaryas text color