@stackoverflow/stacks 2.2.0 → 2.3.1

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 (31) hide show
  1. package/dist/css/stacks.css +2719 -1174
  2. package/dist/css/stacks.min.css +1 -1
  3. package/lib/atomic/__snapshots__/spacing.less.test.ts.snap +1928 -0
  4. package/lib/atomic/spacing.less +59 -303
  5. package/lib/atomic/spacing.less.test.ts +12 -0
  6. package/lib/components/block-link/block-link.less +6 -2
  7. package/lib/components/button/button.a11y.test.ts +14 -18
  8. package/lib/components/button/button.less +10 -17
  9. package/lib/components/button/button.test.setup.ts +36 -0
  10. package/lib/components/button/button.visual.test.ts +3 -33
  11. package/lib/components/button-group/button-group.a11y.test.ts +12 -0
  12. package/lib/components/button-group/button-group.less +49 -50
  13. package/lib/components/button-group/button-group.test.setup.ts +77 -0
  14. package/lib/components/button-group/button-group.visual.test.ts +7 -0
  15. package/lib/components/input_textarea/input_textarea.less +3 -1
  16. package/lib/components/notice/notice.a11y.test.ts +1 -1
  17. package/lib/components/notice/notice.less +105 -76
  18. package/lib/components/notice/notice.visual.test.ts +2 -2
  19. package/lib/components/pagination/pagination.less +5 -1
  20. package/lib/components/post-summary/post-summary.a11y.test.ts +25 -0
  21. package/lib/components/post-summary/post-summary.less +2 -1
  22. package/lib/components/post-summary/post-summary.test.setup.ts +435 -0
  23. package/lib/components/post-summary/post-summary.visual.test.ts +17 -0
  24. package/lib/components/select/select.less +5 -1
  25. package/lib/components/topbar/topbar.less +366 -335
  26. package/lib/components/topbar/topbar.visual.test.ts +28 -0
  27. package/lib/components/uploader/uploader.less +5 -1
  28. package/lib/exports/spacing-mixins.less +67 -0
  29. package/lib/tsconfig.build.json +1 -1
  30. package/lib/tsconfig.json +3 -3
  31. package/package.json +15 -15
