@stackoverflow/stacks 3.0.0-beta.20 → 3.0.0-beta.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/css/stacks.css +166 -297
- package/dist/css/stacks.min.css +1 -1
- package/lib/components/banner/banner.less +11 -10
- package/lib/components/button/button.less +41 -31
- package/lib/components/loader/loader.less +88 -0
- package/lib/components/notice/notice.less +14 -8
- package/lib/components/sidebar-widget/sidebar-widget.less +26 -196
- package/lib/components/toast/toast.less +3 -0
- package/lib/stacks-static.less +1 -1
- package/lib/test/visual-test-utils.ts +42 -10
- package/package.json +1 -1
- package/lib/components/spinner/spinner.less +0 -103
|
@@ -5,6 +5,13 @@
|
|
|
5
5
|
--_no-ty-offset: 0;
|
|
6
6
|
--_no-ty: var(--theme-topbar-height, calc(var(--su-static48) + var(--su-static8)));
|
|
7
7
|
.construct-notice-component(s-banner);
|
|
8
|
+
|
|
9
|
+
&--icon {
|
|
10
|
+
//Remove the icon backgound color
|
|
11
|
+
--_no-icon-bg: transparent;
|
|
12
|
+
margin-right: var(--su8);
|
|
13
|
+
align-self: flex-start;
|
|
14
|
+
}
|
|
8
15
|
|
|
9
16
|
&[aria-hidden="true"] { // If you want to hide and reveal the banner
|
|
10
17
|
--_no-ty-offset: -1;
|
|
@@ -27,18 +34,12 @@
|
|
|
27
34
|
padding-top: 93px;
|
|
28
35
|
}
|
|
29
36
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
position: relative;
|
|
34
|
-
width: 100%;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
border-width: 0 0 var(--su-static1);
|
|
37
|
+
display: flex;
|
|
38
|
+
align-items: center;
|
|
39
|
+
padding: var(--su16);
|
|
38
40
|
inset: 0 0 auto 0;
|
|
39
|
-
padding: var(--su12);
|
|
40
41
|
position: fixed;
|
|
41
42
|
transform: translate3d(0, calc(var(--_no-ty) * var(--_no-ty-offset)), 0);
|
|
42
43
|
width: 100%;
|
|
43
44
|
z-index: calc(var(--zi-navigation-fixed) - 1); // Tuck below topbar
|
|
44
|
-
}
|
|
45
|
+
}
|
|
@@ -6,20 +6,24 @@
|
|
|
6
6
|
--_bu-g: var(--su8);
|
|
7
7
|
--_bu-px: var(--su16);
|
|
8
8
|
--_bu-py: calc(var(--su8) + var(--su2)); // 10px
|
|
9
|
+
--_bu-badge-fs: var(--fs-caption);
|
|
10
|
+
--_bu-badge-px: var(--su6);
|
|
11
|
+
--_bu-badge-py: var(--su2);
|
|
9
12
|
--_bu-dropdown-bw: var(--su-static4);
|
|
10
13
|
|
|
11
14
|
// VARIANTS
|
|
12
15
|
// Base
|
|
13
16
|
&:not(&__danger):not(&__featured):not(&__tonal):not(&__link):not(&__unset):not(&__facebook):not(&__github):not(&__google) { // Exclude default styles from impacting these variants
|
|
14
17
|
--_bu-bg: var(--theme-button-color, var(--theme-secondary));
|
|
15
|
-
--_bu-bg-disabled: var(--
|
|
18
|
+
--_bu-bg-disabled: var(--black-350);
|
|
16
19
|
--_bu-bg-hover: var(--theme-button-hover-background-color, var(--theme-secondary-500));
|
|
17
20
|
--_bu-fc: var(--white);
|
|
21
|
+
--_bu-fc-disabled: var(--black-050);
|
|
18
22
|
--_bu-fc-hover: var(--theme-button-hover-color, var(--white));
|
|
19
|
-
--_bu-badge-bg: var(--theme-secondary-
|
|
20
|
-
--_bu-badge-fc: var(--
|
|
21
|
-
--_bu-badge-bg-disabled: var(--
|
|
22
|
-
--_bu-badge-fc-disabled: var(--
|
|
23
|
+
--_bu-badge-bg: var(--theme-secondary-500);
|
|
24
|
+
--_bu-badge-fc: var(--white);
|
|
25
|
+
--_bu-badge-bg-disabled: var(--black-250);
|
|
26
|
+
--_bu-badge-fc-disabled: var(--black-050);
|
|
23
27
|
|
|
24
28
|
&.s-btn__clear {
|
|
25
29
|
--_bu-bg: transparent;
|
|
@@ -29,10 +33,10 @@
|
|
|
29
33
|
--_bu-fc: var(--theme-secondary-600);
|
|
30
34
|
--_bu-fc-disabled: var(--theme-secondary-300);
|
|
31
35
|
--_bu-fc-hover: var(--_bu-fc);
|
|
32
|
-
--_bu-badge-bg: var(--theme-secondary-
|
|
33
|
-
--_bu-badge-fc: var(--
|
|
34
|
-
--_bu-badge-bg-disabled: var(--
|
|
35
|
-
--_bu-badge-fc-disabled: var(--
|
|
36
|
+
--_bu-badge-bg: var(--theme-secondary-100);
|
|
37
|
+
--_bu-badge-fc: var(--theme-secondary-500);
|
|
38
|
+
--_bu-badge-bg-disabled: var(--black-100);
|
|
39
|
+
--_bu-badge-fc-disabled: var(--black-350);
|
|
36
40
|
|
|
37
41
|
.highcontrast-mode({
|
|
38
42
|
--_bu-bc: var(--theme-secondary-600);
|
|
@@ -44,13 +48,14 @@
|
|
|
44
48
|
--_bu-bg: var(--red-400);
|
|
45
49
|
--_bu-fc: var(--white);
|
|
46
50
|
--_bu-bg-disabled: var(--red-200);
|
|
51
|
+
--_bu-fc-disabled: var(--black-050);
|
|
47
52
|
--_bu-bg-hover: var(--red-500);
|
|
48
53
|
--_bu-bg-selected: var(--red-500);
|
|
49
54
|
--_bu-fc-selected: var(--_bu-fc);
|
|
50
|
-
--_bu-badge-bg: var(--red-
|
|
51
|
-
--_bu-badge-fc: var(--
|
|
52
|
-
--_bu-badge-bg-disabled: var(--
|
|
53
|
-
--_bu-badge-fc-disabled: var(--
|
|
55
|
+
--_bu-badge-bg: var(--red-500);
|
|
56
|
+
--_bu-badge-fc: var(--black-050);
|
|
57
|
+
--_bu-badge-bg-disabled: var(--red-300);
|
|
58
|
+
--_bu-badge-fc-disabled: var(--black-100);
|
|
54
59
|
|
|
55
60
|
&.s-btn__clear {
|
|
56
61
|
--_bu-bg: transparent;
|
|
@@ -61,11 +66,10 @@
|
|
|
61
66
|
--_bu-fc-disabled: var(--red-200);
|
|
62
67
|
--_bu-fc-hover: var(--red-500);
|
|
63
68
|
--_bu-fc-selected: var(--red-500);
|
|
64
|
-
--_bu-badge-bg: var(--red-
|
|
65
|
-
--_bu-badge-
|
|
66
|
-
--_bu-badge-
|
|
67
|
-
--_bu-badge-
|
|
68
|
-
--_bu-badge-fc-disabled: var(--white);
|
|
69
|
+
--_bu-badge-bg: var(--red-100);
|
|
70
|
+
--_bu-badge-fc: var(--red-500);
|
|
71
|
+
--_bu-badge-bg-disabled: var(--red-100);
|
|
72
|
+
--_bu-badge-fc-disabled: var(--red-300);
|
|
69
73
|
|
|
70
74
|
.highcontrast-mode({
|
|
71
75
|
--_bu-bc: var(--red-600);
|
|
@@ -81,23 +85,24 @@
|
|
|
81
85
|
--_bu-bg-selected: var(--purple-500);
|
|
82
86
|
--_bu-fc: var(--white);
|
|
83
87
|
--_bu-fc-selected: var(--_bu-fc);
|
|
84
|
-
--_bu-badge-bg: var(--purple-
|
|
85
|
-
--_bu-badge-fc: var(--
|
|
86
|
-
--_bu-badge-bg-disabled: var(--
|
|
87
|
-
--_bu-badge-fc-disabled: var(--
|
|
88
|
+
--_bu-badge-bg: var(--purple-500);
|
|
89
|
+
--_bu-badge-fc: var(--black-050);
|
|
90
|
+
--_bu-badge-bg-disabled: var(--purple-300);
|
|
91
|
+
--_bu-badge-fc-disabled: var(--black-100);
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
&&__tonal {
|
|
91
95
|
--_bu-bg: var(--black-150);
|
|
92
96
|
--_bu-bg-disabled: var(--black-100);
|
|
93
97
|
--_bu-bg-hover: var(--black-200);
|
|
98
|
+
--_bu-bg-selected: var(--black-200);
|
|
94
99
|
--_bu-fc: var(--black);
|
|
95
100
|
--_bu-fc-disabled: var(--black-300);
|
|
96
101
|
--_bu-fc-selected: var(--_bu-fc);
|
|
97
|
-
--_bu-badge-bg: var(--black-
|
|
98
|
-
--_bu-badge-fc: var(--
|
|
99
|
-
--_bu-badge-bg-disabled: var(--black-
|
|
100
|
-
--_bu-badge-fc-disabled: var(--
|
|
102
|
+
--_bu-badge-bg: var(--black-200);
|
|
103
|
+
--_bu-badge-fc: var(--black-600);
|
|
104
|
+
--_bu-badge-bg-disabled: var(--black-100);
|
|
105
|
+
--_bu-badge-fc-disabled: var(--black-350);
|
|
101
106
|
|
|
102
107
|
.highcontrast-mode({
|
|
103
108
|
--_bu-bc: var(--black-300);
|
|
@@ -200,8 +205,9 @@
|
|
|
200
205
|
var(--_bu-bg-selected, var(--_bu-bg)),
|
|
201
206
|
var(--white) var(--_bu-bg-selected-overlay-o)
|
|
202
207
|
);
|
|
203
|
-
--_bu-bg-gradient-top: var(--_bu-bg-selected, var(--_bu-bg));
|
|
204
|
-
--_bu-bg-gradient-bottom:
|
|
208
|
+
--_bu-bg-gradient-top: var(--_bu-bg-selected-overlay, var(--_bu-bg));
|
|
209
|
+
--_bu-bg-gradient-bottom: var(--_bu-bg-selected, var(--_bu-bg));
|
|
210
|
+
|
|
205
211
|
|
|
206
212
|
.dark-mode({
|
|
207
213
|
--_bu-bg-selected-overlay-o: 13%;
|
|
@@ -229,15 +235,15 @@
|
|
|
229
235
|
}
|
|
230
236
|
|
|
231
237
|
// CHILD ELEMENTS
|
|
232
|
-
// TODO SHINE fine-tune badge styles
|
|
233
238
|
& &--badge {
|
|
234
239
|
background-color: var(--_bu-badge-bg);
|
|
235
240
|
border-radius: var(--br-pill);
|
|
236
241
|
display: inline-block;
|
|
237
|
-
font-size: var(--fs
|
|
242
|
+
font-size: var(--_bu-badge-fs);
|
|
238
243
|
line-height: inherit;
|
|
239
244
|
opacity: var(--_bu-badge-o);
|
|
240
|
-
padding: var(--
|
|
245
|
+
padding: var(--_bu-badge-py) var(--_bu-badge-px);
|
|
246
|
+
margin-block: calc(var(--_bu-badge-py) * -1);
|
|
241
247
|
}
|
|
242
248
|
|
|
243
249
|
& &--number {
|
|
@@ -264,6 +270,9 @@
|
|
|
264
270
|
&&__sm {
|
|
265
271
|
--_bu-lh: var(--lh-sm);
|
|
266
272
|
--_bu-px: var(--su12);
|
|
273
|
+
--_bu-badge-fs: var(--fs-fine);
|
|
274
|
+
--_bu-badge-py: var(--su1);
|
|
275
|
+
--_bu-badge-px: calc(var(--su2) + var(--su1)); // 3px
|
|
267
276
|
}
|
|
268
277
|
&&__xs {
|
|
269
278
|
--_bu-g: var(--su4);
|
|
@@ -279,6 +288,7 @@
|
|
|
279
288
|
--_bu-fs: var(--fs-body2);
|
|
280
289
|
--_bu-px: var(--su24);
|
|
281
290
|
--_bu-py: calc(var(--su12) + var(--su1)); // 13px
|
|
291
|
+
--_bu-badge-py: calc(var(--su2) + var(--su1)); // 3px
|
|
282
292
|
}
|
|
283
293
|
|
|
284
294
|
// INTERACTION
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
.s-loader {
|
|
2
|
+
--_ld-color: var(--black-600);
|
|
3
|
+
--_ld-gap: calc(var(--_ld-size) / 2);
|
|
4
|
+
--_ld-size: calc(var(--su4) + var(--su1)); // 5px
|
|
5
|
+
--_ld-offset: calc(calc(var(--_ld-size) / 8) * -5); // -5/8ths of the size
|
|
6
|
+
|
|
7
|
+
// MODIFIERS
|
|
8
|
+
&__sm {
|
|
9
|
+
--_ld-size: calc(calc(var(--su8) - var(--su1)) / 2); // 3.5px
|
|
10
|
+
margin-left: var(--su1);
|
|
11
|
+
margin-right: var(--su1);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&__lg {
|
|
15
|
+
--_ld-size: var(--su8);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
// CHILD ELEMENTS – three blocks via pseudo-elements (::before, --sr-text::before, ::after)
|
|
19
|
+
&:before,
|
|
20
|
+
& &--sr-text:before,
|
|
21
|
+
&:after {
|
|
22
|
+
background-color: currentColor;
|
|
23
|
+
content: "";
|
|
24
|
+
display: block;
|
|
25
|
+
height: var(--_ld-size);
|
|
26
|
+
width: var(--_ld-size);
|
|
27
|
+
|
|
28
|
+
animation: loader-animation .8s cubic-bezier(1, 1, 0, 1) infinite;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
& &--sr-text {
|
|
32
|
+
// Visible flex item so its ::before (middle block) shows; overflow visible so translateY isn't clipped
|
|
33
|
+
display: block;
|
|
34
|
+
flex-shrink: 0;
|
|
35
|
+
height: var(--_ld-size);
|
|
36
|
+
width: var(--_ld-size);
|
|
37
|
+
font-size: 0;
|
|
38
|
+
overflow: visible;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
& &--sr-text:before {
|
|
42
|
+
animation-delay: .25s;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
&:after {
|
|
46
|
+
animation-delay: .5s;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
display: flex;
|
|
50
|
+
gap: var(--_ld-gap);
|
|
51
|
+
margin-top: var(--_ld-gap);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
@media (prefers-reduced-motion:reduce){
|
|
55
|
+
.s-loader {
|
|
56
|
+
&:before,
|
|
57
|
+
& &--sr-text:before,
|
|
58
|
+
&:after {
|
|
59
|
+
animation: loader-animation-reduced-motion 2s ease-in-out infinite;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
@keyframes loader-animation {
|
|
65
|
+
0%,1%,99%,to{
|
|
66
|
+
opacity: 0.2;
|
|
67
|
+
transform: translateY(0);
|
|
68
|
+
}
|
|
69
|
+
49%,50%{
|
|
70
|
+
opacity: 1;
|
|
71
|
+
transform: translateY(var(--_ld-offset));
|
|
72
|
+
}
|
|
73
|
+
51%{
|
|
74
|
+
opacity: 0.2;
|
|
75
|
+
transform: translateY(var(--_ld-offset));
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
@keyframes loader-animation-reduced-motion {
|
|
80
|
+
0%,to{
|
|
81
|
+
opacity: 0.3;
|
|
82
|
+
transform: none;
|
|
83
|
+
}
|
|
84
|
+
50%{
|
|
85
|
+
opacity: 1;
|
|
86
|
+
transform: none;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
@@ -27,8 +27,9 @@
|
|
|
27
27
|
/**
|
|
28
28
|
* Generate styles for a notice-based component
|
|
29
29
|
*
|
|
30
|
-
* Usage
|
|
30
|
+
* Usage examples:
|
|
31
31
|
* .construct-notice-component(s-banner);
|
|
32
|
+
* .construct-notice-component(s-notice);
|
|
32
33
|
*
|
|
33
34
|
* @baseClass - The base class name for the notice component
|
|
34
35
|
*/
|
|
@@ -110,7 +111,6 @@
|
|
|
110
111
|
&__warning {
|
|
111
112
|
&:not(.@{baseClass}__important) {
|
|
112
113
|
.generate-variant-variables(yellow);
|
|
113
|
-
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
&.@{baseClass}__important {
|
|
@@ -164,16 +164,26 @@
|
|
|
164
164
|
background-color: var(--_no-fc);
|
|
165
165
|
color: var(--_no-bg);
|
|
166
166
|
}
|
|
167
|
+
color: var(--_no-fc);
|
|
167
168
|
}
|
|
168
169
|
|
|
169
|
-
|
|
170
|
+
&--actions {
|
|
171
|
+
display: flex;
|
|
172
|
+
margin-left: auto;
|
|
173
|
+
align-self: flex-start;
|
|
170
174
|
padding-left: var(--su24);
|
|
171
|
-
|
|
175
|
+
color: var(--_no-fc);
|
|
172
176
|
gap: calc(var(--su24) - var(--su2)); //22px
|
|
177
|
+
|
|
173
178
|
//Fix css issue caused by svelte-sonner-toast in the NoticeAction svelte component
|
|
174
179
|
overflow-wrap: initial !important;
|
|
175
180
|
}
|
|
176
181
|
|
|
182
|
+
//Fix notice action color for __important variant
|
|
183
|
+
&--actions > .s-link:not(&--dismiss) {
|
|
184
|
+
color: var(--_no-fc);
|
|
185
|
+
}
|
|
186
|
+
|
|
177
187
|
// STYLES MODIFIED BY COMPONENT-SPECIFIC CUSTOM PROPERTIES
|
|
178
188
|
background: var(--_no-bg);
|
|
179
189
|
color: var(--_no-fc);
|
|
@@ -195,10 +205,6 @@
|
|
|
195
205
|
margin-right: var(--su12);
|
|
196
206
|
align-self: stretch;
|
|
197
207
|
|
|
198
|
-
//Position the svg icon
|
|
199
|
-
display: flex;
|
|
200
|
-
align-items: top;
|
|
201
|
-
|
|
202
208
|
//Negative margin to make up for s-notice's padding
|
|
203
209
|
margin-top: calc(var(--_no-pd) * -1);
|
|
204
210
|
margin-bottom: calc(var(--_no-pd) * -1);
|
|
@@ -1,218 +1,48 @@
|
|
|
1
|
-
|
|
2
|
-
// COMPONENT-SPECIFIC CUSTOM PROPERTIES
|
|
3
|
-
--_sw-bc: var(--bc-medium);
|
|
4
|
-
|
|
5
|
-
// MODIFIERS
|
|
6
|
-
&:not(.s-anchors) {
|
|
7
|
-
a:not(.button):not(.s-tag):not(.post-tag):not(.s-btn):not(.s-sidebarwidget--action):not(.s-user-card--link) {
|
|
8
|
-
&,
|
|
9
|
-
&:visited {
|
|
10
|
-
color: var(--black-600);
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
|
|
15
|
-
// VARIANTS
|
|
16
|
-
.alternate-color(blue);
|
|
17
|
-
.alternate-color(yellow);
|
|
18
|
-
.alternate-color(green);
|
|
1
|
+
@headings: h1, h2, h3, h4, h5, h6;
|
|
19
2
|
|
|
3
|
+
.s-sidebarwidget {
|
|
20
4
|
// CHILD ELEMENTS
|
|
21
|
-
& &--
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
& &--content {
|
|
29
|
-
&:not(table) {
|
|
30
|
-
&:not(.s-sidebarwidget__items),
|
|
31
|
-
&:not(.s-sidebarwidget__block-items) .s-sidebarwidget--item {
|
|
32
|
-
display: flex;
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
+ .s-sidebarwidget--content {
|
|
37
|
-
border-top: var(--su-static1) solid var(--bc-light);
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
&.s-sidebarwidget__items {
|
|
41
|
-
&,
|
|
42
|
-
&.s-sidebarwidget__block-items .s-sidebarwidget--item {
|
|
43
|
-
display: block;
|
|
44
|
-
}
|
|
45
|
-
|
|
46
|
-
padding: var(--su6) var(--su16); // the items themselves provide part of the spacing, so the content padding needs to account for that
|
|
5
|
+
& &--content {
|
|
6
|
+
.s-sidebarwidget--action {
|
|
7
|
+
font-size: var(--fs-fine);
|
|
8
|
+
margin-left: var(--su16);
|
|
9
|
+
align-self: flex-start;
|
|
47
10
|
}
|
|
48
11
|
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
margin: 0;
|
|
55
|
-
padding: var(--su16);
|
|
12
|
+
display: flex;
|
|
13
|
+
padding: var(--su12) 0 var(--su16) 0;
|
|
14
|
+
font-size: var(--fs-body2);
|
|
56
15
|
}
|
|
57
16
|
|
|
58
17
|
& &--header {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
margin-bottom: var(--su16);
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
&.s-sidebarwidget {
|
|
68
|
-
&__expanding-control {
|
|
69
|
-
&:before {
|
|
70
|
-
border: calc(var(--su-static4) + var(--su-static1)) solid transparent;
|
|
71
|
-
border-left-color: var(--black-400);
|
|
72
|
-
border-right-width: 0;
|
|
73
|
-
content: '';
|
|
74
|
-
float: left;
|
|
75
|
-
margin-right: var(--su12);
|
|
76
|
-
margin-top: calc(calc(var(--lh-base) * 1em) / 2 - 5px); // 1.3 is our standard line height
|
|
77
|
-
transition: transform 0.3s cubic-bezier(0.4, 0.4, 0.6, 1);
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
&[aria-expanded='true']:before {
|
|
81
|
-
transform: rotate(90deg);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
cursor: pointer;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
&__small-bold-text {
|
|
88
|
-
.s-sidebarwidget--action {
|
|
89
|
-
font-weight: normal;
|
|
90
|
-
line-height: calc(var(--lh-base) * var(--fs-caption)); // line-height should be the same as in the outside element, so the header and action baselines line up
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
font-size: var(--fs-caption);
|
|
94
|
-
font-weight: bold;
|
|
95
|
-
}
|
|
18
|
+
> @{headings} {
|
|
19
|
+
margin: 0;
|
|
20
|
+
padding-right: var(--su6);
|
|
21
|
+
font-size: var(--fs-body1);
|
|
22
|
+
font-weight: 500;
|
|
96
23
|
}
|
|
97
24
|
|
|
98
|
-
|
|
99
|
-
|
|
25
|
+
.s-sidebarwidget--action {
|
|
26
|
+
margin-left: auto;
|
|
100
27
|
}
|
|
101
28
|
|
|
102
29
|
align-items: center;
|
|
103
|
-
border-top: var(--su-static1) solid var(--bc-light);
|
|
104
|
-
color: var(--black-600);
|
|
105
30
|
display: flex;
|
|
106
|
-
|
|
107
|
-
font-weight: bold;
|
|
108
|
-
justify-content: flex-start;
|
|
109
|
-
line-height: var(--lh-xs);
|
|
110
|
-
margin: 0;
|
|
111
|
-
padding: var(--su16) var(--su16) 0;
|
|
31
|
+
padding: var(--su4) 0;
|
|
112
32
|
}
|
|
113
33
|
|
|
114
|
-
& &--
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
&[aria-current="true"],
|
|
118
|
-
&[aria-current="page"] {
|
|
119
|
-
&:before {
|
|
120
|
-
border-left-color: var(--theme-primary);
|
|
121
|
-
border-left-style: solid;
|
|
122
|
-
border-left-width: calc(var(--su-static1) * 3); // 3px
|
|
123
|
-
content: '';
|
|
124
|
-
height: calc(100% + var(--su16));
|
|
125
|
-
left: 0;
|
|
126
|
-
margin-left: var(--sun16); // the orange selection indicator overlaps with the widget border
|
|
127
|
-
margin-top: var(--sun8);
|
|
128
|
-
position: absolute;
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
a { // TODO: this isn't the best way to go about this. There should be a "is current" highlight without font modification for more complex cases
|
|
132
|
-
&,
|
|
133
|
-
&:visited {
|
|
134
|
-
color: inherit;
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
color: var(--black);
|
|
139
|
-
font-weight: bold;
|
|
140
|
-
position: relative;
|
|
141
|
-
}
|
|
34
|
+
& &--footer {
|
|
35
|
+
.s-sidebarwidget--action {
|
|
36
|
+
flex: 1;
|
|
142
37
|
}
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
& &--subnav {
|
|
148
|
-
li {
|
|
149
|
-
&[aria-current="page"],
|
|
150
|
-
&[aria-current="true"] {
|
|
151
|
-
a {
|
|
152
|
-
&,
|
|
153
|
-
&:visited {
|
|
154
|
-
color: inherit;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
#stacks-internals #bullet-arrow(var(--theme-primary));
|
|
159
|
-
color: var(--black);
|
|
160
|
-
font-weight: bold;
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
#stacks-internals #bullet-arrow(var(--black-225));
|
|
164
|
-
background-position: 0 calc((1.2em - calc(var(--su-static8) + var(--su-static2))) / 2); // 0 ((1.2em - 10) / 2)
|
|
165
|
-
background-repeat: no-repeat;
|
|
166
|
-
background-size: auto calc(var(--su-static8) + var(--su-static2)); // auto 10px
|
|
167
|
-
margin-top: var(--su-static12);
|
|
168
|
-
padding-left: var(--su-static16);
|
|
169
|
-
}
|
|
170
|
-
|
|
171
|
-
list-style-type: none;
|
|
172
|
-
margin-left: var(--su8);
|
|
173
|
-
padding-left: 0;
|
|
38
|
+
|
|
39
|
+
display: flex;
|
|
40
|
+
font-size: var(--fs-body2);
|
|
174
41
|
}
|
|
175
42
|
|
|
176
|
-
&
|
|
177
|
-
|
|
178
|
-
td {
|
|
179
|
-
padding: 0;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
|
-
display: table-row;
|
|
183
|
-
}
|
|
184
|
-
|
|
185
|
-
border-collapse: separate;
|
|
186
|
-
border-spacing: var(--su16) var(--su12);
|
|
187
|
-
padding: var(--su6) 0 0;
|
|
43
|
+
& &--action:is(a, button) {
|
|
44
|
+
white-space: nowrap;
|
|
188
45
|
}
|
|
189
46
|
|
|
190
|
-
background-color: var(--white);
|
|
191
|
-
border: var(--su-static1) solid var(--_sw-bc);
|
|
192
|
-
border-radius: var(--br-md);
|
|
193
47
|
font-size: var(--fs-body1);
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
// COLOR ALTERNATIVES
|
|
197
|
-
.alternate-color(@name) {
|
|
198
|
-
&.s-sidebarwidget__@{name} {
|
|
199
|
-
--_sw-bc: var(~"--@{name}-300");
|
|
200
|
-
|
|
201
|
-
.highcontrast-mode({
|
|
202
|
-
--_sw-bc: var(~"--@{name}-500");
|
|
203
|
-
});
|
|
204
|
-
|
|
205
|
-
&:after,
|
|
206
|
-
.s-sidebarwidget--content + .s-sidebarwidget--content,
|
|
207
|
-
.s-sidebarwidget--header {
|
|
208
|
-
border-color: var(--_sw-bc);
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
.s-sidebarwidget--header {
|
|
212
|
-
color: var(--fc-medium);
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
background-color: var(~"--@{name}-100");
|
|
216
|
-
border-color: var(--_sw-bc);
|
|
217
|
-
}
|
|
218
48
|
}
|
package/lib/stacks-static.less
CHANGED
|
@@ -42,7 +42,7 @@
|
|
|
42
42
|
@import "components/prose/prose.less";
|
|
43
43
|
@import "components/select/select.less";
|
|
44
44
|
@import "components/sidebar-widget/sidebar-widget.less";
|
|
45
|
-
@import "components/
|
|
45
|
+
@import "components/loader/loader.less";
|
|
46
46
|
@import "components/table/table.less";
|
|
47
47
|
@import "components/table-container/table-container.less";
|
|
48
48
|
@import "components/tag/tag.less";
|
|
@@ -23,6 +23,7 @@ const scheduleVisualTest = ({
|
|
|
23
23
|
}
|
|
24
24
|
|
|
25
25
|
let retryAttempts = 3;
|
|
26
|
+
let lastError: Error | null = null;
|
|
26
27
|
|
|
27
28
|
do {
|
|
28
29
|
await fixture(element);
|
|
@@ -37,21 +38,22 @@ const scheduleVisualTest = ({
|
|
|
37
38
|
return;
|
|
38
39
|
} catch (error) {
|
|
39
40
|
const e = error as Error;
|
|
40
|
-
|
|
41
|
-
//
|
|
42
|
-
if (
|
|
43
|
-
retryAttempts > 0 &&
|
|
44
|
-
!e.message.includes("Visual diff failed.")
|
|
45
|
-
) {
|
|
46
|
-
retryAttempts--;
|
|
47
|
-
continue;
|
|
48
|
-
} else {
|
|
41
|
+
lastError = e;
|
|
42
|
+
// if the error is a visual diff failure, fail immediately
|
|
43
|
+
if (e.message.includes("Visual diff failed.")) {
|
|
49
44
|
throw e;
|
|
50
45
|
}
|
|
46
|
+
// otherwise retry (to prevent flaky tests due to snapshot capturing)
|
|
47
|
+
retryAttempts--;
|
|
51
48
|
} finally {
|
|
52
49
|
el.remove();
|
|
53
50
|
}
|
|
54
51
|
} while (retryAttempts > 0);
|
|
52
|
+
|
|
53
|
+
// If we exhausted all retries without success, throw the last error
|
|
54
|
+
if (lastError) {
|
|
55
|
+
throw lastError;
|
|
56
|
+
}
|
|
55
57
|
});
|
|
56
58
|
};
|
|
57
59
|
|
|
@@ -60,4 +62,34 @@ const runVisualTests = (args: VisualTestArgs) => {
|
|
|
60
62
|
testVariations.forEach(scheduleVisualTest);
|
|
61
63
|
};
|
|
62
64
|
|
|
63
|
-
|
|
65
|
+
const replaceHtml = (
|
|
66
|
+
componentTemplateResult: unknown,
|
|
67
|
+
textToReplace: string,
|
|
68
|
+
replacementHtml: string
|
|
69
|
+
) => {
|
|
70
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
71
|
+
const component = componentTemplateResult as any;
|
|
72
|
+
if (!Array.isArray(component.strings) || !Array.isArray(component.values)) {
|
|
73
|
+
throw new Error("Expected Lit TemplateResult type");
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
// Replace placeholder with actual icon in the Lit template
|
|
77
|
+
const originalStrings = component.strings;
|
|
78
|
+
const updatedStrings = originalStrings.map((str: string) =>
|
|
79
|
+
str.replace(textToReplace, replacementHtml)
|
|
80
|
+
);
|
|
81
|
+
// Create a proper TemplateStringsArray with raw property
|
|
82
|
+
Object.defineProperty(updatedStrings, "raw", {
|
|
83
|
+
value: updatedStrings.map((str: string) => str),
|
|
84
|
+
enumerable: false,
|
|
85
|
+
});
|
|
86
|
+
// Reconstruct the template with updated strings and original values
|
|
87
|
+
const updatedComponent = {
|
|
88
|
+
...component,
|
|
89
|
+
strings: updatedStrings,
|
|
90
|
+
values: component.values,
|
|
91
|
+
};
|
|
92
|
+
return updatedComponent;
|
|
93
|
+
};
|
|
94
|
+
|
|
95
|
+
export { runVisualTests, replaceHtml };
|