@stackoverflow/stacks 1.0.0 → 1.2.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.
Files changed (74) hide show
  1. package/README.md +47 -47
  2. package/dist/controllers/s-popover.d.ts +11 -2
  3. package/dist/css/stacks.css +257 -8
  4. package/dist/css/stacks.min.css +1 -1
  5. package/dist/js/stacks.js +18 -2
  6. package/dist/js/stacks.min.js +1 -1
  7. package/lib/css/atomic/borders.less +378 -378
  8. package/lib/css/atomic/colors.less +209 -209
  9. package/lib/css/atomic/flex.less +375 -375
  10. package/lib/css/atomic/grid.less +174 -174
  11. package/lib/css/atomic/misc.less +343 -343
  12. package/lib/css/atomic/spacing.less +342 -314
  13. package/lib/css/atomic/typography.less +273 -273
  14. package/lib/css/atomic/width-height.less +194 -194
  15. package/lib/css/base/body.less +44 -44
  16. package/lib/css/base/configuration-static.less +61 -61
  17. package/lib/css/base/icons.less +20 -20
  18. package/lib/css/base/internals.less +220 -220
  19. package/lib/css/base/reset-meyer.less +64 -64
  20. package/lib/css/base/reset-normalize.less +449 -449
  21. package/lib/css/base/reset.less +20 -20
  22. package/lib/css/components/activity-indicator.less +44 -45
  23. package/lib/css/components/avatars.less +189 -189
  24. package/lib/css/components/badges.less +254 -209
  25. package/lib/css/components/banners.less +80 -80
  26. package/lib/css/components/blank-states.less +26 -26
  27. package/lib/css/components/breadcrumbs.less +44 -44
  28. package/lib/css/components/button-groups.less +104 -104
  29. package/lib/css/components/buttons.less +665 -665
  30. package/lib/css/components/cards.less +44 -44
  31. package/lib/css/components/code-blocks.less +130 -130
  32. package/lib/css/components/collapsible.less +104 -104
  33. package/lib/css/components/inputs.less +728 -728
  34. package/lib/css/components/link-previews.less +136 -136
  35. package/lib/css/components/links.less +218 -218
  36. package/lib/css/components/menu.less +47 -47
  37. package/lib/css/components/modals.less +133 -133
  38. package/lib/css/components/navigation.less +146 -146
  39. package/lib/css/components/notices.less +233 -233
  40. package/lib/css/components/page-titles.less +60 -60
  41. package/lib/css/components/pagination.less +55 -55
  42. package/lib/css/components/popovers.less +197 -197
  43. package/lib/css/components/post-summary.less +436 -425
  44. package/lib/css/components/progress-bars.less +330 -330
  45. package/lib/css/components/prose.less +503 -503
  46. package/lib/css/components/spinner.less +107 -107
  47. package/lib/css/components/tables.less +341 -341
  48. package/lib/css/components/tags.less +236 -236
  49. package/lib/css/components/toggle-switches.less +144 -144
  50. package/lib/css/components/topbar.less +427 -427
  51. package/lib/css/components/uploader.less +210 -210
  52. package/lib/css/components/user-cards.less +169 -169
  53. package/lib/css/components/widget-dynamic.less +33 -33
  54. package/lib/css/components/widget-static.less +273 -273
  55. package/lib/css/exports/constants-colors.less +1092 -1092
  56. package/lib/css/exports/constants-helpers.less +108 -108
  57. package/lib/css/exports/constants-type.less +153 -153
  58. package/lib/css/exports/exports.less +15 -15
  59. package/lib/css/exports/mixins.less +237 -237
  60. package/lib/css/stacks-dynamic.less +35 -35
  61. package/lib/css/stacks-static.less +86 -86
  62. package/lib/css/stacks.less +13 -13
  63. package/lib/ts/controllers/index.ts +7 -7
  64. package/lib/ts/controllers/s-expandable-control.ts +188 -188
  65. package/lib/ts/controllers/s-modal.ts +321 -321
  66. package/lib/ts/controllers/s-navigation-tablist.ts +117 -117
  67. package/lib/ts/controllers/s-popover.ts +567 -547
  68. package/lib/ts/controllers/s-table.ts +220 -220
  69. package/lib/ts/controllers/s-tooltip.ts +246 -246
  70. package/lib/ts/controllers/s-uploader.ts +172 -172
  71. package/lib/ts/index.ts +20 -20
  72. package/lib/ts/stacks.ts +88 -88
  73. package/lib/tsconfig.json +13 -13
  74. package/package.json +86 -87