@@ -1,23 +1,69 @@
1
- .topbar-notice-styles(@border: transparent, @background: transparent, @color: inherit) {
2
- border-color: @border;
3
- background-color: @background;
4
- color: @color;
5
- }
6
-
7
1
  .s-topbar {
8
- min-width: auto;
9
- width: 100%;
10
- z-index: var(--zi-navigation-fixed);
11
- background-color: var(--theme-topbar-background-color, var(--white));
12
- height: var(--theme-topbar-height, calc(var(--su-static48) + var(--su-static8)));
13
- display: flex;
14
- border-top: var(--theme-topbar-accent-border, 3px solid var(--theme-primary));
15
- border-bottom: var(--theme-topbar-bottom-border, 1px solid var(--black-225));
16
- position: relative;
17
- align-items: center;
2
+ // CHILD COMPONENT CUSTOM PROPERTIES
3
+ // Item
4
+ --_tb-item-bg: unset;
5
+ --_tb-item-fc: var(--theme-topbar-item-color, var(--black-400));
6
+ // Item s-activity-indicator
7
+ --_tb-item-ai-bs: 0 0 0 var(--su-static2) var(--theme-topbar-background-color, var(--white));
8
+ --_tb-item-ai-t: calc(50% - calc(var(--su12) + var(--su2))); // 50% - 14px;
9
+ // Logo
10
+ --_tb-logo-bg: transparent;
11
+ // Menu btn
12
+ --_tb-menu-btn-bg: unset;
13
+ --_tb-menu-btn-bg-hover: unset;
14
+ --_tb-menu-btn-fc-hover: unset;
15
+ --_tb-menu-btn-span-bg: var(--theme-topbar-item-color, var(--black-400));
16
+ --_tb-menu-btn-span-fc: unset;
17
+ --_tb-menu-btn-span-after-t: calc(var(--su-static6) - var(--su-static1)); // 5px;
18
+ --_tb-menu-btn-span-after-rotate: 0deg;
19
+ --_tb-menu-btn-span-before-t: calc(var(--su-static1) - var(--su-static6)); // -5px;
20
+ --_tb-menu-btn-span-before-rotate: 0deg;
21
+ // Notice
22
+ --_tb-notice-bg: transparent;
23
+ --_tb-notice-fc: var(--theme-topbar-item-color, var(--black-400));
24
+ --_tb-notice-bg-hover: var(--theme-topbar-item-background-hover, var(--black-200));
25
+ --_tb-notice-fc-hover: var(--theme-topbar-item-color-hover, var(--black-600));
26
+ --_tb-notice-td: none;
27
+ // Searchbar
28
+ --_tb-searchbar-d: flex;
29
+ --_tb-searchbar-p: 0 var(--su8);
30
+ --_tb-searchbar-open-d: unset;
31
+ --_tb-searchbar-open-mxw: 0;
32
+
33
+ // CONTEXTUAL STYLES
34
+ .dark-mode({
35
+ &.s-topbar__light {
36
+ --focus-theme: var(--theme-dark-secondary-custom-200, .set-theme-secondary-default()[200]);
37
+ }
38
+ });
18
39
 
19
- // Redefine the variables for extra contrast in high-contrast mode
20
40
  .highcontrast-mode({
41
+ --_tb-notice-td: underline;
42
+
43
+ &.s-topbar__dark {
44
+ --focus-theme: .theme-dark-default()[secondary];
45
+ }
46
+
47
+ &__dark {
48
+ // TODO HACK remove everything below once light/dark topbars are inheriting forced themes correctly
49
+ --theme-topbar-item-color: var(--_white-static);
50
+ --theme-topbar-item-color-hover: var(--_white-static);
51
+ --theme-topbar-item-background-hover: .set-black()[500];
52
+ --theme-topbar-item-color-current: var(--_white-static);
53
+
54
+ .s-badge {
55
+ border-color: currentColor;
56
+ }
57
+ }
58
+
59
+ &__light {
60
+ // TODO HACK remove everything below once light/dark topbars are inheriting forced themes correctly
61
+ --theme-topbar-item-color: .set-black()[600];
62
+ --theme-topbar-item-color-hover: .set-black()[600]; // TODO hover is now identical color to base color
63
+ --theme-topbar-item-background-hover: .set-black()[200];
64
+ --theme-topbar-item-color-current: var(--_black-static);
65
+ }
66
+
21
67
  // Search input
22
68
  --theme-topbar-search-color: var(--theme-topbar-item-color, var(--black-400));
23
69
  --theme-topbar-search-background: var(--theme-topbar-background-color, var(--white));
@@ -33,19 +79,8 @@
33
79
  --theme-topbar-item-color-hover: var(--black-600);
34
80
  --theme-topbar-item-background-hover: var(--black-300);
35
81
  --theme-topbar-item-color-current: var(--black);
36
- });
37
-
38
- .highcontrast-mode({ border-bottom: 1px solid currentColor; });
39
-
40
- // Overrides for focus style colors in forced light variant
41
- &&__light {
42
- --focus-neutral: .set-white()[default]; // forces white for inner focus ring color
43
- }
44
82
 
45
- .dark-mode({
46
- &.s-topbar__light {
47
- --focus-theme: var(--theme-dark-secondary-custom-200, .set-theme-secondary-default()[200]);
48
- }
83
+ border-bottom: var(--su-static1) solid currentColor;
49
84
  });
50
85
 
51
86
  .highcontrast-dark-mode({
@@ -54,189 +89,362 @@
54
89
  }
55
90
  });
56
91
 
