@stackoverflow/stacks 1.9.0 → 1.9.2

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