@guildofgleks/ui 21.4.3 → 21.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/AGENTS.md CHANGED
@@ -5,8 +5,10 @@ an app that **consumes** the published `@guildofgleks/ui` npm package. It is not
5
5
  authoring the library — if you are working inside the `gleks_web_ui` monorepo itself, read
6
6
  `.github/instructions/*.md` instead.
7
7
 
8
- Everything below reflects the library's actual source as of **`21.4.1`**. `README.md` covers the
9
- same ground at a higher levelinstall, setup, theming, global configuration and is accurate;
8
+ Everything below reflects the library's actual source as of **`21.4.4`** plus the removals
9
+ already landed for the unreleased `21.5.0`see **Removed in 21.5.0** near the end of this file,
10
+ and `CHANGELOG.md`. `README.md` covers the same ground at a higher level — install, setup,
11
+ theming, global configuration — and is accurate;
10
12
  this file goes further, into per-component input tables, and is the one to trust for exact names,
11
13
  types and defaults.
12
14
 
@@ -40,6 +42,10 @@ types and defaults.
40
42
 
41
43
  ```bash
42
44
  npm install @guildofgleks/ui
45
+ # or
46
+ yarn add @guildofgleks/ui
47
+ # or — installs it and adds the stylesheet below to angular.json automatically
48
+ ng add @guildofgleks/ui
43
49
  ```
44
50
 
45
51
  Add the baseline stylesheet once — it carries every token the components read plus their
@@ -164,17 +170,33 @@ Full model is in `README.md`'s Theming section and `theming.md`; short version:
164
170
 
165
171
  - Every visual value (color, spacing, radius, shadow, duration) is a `--gog-*` CSS custom
166
172
  property, layered **foundation** (`--gog-accent-color`, `--gog-space-md`, …, restyles
167
- everything) → **component** (`--gog-btn-primary-bg`, …, one block per component)
168
- **instance** (`--gog-btn-bg`, …, deliberately undeclared escape hatch for one element).
173
+ everything) → **component** (`--gog-button-primary-bg`, …, one block per component, named after
174
+ the component's own element) → **instance** (`--gog-button-bg`, …, deliberately undeclared
175
+ escape hatch for one element).
176
+ - **Component prefixes are spelled out** since 21.5.0: `--gog-button-*`, `--gog-multiselect-*`,
177
+ `--gog-confirmation-dialog-*`. The abbreviated `--gog-btn-*`, `--gog-ms-*` and `--gog-confirm-*`
178
+ still resolve and are removed in 21.7.0 — don't write new code with them. The exception is
179
+ `--gog-input-*`, which is not an abbreviation: it is the shared text-field block that
180
+ `gog-inputfield` and `gog-textarea` both render, and it keeps that name.
169
181
  - Theme switch is a `data-theme` attribute, usually on `<html>`, toggled through the
170
182
  `ThemeService` (`inject(ThemeService).setTheme('dark')` / `.toggleTheme()` / `.theme` signal).
171
183
  Ships `light` and `dark`. Three more importable presets: `slate`, `one-dark`, `one-light`
172
184
  (`@guildofgleks/ui/styles/presets/<name>.css`).
173
- - Restyle one instance without touching a theme: `<gog-button style="--gog-btn-bg: #ff4edb">`.
185
+ - Restyle one instance without touching a theme: `<gog-button style="--gog-button-bg: #ff4edb">`.
174
186
  - Build a custom theme by declaring a palette against a new `data-theme` value (see
175
187
  `theming.md` for the full worked example) — component tokens re-derive automatically, you
176
188
  don't restate them.
177
189
 
190
+ ## Right-to-left
191
+
192
+ Supported since 21.5.0. `dir="rtl"` on `<html>` or on any wrapper mirrors every component —
193
+ you write nothing per component. Portaled overlays (select/multiselect panels, tooltip bubbles)
194
+ copy a _scoped_ `dir` onto themselves, so an RTL region inside an LTR page works too.
195
+
196
+ Physical by design, in both directions: `gogTooltip [position]="'left' | 'right'"` and
197
+ `ToastConfig.position` (`'top-right'`, …). Use the tooltip's `'auto'` for direction-aware
198
+ placement; a toast corner is a deliberate choice, so it is not mirrored.
199
+
178
200
  ## Global configuration — `GOG_CONFIG` / `provideGogConfig(...)`
179
201
 