57
- // Overrides for focus style colors in forced dark variant
58
- .highcontrast-mode({
59
- &.s-topbar__dark {
60
- --focus-theme: .theme-dark-default()[secondary];
92
+ #stacks-internals #screen-sm({
93
+ & &--searchbar {
94
+ --_tb-searchbar-d: none;
95
+ --_tb-searchbar-p: var(--su8) var(--su12);
96
+ --_tb-searchbar-open-d: flex;
97
+ --_tb-searchbar-open-mxw: none;
98
+
99
+ .s-select {
100
+ width: 25% !important;
101
+ }
102
+
103
+ background: var(--theme-topbar-item-background-hover, var(--black-200));
104
+ left: 0;
105
+ max-width: 100%;
106
+ position: absolute;
107
+ right: 0;
108
+ top: 100%;
61
109
  }
62
110
  });
63
111
 
112
+ // VARIANTS
113
+ // Overrides for focus style colors in forced light variant
114
+ &&__light {
115
+ --focus-neutral: .set-white()[default]; // forces white for inner focus ring color
116
+ }
117
+
64
118
  &&__dark {
65
119
  --focus-neutral: .set-black()[600]; // set to match .s-topbar__dark --theme-topbar-background-color;
66
120
  --focus-theme: var(--theme-dark-secondary-custom-400, .theme-dark-default()[secondary]);
67
121
  }
68
122
 
69
- // focus styles
70
- a&--logo,
71
- & &--content &--item:not(&--item__unset),
72
- &--notice {
123
+ // CHILD ELEMENTS
124
+ & a&--logo {
73
125
  &:focus-visible {
74
126
  .focus-styles(true);
75
127
  }
128
+
129
+ &:hover,
130
+ &.is-selected {
131
+ --_tb-logo-bg: var(--theme-topbar-item-background-hover, var(--black-200));
132
+ }
76
133
  }
77
134
 
78
- // Wraps the content so the topbar stretches 100% w/ content at some value below that
79
- .s-topbar--container {
80
- width: var(--s-full); // wmx12; Consumers should use atomic classes to override this
81
- max-width: 100%;
82
- height: 100%;
135
+ & &--container {
136
+ align-items: center;
83
137
  display: flex;
138
+ height: 100%;
84
139
  margin: 0 auto;
85
- align-items: center;
140
+ max-width: 100%;
141
+ width: var(--s-full);
86
142
  }
87
143
 
88
- .s-topbar--logo {
89
- padding: 0 var(--su8);
90
- height: 100%;
144
+ & &--content {
145
+ & > li {
146
+ display: inline-flex;
147
+ }
148
+
149
+ .list-reset;
150
+ @scrollbar-styles();// TODO remove once all topbars include necessary nav.s-topbar--navigation wrapper elements
91
151
  display: flex;
92
- align-items: center;
93
- background-color: transparent;
94
- border-radius: var(--br-sm);
152
+ height: 100%;
153
+ margin-left: auto;// TODO remove once all topbars include necessary nav.s-topbar--navigation wrapper elements
154
+ overflow-x: auto;// TODO remove once all topbars include necessary nav.s-topbar--navigation wrapper elements
95
155
  }
96
156
 
97
- a.s-topbar--logo {
98
- &:hover {
99
- background-color: var(--theme-topbar-item-background-hover, var(--black-200));
157
+ & &--item {
158
+ &:not(.s-topbar--item__unset) {
159
+ .svg-icon {
160
+ vertical-align: text-top;
161
+ }
162
+
163
+ &:focus-visible {
164
+ .focus-styles(true);
165
+ }
166
+
167
+ &:hover,
168
+ &.is-selected,
169
+ &.is-selected:hover {
170
+ --_tb-item-bg: var(--theme-topbar-item-background-hover, var(--black-200));
171
+ --_tb-item-fc: var(--theme-topbar-item-color-hover, var(--black-600));
172
+
173
+ --_tb-item-ai-bs: 0 0 0 var(--su-static2) var(--theme-topbar-item-background-hover, var(--black-200));
174
+ --_tb-item-ai-t: calc(50% - calc(var(--su16) + var(--su2))); // 50% - 18px
175
+
176
+ outline: none;
177
+ }
178
+
179
+ .s-activity-indicator {
180
+ box-shadow: var(--_tb-item-ai-bs);
181
+ top: var(--_tb-item-ai-t);
182
+
183
+ position: absolute;
184
+ right: var(--su-static2);
185
+ transition: top var(--te-smooth) 0.15s;
186
+ }
187
+
188
+ background-color: var(--_tb-item-bg);
189
+ color: var(--_tb-item-fc);
190
+
191
+ align-items: center;
192
+ border-radius: var(--br-sm);
193
+ display: inline-flex;
194
+ padding: 0 calc(var(--su12) - var(--su2));
195
+ position: relative;
196
+ text-decoration: none;
197
+ white-space: nowrap;
100
198
  }
101
199
 
102
- &.is-selected {
103
- background-color: var(--theme-topbar-item-background-hover, var(--black-200));
200
+ &.s-topbar--item__unset { // provide only layout styling for unset items
201
+ align-self: center;
202
+ padding-top: var(--su8);
203
+ padding-bottom: var(--su8);
104
204
  }
105
205
  }
106
206
 
107
- .s-topbar--menu-btn {
207
+ & &--logo {
208
+ background-color: var(--_tb-logo-bg);
209
+
210
+ align-items: center;
211
+ border-radius: var(--br-sm);
108
212
  display: flex;
109
213
  height: 100%;
110
- padding: 0 var(--su16);
111
- flex-shrink: 0;
112
- align-items: center;
113
- justify-content: center;
214
+ padding: 0 var(--su8);
215
+ }
216
+
217
+ & &--menu-btn {
218
+ &.is-selected { // Transforming hamburger into x
219
+ --_tb-menu-btn-bg: var(--theme-topbar-item-background-current);
220
+ --_tb-menu-btn-bg-hover: var(--theme-topbar-item-background-hover, var(--black-200));
221
+ --_tb-menu-btn-fc: var(--theme-topbar-item-color-current, var(--black));
222
+ --_tb-menu-btn-fc-hover: var(--theme-topbar-item-color-hover, var(--black-400));
223
+ --_tb-menu-btn-span-bg: transparent;
224
+ --_tb-menu-btn-span-after-t: 0;
225
+ --_tb-menu-btn-span-after-rotate: 45deg;
226
+ --_tb-menu-btn-span-before-t: 0;
227
+ --_tb-menu-btn-span-before-rotate: -45deg;
228
+ }
114
229
 
115
- // Build a hamburger icon manually using spans instead of using `@Svg` helper so
116
- // we can more easily animate its content and transform the hamburger into an x
117
- span {
230
+ &:not(.is-selected) {
231
+ span {
232
+ transition: background-color;
233
+ transition-duration: 0.1s;
234
+ }
235
+ }
236
+
237
+ span { // hamburger icon
118
238
  &,
119
- &:before,
120
- &:after {
121
- width: var(--su-static16);
239
+ &:after,
240
+ &:before {
122
241
  height: var(--su-static2);
123
- background-color: var(--theme-topbar-item-color, var(--black-400));
124
242
  position: relative;
243
+ width: var(--su-static16);
125
244
  }
126
245
 
127
- &:before,
128
- &:after {
129
- position: absolute;
246
+ &:after,
247
+ &:before {
248
+ background-color: var(--theme-topbar-item-color, var(--black-400));
130
249
  content: '';
131
250
  left: 0;
132
- top: calc(var(--su-static1) - var(--su-static6)); // -5px
133
- transition: top, transform;
251
+ position: absolute;
252
+ transition: top, transform; // `transition` needs to come before duration, timing
134
253
  transition-duration: 0.1s;
135
254
  transition-timing-function: ease-in-out;
136
255
  }
137
256
 
138
257
  &:after {
139
- top: calc(var(--su-static6) - var(--su-static1)); // 5px
258
+ top: var(--_tb-menu-btn-span-after-t);
259
+ transform: rotate(var(--_tb-menu-btn-span-after-rotate));
260
+ }
261
+
262
+ &:before {
263
+ top: var(--_tb-menu-btn-span-before-t);
264
+ transform: rotate(var(--_tb-menu-btn-span-before-rotate));
140
265
  }
266
+
267
+ background-color: var(--_tb-menu-btn-span-bg);
141
268
  }
142
269
 
143
- // Transforming hamburger into x
144
- &.is-selected {
145
- color: var(--theme-topbar-item-color-current, var(--black));
146
- background-color: var(--theme-topbar-item-background-current);
270
+ &:hover {
271
+ background-color: var(--_tb-menu-btn-bg-hover);
272
+ color: var(--_tb-menu-btn-fc-hover);
273
+ }
147
274
 
148
- span {
149
- background-color: transparent;
275
+ background-color: var(--_tb-menu-btn-bg);
276
+ color: var(--_tb-menu-btn-fc);
277
+
278
+ align-items: center;
279
+ display: flex;
280
+ flex-shrink: 0;
281
+ height: 100%;
282
+ justify-content: center;
283
+ padding: 0 var(--su16);
284
+ }
285
+
286
+ & &--navigation {
287
+ @scrollbar-styles();
288
+ display: flex;
289
+ height: 100%;
290
+ margin-left: auto;
291
+ overflow-x: auto;
292
+ }
293
+
294
+ & &--notice {
295
+ &.is-unread {
296
+ --_tb-notice-bg: var(--theme-primary-400);
297
+ --_tb-notice-fc: var(--white);
298
+ --_tb-notice-bg-hover: var(--theme-primary-500);
299
+ --_tb-notice-fc-hover: var(--white);
300
+ }
301
+
302
+ &:focus-visible {
303
+ .focus-styles(true, true);
304
+ }
305
+
306
+ &:hover {
307
+ background-color: var(--_tb-notice-bg-hover);
308
+ border-color: var(--_tb-notice-bg-hover); // notice border-color matches background-color
309
+ color: var(--_tb-notice-fc-hover);
310
+ }
311
+
312
+ background-color: var(--_tb-notice-bg);
313
+ border: var(--su-static1) solid var(--_tb-notice-bg); // notice border-color matches background-color
314
+ color: var(--_tb-notice-fc);
315
+ text-decoration: var(--_tb-notice-td);
150
316
 
151
- &:before,
152
- &:after {
153
- top: 0;
154
- transform: rotate(-45deg);
317
+ border-radius: var(--br-sm);
318
+ display: inline-flex;
319
+ flex-shrink: 0;
320
+ font-size: var(--fs-fine);
321
+ font-weight: 700;
322
+ margin-left: var(--su8);
323
+ margin-right: var(--su8);
324
+ line-height: var(--lh-xxl);
325
+ padding: 0 var(--su6);
326
+ text-transform: uppercase;
327
+ }
328
+
329
+ & &--searchbar {
330
+ .s-topbar--searchbar--input-group {
331
+ .s-input {
332
+ &::placeholder {
333
+ color: var(--theme-topbar-search-placeholder, var(--black-400));
334
+ font-style: normal;
155
335
  }
156
336
 
157
- &:after { transform: rotate(45deg); }
337
+ &:not(:focus-visible):not(.focus) {
338
+ box-shadow: var(--theme-topbar-search-shadow);
339
+ }
340
+
341
+ background-color: var(--theme-topbar-search-background, var(--white));
342
+ border-color: var(--theme-topbar-search-border, var(--black-300));
343
+ color: var(--theme-topbar-search-color, var(--black-500));
344
+ display: block;
345
+ line-height: var(--lh-sm);
346
+ }
347
+
348
+ .s-input-icon {
349
+ color: var(--theme-topbar-search-placeholder, var(--black-400));
158
350
  }
351
+
352
+ flex-grow: 1;
353
+ position: relative;
159
354
  }
160
355
 
161
- &:hover {
162
- color: var(--theme-topbar-item-color-hover, var(--black-400));
163
- background-color: var(--theme-topbar-item-background-hover, var(--black-200));
356
+ .s-select {
357
+ > select {
358
+ &:focus-visible,
359
+ &.focus {
360
+ z-index: var(--zi-selected);
361
+ }
362
+
363
+ background-color: var(--theme-topbar-select-background, var(--black-200));
364
+ border-bottom-right-radius: 0 !important;
365
+ border-color: var(--theme-topbar-search-border, var(--black-300));
366
+ border-top-right-radius: 0 !important;
367
+ color: var(--theme-topbar-select-color, var(--black-500));
368
+ height: 100%;
369
+ line-height: var(--lh-sm);
370
+ }
371
+
372
+ + .s-topbar--searchbar--input-group > .s-input {
373
+ border-bottom-left-radius: 0 !important;
374
+ border-top-left-radius: 0 !important;
375
+ }
376
+
377
+ &:before,
378
+ &:after {
379
+ z-index: var(--zi-active); // Make sure our focus ring is above the search input
380
+ }
381
+
382
+ align-self: stretch;
383
+ color: var(--theme-topbar-select-color, var(--black-500));
384
+ margin-right: calc(var(--su-static1) * -1); //-1px
385
+ max-width: calc(var(--s-step) * 2) !important; // wmx2;
386
+ }
387
+
388
+ &.s-topbar--searchbar__open {
389
+ display: var(--_tb-searchbar-open-d);
390
+ max-width: var(--_tb-searchbar-open-mxw);
164
391
  }
392
+
393
+ display: var(--_tb-searchbar-d);
394
+
395
+ align-items: center;
396
+ flex-grow: 1; // Allow the searchbar to grow if there *is* extra space
397
+ flex-shrink: 10000; // Force the searchbar to shrink as much as possible if there's no extra space
398
+ padding: var(--_tb-searchbar-p);
165
399
  }
166
400
 
167
401
  .s-navigation {
168
- .s-navigation--item:not(.is-selected) {
169
- color: var(--theme-topbar-item-color, var(--black-400));
170
- }
402
+ .s-navigation--item {
403
+ &:not(.is-selected) {
404
+ &:hover {
405
+ background-color: var(--theme-topbar-item-background-hover, var(--black-200));
406
+ color: var(--theme-topbar-item-color-hover, var(--black-400));
407
+ }
171
408
 
172
- .s-navigation--item:not(.is-selected):hover {
173
- color: var(--theme-topbar-item-color-hover, var(--black-400));
174
- background-color: var(--theme-topbar-item-background-hover, var(--black-200));
409
+ color: var(--theme-topbar-item-color, var(--black-400));
410
+ }
175
411
  }
176
412
  }
413
+
177
414
  .s-popover .s-navigation {
178
415
  .s-navigation--item {
179
416
  &:not(.is-selected) {
180
417
  &:hover {
181
- color: var(--black-600);
182
418
  background-color: var(--black-200);
419
+ color: var(--black-600);
183
420
  }
184
421
 
185
422
  color: var(--black-500);
186
423
  }
187
424
  }
188
425
  }
189
- }
190
-
191
- // ===========================================================================
192
- // $ LIGHT
193
- // ---------------------------------------------------------------------------
194
- .s-topbar__light {
195
- // TODO this only works 100% perfectly in light mode, due to child elements inheriting current theme colors
196
- // TODO extend forced light mode instead of overriding
197
-
198
- --theme-topbar-background-color: var(--_white-static);
199
- --theme-topbar-bottom-border: 1px solid .set-black()[225];
200
-
201
- // Search input
202
- --theme-topbar-search-color: .set-black()[500];
203
- --theme-topbar-search-background: var(--_white-static);
204
- --theme-topbar-search-placeholder: .set-black()[400];
205
- --theme-topbar-search-border: .set-black()[300];
206
-
207
- // Search switcher
208
- --theme-topbar-select-color: .set-black()[500];
209
- --theme-topbar-select-background: .set-black()[200];
210
-
211
- // Items
212
- --theme-topbar-item-color: .set-black()[400];
213
- --theme-topbar-item-color-hover: .set-black()[500];
214
- --theme-topbar-item-background-hover: .set-black()[200];
215
- --theme-topbar-item-color-current: var(--_black-static);
216
- // --theme-topbar-item-border-current: var(--theme-primary); // As of Stacks v2, this is unused
217
-
218
- // TODO HACK remove everything below once light/dark topbars are inheriting forced themes correctly
219
- // redefine the variables for extra contrast in high-contrast mode
220
- .highcontrast-mode({
221
- // Topbar items
222
- --theme-topbar-item-color: .set-black()[600];
223
- --theme-topbar-item-color-hover: .set-black()[600]; // TODO hover is now identical color to base color
224
- --theme-topbar-item-background-hover: .set-black()[200];
225
- --theme-topbar-item-color-current: var(--_black-static);
226
- });
227
426
 
228
- --scrollbar: hsla(0, 0%, 0%, 0.2);
427
+ // STATIC COMPONENT STYLES
428
+ align-items: center;
429
+ background-color: var(--theme-topbar-background-color, var(--white));
430
+ border-bottom: var(--theme-topbar-bottom-border, var(--su-static1) solid var(--black-225));
431
+ border-top: var(--theme-topbar-accent-border, 3px solid var(--theme-primary));
432
+ display: flex;
433
+ height: var(--theme-topbar-height, calc(var(--su-static48) + var(--su-static8)));
434
+ min-width: auto;
435
+ position: relative;
436
+ width: 100%;
437
+ z-index: var(--zi-navigation-fixed);
229
438
  }
230
439
 
231
- // ===========================================================================
232
- // $ DARK
233
- // ---------------------------------------------------------------------------
440
+ // DARK/LIGHT VARIANTS
441
+ // NOTE: These are declared outside of the .s-topbar block to allow consumers (Core) to reference them directly
442
+ // TODO move within .s-topbar block once Core no longer references this directly
234
443
  .s-topbar__dark {
235
444
  // TODO this only works 100% perfectly in dark mode, due to child elements inheriting current theme colors
236
445
  // TODO extend forced dark mode instead of overriding
237
-
238
446
  @topbar-actual-background: .set-black()[600];
239
- // TODO
447
+
240
448
  #calc-topbar-lightness-increase() when (lightness(@topbar-actual-background) < 15%) {
241
449
  @topbar-search-lightness-increase: 20%;
242
450
  }
@@ -246,7 +454,7 @@
246
454
  #calc-topbar-lightness-increase();
247
455
 
248
456
  --theme-topbar-background-color: @topbar-actual-background;
249
- --theme-topbar-bottom-border: 1px solid @topbar-actual-background;
457
+ --theme-topbar-bottom-border: var(--su-static1) solid @topbar-actual-background;
250
458
 
251
459
  // Search input
252
460
  --theme-topbar-search-color: lighten(@topbar-actual-background, 80% + @topbar-search-lightness-increase);
@@ -263,213 +471,36 @@
263
471
  --theme-topbar-item-color-hover: var(--_white-static);
264
472
  --theme-topbar-item-background-hover: .set-black()[500];
265
473
  --theme-topbar-item-color-current: var(--_white-static);
266
- // --theme-topbar-item-border-current: var(--theme-primary); // As of Stacks v2, this is unused
267
474
 
268
475
  // Themed border accent
269
476
  --theme-topbar-accent-border: none;
270
477
 
271
- // TODO HACK remove everything below once light/dark topbars are inheriting forced themes correctly
272
- // redefine the variables for extra contrast in high-contrast mode
273
- .highcontrast-mode({
274
- // Topbar items
275
- --theme-topbar-item-color: var(--_white-static);
276
- --theme-topbar-item-color-hover: var(--_white-static);
277
- --theme-topbar-item-background-hover: .set-black()[500];
278
- --theme-topbar-item-color-current: var(--_white-static);
279
-
280
- .s-badge {
281
- border-color: currentColor;
282
- }
283
- });
284
-
285
478
  --scrollbar: hsla(0, 0%, 100%, 0.2);
286
479
  }
287
480
 
288
- // ===========================================================================
289
- // $ CONTENT & CTAS
290
- // ---------------------------------------------------------------------------
291
- .s-topbar--navigation {
292
- display: flex;
293
- height: 100%;
294
-
295
- overflow-x: auto; // Allow this content to scroll if it gets too long
296
- @scrollbar-styles(); // Style the scrollbars
297
- margin-left: auto; // Push this section as far to the right as possible
298
- }
299
-
300
- .s-topbar .s-topbar--content {
301
- display: flex;
302
- height: 100%;
303
- .list-reset;
304
-
305
- & > li {
306
- display: inline-flex;
307
- }
308
-
309
- // TODO remove once all topbars include necessary nav.s-topbar--navigation wrapper elements
310
- overflow-x: auto; // Allow this content to scroll if it gets too long
311
- @scrollbar-styles(); // Style the scrollbars
312
- margin-left: auto; // Push this section as far to the right as possible
313
-
314
- .s-topbar--item:not(.s-topbar--item__unset) {
315
- color: var(--theme-topbar-item-color, var(--black-400));
316
- display: inline-flex;
317
- align-items: center;
318
- padding: 0 calc(var(--su12) - var(--su2));
319
- text-decoration: none;
320
- white-space: nowrap;
321
- position: relative;
322
- border-radius: var(--br-sm);
323
-
324
- &:hover,
325
- &.is-selected,
326
- &.is-selected:hover {
327
- color: var(--theme-topbar-item-color-hover, var(--black-600));
328
- background-color: var(--theme-topbar-item-background-hover, var(--black-200));
329
- text-decoration: none;
330
-
331
- .s-activity-indicator {
332
- top: calc(50% - calc(var(--su16) + var(--su2))); // 50% - 18px
333
- box-shadow: 0 0 0 var(--su-static2) var(--theme-topbar-item-background-hover, var(--black-200));
334
- }
335
- }
336
-
337
- .svg-icon {
338
- vertical-align: text-top;
339
- }
340
-
341
- .s-activity-indicator {
342
- position: absolute;
343
- top: calc(50% - calc(var(--su12) + var(--su2))); // 50% - 14px
344
- right: var(--su-static2);
345
- transition: top var(--te-smooth) 0.15s;
346
- box-shadow: 0 0 0 var(--su-static2) var(--theme-topbar-background-color, var(--white));
347
- }
348
- }
349
-
350
- // provide only layout styling for unset items
351
- .s-topbar--item__unset {
352
- align-self: center;
353
- padding-top: var(--su8);
354
- padding-bottom: var(--su8);
355
- }
356
- }
357
-
358
- // ===========================================================================
359
- // $ NOTICE
360
- // ---------------------------------------------------------------------------
361
- .s-topbar--notice {
362
- &:extend(.s-badge);
363
-
364
- text-transform: uppercase;
365
- font-size: var(--fs-fine);
366
- font-weight: 700;
367
- margin-left: var(--su8);
368
- margin-right: var(--su8);
369
- flex-shrink: 0;
370
-
371
- .topbar-notice-styles(transparent, transparent, var(--theme-topbar-item-color, var(--black-400)));
372
-
373
- &:hover {
374
- .topbar-notice-styles(var(--theme-topbar-item-background-hover, var(--black-200)), var(--theme-topbar-item-background-hover, var(--black-200)), var(--theme-topbar-item-color-hover, var(--black-600)));
375
- }
376
-
377
- &.is-unread {
378
- .topbar-notice-styles(var(--theme-primary), var(--theme-primary), var(--white));
379
-
380
- &:hover {
381
- .topbar-notice-styles(var(--theme-primary-500), var(--theme-primary-500), var(--white));
382
- }
383
- }
384
- }
385
-
386
- // ===========================================================================
387
- // $ SEARCHBAR
388
- // ---------------------------------------------------------------------------
389
- .s-topbar .s-topbar--searchbar {
390
- @inputLineHeights: var(--lh-sm); // Ensure the line heights between the elements match up
391
- padding: 0 var(--su8);
392
- display: flex;
393
- align-items: center;
394
- flex-shrink: 10000; // Force the searchbar to shrink as much as possible if there's no extra space
395
- flex-grow: 1; //...but allow it to grow if there *is* extra space
396
-
397
- .s-topbar--searchbar--input-group {
398
- position: relative;
399
- flex-grow: 1;
400
-
401
- .s-input {
402
- &:not(:focus-visible) {
403
- box-shadow: var(--theme-topbar-search-shadow);
404
- }
405
-
406
- background-color: var(--theme-topbar-search-background, var(--white));
407
- border-color: var(--theme-topbar-search-border, var(--black-300));
408
- color: var(--theme-topbar-search-color, var(--black-500));
409
- display: block;
410
- line-height: @inputLineHeights;
411
-
412
- &::placeholder {
413
- color: var(--theme-topbar-search-placeholder, var(--black-400));
414
- font-style: normal;
415
- }
416
- }
417
-
418
- .s-input-icon {
419
- color: var(--theme-topbar-search-placeholder, var(--black-400));
420
- }
421
- }
422
-
423
- .s-select {
424
- .wmx2;
425
-
426
- align-self: stretch;
427
- margin-right: calc(var(--su-static1) * -1); //-1px
428
- color: var(--theme-topbar-select-color, var(--black-500));
429
-
430
- &:before,
431
- &:after {
432
- z-index: var(--zi-active); // Make sure our focus ring is above the search input
433
- }
434
- }
435
-
436
- .s-select > select {
437
- border-color: var(--theme-topbar-search-border, var(--black-300));
438
-
439
- &:focus-visible {
440
- z-index: var(--zi-selected);
441
- }
442
-
443
- .brr0;
444
- height: 100%;
445
- line-height: @inputLineHeights;
446
- background-color: var(--theme-topbar-select-background, var(--black-200));
447
- color: var(--theme-topbar-select-color, var(--black-500));
481
+ // TODO move within .s-topbar block once Core no longer references this directly
482
+ .s-topbar__light {
483
+ // TODO this only works 100% perfectly in light mode, due to child elements inheriting current theme colors
484
+ // TODO extend forced light mode instead of overriding
448
485
 
449
- }
486
+ --theme-topbar-background-color: var(--_white-static);
487
+ --theme-topbar-bottom-border: var(--su-static1) solid .set-black()[225];
450
488
 
451
- // Drop the left border of the search input when it is next to the select
452
- .s-select + .s-topbar--searchbar--input-group > .s-input {
453
- .blr0;
454
- }
489
+ // Search input
490
+ --theme-topbar-search-color: .set-black()[500];
491
+ --theme-topbar-search-background: var(--_white-static);
492
+ --theme-topbar-search-placeholder: .set-black()[400];
493
+ --theme-topbar-search-border: .set-black()[300];
455
494
 
456
- #stacks-internals #screen-sm({
457
- display: none;
458
- position: absolute;
459
- left: 0;
460
- right: 0;
461
- top: 100%;
462
- max-width: 100%;
463
- padding: var(--su8) var(--su12);
464
- background: var(--theme-topbar-item-background-hover, var(--black-200));
495
+ // Search switcher
496
+ --theme-topbar-select-color: .set-black()[500];
497
+ --theme-topbar-select-background: .set-black()[200];
465
498
 
466
- &.s-topbar--searchbar__open {
467
- display: flex;
468
- max-width: none;
469
- }
499
+ // Items
500
+ --theme-topbar-item-color: .set-black()[400];
501
+ --theme-topbar-item-color-hover: .set-black()[500];
502
+ --theme-topbar-item-background-hover: .set-black()[200];
503
+ --theme-topbar-item-color-current: var(--_black-static);
470
504
 
471
- .s-select {
472
- .w25;
473
- }
474
- });
505
+ --scrollbar: hsla(0, 0%, 0%, 0.2);
475
506
  }