@@ -1,427 +1,427 @@
1
- //
2
- // STACK OVERFLOW
3
- // TOPBAR
4
- //
5
- // This CSS comes from Stacks, our CSS & Pattern library for rapidly building
6
- // Stack Overflow. For documentation of all these classes and how to contribute,
7
- // visit https://stackoverflow.design/
8
- //
9
- // ============================================================================
10
- // $ BASE STYLE
11
- // ----------------------------------------------------------------------------
12
- .s-topbar {
13
- min-width: auto;
14
- box-shadow: var(--bs-sm);
15
- width: 100%;
16
- z-index: var(--zi-navigation-fixed);
17
- background-color: var(--theme-topbar-background-color);
18
- height: var(--theme-topbar-height);
19
- display: flex;
20
- border-top: var(--theme-topbar-accent-border);
21
- position: relative;
22
- align-items: center;
23
-
24
- // Redefine the variables for extra contrast in high-contrast mode
25
- .highcontrast-mode({
26
- // Search input
27
- --theme-topbar-search-color: var(--theme-topbar-item-color);
28
- --theme-topbar-search-background: var(--theme-topbar-background-color);
29
- --theme-topbar-search-placeholder: var(--theme-topbar-item-color);
30
- --theme-topbar-search-border: var(--theme-topbar-item-color);
31
- --theme-topbar-search-border-focus: var(--theme-topbar-item-color);
32
-
33
- // Search switcher
34
- --theme-topbar-select-color: var(--theme-topbar-item-color);
35
- --theme-topbar-select-background: var(--theme-topbar-background-color);
36
-
37
- // Topbar items
38
- --theme-topbar-item-color: var(--black-800);
39
- --theme-topbar-item-color-hover: var(--black-900);
40
- --theme-topbar-item-background-hover: var(--black-200);
41
- --theme-topbar-item-color-current: var(--black);
42
- });
43
-
44
- .highcontrast-mode({ border-bottom: 1px solid currentColor; });
45
-
46
- // Wraps the content so the topbar stretches 100% w/ content at some value below that
47
- .s-topbar--container {
48
- width: var(--s-full); // wmx12; Consumers should use atomic classes to override this
49
- max-width: 100%;
50
- height: 100%;
51
- display: flex;
52
- margin: 0 auto;
53
- align-items: center;
54
- }
55
-
56
- .s-topbar--logo {
57
- padding: 0 var(--su8);
58
- height: 100%;
59
- display: flex;
60
- align-items: center;
61
- background-color: transparent;
62
- }
63
-
64
- a.s-topbar--logo:hover {
65
- background-color: var(--theme-topbar-item-background-hover);
66
- }
67
-
68
- a.s-topbar--logo.is-selected {
69
- background-color: var(--theme-topbar-item-background-hover);
70
- }
71
-
72
- .s-topbar--menu-btn {
73
- display: flex;
74
- height: 100%;
75
- padding: 0 var(--su16);
76
- flex-shrink: 0;
77
- align-items: center;
78
- justify-content: center;
79
-
80
- // Build a hamburger icon manually using spans instead of using `@Svg` helper so
81
- // we can more easily animate its content and transform the hamburger into an x
82
- span {
83
- &,
84
- &:before,
85
- &:after {
86
- width: var(--su-static16);
87
- height: var(--su-static2);
88
- background-color: var(--theme-topbar-item-color);
89
- position: relative;
90
- }
91
-
92
- &:before,
93
- &:after {
94
- position: absolute;
95
- content: '';
96
- left: 0;
97
- top: -5px;
98
- transition: top, transform;
99
- transition-duration: 0.1s;
100
- transition-timing-function: ease-in-out;
101
- }
102
-
103
- &:after {
104
- top: 5px;
105
- }
106
- }
107
-
108
- // Transforming hamburger into x
109
- &.is-selected {
110
- color: var(--theme-topbar-item-color-current);
111
- background-color: var(--theme-topbar-item-background-current);
112
-
113
- span {
114
- background-color: transparent;
115
-
116
- &:before,
117
- &:after {
118
- top: 0;
119
- transform: rotate(-45deg);
120
- }
121
-
122
- &:after { transform: rotate(45deg); }
123
- }
124
- }
125
-
126
- &:hover {
127
- color: var(--theme-topbar-item-color-hover);
128
- background-color: var(--theme-topbar-item-background-hover);
129
- }
130
- }
131
-
132
- .s-navigation {
133
- .s-navigation--item:not(.is-selected) {
134
- color: var(--theme-topbar-item-color);
135
- }
136
-
137
- .s-navigation--item:not(.is-selected):hover {
138
- color: var(--theme-topbar-item-color-hover);
139
- background-color: var(--theme-topbar-item-background-hover);
140
- }
141
- }
142
- }
143
-
144
- // ===========================================================================
145
- // $ LIGHT
146
- // ---------------------------------------------------------------------------
147
- .s-topbar__light {
148
- // TODO this only works 100% perfectly in light mode, due to child elements inheriting current theme colors
149
- // TODO extend forced light mode instead of overriding
150
-
151
- --theme-topbar-background-color: @black-025;
152
-
153
- // Search input
154
- --theme-topbar-search-color: @black-700;
155
- --theme-topbar-search-background: @white;
156
- --theme-topbar-search-placeholder: @black-200;
157
- --theme-topbar-search-border: @black-200;
158
- --theme-topbar-search-border-focus: @blue-300;
159
- --theme-topbar-search-shadow-focus: 0 0 0 var(--su-static4) var(--focus-ring);
160
-
161
- // Search switcher
162
- --theme-topbar-select-color: @black-700;
163
- --theme-topbar-select-background: @black-050;
164
-
165
- // Items
166
- --theme-topbar-item-color: @black-600;
167
- --theme-topbar-item-color-hover: @black-800;
168
- --theme-topbar-item-background-hover: @black-075;
169
- --theme-topbar-item-color-current: @black;
170
- --theme-topbar-item-border-current: var(--theme-primary-color);
171
-
172
- // TODO HACK remove everything below once light/dark topbars are inheriting forced themes correctly
173
- // redefine the variables for extra contrast in high-contrast mode
174
- .highcontrast-mode({
175
- // Topbar items
176
- --theme-topbar-item-color: @black-800;
177
- --theme-topbar-item-color-hover: @black-900;
178
- --theme-topbar-item-background-hover: @black-075;
179
- --theme-topbar-item-color-current: @black;
180
- });
181
-
182
- --scrollbar: hsla(0, 0%, 0%, 0.2);
183
- }
184
-
185
- // ===========================================================================
186
- // $ DARK
187
- // ---------------------------------------------------------------------------
188
- .s-topbar__dark {
189
- // TODO this only works 100% perfectly in dark mode, due to child elements inheriting current theme colors
190
- // TODO extend forced dark mode instead of overriding
191
-
192
- @topbar-actual-background: @black-800;
193
- // TODO
194
- #calc-topbar-lightness-increase() when (lightness(@topbar-actual-background) < 15%) {
195
- @topbar-search-lightness-increase: 20%;
196
- }
197
- #calc-topbar-lightness-increase() when not (lightness(@topbar-actual-background) < 15%) {
198
- @topbar-search-lightness-increase: 10%;
199
- }
200
- #calc-topbar-lightness-increase();
201
-
202
- --theme-topbar-background-color: @topbar-actual-background;
203
-
204
- // Search input
205
- --theme-topbar-search-color: lighten(@topbar-actual-background, 80% + @topbar-search-lightness-increase);
206
- --theme-topbar-search-background: lighten(@topbar-actual-background, @topbar-search-lightness-increase);
207
- --theme-topbar-search-placeholder: lighten(@topbar-actual-background, 60% + @topbar-search-lightness-increase);
208
- --theme-topbar-search-border: lighten(@topbar-actual-background, 20% + @topbar-search-lightness-increase);
209
- --theme-topbar-search-border-focus: lighten(@topbar-actual-background, 45% + @topbar-search-lightness-increase);
210
- --theme-topbar-search-shadow-focus: 0 0 0 var(--su-static4) fade(@white, 30%);
211
-
212
- // Search switcher
213
- --theme-topbar-select-color: lighten(@topbar-actual-background, 60% + @topbar-search-lightness-increase);
214
- --theme-topbar-select-background: lighten(@topbar-actual-background, 10% + @topbar-search-lightness-increase);
215
-
216
- // Items
217
- --theme-topbar-item-color: @black-100;
218
- --theme-topbar-item-color-hover: @white;
219
- --theme-topbar-item-background-hover: @black-700;
220
- --theme-topbar-item-color-current: @white;
221
- --theme-topbar-item-border-current: var(--theme-primary-color);
222
-
223
- // Themed border accent
224
- --theme-topbar-accent-border: none;
225
-
226
- // TODO HACK remove everything below once light/dark topbars are inheriting forced themes correctly
227
- // redefine the variables for extra contrast in high-contrast mode
228
- .highcontrast-mode({
229
- // Topbar items
230
- --theme-topbar-item-color: @white;
231
- --theme-topbar-item-color-hover: @white;
232
- --theme-topbar-item-background-hover: @black-700;
233
- --theme-topbar-item-color-current: @white;
234
-
235
- .s-badge {
236
- border-color: currentColor;
237
- }
238
- });
239
-
240
- --scrollbar: hsla(0, 0%, 100%, 0.2);
241
- }
242
-
243
- // ===========================================================================
244
- // $ CONTENT & CTAS
245
- // ---------------------------------------------------------------------------
246
- .s-topbar .s-topbar--content {
247
- display: flex;
248
- height: 100%;
249
- .list-reset;
250
-
251
- & > li {
252
- display: inline-flex;
253
- }
254
-
255
- overflow-x: auto; // Allow this content to scroll if it gets too long
256
- @scrollbar-styles(); // Style the scrollbars
257
- margin-left: auto; // Push this section as far to the right as possible
258
-
259
- .s-topbar--item:not(.s-topbar--item__unset) {
260
- color: var(--theme-topbar-item-color);
261
- display: inline-flex;
262
- align-items: center;
263
- padding: 0 calc(var(--su12) - var(--su2));
264
- text-decoration: none;
265
- white-space: nowrap;
266
- position: relative;
267
-
268
- &:hover,
269
- &:focus,
270
- &.is-selected,
271
- &.is-selected:hover,
272
- &.is-selected:focus {
273
- color: var(--theme-topbar-item-color-hover);
274
- background-color: var(--theme-topbar-item-background-hover);
275
- text-decoration: none;
276
- outline: none;
277
-
278
- .s-activity-indicator {
279
- top: calc(50% - 18px);
280
- box-shadow: 0 0 0 var(--su-static2) var(--theme-topbar-item-background-hover);
281
- }
282
- }
283
-
284
- .svg-icon {
285
- vertical-align: text-top;
286
- }
287
-
288
- .s-activity-indicator {
289
- position: absolute;
290
- top: calc(50% - 14px);
291
- right: 2px;
292
- transition: top var(--te-smooth) 0.15s;
293
- box-shadow: 0 0 0 var(--su-static2) var(--theme-topbar-background-color);
294
- }
295
- }
296
-
297
- // provide only layout styling for unset items
298
- .s-topbar--item__unset {
299
- align-self: center;
300
- padding-top: var(--su8);
301
- padding-bottom: var(--su8);
302
- }
303
- }
304
-
305
- // ===========================================================================
306
- // $ NOTICE
307
- // ---------------------------------------------------------------------------
308
- .s-topbar--notice {
309
- &:extend(.s-badge);
310
-
311
- text-transform: uppercase;
312
- font-size: var(--fs-fine);
313
- font-weight: 700;
314
- margin-left: var(--su8);
315
- margin-right: var(--su8);
316
- flex-shrink: 0;
317
-
318
- .badge-styles(transparent, transparent, var(--theme-topbar-item-color));
319
-
320
- &:hover,
321
- &:focus {
322
- .badge-styles(var(--theme-topbar-item-background-hover), var(--theme-topbar-item-background-hover), var(--theme-topbar-item-color-hover));
323
- }
324
-
325
- &.is-unread {
326
- .badge-styles(var(--theme-primary-color), var(--theme-primary-color), var(--white));
327
-
328
- &:hover,
329
- &:focus {
330
- .badge-styles(var(--theme-primary-600), var(--theme-primary-600), var(--white));
331
- }
332
- }
333
- }
334
-
335
- // ===========================================================================
336
- // $ SEARCHBAR
337
- // ---------------------------------------------------------------------------
338
- .s-topbar .s-topbar--searchbar {
339
- @inputLineHeights: var(--lh-sm); // Ensure the line heights between the elements match up
340
- padding: 0 var(--su8);
341
- display: flex;
342
- align-items: center;
343
- flex-shrink: 10000; // Force the searchbar to shrink as much as possible if there's no extra space
344
- flex-grow: 1; //...but allow it to grow if there *is* extra space
345
-
346
- .s-topbar--searchbar--input-group {
347
- position: relative;
348
- flex-grow: 1;
349
-
350
- .s-input {
351
- border-color: var(--theme-topbar-search-border);
352
- background-color: var(--theme-topbar-search-background);
353
- box-shadow: var(--theme-topbar-search-shadow);
354
- color: var(--theme-topbar-search-color);
355
- display: block;
356
- line-height: @inputLineHeights;
357
-
358
- &:focus {
359
- border-color: var(--theme-topbar-search-border-focus);
360
- box-shadow: var(--theme-topbar-search-shadow-focus);
361
- }
362
-
363
- &::placeholder {
364
- color: var(--theme-topbar-search-placeholder);
365
- font-style: normal;
366
- }
367
- }
368
-
369
- .s-input-icon {
370
- color: var(--theme-topbar-search-placeholder);
371
- }
372
- }
373
-
374
- .s-select {
375
- .wmx2;
376
-
377
- align-self: stretch;
378
- margin-right: -1px;
379
- color: var(--theme-topbar-select-color);
380
-
381
- &:before,
382
- &:after {
383
- z-index: var(--zi-active); // Make sure our focus ring is above the search input
384
- }
385
- }
386
-
387
- .s-select > select {
388
- .brr0;
389
- height: 100%;
390
- line-height: @inputLineHeights;
391
-
392
- border-color: var(--theme-topbar-search-border);
393
- background-color: var(--theme-topbar-select-background);
394
- color: var(--theme-topbar-select-color);
395
-
396
- &:focus {
397
- border-color: var(--theme-topbar-search-border-focus);
398
- box-shadow: var(--theme-topbar-search-shadow-focus);
399
- z-index: var(--zi-selected);
400
- }
401
- }
402
-
403
- // Drop the left border of the search input when it is next to the select
404
- .s-select + .s-topbar--searchbar--input-group > .s-input {
405
- .blr0;
406
- }
407
-
408
- #stacks-internals #screen-sm({
409
- display: none;
410
- position: absolute;
411
- left: 0;
412
- right: 0;
413
- top: 100%;
414
- max-width: 100%;
415
- padding: var(--su8) var(--su12);
416
- background: var(--theme-topbar-item-background-hover);
417
-
418
- &.s-topbar--searchbar__open {
419
- display: flex;
420
- max-width: none;
421
- }
422
-
423
- .s-select {
424
- .w25;
425
- }
426
- });
427
- }
1
+ //
2
+ // STACK OVERFLOW
3
+ // TOPBAR
4
+ //
5
+ // This CSS comes from Stacks, our CSS & Pattern library for rapidly building
6
+ // Stack Overflow. For documentation of all these classes and how to contribute,
7
+ // visit https://stackoverflow.design/
8
+ //
9
+ // ============================================================================
10
+ // $ BASE STYLE
11
+ // ----------------------------------------------------------------------------
12
+ .s-topbar {
13
+ min-width: auto;
14
+ box-shadow: var(--bs-sm);
15
+ width: 100%;
16
+ z-index: var(--zi-navigation-fixed);
17
+ background-color: var(--theme-topbar-background-color);
18
+ height: var(--theme-topbar-height);
19
+ display: flex;
20
+ border-top: var(--theme-topbar-accent-border);
21
+ position: relative;
22
+ align-items: center;
23
+
24
+ // Redefine the variables for extra contrast in high-contrast mode
25
+ .highcontrast-mode({
26
+ // Search input
27
+ --theme-topbar-search-color: var(--theme-topbar-item-color);
28
+ --theme-topbar-search-background: var(--theme-topbar-background-color);
29
+ --theme-topbar-search-placeholder: var(--theme-topbar-item-color);
30
+ --theme-topbar-search-border: var(--theme-topbar-item-color);
31
+ --theme-topbar-search-border-focus: var(--theme-topbar-item-color);
32
+
33
+ // Search switcher
34
+ --theme-topbar-select-color: var(--theme-topbar-item-color);
35
+ --theme-topbar-select-background: var(--theme-topbar-background-color);
36
+
37
+ // Topbar items
38
+ --theme-topbar-item-color: var(--black-800);
39
+ --theme-topbar-item-color-hover: var(--black-900);
40
+ --theme-topbar-item-background-hover: var(--black-200);
41
+ --theme-topbar-item-color-current: var(--black);
42
+ });
43
+
44
+ .highcontrast-mode({ border-bottom: 1px solid currentColor; });
45
+
46
+ // Wraps the content so the topbar stretches 100% w/ content at some value below that
47
+ .s-topbar--container {
48
+ width: var(--s-full); // wmx12; Consumers should use atomic classes to override this
49
+ max-width: 100%;
50
+ height: 100%;
51
+ display: flex;
52
+ margin: 0 auto;
53
+ align-items: center;
54
+ }
55
+
56
+ .s-topbar--logo {
57
+ padding: 0 var(--su8);
58
+ height: 100%;
59
+ display: flex;
60
+ align-items: center;
61
+ background-color: transparent;
62
+ }
63
+
64
+ a.s-topbar--logo:hover {
65
+ background-color: var(--theme-topbar-item-background-hover);
66
+ }
67
+
68
+ a.s-topbar--logo.is-selected {
69
+ background-color: var(--theme-topbar-item-background-hover);
70
+ }
71
+
72
+ .s-topbar--menu-btn {
73
+ display: flex;
74
+ height: 100%;
75
+ padding: 0 var(--su16);
76
+ flex-shrink: 0;
77
+ align-items: center;
78
+ justify-content: center;
79
+
80
+ // Build a hamburger icon manually using spans instead of using `@Svg` helper so
81
+ // we can more easily animate its content and transform the hamburger into an x
82
+ span {
83
+ &,
84
+ &:before,
85
+ &:after {
86
+ width: var(--su-static16);
87
+ height: var(--su-static2);
88
+ background-color: var(--theme-topbar-item-color);
89
+ position: relative;
90
+ }
91
+
92
+ &:before,
93
+ &:after {
94
+ position: absolute;
95
+ content: '';
96
+ left: 0;
97
+ top: -5px;
98
+ transition: top, transform;
99
+ transition-duration: 0.1s;
100
+ transition-timing-function: ease-in-out;
101
+ }
102
+
103
+ &:after {
104
+ top: 5px;
105
+ }
106
+ }
107
+
108
+ // Transforming hamburger into x
109
+ &.is-selected {
110
+ color: var(--theme-topbar-item-color-current);
111
+ background-color: var(--theme-topbar-item-background-current);
112
+
113
+ span {
114
+ background-color: transparent;
115
+
116
+ &:before,
117
+ &:after {
118
+ top: 0;
119
+ transform: rotate(-45deg);
120
+ }
121
+
122
+ &:after { transform: rotate(45deg); }
123
+ }
124
+ }
125
+
126
+ &:hover {
127
+ color: var(--theme-topbar-item-color-hover);
128
+ background-color: var(--theme-topbar-item-background-hover);
129
+ }
130
+ }
131
+
132
+ .s-navigation {
133
+ .s-navigation--item:not(.is-selected) {
134
+ color: var(--theme-topbar-item-color);
135
+ }
136
+
137
+ .s-navigation--item:not(.is-selected):hover {
138
+ color: var(--theme-topbar-item-color-hover);
139
+ background-color: var(--theme-topbar-item-background-hover);
140
+ }
141
+ }
142
+ }
143
+
144
+ // ===========================================================================
145
+ // $ LIGHT
146
+ // ---------------------------------------------------------------------------
147
+ .s-topbar__light {
148
+ // TODO this only works 100% perfectly in light mode, due to child elements inheriting current theme colors
149
+ // TODO extend forced light mode instead of overriding
150
+
151
+ --theme-topbar-background-color: @black-025;
152
+
153
+ // Search input
154
+ --theme-topbar-search-color: @black-700;
155
+ --theme-topbar-search-background: @white;
156
+ --theme-topbar-search-placeholder: @black-200;
157
+ --theme-topbar-search-border: @black-200;
158
+ --theme-topbar-search-border-focus: @blue-300;
159
+ --theme-topbar-search-shadow-focus: 0 0 0 var(--su-static4) var(--focus-ring);
160
+
161
+ // Search switcher
162
+ --theme-topbar-select-color: @black-700;
163
+ --theme-topbar-select-background: @black-050;
164
+
165
+ // Items
166
+ --theme-topbar-item-color: @black-600;
167
+ --theme-topbar-item-color-hover: @black-800;
168
+ --theme-topbar-item-background-hover: @black-075;
169
+ --theme-topbar-item-color-current: @black;
170
+ --theme-topbar-item-border-current: var(--theme-primary-color);
171
+
172
+ // TODO HACK remove everything below once light/dark topbars are inheriting forced themes correctly
173
+ // redefine the variables for extra contrast in high-contrast mode
174
+ .highcontrast-mode({
175
+ // Topbar items
176
+ --theme-topbar-item-color: @black-800;
177
+ --theme-topbar-item-color-hover: @black-900;
178
+ --theme-topbar-item-background-hover: @black-075;
179
+ --theme-topbar-item-color-current: @black;
180
+ });
181
+
182
+ --scrollbar: hsla(0, 0%, 0%, 0.2);
183
+ }
184
+
185
+ // ===========================================================================
186
+ // $ DARK
187
+ // ---------------------------------------------------------------------------
188
+ .s-topbar__dark {
189
+ // TODO this only works 100% perfectly in dark mode, due to child elements inheriting current theme colors
190
+ // TODO extend forced dark mode instead of overriding
191
+
192
+ @topbar-actual-background: @black-800;
193
+ // TODO
194
+ #calc-topbar-lightness-increase() when (lightness(@topbar-actual-background) < 15%) {
195
+ @topbar-search-lightness-increase: 20%;
196
+ }
197
+ #calc-topbar-lightness-increase() when not (lightness(@topbar-actual-background) < 15%) {
198
+ @topbar-search-lightness-increase: 10%;
199
+ }
200
+ #calc-topbar-lightness-increase();
201
+
202
+ --theme-topbar-background-color: @topbar-actual-background;
203
+
204
+ // Search input
205
+ --theme-topbar-search-color: lighten(@topbar-actual-background, 80% + @topbar-search-lightness-increase);
206
+ --theme-topbar-search-background: lighten(@topbar-actual-background, @topbar-search-lightness-increase);
207
+ --theme-topbar-search-placeholder: lighten(@topbar-actual-background, 60% + @topbar-search-lightness-increase);
208
+ --theme-topbar-search-border: lighten(@topbar-actual-background, 20% + @topbar-search-lightness-increase);
209
+ --theme-topbar-search-border-focus: lighten(@topbar-actual-background, 45% + @topbar-search-lightness-increase);
210
+ --theme-topbar-search-shadow-focus: 0 0 0 var(--su-static4) fade(@white, 30%);
211
+
212
+ // Search switcher
213
+ --theme-topbar-select-color: lighten(@topbar-actual-background, 60% + @topbar-search-lightness-increase);
214
+ --theme-topbar-select-background: lighten(@topbar-actual-background, 10% + @topbar-search-lightness-increase);
215
+
216
+ // Items
217
+ --theme-topbar-item-color: @black-100;
218
+ --theme-topbar-item-color-hover: @white;
219
+ --theme-topbar-item-background-hover: @black-700;
220
+ --theme-topbar-item-color-current: @white;
221
+ --theme-topbar-item-border-current: var(--theme-primary-color);
222
+
223
+ // Themed border accent
224
+ --theme-topbar-accent-border: none;
225
+
226
+ // TODO HACK remove everything below once light/dark topbars are inheriting forced themes correctly
227
+ // redefine the variables for extra contrast in high-contrast mode
228
+ .highcontrast-mode({
229
+ // Topbar items
230
+ --theme-topbar-item-color: @white;
231
+ --theme-topbar-item-color-hover: @white;
232
+ --theme-topbar-item-background-hover: @black-700;
233
+ --theme-topbar-item-color-current: @white;
234
+
235
+ .s-badge {
236
+ border-color: currentColor;
237
+ }
238
+ });
239
+
240
+ --scrollbar: hsla(0, 0%, 100%, 0.2);
241
+ }
242
+
243
+ // ===========================================================================
244
+ // $ CONTENT & CTAS
245
+ // ---------------------------------------------------------------------------
246
+ .s-topbar .s-topbar--content {
247
+ display: flex;
248
+ height: 100%;
249
+ .list-reset;
250
+
251
+ & > li {
252
+ display: inline-flex;
253
+ }
254
+
255
+ overflow-x: auto; // Allow this content to scroll if it gets too long
256
+ @scrollbar-styles(); // Style the scrollbars
257
+ margin-left: auto; // Push this section as far to the right as possible
258
+
259
+ .s-topbar--item:not(.s-topbar--item__unset) {
260
+ color: var(--theme-topbar-item-color);
261
+ display: inline-flex;
262
+ align-items: center;
263
+ padding: 0 calc(var(--su12) - var(--su2));
264
+ text-decoration: none;
265
+ white-space: nowrap;
266
+ position: relative;
267
+
268
+ &:hover,
269
+ &:focus,
270
+ &.is-selected,
271
+ &.is-selected:hover,
272
+ &.is-selected:focus {
273
+ color: var(--theme-topbar-item-color-hover);
274
+ background-color: var(--theme-topbar-item-background-hover);
275
+ text-decoration: none;
276
+ outline: none;
277
+
278
+ .s-activity-indicator {
279
+ top: calc(50% - 18px);
280
+ box-shadow: 0 0 0 var(--su-static2) var(--theme-topbar-item-background-hover);
281
+ }
282
+ }
283
+
284
+ .svg-icon {
285
+ vertical-align: text-top;
286
+ }
287
+
288
+ .s-activity-indicator {
289
+ position: absolute;
290
+ top: calc(50% - 14px);
291
+ right: 2px;
292
+ transition: top var(--te-smooth) 0.15s;
293
+ box-shadow: 0 0 0 var(--su-static2) var(--theme-topbar-background-color);
294
+ }
295
+ }
296
+
297
+ // provide only layout styling for unset items
298
+ .s-topbar--item__unset {
299
+ align-self: center;
300
+ padding-top: var(--su8);
301
+ padding-bottom: var(--su8);
302
+ }
303
+ }
304
+
305
+ // ===========================================================================
306
+ // $ NOTICE
307
+ // ---------------------------------------------------------------------------
308
+ .s-topbar--notice {
309
+ &:extend(.s-badge);
310
+
311
+ text-transform: uppercase;
312
+ font-size: var(--fs-fine);
313
+ font-weight: 700;
314
+ margin-left: var(--su8);
315
+ margin-right: var(--su8);
316
+ flex-shrink: 0;
317
+
318
+ .badge-styles(transparent, transparent, var(--theme-topbar-item-color));
319
+
320
+ &:hover,
321
+ &:focus {
322
+ .badge-styles(var(--theme-topbar-item-background-hover), var(--theme-topbar-item-background-hover), var(--theme-topbar-item-color-hover));
323
+ }
324
+
325
+ &.is-unread {
326
+ .badge-styles(var(--theme-primary-color), var(--theme-primary-color), var(--white));
327
+
328
+ &:hover,
329
+ &:focus {
330
+ .badge-styles(var(--theme-primary-600), var(--theme-primary-600), var(--white));
331
+ }
332
+ }
333
+ }
334
+
335
+ // ===========================================================================
336
+ // $ SEARCHBAR
337
+ // ---------------------------------------------------------------------------
338
+ .s-topbar .s-topbar--searchbar {
339
+ @inputLineHeights: var(--lh-sm); // Ensure the line heights between the elements match up
340
+ padding: 0 var(--su8);
341
+ display: flex;
342
+ align-items: center;
343
+ flex-shrink: 10000; // Force the searchbar to shrink as much as possible if there's no extra space
344
+ flex-grow: 1; //...but allow it to grow if there *is* extra space
345
+
346
+ .s-topbar--searchbar--input-group {
347
+ position: relative;
348
+ flex-grow: 1;
349
+
350
+ .s-input {
351
+ border-color: var(--theme-topbar-search-border);
352
+ background-color: var(--theme-topbar-search-background);
353
+ box-shadow: var(--theme-topbar-search-shadow);
354
+ color: var(--theme-topbar-search-color);
355
+ display: block;
356
+ line-height: @inputLineHeights;
357
+
358
+ &:focus {
359
+ border-color: var(--theme-topbar-search-border-focus);
360
+ box-shadow: var(--theme-topbar-search-shadow-focus);
361
+ }
362
+
363
+ &::placeholder {
364
+ color: var(--theme-topbar-search-placeholder);
365
+ font-style: normal;
366
+ }
367
+ }
368
+
369
+ .s-input-icon {
370
+ color: var(--theme-topbar-search-placeholder);
371
+ }
372
+ }
373
+
374
+ .s-select {
375
+ .wmx2;
376
+
377
+ align-self: stretch;
378
+ margin-right: -1px;
379
+ color: var(--theme-topbar-select-color);
380
+
381
+ &:before,
382
+ &:after {
383
+ z-index: var(--zi-active); // Make sure our focus ring is above the search input
384
+ }
385
+ }
386
+
387
+ .s-select > select {
388
+ .brr0;
389
+ height: 100%;
390
+ line-height: @inputLineHeights;
391
+
392
+ border-color: var(--theme-topbar-search-border);
393
+ background-color: var(--theme-topbar-select-background);
394
+ color: var(--theme-topbar-select-color);
395
+
396
+ &:focus {
397
+ border-color: var(--theme-topbar-search-border-focus);
398
+ box-shadow: var(--theme-topbar-search-shadow-focus);
399
+ z-index: var(--zi-selected);
400
+ }
401
+ }
402
+
403
+ // Drop the left border of the search input when it is next to the select
404
+ .s-select + .s-topbar--searchbar--input-group > .s-input {
405
+ .blr0;
406
+ }
407
+
408
+ #stacks-internals #screen-sm({
409
+ display: none;
410
+ position: absolute;
411
+ left: 0;
412
+ right: 0;
413
+ top: 100%;
414
+ max-width: 100%;
415
+ padding: var(--su8) var(--su12);
416
+ background: var(--theme-topbar-item-background-hover);
417
+
418
+ &.s-topbar--searchbar__open {
419
+ display: flex;
420
+ max-width: none;
421
+ }
422
+
423
+ .s-select {
424
+ .w25;
425
+ }
426
+ });
427
+ }