@stackoverflow/stacks 1.1.0 → 1.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.
- package/dist/controllers/s-expandable-control.d.ts +1 -1
- package/dist/controllers/s-tooltip.d.ts +16 -1
- package/dist/css/stacks.css +887 -708
- package/dist/css/stacks.min.css +1 -1
- package/dist/js/stacks.js +174 -91
- package/dist/js/stacks.min.js +1 -1
- package/lib/css/atomic/misc.less +1 -1
- package/lib/css/atomic/typography.less +0 -6
- package/lib/css/atomic/width-height.less +1 -1
- package/lib/css/components/activity-indicator.less +18 -17
- package/lib/css/components/avatars.less +51 -131
- package/lib/css/components/badges.less +47 -0
- package/lib/css/components/breadcrumbs.less +4 -4
- package/lib/css/components/buttons.less +38 -54
- package/lib/css/components/empty-states.less +15 -0
- package/lib/css/components/{collapsible.less → expandable.less} +0 -0
- package/lib/css/components/inputs.less +44 -110
- package/lib/css/components/labels.less +98 -0
- package/lib/css/components/notices.less +190 -163
- package/lib/css/components/post-summary.less +34 -99
- package/lib/css/components/progress-bars.less +1 -1
- package/lib/css/components/prose.less +4 -4
- package/lib/css/components/spinner.less +39 -1
- package/lib/css/components/tables.less +1 -5
- package/lib/css/components/topbar.less +4 -1
- package/lib/css/components/uploader.less +70 -84
- package/lib/css/exports/constants-colors.less +63 -49
- package/lib/css/stacks-dynamic.less +0 -1
- package/lib/css/stacks-static.less +3 -2
- package/lib/ts/controllers/s-expandable-control.ts +23 -19
- package/lib/ts/controllers/s-modal.ts +16 -16
- package/lib/ts/controllers/s-navigation-tablist.ts +13 -13
- package/lib/ts/controllers/s-popover.ts +26 -18
- package/lib/ts/controllers/s-table.ts +31 -29
- package/lib/ts/controllers/s-tooltip.ts +62 -23
- package/lib/ts/controllers/s-uploader.ts +26 -12
- package/lib/ts/stacks.ts +8 -4
- package/package.json +25 -25
- package/lib/css/components/banners.less +0 -80
- package/lib/css/components/blank-states.less +0 -26
|
@@ -96,6 +96,44 @@
|
|
|
96
96
|
}
|
|
97
97
|
}
|
|
98
98
|
|
|
99
|
+
.is-loading {
|
|
100
|
+
position: relative;
|
|
101
|
+
padding-left: 2.2em;
|
|
102
|
+
|
|
103
|
+
&:before {
|
|
104
|
+
content: "";
|
|
105
|
+
position: absolute;
|
|
106
|
+
opacity: 0.3;
|
|
107
|
+
left: 0.6em;
|
|
108
|
+
top: calc(50% - 0.6em);
|
|
109
|
+
width: 1.23076923em;
|
|
110
|
+
height: 1.23076923em;
|
|
111
|
+
border-width: 2px;
|
|
112
|
+
border-style: solid;
|
|
113
|
+
border-color: currentColor;
|
|
114
|
+
border-radius: var(--br-circle);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
&:after {
|
|
118
|
+
content: "";
|
|
119
|
+
position: absolute;
|
|
120
|
+
left: 0.6em;
|
|
121
|
+
top: calc(50% - 0.6em);
|
|
122
|
+
width: 1.23076923em;
|
|
123
|
+
height: 1.23076923em;
|
|
124
|
+
border-width: 2px;
|
|
125
|
+
border-style: solid;
|
|
126
|
+
border-color: transparent;
|
|
127
|
+
border-left-color: currentColor;
|
|
128
|
+
border-radius: var(--br-circle);
|
|
129
|
+
animation: s-spinner-rotate 0.9s infinite
|
|
130
|
+
cubic-bezier(0.5, 0.1, 0.5, 0.9);
|
|
131
|
+
// see _stacks-spinner.less for an explanation of the following two
|
|
132
|
+
filter: invert(0); // (*)
|
|
133
|
+
transform-origin: 50% 50% 1px; // (*)
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
99
137
|
// Keyframes
|
|
100
138
|
@keyframes s-spinner-rotate {
|
|
101
139
|
from {
|
|
@@ -104,4 +142,4 @@
|
|
|
104
142
|
to {
|
|
105
143
|
transform: rotate(360deg);
|
|
106
144
|
}
|
|
107
|
-
}
|
|
145
|
+
}
|
|
@@ -130,6 +130,9 @@
|
|
|
130
130
|
}
|
|
131
131
|
|
|
132
132
|
.s-navigation {
|
|
133
|
+
.s-navigation--item:focus-visible {
|
|
134
|
+
box-shadow: var(--theme-topbar-search-shadow-focus);
|
|
135
|
+
}
|
|
133
136
|
.s-navigation--item:not(.is-selected) {
|
|
134
137
|
color: var(--theme-topbar-item-color);
|
|
135
138
|
}
|
|
@@ -153,7 +156,7 @@
|
|
|
153
156
|
// Search input
|
|
154
157
|
--theme-topbar-search-color: @black-700;
|
|
155
158
|
--theme-topbar-search-background: @white;
|
|
156
|
-
--theme-topbar-search-placeholder: @black-
|
|
159
|
+
--theme-topbar-search-placeholder: @black-400;
|
|
157
160
|
--theme-topbar-search-border: @black-200;
|
|
158
161
|
--theme-topbar-search-border-focus: @blue-300;
|
|
159
162
|
--theme-topbar-search-shadow-focus: 0 0 0 var(--su-static4) var(--focus-ring);
|
|
@@ -7,106 +7,91 @@
|
|
|
7
7
|
// visit https://stackoverflow.design/
|
|
8
8
|
|
|
9
9
|
.s-uploader {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
min-height: var(--su-static128);
|
|
15
|
-
justify-content: center;
|
|
16
|
-
padding: var(--su8) var(--su16);
|
|
17
|
-
position: relative;
|
|
18
|
-
text-align: center;
|
|
19
|
-
|
|
20
|
-
// Add the dashed border as an SVG background mask
|
|
21
|
-
&:before {
|
|
22
|
-
--s-uploader-background-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='5' ry='5' stroke='%23000000' stroke-width='8' stroke-dasharray='7%2c 22' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
|
|
23
|
-
content: '';
|
|
24
|
-
display: block;
|
|
25
|
-
position: absolute;
|
|
26
|
-
top: 0;
|
|
27
|
-
left: 0;
|
|
28
|
-
right: 0;
|
|
29
|
-
bottom: 0;
|
|
30
|
-
background-color: var(--black-150);
|
|
31
|
-
-webkit-mask-image: var(--s-uploader-background-image);
|
|
32
|
-
mask-image: var(--s-uploader-background-image);
|
|
33
|
-
border-radius: var(--br-lg);
|
|
10
|
+
--_bg: var(--black-025);
|
|
11
|
+
--_bg-focus: var(--black-050);
|
|
12
|
+
--_bg-bc: var(--black-150);
|
|
13
|
+
--_focus-ring-color: var(--focus-ring);
|
|
34
14
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
});
|
|
38
|
-
}
|
|
15
|
+
// Static custom properties (not redefined but repeated enough to warrant a custom property)
|
|
16
|
+
--_bg-b-image: url("data:image/svg+xml,%3csvg width='100%25' height='100%25' xmlns='http://www.w3.org/2000/svg'%3e%3crect width='100%25' height='100%25' fill='none' rx='5' ry='5' stroke='%23000000' stroke-width='8' stroke-dasharray='7%2c 22' stroke-dashoffset='0' stroke-linecap='square'/%3e%3c/svg%3e");
|
|
39
17
|
|
|
40
|
-
|
|
41
|
-
|
|
18
|
+
.highcontrast-mode({
|
|
19
|
+
--_bg-bc-hc: var(--black-400);
|
|
20
|
+
});
|
|
42
21
|
|
|
43
|
-
|
|
44
|
-
|
|
22
|
+
&.is-active {
|
|
23
|
+
--_bg: var(--black-050);
|
|
24
|
+
--_bg-bc: var(--black-200);
|
|
25
|
+
}
|
|
45
26
|
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
}
|
|
27
|
+
&.is-disabled {
|
|
28
|
+
opacity: var(--_o-disabled-static);
|
|
29
|
+
}
|
|
50
30
|
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
31
|
+
&.has-error {
|
|
32
|
+
--_bg: var(--red-050);
|
|
33
|
+
--_bg-focus: var(--red-100);
|
|
34
|
+
--_bg-bc: var(--red-400);
|
|
35
|
+
--_bg-bc-hc-state: var(--red-400);
|
|
36
|
+
--_focus-ring-color: var(--focus-ring-error);
|
|
37
|
+
--_link-fc: var(--red-900);
|
|
54
38
|
}
|
|
55
39
|
|
|
56
40
|
&.has-success {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
background-color: var(--green-400);
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
.s-link {
|
|
68
|
-
color: var(--green-900);
|
|
69
|
-
}
|
|
41
|
+
--_bg: var(--green-025);
|
|
42
|
+
--_bg-focus: var(--green-050);
|
|
43
|
+
--_bg-bc: var(--green-400);
|
|
44
|
+
--_bg-bc-hc-state: var(--green-400);
|
|
45
|
+
--_focus-ring-color: var(--focus-ring-success);
|
|
46
|
+
--_link-fc: var(--green-900);
|
|
70
47
|
}
|
|
71
48
|
|
|
72
49
|
&.has-warning {
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
background-color: var(--yellow-400);
|
|
80
|
-
});
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
.s-link {
|
|
84
|
-
color: var(--yellow-900);
|
|
85
|
-
}
|
|
50
|
+
--_bg: var(--yellow-050);
|
|
51
|
+
--_bg-focus: var(--yellow-100);
|
|
52
|
+
--_bg-bc: var(--yellow-400);
|
|
53
|
+
--_bg-bc-hc-state: var(--yellow-400);
|
|
54
|
+
--_focus-ring-color: var(--focus-ring-warning);
|
|
55
|
+
--_link-fc: var(--yellow-900);
|
|
86
56
|
}
|
|
87
57
|
|
|
88
|
-
&.
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
.highcontrast-mode({
|
|
95
|
-
background-color: var(--black);
|
|
96
|
-
});
|
|
58
|
+
&.has-error,
|
|
59
|
+
&.has-success,
|
|
60
|
+
&.has-warning {
|
|
61
|
+
.s-link {
|
|
62
|
+
color: var(--_link-fc);
|
|
97
63
|
}
|
|
98
64
|
}
|
|
99
65
|
|
|
100
|
-
&.is-disabled {
|
|
101
|
-
opacity: 0.5;
|
|
102
|
-
}
|
|
103
|
-
|
|
104
66
|
// This is to for safari shadow DOM
|
|
105
67
|
// see https://github.com/StackExchange/Stacks/pull/690#issuecomment-861028193
|
|
106
68
|
input[type="file"]::file-selector-button {
|
|
107
69
|
cursor: pointer;
|
|
108
70
|
}
|
|
109
|
-
|
|
71
|
+
.s-uploader--container {
|
|
72
|
+
align-items: center;
|
|
73
|
+
background-color: var(--_bg);
|
|
74
|
+
border-radius: var(--br-lg);
|
|
75
|
+
display: flex;
|
|
76
|
+
flex-direction: column;
|
|
77
|
+
justify-content: center;
|
|
78
|
+
min-height: var(--su-static128);
|
|
79
|
+
padding: var(--su8) var(--su16);
|
|
80
|
+
position: relative;
|
|
81
|
+
text-align: center;
|
|
82
|
+
|
|
83
|
+
// Add the dashed border as an SVG background mask
|
|
84
|
+
&:before {
|
|
85
|
+
-webkit-mask-image: var(--_bg-b-image);
|
|
86
|
+
mask-image: var(--_bg-b-image);
|
|
87
|
+
background-color: var(--_bg-bc-hc-state, var(--_bg-bc-hc, var(--_bg-bc)));
|
|
88
|
+
content: '';
|
|
89
|
+
border-radius: var(--br-lg);
|
|
90
|
+
display: block;
|
|
91
|
+
position: absolute;
|
|
92
|
+
inset: 0;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
110
95
|
.s-uploader--input {
|
|
111
96
|
cursor: pointer;
|
|
112
97
|
height: 100%;
|
|
@@ -114,13 +99,13 @@
|
|
|
114
99
|
opacity: 0;
|
|
115
100
|
position: absolute;
|
|
116
101
|
width: 100%;
|
|
102
|
+
z-index: var(--zi-selected);
|
|
117
103
|
|
|
118
104
|
&:focus:focus-visible + .s-uploader--container {
|
|
119
|
-
background-color: var(--
|
|
120
|
-
box-shadow: 0 0 0 var(--su-static4) var(--
|
|
105
|
+
background-color: var(--_bg-focus);
|
|
106
|
+
box-shadow: 0 0 0 var(--su-static4) var(--_focus-ring-color);
|
|
121
107
|
}
|
|
122
108
|
}
|
|
123
|
-
|
|
124
109
|
.s-uploader--preview {
|
|
125
110
|
max-width: 100%;
|
|
126
111
|
pointer-events: none;
|
|
@@ -185,8 +170,7 @@
|
|
|
185
170
|
object-fit: cover;
|
|
186
171
|
}
|
|
187
172
|
&:not(img) {
|
|
188
|
-
|
|
189
|
-
background-image: var(--s-uploader--preview-document-icon);
|
|
173
|
+
background-image: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' aria-hidden='true' fill='%23535A60' width='18' height='18' viewBox='0 0 18 18'%3E%3Cpath d='M3 3a2 2 0 012-2h6l4 4v10a2 2 0 01-2 2H5a2 2 0 01-2-2V3zm7-1.5V6h4.5L10 1.5z'%3E%3C/path%3E%3C/svg%3E");
|
|
190
174
|
background-position: center;
|
|
191
175
|
background-repeat: no-repeat;
|
|
192
176
|
}
|
|
@@ -207,4 +191,6 @@
|
|
|
207
191
|
top: var(--su8);
|
|
208
192
|
z-index: var(--zi-active);
|
|
209
193
|
}
|
|
194
|
+
|
|
195
|
+
position: relative;
|
|
210
196
|
}
|
|
@@ -247,7 +247,7 @@
|
|
|
247
247
|
// Topbar Search input
|
|
248
248
|
--theme-topbar-search-color: var(--black-700);
|
|
249
249
|
--theme-topbar-search-background: var(--white);
|
|
250
|
-
--theme-topbar-search-placeholder: var(--black-
|
|
250
|
+
--theme-topbar-search-placeholder: var(--black-400);
|
|
251
251
|
--theme-topbar-search-border: var(--black-200);
|
|
252
252
|
--theme-topbar-search-border-focus: var(--blue-300);
|
|
253
253
|
--theme-topbar-search-shadow-focus: 0 0 0 var(--su-static4) var(--focus-ring);
|
|
@@ -409,6 +409,10 @@
|
|
|
409
409
|
--focus-ring-error: hsla(@red-h, 62%, 47%, 15%);
|
|
410
410
|
--focus-ring-muted: hsla(@black-h, @black-s, 15%, 10%);
|
|
411
411
|
|
|
412
|
+
// Opacity
|
|
413
|
+
--_o-disabled: 0.5;
|
|
414
|
+
--_o-disabled-static: 0.5;
|
|
415
|
+
|
|
412
416
|
// Shadows
|
|
413
417
|
--bs-sm: 0 1px 2px hsla(0, 0%, 0%, 0.05), 0 1px 4px hsla(0, 0%, 0%, 0.05), 0 2px 8px hsla(0, 0%, 0%, 0.05);
|
|
414
418
|
--bs-md: 0 1px 3px hsla(0, 0%, 0%, 0.06), 0 2px 6px hsla(0, 0%, 0%, 0.06), 0 3px 8px hsla(0, 0%, 0%, 0.09);
|
|
@@ -605,6 +609,10 @@
|
|
|
605
609
|
--focus-ring-error: hsla(@red-h, 62%, 52%, 30%);
|
|
606
610
|
--focus-ring-muted: hsla(@black-h, @black-s, 100%, 10%);
|
|
607
611
|
|
|
612
|
+
// Opacity
|
|
613
|
+
--_o-disabled: 0.5;
|
|
614
|
+
--_o-disabled-static: 0.5;
|
|
615
|
+
|
|
608
616
|
// Shadows
|
|
609
617
|
--bs-sm: 0 1px 2px hsla(0, 0%, 0%, 0.1), 0 1px 4px hsla(0, 0%, 0%, 0.1), 0 2px 8px hsla(0, 0%, 0%, 0.1);
|
|
610
618
|
--bs-md: 0 1px 3px hsla(0, 0%, 0%, 0.11), 0 2px 6px hsla(0, 0%, 0%, 0.11), 0 3px 8px hsla(0, 0%, 0%, 0.14);
|
|
@@ -709,10 +717,10 @@
|
|
|
709
717
|
--black-900: hsl(@black-h, @black-s, 0%);
|
|
710
718
|
|
|
711
719
|
// Orange
|
|
712
|
-
--orange-050: hsl(@orange-h, 100%,
|
|
713
|
-
--orange-100: hsl(@orange-h, 100%,
|
|
714
|
-
--orange-200: hsl(@orange-h, 100%,
|
|
715
|
-
--orange-300: hsl(@orange-h, 100%,
|
|
720
|
+
--orange-050: hsl(@orange-h, 100%, 93%);
|
|
721
|
+
--orange-100: hsl(@orange-h, 100%, 90%);
|
|
722
|
+
--orange-200: hsl(@orange-h, 100%, 86%);
|
|
723
|
+
--orange-300: hsl(@orange-h, 100%, 81%);
|
|
716
724
|
--orange-400: hsl(@orange-h, 100%, 34%);
|
|
717
725
|
--orange-500: hsl(@orange-h, 100%, 29%);
|
|
718
726
|
--orange-600: hsl(@orange-h, 100%, 24%);
|
|
@@ -721,10 +729,10 @@
|
|
|
721
729
|
--orange-900: hsl(@orange-h, 100%, 8%);
|
|
722
730
|
|
|
723
731
|
// Blue
|
|
724
|
-
--blue-050: hsl(@blue-h, 100%,
|
|
725
|
-
--blue-100: hsl(@blue-h, 100%,
|
|
726
|
-
--blue-200: hsl(@blue-h, 100%,
|
|
727
|
-
--blue-300: hsl(@blue-h, 100%,
|
|
732
|
+
--blue-050: hsl(@blue-h, 100%, 94%);
|
|
733
|
+
--blue-100: hsl(@blue-h, 100%, 92%);
|
|
734
|
+
--blue-200: hsl(@blue-h, 100%, 89%);
|
|
735
|
+
--blue-300: hsl(@blue-h, 100%, 86%);
|
|
728
736
|
--blue-400: hsl(@blue-h, 100%, 25%);
|
|
729
737
|
--blue-500: hsl(@blue-h, 100%, 20%);
|
|
730
738
|
--blue-600: hsl(@blue-h, 100%, 15%);
|
|
@@ -733,10 +741,10 @@
|
|
|
733
741
|
--blue-900: hsl(@blue-h, 100%, 5%);
|
|
734
742
|
|
|
735
743
|
// Powder
|
|
736
|
-
--powder-050: hsl(@powder-h, 100%,
|
|
737
|
-
--powder-100: hsl(@powder-h, 85%,
|
|
738
|
-
--powder-200: hsl(@powder-h, 75%,
|
|
739
|
-
--powder-300: hsl(@powder-h, 70%,
|
|
744
|
+
--powder-050: hsl(@powder-h, 100%, 95%);
|
|
745
|
+
--powder-100: hsl(@powder-h, 85%, 93%);
|
|
746
|
+
--powder-200: hsl(@powder-h, 75%, 89%);
|
|
747
|
+
--powder-300: hsl(@powder-h, 70%, 86%);
|
|
740
748
|
--powder-400: hsl(@powder-h, 55%, 28%);
|
|
741
749
|
--powder-500: hsl(@powder-h, 60%, 24%);
|
|
742
750
|
--powder-600: hsl(@powder-h, 70%, 20%);
|
|
@@ -745,11 +753,11 @@
|
|
|
745
753
|
--powder-900: hsl(@powder-h, 75%, 8%);
|
|
746
754
|
|
|
747
755
|
// Green
|
|
748
|
-
--green-025: hsl(@green-h, 100%,
|
|
749
|
-
--green-050: hsl(@green-h, 100%,
|
|
750
|
-
--green-100: hsl(@green-h, 100%,
|
|
751
|
-
--green-200: hsl(@green-h, 100%,
|
|
752
|
-
--green-300: hsl(@green-h, 100%,
|
|
756
|
+
--green-025: hsl(@green-h, 100%, 94%);
|
|
757
|
+
--green-050: hsl(@green-h, 100%, 91%);
|
|
758
|
+
--green-100: hsl(@green-h, 100%, 87%);
|
|
759
|
+
--green-200: hsl(@green-h, 100%, 83%);
|
|
760
|
+
--green-300: hsl(@green-h, 100%, 78%);
|
|
753
761
|
--green-400: hsl(@green-h, 100%, 18%);
|
|
754
762
|
--green-500: hsl(@green-h, 100%, 15%);
|
|
755
763
|
--green-600: hsl(@green-h, 100%, 12%);
|
|
@@ -758,10 +766,10 @@
|
|
|
758
766
|
--green-900: hsl(@green-h, 100%, 3%);
|
|
759
767
|
|
|
760
768
|
// Yellow
|
|
761
|
-
--yellow-050: hsl(@yellow-h, 100%,
|
|
762
|
-
--yellow-100: hsl(@yellow-h, 100%,
|
|
763
|
-
--yellow-200: hsl(@yellow-h, 95%,
|
|
764
|
-
--yellow-300: hsl(@yellow-h, 95%,
|
|
769
|
+
--yellow-050: hsl(@yellow-h, 100%, 92%);
|
|
770
|
+
--yellow-100: hsl(@yellow-h, 100%, 88%);
|
|
771
|
+
--yellow-200: hsl(@yellow-h, 95%, 83%);
|
|
772
|
+
--yellow-300: hsl(@yellow-h, 95%, 75%);
|
|
765
773
|
--yellow-400: hsl(@yellow-h, 100%, 28%);
|
|
766
774
|
--yellow-500: hsl(@yellow-h, 100%, 26%);
|
|
767
775
|
--yellow-600: hsl(@yellow-h, 100%, 23%);
|
|
@@ -770,10 +778,10 @@
|
|
|
770
778
|
--yellow-900: hsl(@yellow-h, 100%, 7%);
|
|
771
779
|
|
|
772
780
|
// Red
|
|
773
|
-
--red-050: hsl(@red-h, 100%,
|
|
774
|
-
--red-100: hsl(@red-h, 100%,
|
|
775
|
-
--red-200: hsl(@red-h, 100%,
|
|
776
|
-
--red-300: hsl(@red-h, 100%,
|
|
781
|
+
--red-050: hsl(@red-h, 100%, 94%);
|
|
782
|
+
--red-100: hsl(@red-h, 100%, 92%);
|
|
783
|
+
--red-200: hsl(@red-h, 100%, 89%);
|
|
784
|
+
--red-300: hsl(@red-h, 100%, 86%);
|
|
777
785
|
--red-400: hsl(@red-h, 100%, 35%);
|
|
778
786
|
--red-500: hsl(@red-h, 100%, 29%);
|
|
779
787
|
--red-600: hsl(@red-h, 100%, 23%);
|
|
@@ -816,6 +824,9 @@
|
|
|
816
824
|
--focus-ring-error: fade(@red-600, 90%);
|
|
817
825
|
--focus-ring-muted: fade(@black-400, 95%);
|
|
818
826
|
|
|
827
|
+
// Opacity
|
|
828
|
+
--_o-disabled: 0.8;
|
|
829
|
+
|
|
819
830
|
// Shadows
|
|
820
831
|
--bs-sm: none;
|
|
821
832
|
--bs-md: none;
|
|
@@ -865,10 +876,10 @@
|
|
|
865
876
|
--black-900: hsl(@black-h, @black-s, 100%);
|
|
866
877
|
|
|
867
878
|
// Orange
|
|
868
|
-
--orange-050: hsl(@orange-h, 100%,
|
|
869
|
-
--orange-100: hsl(@orange-h, 100%,
|
|
870
|
-
--orange-200: hsl(@orange-h, 100%,
|
|
871
|
-
--orange-300: hsl(@orange-h, 100%,
|
|
879
|
+
--orange-050: hsl(@orange-h, 100%, 7%);
|
|
880
|
+
--orange-100: hsl(@orange-h, 100%, 9%);
|
|
881
|
+
--orange-200: hsl(@orange-h, 100%, 15%);
|
|
882
|
+
--orange-300: hsl(@orange-h, 100%, 22%);
|
|
872
883
|
--orange-400: hsl(@orange-h, 100%, 64%);
|
|
873
884
|
--orange-500: hsl(@orange-h, 100%, 71%);
|
|
874
885
|
--orange-600: hsl(@orange-h, 100%, 77%);
|
|
@@ -877,10 +888,10 @@
|
|
|
877
888
|
--orange-900: hsl(@orange-h, 100%, 91%);
|
|
878
889
|
|
|
879
890
|
// Blue
|
|
880
|
-
--blue-050: hsl(@blue-h, 100%,
|
|
891
|
+
--blue-050: hsl(@blue-h, 100%, 7%);
|
|
881
892
|
--blue-100: hsl(@blue-h, 100%, 11%);
|
|
882
|
-
--blue-200: hsl(@blue-h, 100%,
|
|
883
|
-
--blue-300: hsl(@blue-h, 100%,
|
|
893
|
+
--blue-200: hsl(@blue-h, 100%, 17%);
|
|
894
|
+
--blue-300: hsl(@blue-h, 100%, 24%);
|
|
884
895
|
--blue-400: hsl(@blue-h, 100%, 75%);
|
|
885
896
|
--blue-500: hsl(@blue-h, 100%, 80%);
|
|
886
897
|
--blue-600: hsl(@blue-h, 100%, 85%);
|
|
@@ -889,10 +900,10 @@
|
|
|
889
900
|
--blue-900: hsl(@blue-h, 100%, 95%);
|
|
890
901
|
|
|
891
902
|
// Powder
|
|
892
|
-
--powder-050: hsl(@powder-h, 100%,
|
|
893
|
-
--powder-100: hsl(@powder-h,
|
|
903
|
+
--powder-050: hsl(@powder-h, 100%, 7%);
|
|
904
|
+
--powder-100: hsl(@powder-h, 95%, 10%);
|
|
894
905
|
--powder-200: hsl(@powder-h, 80%, 14%);
|
|
895
|
-
--powder-300: hsl(@powder-h,
|
|
906
|
+
--powder-300: hsl(@powder-h, 76%, 19%);
|
|
896
907
|
--powder-400: hsl(@powder-h, 55%, 72%);
|
|
897
908
|
--powder-500: hsl(@powder-h, 60%, 76%);
|
|
898
909
|
--powder-600: hsl(@powder-h, 70%, 80%);
|
|
@@ -901,11 +912,11 @@
|
|
|
901
912
|
--powder-900: hsl(@powder-h, 75%, 92%);
|
|
902
913
|
|
|
903
914
|
// Green
|
|
904
|
-
--green-025: hsl(@green-h, 100%,
|
|
905
|
-
--green-050: hsl(@green-h, 100%,
|
|
906
|
-
--green-100: hsl(@green-h, 100%,
|
|
907
|
-
--green-200: hsl(@green-h, 100%,
|
|
908
|
-
--green-300: hsl(@green-h, 100%,
|
|
915
|
+
--green-025: hsl(@green-h, 100%, 5%);
|
|
916
|
+
--green-050: hsl(@green-h, 100%, 6%);
|
|
917
|
+
--green-100: hsl(@green-h, 100%, 7%);
|
|
918
|
+
--green-200: hsl(@green-h, 100%, 11%);
|
|
919
|
+
--green-300: hsl(@green-h, 100%, 15%);
|
|
909
920
|
--green-400: hsl(@green-h, 100%, 65%);
|
|
910
921
|
--green-500: hsl(@green-h, 100%, 71%);
|
|
911
922
|
--green-600: hsl(@green-h, 100%, 77%);
|
|
@@ -914,10 +925,10 @@
|
|
|
914
925
|
--green-900: hsl(@green-h, 100%, 94%);
|
|
915
926
|
|
|
916
927
|
// Yellow
|
|
917
|
-
--yellow-050: hsl(@yellow-h, 100%,
|
|
918
|
-
--yellow-100: hsl(@yellow-h, 100%,
|
|
919
|
-
--yellow-200: hsl(@yellow-h,
|
|
920
|
-
--yellow-300: hsl(@yellow-h,
|
|
928
|
+
--yellow-050: hsl(@yellow-h, 100%, 6%);
|
|
929
|
+
--yellow-100: hsl(@yellow-h, 100%, 9%);
|
|
930
|
+
--yellow-200: hsl(@yellow-h, 100%, 14%);
|
|
931
|
+
--yellow-300: hsl(@yellow-h, 100%, 20%);
|
|
921
932
|
--yellow-400: hsl(@yellow-h, 100%, 55%);
|
|
922
933
|
--yellow-500: hsl(@yellow-h, 100%, 63%);
|
|
923
934
|
--yellow-600: hsl(@yellow-h, 100%, 71%);
|
|
@@ -926,10 +937,10 @@
|
|
|
926
937
|
--yellow-900: hsl(@yellow-h, 100%, 95%);
|
|
927
938
|
|
|
928
939
|
// Red
|
|
929
|
-
--red-050: hsl(@red-h, 100%,
|
|
930
|
-
--red-100: hsl(@red-h, 100%,
|
|
931
|
-
--red-200: hsl(@red-h, 100%,
|
|
932
|
-
--red-300: hsl(@red-h, 100%,
|
|
940
|
+
--red-050: hsl(@red-h, 100%, 9%);
|
|
941
|
+
--red-100: hsl(@red-h, 100%, 12%);
|
|
942
|
+
--red-200: hsl(@red-h, 100%, 17%);
|
|
943
|
+
--red-300: hsl(@red-h, 100%, 22%);
|
|
933
944
|
--red-400: hsl(@red-h, 100%, 70%);
|
|
934
945
|
--red-500: hsl(@red-h, 100%, 75%);
|
|
935
946
|
--red-600: hsl(@red-h, 100%, 80%);
|
|
@@ -972,6 +983,9 @@
|
|
|
972
983
|
--fc-medium: var(--black-700);
|
|
973
984
|
--fc-light: var(--black-500);
|
|
974
985
|
|
|
986
|
+
// Opacity
|
|
987
|
+
--_o-disabled: 0.8;
|
|
988
|
+
|
|
975
989
|
// Shadows
|
|
976
990
|
--bs-sm: none;
|
|
977
991
|
--bs-md: none;
|
|
@@ -20,13 +20,14 @@
|
|
|
20
20
|
@import "components/activity-indicator.less";
|
|
21
21
|
@import "components/avatars.less";
|
|
22
22
|
@import "components/badges.less";
|
|
23
|
-
@import "components/
|
|
23
|
+
@import "components/empty-states.less";
|
|
24
24
|
@import "components/breadcrumbs.less";
|
|
25
25
|
@import "components/button-groups.less";
|
|
26
26
|
@import "components/cards.less";
|
|
27
27
|
@import "components/code-blocks.less";
|
|
28
|
-
@import "components/
|
|
28
|
+
@import "components/expandable.less";
|
|
29
29
|
@import "components/inputs.less";
|
|
30
|
+
@import "components/labels.less";
|
|
30
31
|
@import "components/menu.less";
|
|
31
32
|
@import "components/modals.less";
|
|
32
33
|
@import "components/navigation.less";
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as Stacks from '../stacks';
|
|
2
2
|
|
|
3
3
|
// Radio buttons only trigger a change event when they're *checked*, but not when
|
|
4
|
-
// they're *unchecked*. Therefore, if we have an active `s-
|
|
4
|
+
// they're *unchecked*. Therefore, if we have an active `s-expandable-control` in
|
|
5
5
|
// the document, we listen for change events on *all* radio buttons and find any
|
|
6
6
|
// other radio buttons in the same `name` group, triggering a custom event on all
|
|
7
7
|
// of them so the controller can re-evaluate.
|
|
@@ -20,7 +20,7 @@ function globalChangeListener(e: UIEvent) {
|
|
|
20
20
|
if (other === e.target) {
|
|
21
21
|
return;
|
|
22
22
|
}
|
|
23
|
-
|
|
23
|
+
let customEvent;
|
|
24
24
|
try {
|
|
25
25
|
customEvent = new Event(RADIO_OFF_EVENT);
|
|
26
26
|
} catch (ex) {
|
|
@@ -32,7 +32,7 @@ function globalChangeListener(e: UIEvent) {
|
|
|
32
32
|
});
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
let refCount = 0;
|
|
36
36
|
function globalChangeListenerRequired(required: boolean) {
|
|
37
37
|
if (required) {
|
|
38
38
|
refCount++;
|
|
@@ -52,16 +52,16 @@ export class ExpandableController extends Stacks.StacksController {
|
|
|
52
52
|
private events!: string[];
|
|
53
53
|
private isCheckable!: boolean;
|
|
54
54
|
private isRadio!: boolean;
|
|
55
|
-
private lastKeydownClickTimestamp
|
|
55
|
+
private lastKeydownClickTimestamp = 0;
|
|
56
56
|
|
|
57
57
|
initialize() {
|
|
58
58
|
if (this.element.nodeName === "INPUT" && ["radio", "checkbox"].indexOf((<HTMLInputElement>this.element).type) >= 0) {
|
|
59
|
-
this.isCollapsed = this._isCollapsedForCheckable;
|
|
59
|
+
this.isCollapsed = this._isCollapsedForCheckable.bind(this);
|
|
60
60
|
this.events = ["change", RADIO_OFF_EVENT];
|
|
61
61
|
this.isCheckable = true;
|
|
62
62
|
this.isRadio = (<HTMLInputElement>this.element).type === "radio";
|
|
63
63
|
} else {
|
|
64
|
-
this.isCollapsed = this._isCollapsedForClickable;
|
|
64
|
+
this.isCollapsed = this._isCollapsedForClickable.bind(this);
|
|
65
65
|
this.events = ["click", "keydown"];
|
|
66
66
|
}
|
|
67
67
|
this.listener = this.listener.bind(this);
|
|
@@ -71,7 +71,7 @@ export class ExpandableController extends Stacks.StacksController {
|
|
|
71
71
|
// for non-checkable elements, the initial source of truth is the collapsed/expanded
|
|
72
72
|
// state of the controlled element (unless the element doesn't exist)
|
|
73
73
|
_isCollapsedForClickable() {
|
|
74
|
-
|
|
74
|
+
const cc = this.controlledExpandables;
|
|
75
75
|
// the element is considered collapsed if *any* target element is collapsed
|
|
76
76
|
return cc.length > 0 ? !cc.every(element => element.classList.contains("is-expanded")) : this.element.getAttribute("aria-expanded") === "false";
|
|
77
77
|
};
|
|
@@ -82,7 +82,7 @@ export class ExpandableController extends Stacks.StacksController {
|
|
|
82
82
|
};
|
|
83
83
|
|
|
84
84
|
|
|
85
|
-
get
|
|
85
|
+
get controlledExpandables() {
|
|
86
86
|
const attr = this.element.getAttribute("aria-controls");
|
|
87
87
|
if (!attr) {
|
|
88
88
|
throw `[aria-controls="targetId1 ... targetIdN"] attribute required`;
|
|
@@ -104,8 +104,8 @@ export class ExpandableController extends Stacks.StacksController {
|
|
|
104
104
|
if (!this.data.has("toggle-class")) {
|
|
105
105
|
return;
|
|
106
106
|
}
|
|
107
|
-
|
|
108
|
-
|
|
107
|
+
const cl = this.element.classList;
|
|
108
|
+
const toggleClass = this.data.get("toggle-class");
|
|
109
109
|
if (!toggleClass) {
|
|
110
110
|
throw "couldn't find toggle class"
|
|
111
111
|
}
|
|
@@ -115,7 +115,7 @@ export class ExpandableController extends Stacks.StacksController {
|
|
|
115
115
|
};
|
|
116
116
|
|
|
117
117
|
listener(e: Event) {
|
|
118
|
-
|
|
118
|
+
let newCollapsed;
|
|
119
119
|
if (this.isCheckable) {
|
|
120
120
|
newCollapsed = !(<HTMLInputElement>this.element).checked;
|
|
121
121
|
} else {
|
|
@@ -142,7 +142,7 @@ export class ExpandableController extends Stacks.StacksController {
|
|
|
142
142
|
}
|
|
143
143
|
}
|
|
144
144
|
this.element.setAttribute("aria-expanded", newCollapsed ? "false" : "true");
|
|
145
|
-
for (
|
|
145
|
+
for (const controlledElement of this.controlledExpandables) {
|
|
146
146
|
controlledElement.classList.toggle("is-expanded", !newCollapsed);
|
|
147
147
|
}
|
|
148
148
|
this._dispatchShowHideEvent(!newCollapsed);
|
|
@@ -151,7 +151,7 @@ export class ExpandableController extends Stacks.StacksController {
|
|
|
151
151
|
|
|
152
152
|
connect() {
|
|
153
153
|
this.events.forEach(e => {
|
|
154
|
-
this.element.addEventListener(e, this.listener);
|
|
154
|
+
this.element.addEventListener(e, this.listener.bind(this));
|
|
155
155
|
}, this);
|
|
156
156
|
|
|
157
157
|
if (this.isRadio) {
|
|
@@ -159,15 +159,19 @@ export class ExpandableController extends Stacks.StacksController {
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
// synchronize state -- in all cases, this means setting the correct `aria-expanded`
|
|
162
|
-
// attribute; for checkable controls this also means setting the `is-collapsed` class
|
|
163
|
-
|
|
162
|
+
// attribute; for checkable controls this also means setting the `is-collapsed` class.
|
|
163
|
+
// Note: aria-expanded is currently an invalid attribute on radio elements
|
|
164
|
+
// Support for aria-expanded is being debated by the W3C https://github.com/w3c/aria/issues/1404 as recently as June 2022
|
|
165
|
+
if (!this.isRadio) {
|
|
166
|
+
this.element.setAttribute("aria-expanded", this.isCollapsed() ? "false" : "true");
|
|
167
|
+
}
|
|
164
168
|
if (this.isCheckable) {
|
|
165
|
-
|
|
169
|
+
const cc = this.controlledExpandables;
|
|
166
170
|
if (cc.length) {
|
|
167
|
-
|
|
171
|
+
const expected = !this.isCollapsed();
|
|
168
172
|
// if any element does not match the expected state, set them all to the expected state
|
|
169
173
|
if (cc.some(element => element.classList.contains("is-expanded") !== expected)) {
|
|
170
|
-
for (
|
|
174
|
+
for (const controlledElement of this.controlledExpandables) {
|
|
171
175
|
controlledElement.classList.toggle("is-expanded", expected);
|
|
172
176
|
}
|
|
173
177
|
this._dispatchShowHideEvent(expected);
|
|
@@ -179,7 +183,7 @@ export class ExpandableController extends Stacks.StacksController {
|
|
|
179
183
|
|
|
180
184
|
disconnect() {
|
|
181
185
|
this.events.forEach(e => {
|
|
182
|
-
this.element.removeEventListener(e, this.listener);
|
|
186
|
+
this.element.removeEventListener(e, this.listener.bind(this));
|
|
183
187
|
}, this);
|
|
184
188
|
|
|
185
189
|
if (this.isRadio) {
|