@guildofgleks/ui 21.9.1 → 21.10.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 +1951 -1930
- package/CHANGELOG.md +2340 -2225
- package/TOKENS.md +1 -1
- package/fesm2022/guildofgleks-ui.mjs +17 -3
- package/fesm2022/guildofgleks-ui.mjs.map +1 -1
- package/package.json +1 -1
- package/styles/button.css +401 -387
- package/styles/presets/slate.css +92 -86
- package/styles/theme.css +2396 -2357
- package/types/guildofgleks-ui.d.ts +25 -9
package/styles/button.css
CHANGED
|
@@ -1,387 +1,401 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* The button's visual block, in a **global** stylesheet rather than the component's own.
|
|
3
|
-
*
|
|
4
|
-
* `gog-button` is not the only thing that renders it: `[gogButton]` applies these same classes to
|
|
5
|
-
* a consumer's own `<a>` or `<button>`, and Angular's emulated encapsulation would never let a
|
|
6
|
-
* component stylesheet reach an element declared in someone else's template. The same reason
|
|
7
|
-
* `gogBadge` and `gog-collapsible` keep their CSS here.
|
|
8
|
-
*
|
|
9
|
-
* Token layering (see theme.css):
|
|
10
|
-
* --gog-button-<prop> per-instance override. Never declared here or in the
|
|
11
|
-
* theme, so it always wins when a consumer sets it.
|
|
12
|
-
* --gog-button-variant-<prop> internal, set by the variant classes below.
|
|
13
|
-
* --gog-button-size-<prop> internal, set by the size classes below.
|
|
14
|
-
* --gog-button-<variant>-<prop> the actual values, all in theme.css.
|
|
15
|
-
* Nothing in this file is a literal: every colour, font, metric and duration resolves
|
|
16
|
-
* to a theme token, so a theme can restyle the button without touching this stylesheet.
|
|
17
|
-
*/
|
|
18
|
-
.gog-btn {
|
|
19
|
-
/* Scopes the spinner rendered inside a loading button to the variant's spinner colour. */
|
|
20
|
-
--gog-spinner-color: var(
|
|
21
|
-
--gog-button-spinner-color,
|
|
22
|
-
var(--gog-button-variant-spinner-color, var(--gog-button-primary-spinner-color))
|
|
23
|
-
);
|
|
24
|
-
|
|
25
|
-
gap: var(--gog-button-gap);
|
|
26
|
-
border: var(--gog-button-border-width) var(--gog-button-border-style)
|
|
27
|
-
var(--gog-button-border, var(--gog-button-variant-border, var(--gog-button-primary-border)));
|
|
28
|
-
border-radius: var(--gog-button-radius);
|
|
29
|
-
padding: var(--gog-button-padding, var(--gog-button-size-padding, var(--gog-button-md-padding)));
|
|
30
|
-
font-family: var(--gog-button-font-family);
|
|
31
|
-
font-weight: var(--gog-button-font-weight);
|
|
32
|
-
font-size: var(
|
|
33
|
-
--gog-button-font-size,
|
|
34
|
-
var(--gog-button-size-font-size, var(--gog-button-md-font-size))
|
|
35
|
-
);
|
|
36
|
-
letter-spacing: var(--gog-button-letter-spacing);
|
|
37
|
-
text-transform: var(--gog-button-text-transform);
|
|
38
|
-
line-height: var(--gog-button-line-height);
|
|
39
|
-
background-color: var(
|
|
40
|
-
--gog-button-bg,
|
|
41
|
-
var(--gog-button-variant-bg, var(--gog-button-primary-bg))
|
|
42
|
-
);
|
|
43
|
-
color: var(--gog-button-color, var(--gog-button-variant-color, var(--gog-button-primary-color)));
|
|
44
|
-
box-shadow: var(
|
|
45
|
-
--gog-button-shadow,
|
|
46
|
-
var(--gog-button-variant-shadow, var(--gog-button-primary-shadow))
|
|
47
|
-
);
|
|
48
|
-
cursor: pointer;
|
|
49
|
-
/* An `<a>` carries the UA underline; a `<button>` never did, which is why the component never
|
|
50
|
-
needed this. Reset here so `[gogButton]` on a link is visually identical to the component. */
|
|
51
|
-
text-decoration: none;
|
|
52
|
-
transition:
|
|
53
|
-
background-color var(--gog-button-transition-duration) var(--gog-easing),
|
|
54
|
-
box-shadow var(--gog-button-transition-duration) var(--gog-easing),
|
|
55
|
-
color var(--gog-button-transition-duration) var(--gog-easing);
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/*
|
|
59
|
-
* The doubled class on this rule and the disabled one below is deliberate, and the only two
|
|
60
|
-
* rules in this file that need it.
|
|
61
|
-
*
|
|
62
|
-
* `[gogButton]` goes on the *consumer's* own element, which is the element they style — and
|
|
63
|
-
* Angular's emulated encapsulation stamps `[_ngcontent-…]` onto every rule in a component
|
|
64
|
-
* stylesheet, so an ordinary `.my-btn { cursor: pointer }` is (0,2,0). That exactly ties
|
|
65
|
-
* `.gog-btn:disabled` and wins on source order, because this file loads before the app's own
|
|
66
|
-
* styles. Measured in the showcase: a disabled button went from `not-allowed`/`0.4` to
|
|
67
|
-
* `pointer`/`1` under a single-class consumer rule — it looked and felt enabled while disabled.
|
|
68
|
-
*
|
|
69
|
-
* `:hover` and `:active` below need no help: their `:not(:disabled)` already makes them (0,3,0).
|
|
70
|
-
* The base `.gog-btn` is left beatable on purpose — restyling the look is the consumer's call.
|
|
71
|
-
* These two are not look, they are state and focus visibility, and losing them silently is a
|
|
72
|
-
* correctness and accessibility regression rather than a taste one. A consumer who genuinely
|
|
73
|
-
* wants to restyle them can still do it by being specific about it.
|
|
74
|
-
*/
|
|
75
|
-
.gog-btn.gog-btn:focus-visible {
|
|
76
|
-
outline: var(--gog-button-focus-ring-width) solid
|
|
77
|
-
var(
|
|
78
|
-
--gog-button-hover-bg,
|
|
79
|
-
var(--gog-button-variant-hover-bg, var(--gog-button-primary-hover-bg))
|
|
80
|
-
);
|
|
81
|
-
outline-offset: var(--gog-button-focus-ring-offset);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
.gog-btn:hover:not(:disabled) {
|
|
85
|
-
background-color: var(
|
|
86
|
-
--gog-button-hover-bg,
|
|
87
|
-
var(--gog-button-variant-hover-bg, var(--gog-button-primary-hover-bg))
|
|
88
|
-
);
|
|
89
|
-
color: var(
|
|
90
|
-
--gog-button-hover-color,
|
|
91
|
-
var(--gog-button-variant-hover-color, var(--gog-button-primary-hover-color))
|
|
92
|
-
);
|
|
93
|
-
box-shadow: var(
|
|
94
|
-
--gog-button-hover-shadow,
|
|
95
|
-
var(--gog-button-variant-hover-shadow, var(--gog-button-primary-hover-shadow))
|
|
96
|
-
);
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/*
|
|
100
|
-
* The held state. It changes colour *and* scales, and the colour is the part that matters:
|
|
101
|
-
* `prefers-reduced-motion` switches the transform off below, and until 21.9.0 that was the whole
|
|
102
|
-
* rule — so a reader with animations off pressed a button and nothing whatsoever happened. The
|
|
103
|
-
* ripple does not cover it either: it is off by default and is itself suppressed under reduced
|
|
104
|
-
* motion, deliberately, because it really is decoration. A colour change is not.
|
|
105
|
-
*
|
|
106
|
-
* This sits after `:hover` on purpose. Both are (0,3,0), so source order decides, and a pointer
|
|
107
|
-
* is nearly always hovering the button it is pressing — the press has to win that tie or it is
|
|
108
|
-
* invisible exactly when it is happening.
|
|
109
|
-
*/
|
|
110
|
-
.gog-btn:active:not(:disabled) {
|
|
111
|
-
background-color: var(
|
|
112
|
-
--gog-button-press-bg,
|
|
113
|
-
var(--gog-button-variant-press-bg, var(--gog-button-primary-press-bg))
|
|
114
|
-
);
|
|
115
|
-
color: var(
|
|
116
|
-
--gog-button-press-color,
|
|
117
|
-
var(--gog-button-variant-press-color, var(--gog-button-primary-press-color))
|
|
118
|
-
);
|
|
119
|
-
transform: scale(var(--gog-button-active-scale));
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/*
|
|
123
|
-
* A toggle button that is on, and the only state here that persists rather than tracking the
|
|
124
|
-
* pointer. It therefore has to survive the ones that do not: `:hover` and `:active` both own the
|
|
125
|
-
* background, so a ring is what is left that they cannot paint over. Last of the state rules and
|
|
126
|
-
* (0,3,0) like them, so it wins the tie by source order — a toggled button that loses its ring
|
|
127
|
-
* the moment the pointer arrives would announce `aria-pressed="true"` and show nothing, which is
|
|
128
|
-
* the WCAG 1.4.1 failure this rule exists to prevent.
|
|
129
|
-
*
|
|
130
|
-
* `mixed` is styled like `true`: a partially-checked toggle is on for the purpose of "does this
|
|
131
|
-
* look different from off".
|
|
132
|
-
*
|
|
133
|
-
* This matches `[gogButton]` on a consumer's own element too, which is the whole reason it keys
|
|
134
|
-
* off the attribute rather than an input — the directive styles markup you own, so you write
|
|
135
|
-
* `aria-pressed` there yourself and get the look for free.
|
|
136
|
-
|
|
137
|
-
.
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
/*
|
|
165
|
-
.
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
.gog-btn--
|
|
180
|
-
--gog-button-variant-bg: var(--gog-button-
|
|
181
|
-
--gog-button-variant-color: var(--gog-button-
|
|
182
|
-
--gog-button-variant-border: var(--gog-button-
|
|
183
|
-
--gog-button-variant-shadow: var(--gog-button-
|
|
184
|
-
--gog-button-variant-hover-bg: var(--gog-button-
|
|
185
|
-
--gog-button-variant-hover-color: var(--gog-button-
|
|
186
|
-
--gog-button-variant-hover-shadow: var(--gog-button-
|
|
187
|
-
--gog-button-variant-toggled-shadow: var(--gog-button-
|
|
188
|
-
--gog-button-variant-press-bg: var(--gog-button-
|
|
189
|
-
--gog-button-variant-press-color: var(--gog-button-
|
|
190
|
-
--gog-button-variant-spinner-color: var(--gog-button-
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
--gog-button-variant-
|
|
196
|
-
--gog-button-variant-
|
|
197
|
-
--gog-button-variant-
|
|
198
|
-
--gog-button-variant-
|
|
199
|
-
--gog-button-variant-hover-
|
|
200
|
-
--gog-button-variant-hover-
|
|
201
|
-
--gog-button-variant-
|
|
202
|
-
--gog-button-variant-
|
|
203
|
-
--gog-button-variant-press-
|
|
204
|
-
--gog-button-variant-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
--gog-button-variant-
|
|
211
|
-
--gog-button-variant-
|
|
212
|
-
--gog-button-variant-
|
|
213
|
-
--gog-button-variant-
|
|
214
|
-
--gog-button-variant-hover-
|
|
215
|
-
--gog-button-variant-hover-
|
|
216
|
-
--gog-button-variant-
|
|
217
|
-
--gog-button-variant-
|
|
218
|
-
--gog-button-variant-press-
|
|
219
|
-
--gog-button-variant-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
.
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
--gog-button-severity-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
--gog-button-severity-
|
|
258
|
-
--gog-button-severity-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
--gog-button-severity-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
--gog-button-severity-
|
|
267
|
-
--gog-button-severity-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
--gog-button-severity-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
)
|
|
281
|
-
--gog-button-
|
|
282
|
-
--gog-button-
|
|
283
|
-
--gog-button-
|
|
284
|
-
--gog-button-
|
|
285
|
-
--gog-button-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
--gog-button-variant-bg:
|
|
300
|
-
--gog-button-variant-color: var(--gog-button-severity-
|
|
301
|
-
--gog-button-variant-
|
|
302
|
-
--gog-button-variant-shadow:
|
|
303
|
-
|
|
304
|
-
--gog-button-variant-
|
|
305
|
-
--gog-button-variant-
|
|
306
|
-
--gog-button-variant-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
--gog-button-variant-
|
|
319
|
-
--gog-button-variant-
|
|
320
|
-
--gog-button-variant-
|
|
321
|
-
|
|
322
|
-
--gog-button-variant-
|
|
323
|
-
--gog-button-variant-
|
|
324
|
-
--gog-button-variant-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
--gog-button-
|
|
335
|
-
--gog-button-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
--gog-button-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
--gog-button-size-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
--gog-button-size-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
.gog-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
.gog-
|
|
373
|
-
position:
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
1
|
+
/*
|
|
2
|
+
* The button's visual block, in a **global** stylesheet rather than the component's own.
|
|
3
|
+
*
|
|
4
|
+
* `gog-button` is not the only thing that renders it: `[gogButton]` applies these same classes to
|
|
5
|
+
* a consumer's own `<a>` or `<button>`, and Angular's emulated encapsulation would never let a
|
|
6
|
+
* component stylesheet reach an element declared in someone else's template. The same reason
|
|
7
|
+
* `gogBadge` and `gog-collapsible` keep their CSS here.
|
|
8
|
+
*
|
|
9
|
+
* Token layering (see theme.css):
|
|
10
|
+
* --gog-button-<prop> per-instance override. Never declared here or in the
|
|
11
|
+
* theme, so it always wins when a consumer sets it.
|
|
12
|
+
* --gog-button-variant-<prop> internal, set by the variant classes below.
|
|
13
|
+
* --gog-button-size-<prop> internal, set by the size classes below.
|
|
14
|
+
* --gog-button-<variant>-<prop> the actual values, all in theme.css.
|
|
15
|
+
* Nothing in this file is a literal: every colour, font, metric and duration resolves
|
|
16
|
+
* to a theme token, so a theme can restyle the button without touching this stylesheet.
|
|
17
|
+
*/
|
|
18
|
+
.gog-btn {
|
|
19
|
+
/* Scopes the spinner rendered inside a loading button to the variant's spinner colour. */
|
|
20
|
+
--gog-spinner-color: var(
|
|
21
|
+
--gog-button-spinner-color,
|
|
22
|
+
var(--gog-button-variant-spinner-color, var(--gog-button-primary-spinner-color))
|
|
23
|
+
);
|
|
24
|
+
|
|
25
|
+
gap: var(--gog-button-gap);
|
|
26
|
+
border: var(--gog-button-border-width) var(--gog-button-border-style)
|
|
27
|
+
var(--gog-button-border, var(--gog-button-variant-border, var(--gog-button-primary-border)));
|
|
28
|
+
border-radius: var(--gog-button-radius);
|
|
29
|
+
padding: var(--gog-button-padding, var(--gog-button-size-padding, var(--gog-button-md-padding)));
|
|
30
|
+
font-family: var(--gog-button-font-family);
|
|
31
|
+
font-weight: var(--gog-button-font-weight);
|
|
32
|
+
font-size: var(
|
|
33
|
+
--gog-button-font-size,
|
|
34
|
+
var(--gog-button-size-font-size, var(--gog-button-md-font-size))
|
|
35
|
+
);
|
|
36
|
+
letter-spacing: var(--gog-button-letter-spacing);
|
|
37
|
+
text-transform: var(--gog-button-text-transform);
|
|
38
|
+
line-height: var(--gog-button-line-height);
|
|
39
|
+
background-color: var(
|
|
40
|
+
--gog-button-bg,
|
|
41
|
+
var(--gog-button-variant-bg, var(--gog-button-primary-bg))
|
|
42
|
+
);
|
|
43
|
+
color: var(--gog-button-color, var(--gog-button-variant-color, var(--gog-button-primary-color)));
|
|
44
|
+
box-shadow: var(
|
|
45
|
+
--gog-button-shadow,
|
|
46
|
+
var(--gog-button-variant-shadow, var(--gog-button-primary-shadow))
|
|
47
|
+
);
|
|
48
|
+
cursor: pointer;
|
|
49
|
+
/* An `<a>` carries the UA underline; a `<button>` never did, which is why the component never
|
|
50
|
+
needed this. Reset here so `[gogButton]` on a link is visually identical to the component. */
|
|
51
|
+
text-decoration: none;
|
|
52
|
+
transition:
|
|
53
|
+
background-color var(--gog-button-transition-duration) var(--gog-easing),
|
|
54
|
+
box-shadow var(--gog-button-transition-duration) var(--gog-easing),
|
|
55
|
+
color var(--gog-button-transition-duration) var(--gog-easing);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/*
|
|
59
|
+
* The doubled class on this rule and the disabled one below is deliberate, and the only two
|
|
60
|
+
* rules in this file that need it.
|
|
61
|
+
*
|
|
62
|
+
* `[gogButton]` goes on the *consumer's* own element, which is the element they style — and
|
|
63
|
+
* Angular's emulated encapsulation stamps `[_ngcontent-…]` onto every rule in a component
|
|
64
|
+
* stylesheet, so an ordinary `.my-btn { cursor: pointer }` is (0,2,0). That exactly ties
|
|
65
|
+
* `.gog-btn:disabled` and wins on source order, because this file loads before the app's own
|
|
66
|
+
* styles. Measured in the showcase: a disabled button went from `not-allowed`/`0.4` to
|
|
67
|
+
* `pointer`/`1` under a single-class consumer rule — it looked and felt enabled while disabled.
|
|
68
|
+
*
|
|
69
|
+
* `:hover` and `:active` below need no help: their `:not(:disabled)` already makes them (0,3,0).
|
|
70
|
+
* The base `.gog-btn` is left beatable on purpose — restyling the look is the consumer's call.
|
|
71
|
+
* These two are not look, they are state and focus visibility, and losing them silently is a
|
|
72
|
+
* correctness and accessibility regression rather than a taste one. A consumer who genuinely
|
|
73
|
+
* wants to restyle them can still do it by being specific about it.
|
|
74
|
+
*/
|
|
75
|
+
.gog-btn.gog-btn:focus-visible {
|
|
76
|
+
outline: var(--gog-button-focus-ring-width) solid
|
|
77
|
+
var(
|
|
78
|
+
--gog-button-hover-bg,
|
|
79
|
+
var(--gog-button-variant-hover-bg, var(--gog-button-primary-hover-bg))
|
|
80
|
+
);
|
|
81
|
+
outline-offset: var(--gog-button-focus-ring-offset);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.gog-btn:hover:not(:disabled) {
|
|
85
|
+
background-color: var(
|
|
86
|
+
--gog-button-hover-bg,
|
|
87
|
+
var(--gog-button-variant-hover-bg, var(--gog-button-primary-hover-bg))
|
|
88
|
+
);
|
|
89
|
+
color: var(
|
|
90
|
+
--gog-button-hover-color,
|
|
91
|
+
var(--gog-button-variant-hover-color, var(--gog-button-primary-hover-color))
|
|
92
|
+
);
|
|
93
|
+
box-shadow: var(
|
|
94
|
+
--gog-button-hover-shadow,
|
|
95
|
+
var(--gog-button-variant-hover-shadow, var(--gog-button-primary-hover-shadow))
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/*
|
|
100
|
+
* The held state. It changes colour *and* scales, and the colour is the part that matters:
|
|
101
|
+
* `prefers-reduced-motion` switches the transform off below, and until 21.9.0 that was the whole
|
|
102
|
+
* rule — so a reader with animations off pressed a button and nothing whatsoever happened. The
|
|
103
|
+
* ripple does not cover it either: it is off by default and is itself suppressed under reduced
|
|
104
|
+
* motion, deliberately, because it really is decoration. A colour change is not.
|
|
105
|
+
*
|
|
106
|
+
* This sits after `:hover` on purpose. Both are (0,3,0), so source order decides, and a pointer
|
|
107
|
+
* is nearly always hovering the button it is pressing — the press has to win that tie or it is
|
|
108
|
+
* invisible exactly when it is happening.
|
|
109
|
+
*/
|
|
110
|
+
.gog-btn:active:not(:disabled) {
|
|
111
|
+
background-color: var(
|
|
112
|
+
--gog-button-press-bg,
|
|
113
|
+
var(--gog-button-variant-press-bg, var(--gog-button-primary-press-bg))
|
|
114
|
+
);
|
|
115
|
+
color: var(
|
|
116
|
+
--gog-button-press-color,
|
|
117
|
+
var(--gog-button-variant-press-color, var(--gog-button-primary-press-color))
|
|
118
|
+
);
|
|
119
|
+
transform: scale(var(--gog-button-active-scale));
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/*
|
|
123
|
+
* A toggle button that is on, and the only state here that persists rather than tracking the
|
|
124
|
+
* pointer. It therefore has to survive the ones that do not: `:hover` and `:active` both own the
|
|
125
|
+
* background, so a ring is what is left that they cannot paint over. Last of the state rules and
|
|
126
|
+
* (0,3,0) like them, so it wins the tie by source order — a toggled button that loses its ring
|
|
127
|
+
* the moment the pointer arrives would announce `aria-pressed="true"` and show nothing, which is
|
|
128
|
+
* the WCAG 1.4.1 failure this rule exists to prevent.
|
|
129
|
+
*
|
|
130
|
+
* `mixed` is styled like `true`: a partially-checked toggle is on for the purpose of "does this
|
|
131
|
+
* look different from off".
|
|
132
|
+
*
|
|
133
|
+
* This matches `[gogButton]` on a consumer's own element too, which is the whole reason it keys
|
|
134
|
+
* off the attribute rather than an input — the directive styles markup you own, so you write
|
|
135
|
+
* `aria-pressed` there yourself and get the look for free.
|
|
136
|
+
*
|
|
137
|
+
* **A disabled toggle keeps the ring** (21.10.0). It carried `:not(:disabled)` until then, copied
|
|
138
|
+
* from the pointer states above where the guard is correct — but "on, and you cannot change it
|
|
139
|
+
* right now" is a real state, and `disabled` on a real `<button>` does not remove `aria-pressed`,
|
|
140
|
+
* so dropping the look left the button announcing itself as on and looking exactly like an off
|
|
141
|
+
* one: the failure this rule was written to prevent, in the one case nobody looks at.
|
|
142
|
+
* `gog-chip` had it right from the start (`:host(.gog-chip--selected)`, no disabled guard) and
|
|
143
|
+
* the two had drifted apart. The `--gog-button-disabled-opacity` on the rule below dims the ring
|
|
144
|
+
* along with everything else, which is the correct amount of "unavailable".
|
|
145
|
+
*
|
|
146
|
+
* The doubled class is what the removed `:not(:disabled)` was silently paying for: both are
|
|
147
|
+
* (0,3,0), and this rule has to stay level with `:hover:not(:disabled)` to win the tie by source
|
|
148
|
+
* order. It buys the same protection `:focus-visible` and `:disabled` have from a consumer's
|
|
149
|
+
* single-class rule, which is right for a state and wrong for a look — see the comment on those.
|
|
150
|
+
*/
|
|
151
|
+
.gog-btn.gog-btn[aria-pressed='true'],
|
|
152
|
+
.gog-btn.gog-btn[aria-pressed='mixed'] {
|
|
153
|
+
box-shadow: var(
|
|
154
|
+
--gog-button-toggled-shadow,
|
|
155
|
+
var(--gog-button-variant-toggled-shadow, var(--gog-button-primary-toggled-shadow))
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
@media (prefers-reduced-motion: reduce) {
|
|
160
|
+
.gog-btn {
|
|
161
|
+
transition: none;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/* Only the movement goes. The colour above stays, and with the transition off it lands on the
|
|
165
|
+
first frame of the press instead of easing in. */
|
|
166
|
+
.gog-btn:active:not(:disabled) {
|
|
167
|
+
transform: none;
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
.gog-btn.gog-btn:disabled {
|
|
172
|
+
opacity: var(--gog-button-disabled-opacity);
|
|
173
|
+
cursor: not-allowed;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/* === Variants === */
|
|
177
|
+
|
|
178
|
+
/* primary: solid gold */
|
|
179
|
+
.gog-btn--primary {
|
|
180
|
+
--gog-button-variant-bg: var(--gog-button-primary-bg);
|
|
181
|
+
--gog-button-variant-color: var(--gog-button-primary-color);
|
|
182
|
+
--gog-button-variant-border: var(--gog-button-primary-border);
|
|
183
|
+
--gog-button-variant-shadow: var(--gog-button-primary-shadow);
|
|
184
|
+
--gog-button-variant-hover-bg: var(--gog-button-primary-hover-bg);
|
|
185
|
+
--gog-button-variant-hover-color: var(--gog-button-primary-hover-color);
|
|
186
|
+
--gog-button-variant-hover-shadow: var(--gog-button-primary-hover-shadow);
|
|
187
|
+
--gog-button-variant-toggled-shadow: var(--gog-button-primary-toggled-shadow);
|
|
188
|
+
--gog-button-variant-press-bg: var(--gog-button-primary-press-bg);
|
|
189
|
+
--gog-button-variant-press-color: var(--gog-button-primary-press-color);
|
|
190
|
+
--gog-button-variant-spinner-color: var(--gog-button-primary-spinner-color);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
.gog-btn--secondary {
|
|
194
|
+
--gog-button-variant-bg: var(--gog-button-secondary-bg);
|
|
195
|
+
--gog-button-variant-color: var(--gog-button-secondary-color);
|
|
196
|
+
--gog-button-variant-border: var(--gog-button-secondary-border);
|
|
197
|
+
--gog-button-variant-shadow: var(--gog-button-secondary-shadow);
|
|
198
|
+
--gog-button-variant-hover-bg: var(--gog-button-secondary-hover-bg);
|
|
199
|
+
--gog-button-variant-hover-color: var(--gog-button-secondary-hover-color);
|
|
200
|
+
--gog-button-variant-hover-shadow: var(--gog-button-secondary-hover-shadow);
|
|
201
|
+
--gog-button-variant-toggled-shadow: var(--gog-button-secondary-toggled-shadow);
|
|
202
|
+
--gog-button-variant-press-bg: var(--gog-button-secondary-press-bg);
|
|
203
|
+
--gog-button-variant-press-color: var(--gog-button-secondary-press-color);
|
|
204
|
+
--gog-button-variant-spinner-color: var(--gog-button-secondary-spinner-color);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/* outline: transparent with golden border */
|
|
208
|
+
.gog-btn--outline {
|
|
209
|
+
--gog-button-variant-bg: var(--gog-button-outline-bg);
|
|
210
|
+
--gog-button-variant-color: var(--gog-button-outline-color);
|
|
211
|
+
--gog-button-variant-border: var(--gog-button-outline-border);
|
|
212
|
+
--gog-button-variant-shadow: var(--gog-button-outline-shadow);
|
|
213
|
+
--gog-button-variant-hover-bg: var(--gog-button-outline-hover-bg);
|
|
214
|
+
--gog-button-variant-hover-color: var(--gog-button-outline-hover-color);
|
|
215
|
+
--gog-button-variant-hover-shadow: var(--gog-button-outline-hover-shadow);
|
|
216
|
+
--gog-button-variant-toggled-shadow: var(--gog-button-outline-toggled-shadow);
|
|
217
|
+
--gog-button-variant-press-bg: var(--gog-button-outline-press-bg);
|
|
218
|
+
--gog-button-variant-press-color: var(--gog-button-outline-press-color);
|
|
219
|
+
--gog-button-variant-spinner-color: var(--gog-button-outline-spinner-color);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/* ghost: no border, subtle hover */
|
|
223
|
+
.gog-btn--ghost {
|
|
224
|
+
--gog-button-variant-bg: var(--gog-button-ghost-bg);
|
|
225
|
+
--gog-button-variant-color: var(--gog-button-ghost-color);
|
|
226
|
+
--gog-button-variant-border: var(--gog-button-ghost-border);
|
|
227
|
+
--gog-button-variant-shadow: var(--gog-button-ghost-shadow);
|
|
228
|
+
--gog-button-variant-hover-bg: var(--gog-button-ghost-hover-bg);
|
|
229
|
+
--gog-button-variant-hover-color: var(--gog-button-ghost-hover-color);
|
|
230
|
+
--gog-button-variant-hover-shadow: var(--gog-button-ghost-hover-shadow);
|
|
231
|
+
--gog-button-variant-toggled-shadow: var(--gog-button-ghost-toggled-shadow);
|
|
232
|
+
--gog-button-variant-press-bg: var(--gog-button-ghost-press-bg);
|
|
233
|
+
--gog-button-variant-press-color: var(--gog-button-ghost-press-color);
|
|
234
|
+
--gog-button-variant-spinner-color: var(--gog-button-ghost-spinner-color);
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/* === Severity ===
|
|
238
|
+
*
|
|
239
|
+
* `severity` is orthogonal to `variant` — a destructive action can be filled, outlined or a
|
|
240
|
+
* ghost and is destructive in all three — so these do not add a fifth variant. They re-point the
|
|
241
|
+
* `--gog-button-variant-*` layer the variant classes above set, and they come *after* those
|
|
242
|
+
* classes so the tie is decided by source order where specificity allows it.
|
|
243
|
+
*
|
|
244
|
+
* Two halves. The severity class carries only the ingredients (`--gog-button-severity-*`, from
|
|
245
|
+
* the per-severity tokens in theme.css); the shape rules below say what a variant does with
|
|
246
|
+
* them, once each rather than once per severity. Four plus three blocks instead of sixteen, and
|
|
247
|
+
* a fifth status colour would be one more block rather than four.
|
|
248
|
+
*
|
|
249
|
+
* The shape rules are `(0,2,0)` through the doubled `:is()`, which is what puts them above the
|
|
250
|
+
* `(0,1,0)` variant classes regardless of the order the two classes appear in on the element.
|
|
251
|
+
*/
|
|
252
|
+
.gog-btn--success {
|
|
253
|
+
--gog-button-severity-fill: var(--gog-button-success-fill);
|
|
254
|
+
--gog-button-severity-on-fill: var(--gog-button-success-on-fill);
|
|
255
|
+
--gog-button-severity-fill-hover: var(--gog-button-success-fill-hover);
|
|
256
|
+
--gog-button-severity-fill-press: var(--gog-button-success-fill-press);
|
|
257
|
+
--gog-button-severity-ink: var(--gog-button-success-ink);
|
|
258
|
+
--gog-button-severity-wash: var(--gog-button-success-wash);
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
.gog-btn--danger {
|
|
262
|
+
--gog-button-severity-fill: var(--gog-button-danger-fill);
|
|
263
|
+
--gog-button-severity-on-fill: var(--gog-button-danger-on-fill);
|
|
264
|
+
--gog-button-severity-fill-hover: var(--gog-button-danger-fill-hover);
|
|
265
|
+
--gog-button-severity-fill-press: var(--gog-button-danger-fill-press);
|
|
266
|
+
--gog-button-severity-ink: var(--gog-button-danger-ink);
|
|
267
|
+
--gog-button-severity-wash: var(--gog-button-danger-wash);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
.gog-btn--warning {
|
|
271
|
+
--gog-button-severity-fill: var(--gog-button-warning-fill);
|
|
272
|
+
--gog-button-severity-on-fill: var(--gog-button-warning-on-fill);
|
|
273
|
+
--gog-button-severity-fill-hover: var(--gog-button-warning-fill-hover);
|
|
274
|
+
--gog-button-severity-fill-press: var(--gog-button-warning-fill-press);
|
|
275
|
+
--gog-button-severity-ink: var(--gog-button-warning-ink);
|
|
276
|
+
--gog-button-severity-wash: var(--gog-button-warning-wash);
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
.gog-btn--info {
|
|
280
|
+
--gog-button-severity-fill: var(--gog-button-info-fill);
|
|
281
|
+
--gog-button-severity-on-fill: var(--gog-button-info-on-fill);
|
|
282
|
+
--gog-button-severity-fill-hover: var(--gog-button-info-fill-hover);
|
|
283
|
+
--gog-button-severity-fill-press: var(--gog-button-info-fill-press);
|
|
284
|
+
--gog-button-severity-ink: var(--gog-button-info-ink);
|
|
285
|
+
--gog-button-severity-wash: var(--gog-button-info-wash);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
/* The two filled variants: the status colour is the fill, and the label is the one that reads
|
|
289
|
+
on it. `secondary` loses its own neutral fill here, which is the point — a severity says what
|
|
290
|
+
the action does, and the variant is left saying only how loud it is. */
|
|
291
|
+
:is(.gog-btn--success, .gog-btn--danger, .gog-btn--warning, .gog-btn--info):is(
|
|
292
|
+
.gog-btn--primary,
|
|
293
|
+
.gog-btn--secondary
|
|
294
|
+
) {
|
|
295
|
+
--gog-button-variant-bg: var(--gog-button-severity-fill);
|
|
296
|
+
--gog-button-variant-color: var(--gog-button-severity-on-fill);
|
|
297
|
+
--gog-button-variant-border: transparent;
|
|
298
|
+
--gog-button-variant-shadow: none;
|
|
299
|
+
--gog-button-variant-hover-bg: var(--gog-button-severity-fill-hover);
|
|
300
|
+
--gog-button-variant-hover-color: var(--gog-button-severity-on-fill);
|
|
301
|
+
--gog-button-variant-hover-shadow: none;
|
|
302
|
+
--gog-button-variant-toggled-shadow: inset 0 0 0 var(--gog-button-toggled-ring-width)
|
|
303
|
+
var(--gog-button-severity-on-fill);
|
|
304
|
+
--gog-button-variant-press-bg: var(--gog-button-severity-fill-press);
|
|
305
|
+
--gog-button-variant-press-color: var(--gog-button-severity-on-fill);
|
|
306
|
+
--gog-button-variant-spinner-color: var(--gog-button-severity-on-fill);
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
/* Outline: the border and the label are the *ink* rather than the raw status colour, because
|
|
310
|
+
this label is text on the page and the raw hue clears AA in only five of the eleven themes.
|
|
311
|
+
Hovering fills with the status colour proper, which is where `-on-fill` comes back. */
|
|
312
|
+
:is(.gog-btn--success, .gog-btn--danger, .gog-btn--warning, .gog-btn--info).gog-btn--outline {
|
|
313
|
+
--gog-button-variant-bg: transparent;
|
|
314
|
+
--gog-button-variant-color: var(--gog-button-severity-ink);
|
|
315
|
+
--gog-button-variant-border: var(--gog-button-severity-ink);
|
|
316
|
+
--gog-button-variant-shadow: none;
|
|
317
|
+
--gog-button-variant-hover-bg: var(--gog-button-severity-fill);
|
|
318
|
+
--gog-button-variant-hover-color: var(--gog-button-severity-on-fill);
|
|
319
|
+
--gog-button-variant-hover-shadow: none;
|
|
320
|
+
--gog-button-variant-toggled-shadow: inset 0 0 0 var(--gog-button-toggled-ring-width)
|
|
321
|
+
var(--gog-button-severity-ink);
|
|
322
|
+
--gog-button-variant-press-bg: var(--gog-button-severity-fill-press);
|
|
323
|
+
--gog-button-variant-press-color: var(--gog-button-severity-on-fill);
|
|
324
|
+
--gog-button-variant-spinner-color: var(--gog-button-severity-ink);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
/* Ghost: a wash on hover rather than a fill, the same shape the accent ghost has. Its hover
|
|
328
|
+
label is `--gog-text-color` for the reason 21.9.0 recorded on `--gog-button-ghost-hover-color`
|
|
329
|
+
— a label and a ground made of the same hue walk toward each other — and the press then fills
|
|
330
|
+
properly, which is also what the accent ghost does. */
|
|
331
|
+
:is(.gog-btn--success, .gog-btn--danger, .gog-btn--warning, .gog-btn--info).gog-btn--ghost {
|
|
332
|
+
--gog-button-variant-bg: transparent;
|
|
333
|
+
--gog-button-variant-color: var(--gog-button-severity-ink);
|
|
334
|
+
--gog-button-variant-border: transparent;
|
|
335
|
+
--gog-button-variant-shadow: none;
|
|
336
|
+
--gog-button-variant-hover-bg: var(--gog-button-severity-wash);
|
|
337
|
+
--gog-button-variant-hover-color: var(--gog-text-color);
|
|
338
|
+
--gog-button-variant-hover-shadow: none;
|
|
339
|
+
--gog-button-variant-toggled-shadow: inset 0 0 0 var(--gog-button-toggled-ring-width)
|
|
340
|
+
var(--gog-button-severity-ink);
|
|
341
|
+
--gog-button-variant-press-bg: var(--gog-button-severity-fill-press);
|
|
342
|
+
--gog-button-variant-press-color: var(--gog-button-severity-on-fill);
|
|
343
|
+
--gog-button-variant-spinner-color: var(--gog-button-severity-ink);
|
|
344
|
+
}
|
|
345
|
+
|
|
346
|
+
/* === Sizes === */
|
|
347
|
+
.gog-btn--xsm {
|
|
348
|
+
--gog-button-size-padding: var(--gog-button-xsm-padding);
|
|
349
|
+
--gog-button-size-font-size: var(--gog-button-xsm-font-size);
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
.gog-btn--sm {
|
|
353
|
+
--gog-button-size-padding: var(--gog-button-sm-padding);
|
|
354
|
+
--gog-button-size-font-size: var(--gog-button-sm-font-size);
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
.gog-btn--md {
|
|
358
|
+
--gog-button-size-padding: var(--gog-button-md-padding);
|
|
359
|
+
--gog-button-size-font-size: var(--gog-button-md-font-size);
|
|
360
|
+
}
|
|
361
|
+
|
|
362
|
+
.gog-btn--lg {
|
|
363
|
+
--gog-button-size-padding: var(--gog-button-lg-padding);
|
|
364
|
+
--gog-button-size-font-size: var(--gog-button-lg-font-size);
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
.gog-btn--slg {
|
|
368
|
+
--gog-button-size-padding: var(--gog-button-slg-padding);
|
|
369
|
+
--gog-button-size-font-size: var(--gog-button-slg-font-size);
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
.gog-btn--loading {
|
|
373
|
+
position: relative;
|
|
374
|
+
pointer-events: none;
|
|
375
|
+
/* Loading buttons stay natively focusable (aria-disabled + aria-busy instead of
|
|
376
|
+
`disabled`) so keyboard users don't lose focus mid-action. `:disabled` styling
|
|
377
|
+
below therefore no longer covers this state, so the dim is applied explicitly. */
|
|
378
|
+
opacity: var(--gog-button-loading-opacity);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
.gog-btn__content--hidden {
|
|
382
|
+
visibility: hidden;
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
/* absolute center so the spinner is always in the middle of the button */
|
|
386
|
+
.gog-btn__spinner {
|
|
387
|
+
position: absolute;
|
|
388
|
+
top: 50%;
|
|
389
|
+
left: 50%;
|
|
390
|
+
transform: translate(-50%, -50%);
|
|
391
|
+
max-width: var(--gog-button-spinner-max-size);
|
|
392
|
+
max-height: var(--gog-button-spinner-max-size);
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/*
|
|
396
|
+
* `gog-button` gets its full width through `:host`, having a wrapper element to work with.
|
|
397
|
+
* `[gogButton]` has none — the element *is* the button — so it needs a class of its own.
|
|
398
|
+
*/
|
|
399
|
+
.gog-btn--full-width {
|
|
400
|
+
width: 100%;
|
|
401
|
+
}
|