A debounced action button with four variants, five sizes, and built-in loading, disabled, and full-width states — plus, since 21.4.0, a [gogButton] directive that gives the same look to a link you own.
Clicks are throttled leading-edge: the first click fires immediately, further clicks are dropped for debounce ms (default 300). Click rapidly and watch the counter lag behind your clicks.
Accepted clicks: 0
<gog-buttonvariant="primary" [debounce]="300" (gogClick)="onSpamClick()">Click me fast</gog-button>
gog-button renders its own <button>, so it can never be a link. The directive inverts that: the element stays yours and [gogButton] only gives it the look.
The selector is a[gogButton], button[gogButton] — deliberately not a bare [gogButton]. On a <div> the result would look like a button while being invisible to the keyboard and to assistive technology.
Which one to reach for
The component when the button acts on the page: it owns loading (a centred spinner it projects), debounce click throttling and the gogClick output — none of which a bare element can provide. The directive when the element must be a link, or must keep directives of its own. routerLink, href, target, download, type="submit" and the rest keep working because they were never brokered through an input in the first place.
That is also why the library still has no @angular/router dependency — a design point, not an omission. A component that took a routerLink input would force the router on every app that installs the package.
Two things the directive deliberately does not do: no disabled on an <a> (there is no such thing — drop the href or render a real <button>), and no loading state (the spinner is a projected child, which a directive cannot add without taking over the element's content).
Its styles live in the global styles/button.css, pulled in by index.css, because Angular's emulated encapsulation could never reach an element declared in your template. Nothing changes in your setup — see Theming.
[gogButton] — Inputs
Name
Type
Default
Description
variant
'primary' | 'secondary' | 'outline' | 'ghost'
'primary'
Visual style — the same four the component offers.
size
'xsm' | 'sm' | 'md' | 'lg' | 'slg'
'md'
Also settable app-wide via GOG_CONFIG.control.size.
fullWidth
boolean
false
Stretches the element to fill its container. A bare attribute works.
API Reference
Inputs
Name
Type
Default
Description
variant
'primary' | 'secondary' | 'outline' | 'ghost'
'primary'
Visual style of the button.
size
'xsm' | 'sm' | 'md' | 'lg' | 'slg'
'md'
Button size.
disabled
boolean
false
Fully non-interactive: excluded from tab order via the native disabled attribute.
fullWidth
boolean
false
Stretches the button to fill its container.
type
'button' | 'submit' | 'reset'
'button'
Forwarded to the native <button> type attribute.
loading
boolean
false
Shows a spinner in place of the label and blocks activation. Uses aria-disabled rather than the native disabled attribute, so the button stays focusable.
debounce
number
300
Minimum time, in ms, between accepted clicks. Leading-edge throttle: the first click fires immediately, further clicks are dropped until the window elapses.
ariaLabel
string | null
null
Accessible name forwarded to the native <button>. Required for icon-only buttons — a plain aria-label attribute on <gog-button> lands on the host element, not the inner button, so assistive tech never sees it.
Outputs
Name
Type
Description
gogClick
EventEmitter<MouseEvent>
Emitted on each accepted click, after debounce throttling.
Styling Tokens
Every CSS custom property the button paints with. Override any of them — on a single instance, a subtree, or a theme — to restyle it. See the Theming guide for the full token-layering model, or the Theme Generator to tweak these live.