180
202
  For the handful of inputs an app typically wants to set once (a size for every form control, a
@@ -199,22 +221,22 @@ Precedence, always: **instance input → `GOG_CONFIG` → component's built-in d
199
221
  `provideGogConfig(...)` (in a route's or component's own `providers`) **layers onto the
200
222
  parent's config**, one level deep per key — it does not replace it.
201
223
 
202
- | Key | Fields | Applies to |
203
- | -------------- | ------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
204
- | `control` | `size`, `errorDisplay`, `clearable` | `size`: button, inputfield, textarea, select, multiselect, checkbox, radio-group, button-toggle-group, datepicker. `errorDisplay`: inputfield, textarea, select, multiselect, autocomplete, radio-group, slider, datepicker. `clearable`: inputfield, textarea, select, multiselect, autocomplete, datepicker. Not table/accordion/paginator (density, not form size), not spinner/skeleton/tag/chip/toggle. |
205
- | `dropdown` | `appendToBody`, `direction`, `filter`, `filterPosition` | `gog-select`, `gog-multiselect`. `gog-datepicker`/`gog-autocomplete` honour `appendToBody`/`direction` too (autocomplete has no `filter` box — it filters via the trigger's own text). |
206
- | `floatLabel` | `variant`, `showPlaceholder` | inputfield, textarea, select, multiselect, autocomplete, datepicker. |
207
- | `datepicker` | `locale`, `firstDayOfWeek`, `format` | `gog-datepicker`, `gog-calendar`. |
208
- | `autocomplete` | `searchDebounce`, `minLength`, `openOnFocus` | `gog-autocomplete`. |
209
- | `tooltip` | `position`, `showDelay`, `hideDelay` | the `gogTooltip` directive. |
210
- | `scroll` | `autoHide`, `hideDelay`, `size`, `overscrollBehavior`, `showTrack` | `gog-scroll` (and every component that uses one internally). |
211
- | `button` | `debounce` | `gog-button`. |
212
- | `inputfield` | `showSpinButtons` | `gog-inputfield`. |
213
- | `textarea` | `resize` | `gog-textarea`. |
214
- | `paginator` | `showPageSizeSelect`, `pageSizeOptions` | `gog-paginator`, and through it `gog-table`'s built-in pagination.
215
- | `toast` | `position`, `duration` | `ToastService`. |
216
- | `theme` | `storageKey`, `defaultTheme`, `followSystem`, `lightTheme`, `darkTheme` | `ThemeService`. All off/neutral by default — see below. |
217
- | `labels` | every fixed string the library renders — see below | inputfield, textarea, select, multiselect, autocomplete, datepicker, calendar, paginator, table, `DialogService`, `ToastService`. |
224
+ | Key | Fields | Applies to |
225
+ | -------------- | ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
226
+ | `control` | `size`, `errorDisplay`, `clearable` | `size`: button, inputfield, textarea, select, multiselect, checkbox, radio-group, button-toggle-group, datepicker. `errorDisplay`: inputfield, textarea, select, multiselect, autocomplete, radio-group, slider, datepicker. `clearable`: inputfield, textarea, select, multiselect, autocomplete, datepicker. Not table/accordion/paginator (density, not form size), not spinner/skeleton/tag/chip/toggle. |
227
+ | `dropdown` | `appendToBody`, `direction`, `filter`, `filterPosition` | `gog-select`, `gog-multiselect`. `gog-datepicker`/`gog-autocomplete` honour `appendToBody`/`direction` too (autocomplete has no `filter` box — it filters via the trigger's own text). |
228
+ | `floatLabel` | `variant`, `showPlaceholder` | inputfield, textarea, select, multiselect, autocomplete, datepicker. |
229
+ | `datepicker` | `locale`, `firstDayOfWeek`, `format` | `gog-datepicker`, `gog-calendar`. |
230
+ | `autocomplete` | `searchDebounce`, `minLength`, `openOnFocus` | `gog-autocomplete`. |
231
+ | `tooltip` | `position`, `showDelay`, `hideDelay` | the `gogTooltip` directive. |
232
+ | `scroll` | `autoHide`, `hideDelay`, `size`, `overscrollBehavior`, `showTrack` | `gog-scroll` (and every component that uses one internally). |
233
+ | `button` | `debounce` | `gog-button`. |
234
+ | `inputfield` | `showSpinButtons` | `gog-inputfield`. |
235
+ | `textarea` | `resize` | `gog-textarea`. |
236
+ | `paginator` | `showPageSizeSelect`, `pageSizeOptions` | `gog-paginator`, and through it `gog-table`'s built-in pagination. |
237
+ | `toast` | `position`, `duration` | `ToastService`. |
238
+ | `theme` | `storageKey`, `defaultTheme`, `followSystem`, `lightTheme`, `darkTheme` | `ThemeService`. All off/neutral by default — see below. |
239
+ | `labels` | every fixed string the library renders — see below | inputfield, textarea, select, multiselect, autocomplete, datepicker, calendar, paginator, table, `DialogService`, `ToastService`. |
218
240
 
219
241
  Anything visual does **not** belong here — override the `--gog-*` token instead.
220
242
 
@@ -434,25 +456,25 @@ toggles) — this is a real ARIA distinction, not cosmetic.
434
456
 
435
457
  #### `gog-inputfield`
436
458
 
437
- | Input | Type | Default | Notes |
438
- | ----------------------------------------- | ------------------------------------------------------- | ----------------------------------- | ------------------------------------------------------------------------------ |
439
- | `label`, `placeholder` | `string` | `''` | |
440
- | `type` | `GogInputType` | `'text'` | `text`/`password`/`email`/`number`/`search`/`tel`/`url`/`date`/`time`/`datetime-local` |
441
- | `readonly` | `boolean` | `false` | value stays focusable and submitted, edits blocked; hides the clear button and stepper |
442
- | `maxlength`, `minlength` | `number \| null` | `null` | native attributes |
443
- | `pattern` | `string` | `''` | native attribute, regex source |
444
- | `inputMode` | `GogInputMode \| null` | `null` | on-screen keyboard hint (`numeric`, `tel`, …) |
445
- | `spellcheck` | `boolean \| null` | `null` | unset = browser default |
446
- | `inputId` | `string` | `''` → generated | a real id is always rendered; pass one only to reference the field externally |
447
- | `min`, `max`, `step` | `number \| null` | `null` | `type="number"` only |
448
- | `showSpinButtons` | `boolean \| undefined` | `true` | own +/- glyphs on `type="number"`; via `GOG_CONFIG.inputfield.showSpinButtons` |
449
- | `errorMessage`, `errorDisplay` | | `''`, `'manual'` | see conventions |
450
- | `disabled`, `size`, `fullWidth` | | `false`, `'md'`, `true` | |
451
- | `iconStart` / `iconEnd` | `GogIconName \| ''` | `''` | bare leading/trailing icon |
452
- | `clearable`, `clearAriaLabel` | | `false`, `'Clear'` | on `type="number"` the clear button renders alongside the stepper |
453
- | `floatLabel`, `floatLabelShowPlaceholder` | | `'none'`, `false` | |
454
- | `showPasswordLabel` / `hidePasswordLabel` | `string \| undefined` | `'Show password'`/`'Hide password'` | `type="password"` reveal toggle aria-labels; via `GOG_CONFIG.labels` |
455
- | `incrementLabel` / `decrementLabel` | `string \| undefined` | `'Increment'`/`'Decrement'` | spin button aria-labels; via `GOG_CONFIG.labels` |
459
+ | Input | Type | Default | Notes |
460
+ | ----------------------------------------- | ---------------------- | ----------------------------------- | -------------------------------------------------------------------------------------- |
461
+ | `label`, `placeholder` | `string` | `''` | |
462
+ | `type` | `GogInputType` | `'text'` | `text`/`password`/`email`/`number`/`search`/`tel`/`url`/`date`/`time`/`datetime-local` |
463
+ | `readonly` | `boolean` | `false` | value stays focusable and submitted, edits blocked; hides the clear button and stepper |
464
+ | `maxlength`, `minlength` | `number \| null` | `null` | native attributes |
465
+ | `pattern` | `string` | `''` | native attribute, regex source |
466
+ | `inputMode` | `GogInputMode \| null` | `null` | on-screen keyboard hint (`numeric`, `tel`, …) |
467
+ | `spellcheck` | `boolean \| null` | `null` | unset = browser default |
468
+ | `inputId` | `string` | `''` → generated | a real id is always rendered; pass one only to reference the field externally |
469
+ | `min`, `max`, `step` | `number \| null` | `null` | `type="number"` only |
470
+ | `showSpinButtons` | `boolean \| undefined` | `true` | own +/- glyphs on `type="number"`; via `GOG_CONFIG.inputfield.showSpinButtons` |
471
+ | `errorMessage`, `errorDisplay` | | `''`, `'manual'` | see conventions |
472
+ | `disabled`, `size`, `fullWidth` | | `false`, `'md'`, `true` | |
473
+ | `iconStart` / `iconEnd` | `GogIconName \| ''` | `''` | bare leading/trailing icon |
474
+ | `clearable`, `clearAriaLabel` | | `false`, `'Clear'` | on `type="number"` the clear button renders alongside the stepper |
475
+ | `floatLabel`, `floatLabelShowPlaceholder` | | `'none'`, `false` | |
476
+ | `showPasswordLabel` / `hidePasswordLabel` | `string \| undefined` | `'Show password'`/`'Hide password'` | `type="password"` reveal toggle aria-labels; via `GOG_CONFIG.labels` |
477
+ | `incrementLabel` / `decrementLabel` | `string \| undefined` | `'Increment'`/`'Decrement'` | spin button aria-labels; via `GOG_CONFIG.labels` |
456
478
 
457
479
  Model: `value: string` (always a string, even for `type="number"` — the _form control_ value is
458
480
  `number | null`, but the `[(value)]` model mirrors the raw text). CVA: yes.
@@ -600,7 +622,7 @@ not from `value`, since `value` clears the moment the text stops matching the se
600
622
  | `indeterminate`, `disabled`, `fullWidth` | `boolean` | `false` |
601
623
 
602
624
  Model: `checked: boolean`. CVA: yes. Slot: `<ng-template gogCheckboxIcon>` for a custom tick
603
- icon (replaces the deprecated `checkIconTemplate` input).
625
+ icon.
604
626
 
605
627
  ```html
606
628
  <gog-checkbox label="I agree to the terms" formControlName="agree" />
@@ -648,18 +670,18 @@ a generic accessor, unlike select/multiselect/button-toggle).
648
670
 
649
671
  #### `gog-slider`
650
672
 
651
- | Input | Type | Default |
652
- | --------------------------------- | ---------------------- | ---------------------------------------------- |
653
- | `label`, `ariaLabel` | `string` | `''` |
654
- | `min`, `max`, `step` | `number` | `0`, `100`, `1` |
655
- | `showValue`, `showThumb` | `boolean` | `true` |
656
- | `errorMessage`, `errorDisplay` | | `''`, `'manual'` |
657
- | `disabled` | `boolean` | `false` |
658
- | `fullWidth` | `boolean` | `true` (ignored when `orientation="vertical"`) |
659
- | `orientation` | `GogSliderOrientation` | `'horizontal'` |
660
- | `range` | `boolean` | `false` — two thumbs; see below |
661
- | `startDisabled`, `endDisabled` | `boolean` | `false` — `range` only |
662
- | `startAriaLabel`, `endAriaLabel` | `string` | `'Minimum'` / `'Maximum'`, prefixed by `label` |
673
+ | Input | Type | Default |
674
+ | -------------------------------- | ---------------------- | ---------------------------------------------- |
675
+ | `label`, `ariaLabel` | `string` | `''` |
676
+ | `min`, `max`, `step` | `number` | `0`, `100`, `1` |
677
+ | `showValue`, `showThumb` | `boolean` | `true` |
678
+ | `errorMessage`, `errorDisplay` | | `''`, `'manual'` |
679
+ | `disabled` | `boolean` | `false` |
680
+ | `fullWidth` | `boolean` | `true` (ignored when `orientation="vertical"`) |
681
+ | `orientation` | `GogSliderOrientation` | `'horizontal'` |
682
+ | `range` | `boolean` | `false` — two thumbs; see below |
683
+ | `startDisabled`, `endDisabled` | `boolean` | `false` — `range` only |
684
+ | `startAriaLabel`, `endAriaLabel` | `string` | `'Minimum'` / `'Maximum'`, prefixed by `label` |
663
685
 
664
686
  Models: `value: number`, and `rangeValue: GogSliderRange` (`{ start: number; end: number }`).
665
687
  CVA: yes. Backed by a real `<input type="range">` (rotated via `writing-mode` for vertical), so
@@ -751,15 +773,15 @@ calendar that fills its container. This is also what sizes `inline` mode, becaus
751
773
  The package ships **41** glyphs (`GogBuiltinIconName`), all from [Lucide](https://lucide.dev)
752
774
  and inlined so the package keeps zero runtime dependencies:
753
775
 
754
- | Group | Names |
755
- | --- | --- |
756
- | Chevrons & arrows | `chevron-up`, `chevron-down`, `chevron-left`, `chevron-right`, `arrow-left`, `arrow-right` |
757
- | Confirm & dismiss | `check`, `close`, `checkbox`, `checkbox-checked` |
758
- | Status | `success`, `error`, `warning`, `info` |
759
- | Sorting | `sort`, `sort-up`, `sort-down`, `filter` |
760
- | Actions | `search`, `plus`, `minus`, `trash`, `pencil`, `copy`, `download`, `upload`, `refresh`, `external-link` |
761
- | Chrome | `menu`, `more-horizontal`, `more-vertical`, `settings` |
762
- | Objects & state | `user`, `lock`, `mail`, `calendar`, `clock`, `eye`, `eye-off`, `star`, `star-filled` |
776
+ | Group | Names |
777
+ | ----------------- | ------------------------------------------------------------------------------------------------------ |
778
+ | Chevrons & arrows | `chevron-up`, `chevron-down`, `chevron-left`, `chevron-right`, `arrow-left`, `arrow-right` |
779
+ | Confirm & dismiss | `check`, `close`, `checkbox`, `checkbox-checked` |
780
+ | Status | `success`, `error`, `warning`, `info` |
781
+ | Sorting | `sort`, `sort-up`, `sort-down`, `filter` |
782
+ | Actions | `search`, `plus`, `minus`, `trash`, `pencil`, `copy`, `download`, `upload`, `refresh`, `external-link` |
783
+ | Chrome | `menu`, `more-horizontal`, `more-vertical`, `settings` |
784
+ | Objects & state | `user`, `lock`, `mail`, `calendar`, `clock`, `eye`, `eye-off`, `star`, `star-filled` |
763
785
 
764
786
  `star` / `star-filled` is the one outline/filled pair, for a rating or favourite **toggle** —
765
787
  the same reason `checkbox` / `checkbox-checked` exists. The set is otherwise outline-only on
@@ -819,7 +841,7 @@ providers: [
819
841
 
820
842
  #### `[gogButton]` — the link-flavoured button
821
843
 
822
- `gog-button` renders its own `<button>`, so it can never *be* a link. `[gogButton]` inverts that:
844
+ `gog-button` renders its own `<button>`, so it can never _be_ a link. `[gogButton]` inverts that:
823
845
  the element stays yours and the directive only gives it the look.
824
846
 
825
847
  ```html
@@ -829,11 +851,11 @@ the element stays yours and the directive only gives it the look.
829
851
  <a gogButton fullWidth routerLink="/checkout">Checkout</a>
830
852
  ```
831
853
 
832
- | Input | Type | Default |
833
- | ----------- | ----------------------- | ------------------------------------ |
834
- | `variant` | `GogVariant` | `'primary'` |
835
- | `size` | `GogSize \| undefined` | `'md'`; via `GOG_CONFIG.control.size` |
836
- | `fullWidth` | `boolean` (bare attr ok) | `false` |
854
+ | Input | Type | Default |
855
+ | ----------- | ------------------------ | ------------------------------------- |
856
+ | `variant` | `GogVariant` | `'primary'` |
857
+ | `size` | `GogSize \| undefined` | `'md'`; via `GOG_CONFIG.control.size` |
858
+ | `fullWidth` | `boolean` (bare attr ok) | `false` |
837
859
 
838
860
  Selector is `a[gogButton], button[gogButton]` — deliberately not a bare `[gogButton]`, because on
839
861
  a `<div>` the result looks like a button and is invisible to the keyboard and to assistive tech.
@@ -903,7 +925,7 @@ Outputs: `gogClick: MouseEvent | KeyboardEvent`, `gogRemove: void`.
903
925
  | `iconName` | `GogIconName \| null` | `null` |
904
926
  | `fullWidth` | `boolean` | `false` |
905
927
 
906
- Slot: `<ng-template gogTagIcon>` for custom icon markup (replaces the deprecated `iconTemplate`).
928
+ Slot: `<ng-template gogTagIcon>` for custom icon markup.
907
929
 
908
930
  ```html
909
931
  <gog-tag variant="success">Active</gog-tag>
@@ -1038,6 +1060,17 @@ Model: `open: boolean`.
1038
1060
  </gog-collapsible>
1039
1061
  ```
1040
1062
 
1063
+ **The trigger can be any element.** On a `<button>` or `<a href>` the directive adds only the
1064
+ ARIA wiring, because the browser already handles focus and keys. On anything else — a `<div>`, a
1065
+ `<span>` — it also supplies `role="button"`, `tabindex="0"` and Enter/Space, so the control it
1066
+ announces is one a keyboard can actually reach. If you set `role` or `tabindex` yourself, the
1067
+ directive leaves both alone: you have said what the element is.
1068
+
1069
+ An open panel is as tall as its content — `--gog-collapsible-max-height` defaults to
1070
+ `max-content`. Set it to a length on an instance to cap one deliberately; the panel is
1071
+ `overflow: hidden`, so a cap **clips** rather than scrolls. (Before 21.4.4 that default was
1072
+ `480px`, which clipped taller panels silently.)
1073
+
1041
1074
  #### `gog-tabs` + `gog-tab`
1042
1075
 
1043
1076
  | Input (on `gog-tabs`) | Type | Default |
@@ -1073,18 +1106,18 @@ hidden via `[hidden]` while inactive — preserves scroll/input state).
1073
1106
 
1074
1107
  #### `gog-paginator`
1075
1108
 
1076
- | Input | Type | Default |
1077
- | ------------------------------- | ------------------------------------------------ | ------------------------------ |
1078
- | `fullWidth`, `totalPages` | `boolean`, `number` | `true`, `1` |
1079
- | `rangeMode` | `GogPaginatorRangeMode` (`'window'\|'ellipsis'`) | `'window'` — see note |
1080
- | `visiblePages` | `number` | `5` — `'window'` mode only |
1081
- | `showFirstPage`, `showLastPage` | `boolean` | `false` — `'window'` mode only |
1082
- | `siblingCount` | `number` | `2` — `'ellipsis'` mode only |
1083
- | `size` | `GogSize` | `'sm'` |
1084
- | `disabled`, `ariaLabel` | | `false`, `'Pagination'` |
1085
- | `totalRecords` | `number \| null` | `null` — see below |
1086
- | `pageSize` | `model<number>` | `10` — two-way bindable |
1087
- | `showPageSizeSelect` | `boolean \| undefined` | `false`; via `GOG_CONFIG.paginator` |
1109
+ | Input | Type | Default |
1110
+ | ------------------------------- | ------------------------------------------------ | -------------------------------------------------- |
1111
+ | `fullWidth`, `totalPages` | `boolean`, `number` | `true`, `1` |
1112
+ | `rangeMode` | `GogPaginatorRangeMode` (`'window'\|'ellipsis'`) | `'window'` — see note |
1113
+ | `visiblePages` | `number` | `5` — `'window'` mode only |
1114
+ | `showFirstPage`, `showLastPage` | `boolean` | `false` — `'window'` mode only |
1115
+ | `siblingCount` | `number` | `2` — `'ellipsis'` mode only |
1116
+ | `size` | `GogSize` | `'sm'` |
1117
+ | `disabled`, `ariaLabel` | | `false`, `'Pagination'` |
1118
+ | `totalRecords` | `number \| null` | `null` — see below |
1119
+ | `pageSize` | `model<number>` | `10` — two-way bindable |
1120
+ | `showPageSizeSelect` | `boolean \| undefined` | `false`; via `GOG_CONFIG.paginator` |
1088
1121
  | `pageSizeOptions` | `number[] \| undefined` | `[10, 20, 30, 40, 50]`; via `GOG_CONFIG.paginator` |
1089
1122
 
1090
1123
  The step buttons (`'Previous page'`/`'Next page'`) and the per-page names are configured, not
@@ -1096,7 +1129,7 @@ Models: `page: number` (1-based, self-clamps) and `pageSize: number`.
1096
1129
 
1097
1130
  **Give it `totalRecords` instead of `totalPages` when you know the row count** — it then derives
1098
1131
  the page count from `pageSize` itself, which is what removes the
1099
- `computed(() => Math.ceil(total / size))` a consumer would otherwise have to write *and* keep in
1132
+ `computed(() => Math.ceil(total / size))` a consumer would otherwise have to write _and_ keep in
1100
1133
  sync with the rows-per-page select:
1101
1134
 
1102
1135
  ```html
@@ -1123,28 +1156,28 @@ they never asked to be.
1123
1156
 
1124
1157
  #### `gog-table<T>`
1125
1158
 
1126
- | Input | Type | Default |
1127
- | ----------------------------- | ----------------------------- | --------------------------------- |
1128
- | `value` | `T[]` | `[]` |
1129
- | `fullWidth` | `boolean` | `true` |
1130
- | `pageSize` | `model<number>` | `0` (no pagination) — two-way |
1159
+ | Input | Type | Default |
1160
+ | ----------------------------- | ----------------------------- | ----------------------------------- |
1161
+ | `value` | `T[]` | `[]` |
1162
+ | `fullWidth` | `boolean` | `true` |
1163
+ | `pageSize` | `model<number>` | `0` (no pagination) — two-way |
1131
1164
  | `showPageSizeSelect` | `boolean \| undefined` | `false`; forwarded to the paginator |
1132
- | `pageSizeOptions` | `number[] \| undefined` | `[10, 20, 30, 40, 50]`; forwarded |
1133
- | `showRowNumbers`, `showTotal` | `boolean` | `true`, `false` |
1134
- | `emptyPlaceholder` | `string` | `'-'` |
1135
- | `paginatorPosition` | `'left'\|'center'\|'right'` | `'center'` |
1136
- | `totalPosition` | `'left'\|'right'\|'opposite'` | `'opposite'` |
1137
- | `loading` | `boolean` | `false` |
1138
- | `showColumnBorders` | `boolean` | `false` |
1139
- | `stickyHeader` | `boolean` | `false` |
1140
- | `size` | `GogSize` | `'lg'` (row density — not `'md'`) |
1141
- | `lazy` | `boolean` | `false` — see below |
1142
- | `totalRecords` | `number \| null` | `null` — `lazy` only |
1143
- | `selectionMode` | `GogTableSelectionMode` | `'none'` |
1144
- | `selection` | `model<T[]>` | `[]` — two-way bindable |
1145
- | `dataKey` | `string` | `''` — row identity field |
1146
- | `showSelectionColumn` | `boolean` | `true` (once selection is on) |
1147
- | `interactiveRows` | `boolean` | `false` |
1165
+ | `pageSizeOptions` | `number[] \| undefined` | `[10, 20, 30, 40, 50]`; forwarded |
1166
+ | `showRowNumbers`, `showTotal` | `boolean` | `true`, `false` |
1167
+ | `emptyPlaceholder` | `string` | `'-'` |
1168
+ | `paginatorPosition` | `'left'\|'center'\|'right'` | `'center'` |
1169
+ | `totalPosition` | `'left'\|'right'\|'opposite'` | `'opposite'` |
1170
+ | `loading` | `boolean` | `false` |
1171
+ | `showColumnBorders` | `boolean` | `false` |
1172
+ | `stickyHeader` | `boolean` | `false` |
1173
+ | `size` | `GogSize` | `'lg'` (row density — not `'md'`) |
1174
+ | `lazy` | `boolean` | `false` — see below |
1175
+ | `totalRecords` | `number \| null` | `null` — `lazy` only |
1176
+ | `selectionMode` | `GogTableSelectionMode` | `'none'` |
1177
+ | `selection` | `model<T[]>` | `[]` — two-way bindable |
1178
+ | `dataKey` | `string` | `''` — row identity field |
1179
+ | `showSelectionColumn` | `boolean` | `true` (once selection is on) |
1180
+ | `interactiveRows` | `boolean` | `false` |
1148
1181
 
1149
1182
  Outputs: `gogSortChange: GogTableSortEvent` (`{ field, direction }`, `{ field: '', direction:
1150
1183
  null }` when the third click clears it), `gogPageChange: number` (1-based; **does not fire** on
@@ -1182,7 +1215,7 @@ exist, so pagination stays hidden and it warns in dev), then refetch from the tw
1182
1215
  dataKey="id"
1183
1216
  (gogSortChange)="sort.set($event); reload()"
1184
1217
  (gogPageChange)="pageNumber.set($event); reload()"
1185
- >
1218
+ ></gog-table>
1186
1219
  ```
1187
1220
 
1188
1221
  Row numbers still count from the current page (`(page - 1) * pageSize + i + 1`), and `showTotal`
@@ -1198,7 +1231,12 @@ through it, and there is no intermediate signal to keep in sync in either direct
1198
1231
 
1199
1232
  ```html
1200
1233
  <!-- off by default; turn it on per table, or app-wide via GOG_CONFIG.paginator -->
1201
- <gog-table [value]="rows" [(pageSize)]="size" [showPageSizeSelect]="true" [pageSizeOptions]="[5, 10, 20]">
1234
+ <gog-table
1235
+ [value]="rows"
1236
+ [(pageSize)]="size"
1237
+ [showPageSizeSelect]="true"
1238
+ [pageSizeOptions]="[5, 10, 20]"
1239
+ ></gog-table>
1202
1240
  ```
1203
1241
 
1204
1242
  Changing the size returns to page 1 and does **not** emit `gogPageChange` — the consumer already
@@ -1215,7 +1253,12 @@ user on whatever size produced that one page, with no control left to pick a sma
1215
1253
  where it holds zero or one row — one shape rather than a union to narrow on every read.
1216
1254
 
1217
1255
  ```html
1218
- <gog-table [value]="rows" selectionMode="multiple" [(selection)]="selected" dataKey="id">
1256
+ <gog-table
1257
+ [value]="rows"
1258
+ selectionMode="multiple"
1259
+ [(selection)]="selected"
1260
+ dataKey="id"
1261
+ ></gog-table>
1219
1262
  ```
1220
1263
 
1221
1264
  - **Set `dataKey`.** Without it rows are matched by object identity, so any refetch that produces
@@ -1279,6 +1322,63 @@ Methods (via template ref): `scrollTo(options)`, `scrollToTop()`, `scrollToBotto
1279
1322
 
1280
1323
  ### Overlays
1281
1324
 
1325
+ #### `gog-menu` + `gogMenuTrigger` / `gogMenuItem`
1326
+
1327
+ A command menu. The trigger is a directive on **your own button** — usually the icon button you
1328
+ already styled — and the items are your own buttons too, so an item can hold an icon, a label and
1329
+ a shortcut hint without an input per piece:
1330
+
1331
+ ```html
1332
+ <button gogButton variant="ghost" [gogMenuTrigger]="rowMenu" aria-label="Row actions">
1333
+ <gog-icon name="more-vertical" />
1334
+ </button>
1335
+
1336
+ <gog-menu #rowMenu ariaLabel="Row actions">
1337
+ <button gogMenuItem (click)="edit(row)"><gog-icon name="check" /> Edit</button>
1338
+ <button gogMenuItem disabled>Transfer ownership</button>
1339
+ <button gogMenuItem (click)="remove(row)"><gog-icon name="close" /> Remove</button>
1340
+ </gog-menu>
1341
+ ```
1342
+
1343
+ | Input | Type | Default | Notes |
1344
+ | ----------- | -------------------------- | -------- | ---------------------------------------------------------------------------- |
1345
+ | `direction` | `'auto' \| 'up' \| 'down'` | `'auto'` | `'auto'` drops down whenever the panel fits and flips up only when it cannot |
1346
+ | `ariaLabel` | `string` | `''` | Names the panel itself |
1347
+
1348
+ **There is no `appendToBody`.** The panel always renders into `<body>` and is placed from the
1349
+ trigger's measured rect, so a menu inside `gog-scroll`, `gog-table` or any `overflow: hidden`
1350
+ ancestor is not clipped and needs no configuration. It also takes the `--gog-dropdown-z` its
1351
+ trigger inherits, so a menu opened inside a `gog-dialog` stacks above the dialog.
1352
+
1353
+ Output: `gogClosed` — fires after every close, whatever caused it.
1354
+
1355
+ Public methods, for driving it yourself: `open(trigger, 'first' | 'last')`, `close(restoreFocus?)`,
1356
+ `toggle(trigger)`, and the `isOpen` signal.
1357
+
1358
+ **Keyboard**, the WAI-ARIA menu button pattern: Enter/Space/ArrowDown open with the first item
1359
+ focused, ArrowUp opens with the last, arrows and Home/End move between items and step over
1360
+ disabled ones, Escape closes and returns focus to the trigger, Tab closes and lets focus move on.
1361
+ A press outside closes without pulling focus back.
1362
+
1363
+ **Disabling an item** is the native `disabled` attribute on your own button — static or bound,
1364
+ there is no input for it:
1365
+
1366
+ ```html
1367
+ <button gogMenuItem disabled>Transfer ownership</button>
1368
+ <button gogMenuItem [disabled]="isLocked()" (click)="edit()">Edit</button>
1369
+ ```
1370
+
1371
+ A disabled item stays in the list rather than disappearing (removing it would shift the others
1372
+ under the pointer), the arrow keys step over it, and clicking it does nothing.
1373
+
1374
+ **A long menu scrolls itself** past `--gog-menu-max-height`, using `gog-scroll` — the same thin,
1375
+ auto-hiding scroller as everywhere else in the package, with `overscrollBehavior="contain"` so a
1376
+ wheel at the end of the list does not scroll the page behind it. Arrowing past the last visible
1377
+ item scrolls it into view.
1378
+
1379
+ A closed menu renders nothing at all, so its commands are not in the accessibility tree until it
1380
+ opens.
1381
+
1282
1382
  #### `gog-dialog`
1283
1383
 
1284
1384
  A **single** `<gog-dialog />` renders **every** dialog `DialogService.open(...)` creates —
@@ -1316,24 +1416,45 @@ screen readers, and a second region would announce everything twice. Don't add e
1316
1416
 
1317
1417
  ---
1318
1418
 
1319
- ## Deprecated patterns do not use in new code
1419
+ ## Reading the deprecations at runtime `GOG_DEPRECATIONS`
1320
1420
 
1321
- These still work (nothing breaks if you use them), but are marked `@deprecated` and **will be
1322
- removed** on the stated schedule. Don't generate new code using any of them — use the listed
1323
- replacement instead.
1421
+ Everything the package currently deprecates, as data:
1324
1422
 
1325
- | Deprecated | Removed in | Replacement |
1326
- | ---------------------------------------------------------------------------------------------------------------- | ---------- | --------------------------------------------------------------------------------------------------------------- |
1327
- | `GogSelectOption`, `GogMultiselectOption` type aliases | `21.4.0` | `GogDropdownOption` |
1328
- | `gog-select`/`gog-multiselect` `chevronTemplate` input | `21.5.0` | `<ng-template gogDropdownChevron>` |
1329
- | `gog-checkbox` `checkIconTemplate` input | `21.5.0` | `<ng-template gogCheckboxIcon>` |
1330
- | `gog-tag` `iconTemplate` input | `21.5.0` | `<ng-template gogTagIcon>` |
1331
- | `gog-multiselect` `clearIconTemplate` input | `21.5.0` | `<ng-template gogMultiselectClearIcon>` |
1332
- | `gog-inputfield` `iconStartTemplate`/`iconEndTemplate`/`iconStartFn`/`iconEndFn`/`iconStartLabel`/`iconEndLabel` | `21.5.0` | `<span gogInputAddonStart>`/`<span gogInputAddonEnd>` (or a `<button>` with its own handler) |
1333
- | `gog-table`'s `[template]` attribute (`<ng-template template="field" type="body">`) | `21.5.0` | `<ng-template gogColumnBody>` / `<ng-template gogColumnHeader>` declared **inside** the matching `<gog-column>` |
1334
- | `<column>` selector / `Column` export | `21.5.0` | `<gog-column>` / `GogColumn` |
1423
+ ```ts
1424
+ import { GOG_DEPRECATIONS, type GogDeprecation } from '@guildofgleks/ui';
1425
+
1426
+ GOG_DEPRECATIONS.filter((entry) => entry.removedIn === '21.7.0');
1427
+ // { kind: 'token', name: '--gog-btn-bg', replacement: '--gog-button-bg',
1428
+ // since: '21.5.0', sinceDate: '2026-08-19', removedIn: '21.7.0' }
1429
+ ```
1335
1430
 
1336
- The general rule they all follow: a `TemplateRef` **input** or a string-keyed lookup is the old
1431
+ `kind` is `'symbol'` for an export or input and `'token'` for a `--gog-*` custom property. The
1432
+ list is generated from the library's source — tags for symbols, stylesheets for tokens — so it
1433
+ matches what actually still resolves in the version you installed.
1434
+
1435
+ **In 21.5.0 it holds 154 tokens and no symbols.** Nothing in the TypeScript API is deprecated
1436
+ right now; the three abbreviated token prefixes are, until 21.7.0.
1437
+
1438
+ ## Removed in 21.5.0
1439
+
1440
+ **Nothing in this table exists any more.** It is here so that code written against 21.4.x — or
1441
+ generated from a stale copy of this file — can be migrated: each row names what a call site must
1442
+ become. If you are writing new code, ignore this section entirely and use the right-hand column,
1443
+ which is documented in full above.
1444
+
1445
+ | Removed | Replacement |
1446
+ | ---------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
1447
+ | `gog-select`/`gog-multiselect` `chevronTemplate` input | `<ng-template gogDropdownChevron>` |
1448
+ | `gog-checkbox` `checkIconTemplate` input | `<ng-template gogCheckboxIcon>` |
1449
+ | `gog-tag` `iconTemplate` input | `<ng-template gogTagIcon>` |
1450
+ | `gog-multiselect` `clearIconTemplate` input | `<ng-template gogMultiselectClearIcon>` |
1451
+ | `gog-inputfield` `iconStartTemplate`/`iconEndTemplate`/`iconStartFn`/`iconEndFn`/`iconStartLabel`/`iconEndLabel` | `<span gogInputAddonStart>`/`<span gogInputAddonEnd>` (or a `<button>` with its own handler) |
1452
+ | `gog-table`'s `[template]` attribute (`<ng-template template="field" type="body">`) | `<ng-template gogColumnBody>` / `<ng-template gogColumnHeader>` declared **inside** the matching `<gog-column>` |
1453
+ | `<column>` selector / `Column` export | `<gog-column>` / `GogColumn` |
1454
+ | `GogSelectOption` / `GogMultiselectOption` types | `GogDropdownOption` (the same type — they were aliases of it) |
1455
+ | `@guildofgleks/ui/src/styles/…` asset path | `@guildofgleks/ui/styles/…` |
1456
+
1457
+ The general rule they all followed: a `TemplateRef` **input** or a string-keyed lookup was the old
1337
1458
  shape; a **projected content directive with a typed context**, declared where it's used, is the
1338
1459
  current one. If you're about to write `fooTemplate` next to an existing `foo` input, or key
1339
1460
  something off a string that has to match another string elsewhere, that's this exact
@@ -1343,39 +1464,39 @@ anti-pattern — reach for a slot directive instead.
1343
1464
 
1344
1465
  Shared enum-like types (`import type { ... } from '@guildofgleks/ui'`):
1345
1466
 
1346
- | Type | Values |
1347
- | ----------------------------- | --------------------------------------------------------------------------------------------- |
1348
- | `GogSize` | `'xsm' \| 'sm' \| 'md' \| 'lg' \| 'slg'` |
1349
- | `GogVariant` | `'primary' \| 'secondary' \| 'outline' \| 'ghost'` |
1350
- | `GogTagVariant` | `'success' \| 'danger' \| 'warning' \| 'info'` |
1351
- | `GogOrientation` | `'horizontal' \| 'vertical'` |
1352
- | `GogTagShape` | `'rounded' \| 'pill'` |
1353
- | `GogSpinnerVariant` | `'runic' \| 'ring' \| 'custom'` |
1354
- | `GogSkeletonShape` | `'text' \| 'circle' \| 'rect'` |
1355
- | `GogSkeletonAnimation` | `'pulse' \| 'wave' \| 'none'` |
1356
- | `GogPaginatorRangeMode` | `'window' \| 'ellipsis'` |
1357
- | `GogScrollAxis` | `'vertical' \| 'horizontal' \| 'both'` |
1358
- | `GogScrollSize` | `'normal' \| 'thin'` |
1359
- | `GogScrollOverscrollBehavior` | `'auto' \| 'contain' \| 'none'` |
1360
- | `GogTooltipPosition` | `'auto' \| 'top' \| 'bottom' \| 'left' \| 'right'` |
1361
- | `GogFloatLabelVariant` | `'none' \| 'in' \| 'on' \| 'over'` |
1362
- | `GogDropdownFilterPosition` | `'top' \| 'bottom'` |
1363
- | `GogDividerVariant` | `'solid' \| 'dashed' \| 'dotted'` |
1364
- | `GogBadgePosition` | `'top-end' \| 'top-start' \| 'bottom-end' \| 'bottom-start'` |
1365
- | `GogProgressbarMode` | `'determinate' \| 'indeterminate' \| 'buffer'` |
1366
- | `GogProgressbarVariant` | `'accent' \| 'success' \| 'danger' \| 'warning' \| 'info'` |
1367
- | `GogButtonToggleAppearance` | `'joined' \| 'separated'` |
1368
- | `GogTabsAlign` | `'start' \| 'center' \| 'end' \| 'stretch'` |
1369
- | `GogDateSelectionMode` | `'single' \| 'range'` |
1370
- | `GogHourFormat` | `'12' \| '24'` |
1371
- | `GogTextareaResize` | `'vertical' \| 'horizontal' \| 'both' \| 'none'` |
1467
+ | Type | Values |
1468
+ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------- |
1469
+ | `GogSize` | `'xsm' \| 'sm' \| 'md' \| 'lg' \| 'slg'` |
1470
+ | `GogVariant` | `'primary' \| 'secondary' \| 'outline' \| 'ghost'` |
1471
+ | `GogTagVariant` | `'success' \| 'danger' \| 'warning' \| 'info'` |
1472
+ | `GogOrientation` | `'horizontal' \| 'vertical'` |
1473
+ | `GogTagShape` | `'rounded' \| 'pill'` |
1474
+ | `GogSpinnerVariant` | `'runic' \| 'ring' \| 'custom'` |
1475
+ | `GogSkeletonShape` | `'text' \| 'circle' \| 'rect'` |
1476
+ | `GogSkeletonAnimation` | `'pulse' \| 'wave' \| 'none'` |
1477
+ | `GogPaginatorRangeMode` | `'window' \| 'ellipsis'` |
1478
+ | `GogScrollAxis` | `'vertical' \| 'horizontal' \| 'both'` |
1479
+ | `GogScrollSize` | `'normal' \| 'thin'` |
1480
+ | `GogScrollOverscrollBehavior` | `'auto' \| 'contain' \| 'none'` |
1481
+ | `GogTooltipPosition` | `'auto' \| 'top' \| 'bottom' \| 'left' \| 'right'` |
1482
+ | `GogFloatLabelVariant` | `'none' \| 'in' \| 'on' \| 'over'` |
1483
+ | `GogDropdownFilterPosition` | `'top' \| 'bottom'` |
1484
+ | `GogDividerVariant` | `'solid' \| 'dashed' \| 'dotted'` |
1485
+ | `GogBadgePosition` | `'top-end' \| 'top-start' \| 'bottom-end' \| 'bottom-start'` |
1486
+ | `GogProgressbarMode` | `'determinate' \| 'indeterminate' \| 'buffer'` |
1487
+ | `GogProgressbarVariant` | `'accent' \| 'success' \| 'danger' \| 'warning' \| 'info'` |
1488
+ | `GogButtonToggleAppearance` | `'joined' \| 'separated'` |
1489
+ | `GogTabsAlign` | `'start' \| 'center' \| 'end' \| 'stretch'` |
1490
+ | `GogDateSelectionMode` | `'single' \| 'range'` |
1491
+ | `GogHourFormat` | `'12' \| '24'` |
1492
+ | `GogTextareaResize` | `'vertical' \| 'horizontal' \| 'both' \| 'none'` |
1372
1493
  | `GogInputType` | `'text' \| 'password' \| 'email' \| 'number' \| 'search' \| 'tel' \| 'url' \| 'date' \| 'time' \| 'datetime-local'` |
1373
- | `GogInputMode` | `'none' \| 'text' \| 'decimal' \| 'numeric' \| 'tel' \| 'search' \| 'email' \| 'url'` |
1374
- | `GogTableSelectionMode` | `'none' \| 'single' \| 'multiple'` |
1375
- | `GogTableSortEvent` | `{ field: string; direction: SortDirection }` |
1376
- | `GogTableRowClickEvent<T>` | `{ row: T; index: number; originalEvent: MouseEvent \| KeyboardEvent }` |
1377
- | `GogErrorDisplay` | `'auto' \| 'manual'` |
1378
- | `GogDropdownDirection` | `'auto' \| 'up' \| 'down'` |
1379
- | `GogTooltipSide` | `'top' \| 'bottom' \| 'left' \| 'right'` (resolved form of `GogTooltipPosition`, no `'auto'`) |
1380
- | `GogBuiltinIconName` | the 20 glyphs the package ships — see [`gog-icon`](#gog-icon) |
1381
- | `GogIconName` | `GogBuiltinIconName \| (string & {})` — built-ins plus anything registered via `provideGogIcons` |
1494
+ | `GogInputMode` | `'none' \| 'text' \| 'decimal' \| 'numeric' \| 'tel' \| 'search' \| 'email' \| 'url'` |
1495
+ | `GogTableSelectionMode` | `'none' \| 'single' \| 'multiple'` |
1496
+ | `GogTableSortEvent` | `{ field: string; direction: SortDirection }` |
1497
+ | `GogTableRowClickEvent<T>` | `{ row: T; index: number; originalEvent: MouseEvent \| KeyboardEvent }` |
1498
+ | `GogErrorDisplay` | `'auto' \| 'manual'` |
1499
+ | `GogDropdownDirection` | `'auto' \| 'up' \| 'down'` |
1500
+ | `GogTooltipSide` | `'top' \| 'bottom' \| 'left' \| 'right'` (resolved form of `GogTooltipPosition`, no `'auto'`) |
1501
+ | `GogBuiltinIconName` | the 20 glyphs the package ships — see [`gog-icon`](#gog-icon) |
1502
+ | `GogIconName` | `GogBuiltinIconName \| (string & {})` — built-ins plus anything registered via `provideGogIcons` |