guide
Getting Started
Add the library, import its stylesheet once, and use any component standalone — no module system, no build-time theming step.
Install
Three ways in, and they differ only in how much they do for you:
# Installs the package and adds the stylesheet to angular.json for you.
ng add @guildofgleks/ui
# Or install it yourself, then follow "Import the styles" below.
npm install @guildofgleks/ui
yarn add @guildofgleks/ui
ng addangular.json, so the next section is already done when it finishes. npm and yarn only fetch the package — identical results, pick whichever your project already uses — and leave that one step to you.
Nothing else is automated in any of the three. Importing components where you use them, and placing <gog-dialog /> and <gog-toast-container />, stay manual on purpose: a schematic cannot know which components you want or where those hosts belong in your layout.
Requires Angular 21.2 or newer. The peer dependencies are @angular/core, common, forms and platform-browser at ^21.2.0 — npm installs nothing else, since the library's only runtime dependency is tslib. There is no build for older Angular majors and no @angular/cdk anywhere in the tree.
Import the styles
Skip this if you used ng add — it wrote exactly this entry already. Otherwise add the library stylesheet once, in your app's global styles (angular.json):
"styles": [
"node_modules/@guildofgleks/ui/styles/index.css",
"src/styles.scss"
]
That one file carries every --gog-* token the components read, the typography helpers and the utility classes their templates apply to themselves — without it, components render unstyled. See Theming for what it pulls in.
It does not pull in fonts. styles/fonts.css exists and is what this site uses, but it downloads three families from Google Fonts — a decision a component library shouldn't make for you, so it is a separate import. Components inherit whatever typography your app already has.
The short @guildofgleks/ui/styles/… path arrived in @guildofgleks/ui/src/styles/… still resolves and keeps working until 21.5.0, so an existing setup has time — but write the short form in new ones.
Pick a theme
Everything keys off one attribute on <html>. theme.css ships light — which is also what you get with no attribute — and dark:
<!-- index.html — or set it from your own code before the app boots -->
<html lang="en" data-theme="dark">
The three presets (slate, one-dark, one-light) are separate stylesheets: add the one you want to styles for that name to resolve.
"styles": [
"node_modules/@guildofgleks/ui/styles/index.css",
"node_modules/@guildofgleks/ui/styles/presets/slate.css",
"src/styles.scss"
]
To switch at runtime, inject ThemeService. With no configuration it adopts whatever data-theme is already on the document and otherwise uses light — remembering the choice and following the OS setting are both opt-in, so nothing starts writing to localStorage behind your back.
import { ThemeService, provideGogConfig } from '@guildofgleks/ui';
// switching
private readonly theme = inject(ThemeService);
this.theme.setTheme('dark');
this.theme.toggleTheme();
this.theme.theme(); // a signal — read it in a template
// opt in to persistence and following the OS setting
provideGogConfig({
theme: { storageKey: 'app-theme', followSystem: true },
});
Use a component
Every component is standalone — import only what you use.
import { Component } from '@angular/core';
import { ButtonComponent } from '@guildofgleks/ui';
@Component({
selector: 'app-example',
imports: [ButtonComponent],
template: `<gog-button variant="primary">Click me</gog-button>`,
})
export class ExampleComponent {}
Use it in a form
Every control implements ControlValueAccessor — input field, textarea, select, multiselect, autocomplete, checkbox, radio group, toggle, slider, datepicker and the button-toggle group — so formControlName, [formControl] and [(ngModel)] work with no adapter and no wrapper component.
form = new FormGroup({
email: new FormControl('', [Validators.required, Validators.email]),
});
<form [formGroup]="form">
<gog-inputfield
label="Email"
formControlName="email"
errorMessage="A valid email is required"
errorDisplay="auto"
/>
</form>
errorDisplay="auto" is the part worth knowing: with a form control attached, the field shows errorMessage once the control is touched and invalid, so you supply the text and not the timing. The default is manual, where the message shows for as long as errorMessage is non-empty.
Set app-wide defaults (optional)
Anything a whole app decides once — a compact size, automatic error timing, a date format — goes in one place instead of on every instance.
import { provideGogConfig } from '@guildofgleks/ui';
bootstrapApplication(App, {
providers: [
provideGogConfig({
control: { size: 'sm', errorDisplay: 'auto' },
datepicker: { locale: 'de-DE', firstDayOfWeek: 1 },
}),
],
});
A component's own input always wins over this. See Global Configuration for the full list of keys.
Building with an AI agent
The package ships AGENTS.md — a per-component API reference written for the coding agent, not for this site: exact input names, types and defaults, in one file it can read in a single pass. It sits at node_modules/@guildofgleks/ui/AGENTS.md, and pointing an agent at it is usually the difference between generated code that compiles and code written against inputs that never existed.
Two more files ship alongside it: README.md, the same ground at a higher level, and TOKENS.md, the generated catalogue of every theming token.
Accessibility you get for free
Every form control generates its own id and wires its label to it inputId only when something outside the component has to reference the field — your own <label for>, an aria-describedby on a sibling, or a test hook.