@guildofgleks/ui 21.5.1 → 21.6.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 +29 -1
- package/CHANGELOG.md +154 -2
- package/README.md +4 -0
- package/fesm2022/guildofgleks-ui.mjs +73 -8
- package/fesm2022/guildofgleks-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/button.css +19 -2
- package/styles/menu.css +13 -3
- package/styles/utilities.css +37 -1
- package/types/guildofgleks-ui.d.ts +50 -3
package/AGENTS.md
CHANGED
|
@@ -178,6 +178,10 @@ Full model is in `README.md`'s Theming section and `theming.md`; short version:
|
|
|
178
178
|
still resolve and are removed in 21.7.0 — don't write new code with them. The exception is
|
|
179
179
|
`--gog-input-*`, which is not an abbreviation: it is the shared text-field block that
|
|
180
180
|
`gog-inputfield` and `gog-textarea` both render, and it keeps that name.
|
|
181
|
+
- **The package does not need the app's `box-sizing` reset** (since 21.6.0): `utilities.css`
|
|
182
|
+
sets `border-box` on every element carrying a `gog-*` class, including the ones the library
|
|
183
|
+
puts on a consumer's own element. Do not add a reset "so the components line up" — they
|
|
184
|
+
already do, and a `* { box-sizing: content-box }` in an app is the only thing that undoes it.
|
|
181
185
|
- Theme switch is a `data-theme` attribute, usually on `<html>`, toggled through the
|
|
182
186
|
`ThemeService` (`inject(ThemeService).setTheme('dark')` / `.toggleTheme()` / `.theme` signal).
|
|
183
187
|
Ships `light` and `dark`. Three more importable presets: `slate`, `one-dark`, `one-light`
|
|
@@ -1169,7 +1173,8 @@ they never asked to be.
|
|
|
1169
1173
|
| `totalPosition` | `'left'\|'right'\|'opposite'` | `'opposite'` |
|
|
1170
1174
|
| `loading` | `boolean` | `false` |
|
|
1171
1175
|
| `showColumnBorders` | `boolean` | `false` |
|
|
1172
|
-
| `stickyHeader` | `boolean` | `false`
|
|
1176
|
+
| `stickyHeader` | `boolean` | `false` — pair with `maxHeight` |
|
|
1177
|
+
| `maxHeight` | `string \| null` | `null` — any CSS length |
|
|
1173
1178
|
| `size` | `GogSize` | `'lg'` (row density — not `'md'`) |
|
|
1174
1179
|
| `lazy` | `boolean` | `false` — see below |
|
|
1175
1180
|
| `totalRecords` | `number \| null` | `null` — `lazy` only |
|
|
@@ -1184,6 +1189,29 @@ null }` when the third click clears it), `gogPageChange: number` (1-based; **doe
|
|
|
1184
1189
|
first render, nor for the page reset a new sort causes — that reset belongs to the sort),
|
|
1185
1190
|
`gogRowClick: GogTableRowClickEvent<T>` (`{ row, index, originalEvent }`).
|
|
1186
1191
|
|
|
1192
|
+
**`fullWidth` also picks the layout algorithm.** Left at its default the table is `100%` wide with
|
|
1193
|
+
`table-layout: fixed`; since 21.6.0 `[fullWidth]="false"` makes it `fit-content` with
|
|
1194
|
+
`table-layout: auto`, so the columns are measured against their content instead of splitting the
|
|
1195
|
+
total evenly. Before 21.6.0 that split clipped the widest header, and a `width` on the column was
|
|
1196
|
+
the workaround — under auto layout a stated `width` is a suggestion weighed against content
|
|
1197
|
+
rather than a hard split, so those can usually go.
|
|
1198
|
+
|
|
1199
|
+
**`stickyHeader` needs `maxHeight`** (both since 21.6.0 for the pairing). A sticky element
|
|
1200
|
+
resolves against its nearest scroll container, and the table wraps itself in a `gog-scroll`;
|
|
1201
|
+
once that scroller moves on either axis it is a scroll container on *both*, because CSS coerces
|
|
1202
|
+
`overflow-y: visible` to `auto` beside a scrolling `overflow-x` (and `clip` to `hidden`). So the
|
|
1203
|
+
header can only ever stick to something inside the table — and without `maxHeight` that viewport
|
|
1204
|
+
is exactly as tall as its content and never scrolls, so there is nothing to stick to.
|
|
1205
|
+
|
|
1206
|
+
```html
|
|
1207
|
+
<gog-table [value]="rows" maxHeight="260px" [stickyHeader]="true">…</gog-table>
|
|
1208
|
+
```
|
|
1209
|
+
|
|
1210
|
+
`maxHeight` takes any CSS length and is what makes the table own its vertical scrolling. Left
|
|
1211
|
+
`null`, the table grows to its content and an ancestor scrolls it — the header then follows that
|
|
1212
|
+
ancestor's scroll like everything else, which is the pre-21.6.0 behaviour and is fine as long as
|
|
1213
|
+
you are not asking for a sticky header.
|
|
1214
|
+
|
|
1187
1215
|
Columns are declared as **projected `gog-column` children**, not an input array:
|
|
1188
1216
|
|
|
1189
1217
|
```html
|
package/CHANGELOG.md
CHANGED
|
@@ -4,7 +4,151 @@ All notable changes to `@guildofgleks/ui` are documented here. Format follows
|
|
|
4
4
|
[Keep a Changelog](https://keepachangelog.com/en/1.0.0/); this project has not yet
|
|
5
5
|
reached 1.0, so breaking changes may land in minor versions.
|
|
6
6
|
|
|
7
|
-
## [21.
|
|
7
|
+
## [21.6.0] - 23.08.2026
|
|
8
|
+
|
|
9
|
+
### Fixed
|
|
10
|
+
|
|
11
|
+
- **A loading `gog-accordion` announces itself.** It sets `aria-busy="true"` while `loading` is
|
|
12
|
+
on. Its skeleton bars are `aria-hidden` and the real headers are not rendered, so without it the
|
|
13
|
+
component was not "loading" to a screen reader — it was **empty**, which reads as "there is
|
|
14
|
+
nothing here" rather than "this is coming".
|
|
15
|
+
|
|
16
|
+
The placeholder rows also gained the shape they were missing: **a chevron placeholder**, so the
|
|
17
|
+
silhouette is the one that arrives instead of the chevron appearing out of nowhere, and
|
|
18
|
+
**varying title widths** instead of every bar at a flat 55%, which read as a repeating progress
|
|
19
|
+
artifact rather than as titles of differing length. Widths cycle by row index rather than
|
|
20
|
+
randomising, so a server-rendered pass and its hydration agree.
|
|
21
|
+
|
|
22
|
+
The geometry was already correct and is unchanged — measured at the same `size`, the skeleton
|
|
23
|
+
header is 46px against the real 47px.
|
|
24
|
+
|
|
25
|
+
**`gog-table` and `gog-autocomplete` still do not set `aria-busy`.** The rule is now written
|
|
26
|
+
down in the repo's API guide along with which loading treatment belongs to which kind of
|
|
27
|
+
component; those two are its known violations and are tracked.
|
|
28
|
+
|
|
29
|
+
- **The library no longer needs your `box-sizing` reset.** Everything it renders now sizes itself
|
|
30
|
+
`border-box`, set once in `styles/utilities.css` on any element carrying a `gog-*` class.
|
|
31
|
+
|
|
32
|
+
Without a reset the components quietly stopped honouring their own size tokens:
|
|
33
|
+
`--gog-select-min-width` is `120px`, and a `gog-select` measured **148px**; its inner control
|
|
34
|
+
went from 120px to 176px, and `gog-toggle__track` and `gog-checkbox__box` inflated the same way.
|
|
35
|
+
Measured across four showcase pages, 12–16 elements per page came out a different size. Nothing
|
|
36
|
+
looked broken, which is why it went unreported — a consumer without a reset simply got a
|
|
37
|
+
differently-proportioned library.
|
|
38
|
+
|
|
39
|
+
**If your app has `* { box-sizing: border-box }`, nothing changes**; the library was already
|
|
40
|
+
rendering under it. The rule is a single class in specificity, so your own styles still win.
|
|
41
|
+
|
|
42
|
+
- **Disabled and focus styling can no longer be lost to an ordinary app stylesheet.** `[gogButton]`
|
|
43
|
+
and `gogMenuItem` are applied to *your* element, which is the element you style — and a plain
|
|
44
|
+
`.my-button { cursor: pointer }` in an Angular component stylesheet is the same specificity as
|
|
45
|
+
the library's `.gog-btn:disabled` once `[_ngcontent-…]` is stamped on it, so it won on source
|
|
46
|
+
order. Measured: a disabled button reading `cursor: pointer` at full opacity — enabled-looking
|
|
47
|
+
and enabled-feeling while disabled. For a menu item it is worse, because the arrow keys step
|
|
48
|
+
over a disabled item: the pointer and the keyboard disagreed about what was there.
|
|
49
|
+
|
|
50
|
+
Five rules across `styles/button.css` and `styles/menu.css` — the `:disabled` and
|
|
51
|
+
`:focus-visible` pairs — now carry one more point of specificity. `:hover` and `:active` needed
|
|
52
|
+
nothing; their `:not(:disabled)` already had it.
|
|
53
|
+
|
|
54
|
+
**Restyling these is still yours**, it just has to be deliberate now: any selector of your own
|
|
55
|
+
with two classes wins, as before. The base `.gog-btn` look is untouched and as overridable as
|
|
56
|
+
it ever was — what is defended is state and focus visibility, where losing silently is a
|
|
57
|
+
correctness and accessibility bug rather than a difference of taste.
|
|
58
|
+
|
|
59
|
+
- **A disabled `gogCollapsibleTrigger` shows a disabled cursor.** It carried whatever cursor the
|
|
60
|
+
consumer had put on the element — usually `pointer`, since the trigger is their own button.
|
|
61
|
+
The library's `cursor: not-allowed` was there, and losing: an ordinary
|
|
62
|
+
`.my-trigger { cursor: pointer }` in a consumer's component stylesheet is the same specificity
|
|
63
|
+
once Angular stamps `[_ngcontent-…]` onto it, and it comes later in the cascade. The rule is
|
|
64
|
+
now scoped through `gog-collapsible`, which settles it without `!important`.
|
|
65
|
+
|
|
66
|
+
If you added a `cursor` to your own trigger, you can drop it — the directive has set
|
|
67
|
+
`cursor: pointer` since it started applying `.gog-collapsible__trigger`.
|
|
68
|
+
|
|
69
|
+
- **`gog-autocomplete`: the text can be erased again.** With a selection held, backspacing could
|
|
70
|
+
not clear the field — nine backspaces on "Amsterdam" left "Amsterdam". Deleting the last
|
|
71
|
+
character takes the text under `minLength`, which closes the panel; the effect that keeps the
|
|
72
|
+
field showing its selection used `!isOpen()` to mean "the user is not mid-edit", so closing the
|
|
73
|
+
panel made it write the selected label straight back into the input.
|
|
74
|
+
|
|
75
|
+
The panel closes for reasons that are not "the user finished" — text under `minLength`, Escape,
|
|
76
|
+
Tab — so editing is now tracked directly instead of inferred from it. The effect keeps its real
|
|
77
|
+
job, which is syncing a value the component did not set: a form writing one in, or the options
|
|
78
|
+
arriving after the value did.
|
|
79
|
+
|
|
80
|
+
**`forceSelection` is unaffected.** It still snaps the field back to the selection on blur and
|
|
81
|
+
on Escape, which is where that was always meant to happen; what stopped is the snap-back firing
|
|
82
|
+
mid-keystroke.
|
|
83
|
+
|
|
84
|
+
### Added
|
|
85
|
+
|
|
86
|
+
- **`gog-table`: `maxHeight`** — any CSS length (`'420px'`, `'60vh'`), capping the table's own
|
|
87
|
+
scroll viewport so the table owns its vertical scrolling. **This is what makes `stickyHeader`
|
|
88
|
+
work**, and the two are meant to be used together:
|
|
89
|
+
|
|
90
|
+
```html
|
|
91
|
+
<gog-table [value]="rows" maxHeight="260px" [stickyHeader]="true">…</gog-table>
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
`stickyHeader` has never held while the table scrolled sideways. A sticky element resolves
|
|
95
|
+
against its nearest scroll container; the table wraps itself in a `gog-scroll`, and the moment
|
|
96
|
+
that scroller moves on one axis it is a scroll container on **both**, because CSS coerces
|
|
97
|
+
`overflow-y: visible` to `auto` next to a scrolling `overflow-x` — and `clip` to `hidden`, which
|
|
98
|
+
is also a scroll container. Measured in a browser: a header 147px out of view, with the
|
|
99
|
+
component's own `overflow-y: visible` showing as a computed `auto`.
|
|
100
|
+
|
|
101
|
+
So the header cannot be made to stick to anything outside the table, and the fix is to give the
|
|
102
|
+
inside something to stick to. With `maxHeight` set the viewport is the vertical scrollport and
|
|
103
|
+
the header pins to it — verified with both axes scrolling at once.
|
|
104
|
+
|
|
105
|
+
An input rather than a `--gog-table-*` token, even though the value only lands in CSS, because
|
|
106
|
+
it also decides whether the internal scroller handles the vertical axis. It has to for a capped
|
|
107
|
+
table; it must **not** for an uncapped one, or every table becomes a scroll container and takes
|
|
108
|
+
the consumer's own scrolling region out of its descendants' sticky chain — measured at 147px
|
|
109
|
+
when tried that way. That is behaviour, not appearance.
|
|
110
|
+
|
|
111
|
+
**Nothing changes for a table without it.** `maxHeight` defaults to `null`, the viewport stays
|
|
112
|
+
at content height and its vertical axis stays inert.
|
|
113
|
+
|
|
114
|
+
### Fixed
|
|
115
|
+
|
|
116
|
+
- **`[fullWidth]="false"` no longer clips the widest column's header.** The table is
|
|
117
|
+
`table-layout: fixed` and switches to `width: fit-content` in this mode, so the browser split
|
|
118
|
+
that width evenly across the columns instead of measuring them against their content — and
|
|
119
|
+
`overflow: hidden` on the cell cut whatever did not fit. Measured on a five-column table:
|
|
120
|
+
"Component" was given 100px of 448px while needing 119px.
|
|
121
|
+
|
|
122
|
+
It now lays out with `table-layout: auto` whenever `fullWidth` is false. Fixed layout only buys
|
|
123
|
+
anything when the width comes from outside the table; at `fit-content` it comes from the content
|
|
124
|
+
anyway, so there was nothing to trade away. The same table now gives "Component" 133px of 454px.
|
|
125
|
+
|
|
126
|
+
**`fullWidth` left at its default is untouched** and still uses fixed layout. If you set `width`
|
|
127
|
+
on a `gog-column` purely to work around the clipping, you can drop it — under auto layout a
|
|
128
|
+
stated width becomes a suggestion the browser weighs against content, rather than a hard split.
|
|
129
|
+
|
|
130
|
+
## [21.5.2] - 22.08.2026
|
|
131
|
+
|
|
132
|
+
Documentation only, and specifically the copy of this file that ships inside the package: 21.5.0
|
|
133
|
+
and 21.5.1 were both published while their headings still read `planned`, so the changelog in the
|
|
134
|
+
tarball described two live releases as unreleased. Nothing in the code changed — there is no
|
|
135
|
+
reason to upgrade from 21.5.1 except to get a changelog that reads correctly.
|
|
136
|
+
|
|
137
|
+
### Fixed
|
|
138
|
+
|
|
139
|
+
- **21.5.0 and 21.5.1 carry their real release dates** (21.08.2026 and 22.08.2026, from the npm
|
|
140
|
+
registry) instead of `planned`. This file is the only source that cannot drift from the package
|
|
141
|
+
it documents, because it travels inside it — which is exactly why a wrong date in it is worth a
|
|
142
|
+
patch. It is also what the documentation site renders on its releases page: that page reads
|
|
143
|
+
`node_modules/@guildofgleks/ui/CHANGELOG.md` at build time rather than any copy of its own, so
|
|
144
|
+
until this ships it shows "planned" beside the version its reader is running.
|
|
145
|
+
|
|
146
|
+
`npm run release` now refuses to publish when the top heading's version does not match
|
|
147
|
+
`package.json` or its date still says `planned`. Swapping that word for the date is a manual
|
|
148
|
+
step at the end of a long list, which is a step that gets missed — twice, here — and nothing
|
|
149
|
+
downstream could tell the difference.
|
|
150
|
+
|
|
151
|
+
## [21.5.1] - 22.08.2026
|
|
8
152
|
|
|
9
153
|
Two defects 21.5.0 shipped, both of the same shape: correct-looking CSS whose effect was cancelled
|
|
10
154
|
by something else in the box model, and neither visible to a test suite that runs without a style
|
|
@@ -58,7 +202,15 @@ a version bump with nothing to migrate.
|
|
|
58
202
|
now written down where you meet it — README's "Overlays and the viewport", `AGENTS.md`, and the
|
|
59
203
|
TSDoc of each overlay.
|
|
60
204
|
|
|
61
|
-
|
|
205
|
+
- **The package's own front page was two releases stale.** `README.md` opened with "An Angular 21
|
|
206
|
+
component library … 27 components", while `package.json`'s description had said Angular 21 and
|
|
207
|
+
22 since 21.5.0 — two files in one tarball contradicting each other. It now says 21 and 22, 29
|
|
208
|
+
components and 17 (not fifteen) directives beyond the five named ones, and mentions RTL, which
|
|
209
|
+
it never did. `AGENTS.md`'s version marker still read `21.4.4` "plus the removals already landed
|
|
210
|
+
for the unreleased 21.5.0"; it now reads 21.5.1, with the **Removed in 21.5.0** section framed as
|
|
211
|
+
what it is — a migration table for code written against 21.4.x.
|
|
212
|
+
|
|
213
|
+
## [21.5.0] - 21.08.2026
|
|
62
214
|
|
|
63
215
|
**The breaking release** — the one version consumers have to read before upgrading into. It
|
|
64
216
|
carries the removals below and the token-prefix rename (`--gog-btn-*`, `--gog-ms-*` and
|
package/README.md
CHANGED
|
@@ -59,6 +59,10 @@ use — without it they render unstyled.
|
|
|
59
59
|
]
|
|
60
60
|
```
|
|
61
61
|
|
|
62
|
+
It brings its own `box-sizing: border-box`, scoped to the elements the library renders, so the
|
|
63
|
+
components size correctly whether or not your app has a global reset — since 21.6.0. Your own
|
|
64
|
+
reset is untouched either way, and a single class of specificity means your own styles still win.
|
|
65
|
+
|
|
62
66
|
**2. Import components where you use them** — each is standalone:
|
|
63
67
|
|
|
64
68
|
```ts
|