@stackoverflow/stacks 1.5.0 → 1.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,251 @@
1
+ .s-sidebarwidget {
2
+ // CONSTANTS
3
+ --_sw-content-px: calc(var(--su16) - var(--su1)); // subtract 1px for border
4
+ --_sw-content-spacing-inner: var(--su12); // the spacing between two adjacent simple items
5
+ --_sw-content-spacing-outer: var(--su16); // the spacing at the start/end of a group of simple items, as well as between a complex item and its separator line
6
+
7
+ // VARIABLES
8
+ --_sw-bc: var(--bc-medium);
9
+ --_sw-after-bc: var(--_sw-bc);
10
+ --_sw-content-bc: var(--bc-light);
11
+ --_sw-header-bc: var(--_sw-content-bc);
12
+
13
+ // VARIANTS
14
+ .alternate-color(blue);
15
+ .alternate-color(yellow);
16
+ .alternate-color(green);
17
+
18
+ // CHILD ELEMENTS
19
+ & &--action {
20
+ color: var(--blue);
21
+ float: right;
22
+ font-size: var(--fs-fine);
23
+ line-height: calc(var(--fs-body1) * 1.5); // 19.5px - line-height should be the same as in the outside element, so the header and action baselines line up
24
+ margin: 0 0 var(--su4) var(--su8);
25
+ }
26
+
27
+ & &--content {
28
+ &.s-sidebarwidget__items {
29
+ &,
30
+ &.s-sidebarwidget__block-items .s-sidebarwidget--item {
31
+ display: block;
32
+ }
33
+
34
+ padding: calc(var(--_sw-content-spacing-outer) - var(--_sw-content-spacing-inner)) var(--_sw-content-px); // the items themselves provide part of the spacing, so the content padding needs to account for that
35
+ }
36
+
37
+ &:active {
38
+ outline: none;
39
+ }
40
+
41
+ &:not(table) {
42
+ &:not(.s-sidebarwidget__items),
43
+ &:not(.s-sidebarwidget__block-items) .s-sidebarwidget--item {
44
+ display: flex;
45
+ }
46
+ }
47
+
48
+ border-top: var(--su-static1) solid var(--_sw-content-bc);
49
+ margin: 0;
50
+ padding: var(--_sw-content-spacing-outer) var(--_sw-content-px);
51
+ }
52
+
53
+ & &--header {
54
+ &.s-sidebarwidget__expanding-control {
55
+ &:before {
56
+ border: calc(var(--su-static4) + var(--su-static1)) solid transparent;
57
+ border-left-color: var(--bc-darker);
58
+ border-right-width: 0;
59
+ content: '';
60
+ float: left;
61
+ margin-right: var(--su12);
62
+ margin-top: calc(calc(var(--lh-base) * 1em) / 2 - 5px); // 1.3 is our standard line height
63
+ transition: transform 0.3s cubic-bezier(0.4, 0.4, 0.6, 1);
64
+ }
65
+
66
+ &[aria-expanded='true']:before {
67
+ transform: rotate(90deg);
68
+ }
69
+
70
+ cursor: pointer;
71
+ }
72
+
73
+ &.s-sidebarwidget__small-bold-text {
74
+ .s-sidebarwidget--action {
75
+ font-weight: normal;
76
+ 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
77
+ }
78
+
79
+ font-size: var(--fs-caption);
80
+ font-weight: bold;
81
+ }
82
+
83
+ &:first-child {
84
+ border-top-left-radius: var(--br-sm);
85
+ border-top-right-radius: var(--br-sm);
86
+ }
87
+
88
+ &:active {
89
+ outline: none;
90
+ }
91
+
92
+ background: var(--black-025);
93
+ border-top: var(--su-static1) solid var(--_sw-header-bc);
94
+ color: var(--black-600);
95
+ font-size: var(--fs-body2);
96
+ font-weight: normal;
97
+ margin: 0;
98
+ padding: var(--_sw-content-spacing-inner) var(--_sw-content-px);
99
+ }
100
+
101
+ & &--item {
102
+ &,
103
+ & > :first-child {
104
+ &[aria-current="true"],
105
+ &[aria-current="page"] {
106
+ &:before {
107
+ border-left-color: var(--theme-primary-color);
108
+ border-left-style: solid;
109
+ border-left-width: calc(var(--su-static1) * 3); // 3px
110
+ content: '';
111
+ height: calc(100% + var(--_sw-content-spacing-inner));
112
+ left: 0;
113
+ margin-left: calc(var(--_sw-content-px) * -1 - var(--su-static1)); // the orange selection indicator overlaps with the widget border
114
+ margin-top: calc(var(--_sw-content-spacing-inner) / 2 * -1);
115
+ position: absolute;
116
+ }
117
+
118
+ a,
119
+ a:visited { // 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
120
+ color: inherit;
121
+ }
122
+
123
+ color: var(--black);
124
+ font-weight: bold;
125
+ position: relative;
126
+ }
127
+ }
128
+
129
+ margin: var(--_sw-content-spacing-inner) 0;
130
+ }
131
+
132
+ & &--subnav {
133
+ li {
134
+ &[aria-current="page"],
135
+ &[aria-current="true"] {
136
+ a,
137
+ a:visited {
138
+ color: inherit;
139
+ }
140
+
141
+ #stacks-internals #bullet-arrow(var(--theme-primary-color));
142
+ color: var(--black);
143
+ font-weight: bold;
144
+ }
145
+
146
+ #stacks-internals #bullet-arrow(var(--black-100));
147
+ background-position: 0 calc((1.2em - 10px) / 2);
148
+ background-repeat: no-repeat;
149
+ background-size: auto 10px;
150
+ margin-top: var(--su-static12);
151
+ padding-left: var(--su-static16);
152
+ }
153
+
154
+ list-style-type: none;
155
+ margin-left: var(--su8);
156
+ padding-left: 0;
157
+ }
158
+
159
+ & table&--content&__items {
160
+ tr.s-sidebarwidget--item {
161
+ td {
162
+ padding: 0;
163
+ }
164
+
165
+ display: table-row;
166
+ }
167
+
168
+ border-collapse: separate;
169
+ border-spacing: var(--_sw-content-spacing-inner);
170
+ padding: calc(var(--_sw-content-spacing-outer) - var(--_sw-content-spacing-inner)) calc(var(--_sw-content-px) - var(--_sw-content-spacing-inner));
171
+ }
172
+
173
+ &:not(.s-anchors) a:not(.button):not(.s-btn):not(.post-tag):not(&--action):not(.s-user-card--link) {
174
+ &,
175
+ &:visited {
176
+ color: var(--black-500);
177
+ }
178
+ }
179
+
180
+ &:before { // [1]
181
+ content: '';
182
+ display: block;
183
+ margin-top: calc(var(--su-static1) * -1); // -1px
184
+ }
185
+
186
+ &:after { // [2]
187
+ border: var(--su-static1) solid var(--_sw-after-bc);
188
+ border-radius: var(--br-sm);
189
+ clip-path: polygon(0% 0%, 100% 0%, 100% 50%, 0% 50%); // [3]
190
+ content: '';
191
+ // TODO: this makes no sense. revisit.
192
+ height: calc(2px + var(--br-sm)); // we need 2px border + 2px border radius to have the correct corner shape
193
+ left: calc(var(--su-static1) * -1); // -1px
194
+ pointer-events: none; // if the top item is clickable, then we don't want to prevent clicking the top 2 pixels
195
+ position: absolute;
196
+ right: calc(var(--su-static1) * -1); // -1px
197
+ top: calc(var(--su-static1) * -1); // -1px
198
+ }
199
+
200
+ background-color: var(--white);
201
+ border: var(--su-static1) solid var(--_sw-bc);
202
+ border-radius: var(--br-sm);
203
+ box-shadow: var(--bs-sm);
204
+ font-size: var(--fs-body1);
205
+ position: relative; // so that it's the positioning parent for the :after
206
+ }
207
+
208
+
209
+ // COLOR ALTERNATIVES
210
+ .alternate-color(@name) {
211
+ &.s-sidebarwidget__@{name} {
212
+ --_sw-bc: var(~"--@{name}-200");
213
+
214
+ .highcontrast-mode({
215
+ --_sw-bc: var(~"--@{name}-700");
216
+ });
217
+
218
+ .s-sidebarwidget--header {
219
+ background-color: var(~"--@{name}-100");
220
+ color: var(--fc-medium);
221
+ }
222
+
223
+ .s-sidebarwidget--header,
224
+ .s-sidebarwidget--content,
225
+ &:after {
226
+ border-color: var(--_sw-bc);
227
+ }
228
+
229
+ background-color: var(~"--@{name}-050");
230
+ border-color: var(--_sw-bc);
231
+ }
232
+ }
233
+
234
+ // [1] We must support things like collapsible (in particular invisble) elements, wrapper elements,
235
+ // etc. Therefore every .-content and .-header must stand on its own; we cannot rely on things
236
+ // like :first-child, because the *first* child may not be the first *visible* child, and it may
237
+ // also be the :first-child of some wrapper. This is why every .-header and .-content has a
238
+ // border-top. But because you shouldn't see the first visible item's or header's top border
239
+ // (the widget itself provides for that border), we shift everything up by one pixel with the following pseudo-element.
240
+
241
+ // [2] The top item's divider line sits above the .s-sidebarwidget's top border.
242
+ // We could fix this by using overflow: hidden, but that would constrain users of
243
+ // .s-sidebarwidget to never have things like tooltips, autocompletes or the like that reach
244
+ // outside the widget boundaries.
245
+ // What we do instead is re-create the widget's top border in an absolutely positioned :after,
246
+ // which sits above our item's top border. Technically, a tiny corner of the item's border will
247
+ // still be visible, but at its highest point, this corner has a height of 0.27 pixels. And for
248
+ // this sub-pixel issues, we're talking about different shades of gray. So we can live with that.
249
+
250
+ // [3] In order to perfectly recreate the inner corner shape, our pseudo-element needs
251
+ // the border on all sides. But we can only do that if we're able to hide the bottom part.
@@ -1,27 +1,3 @@
1
- //
2
- // STACK OVERFLOW
3
- // TABLES
4
- //
5
- // This CSS comes from Stacks, our CSS & Pattern library for rapidly building
6
- // Stack Overflow. For documentation of all these classes and how to contribute,
7
- // visit https://stackoverflow.design/
8
- //
9
- // TABLE OF CONTENTS
10
- // • CONTAINER
11
- // • BASE TABLE STYLE
12
- // • TABLE ALIGNMENT
13
- // - Vertical alignment
14
- // - Text alignment
15
- // • LAYOUT VARIATIONS
16
- // - Stripes
17
- // - Spacing
18
- // - Borders
19
- // - Backgrounds
20
- // - Totals row
21
- // - Sortable tables
22
- // • TABLE CELL SIZES
23
- //
24
-
25
1
  // ============================================================================
26
2
  // $ CONTAINER
27
3
  // Give tables an optional container for responsive scrolling
@@ -1,14 +1,3 @@
1
- //
2
- // STACK OVERFLOW
3
- // TOPBAR
4
- //
5
- // This CSS comes from Stacks, our CSS & Pattern library for rapidly building
6
- // Stack Overflow. For documentation of all these classes and how to contribute,
7
- // visit https://stackoverflow.design/
8
- //
9
- // ============================================================================
10
- // $ BASE STYLE
11
- // ----------------------------------------------------------------------------
12
1
  .topbar-notice-styles(@border: transparent, @background: transparent, @color: inherit) {
13
2
  border-color: @border;
14
3
  background-color: @background;
@@ -252,6 +241,15 @@
252
241
  // ===========================================================================
253
242
  // $ CONTENT & CTAS
254
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
+
255
253
  .s-topbar .s-topbar--content {
256
254
  display: flex;
257
255
  height: 100%;
@@ -261,6 +259,7 @@
261
259
  display: inline-flex;
262
260
  }
263
261
 
262
+ // TODO remove once all topbars include necessary nav.s-topbar--navigation wrapper elements
264
263
  overflow-x: auto; // Allow this content to scroll if it gets too long
265
264
  @scrollbar-styles(); // Style the scrollbars
266
265
  margin-left: auto; // Push this section as far to the right as possible
@@ -24,7 +24,6 @@
24
24
  @import "components/notices.less";
25
25
  @import "components/tags.less";
26
26
  @import "components/pagination.less";
27
- @import "components/widget-dynamic.less";
28
27
 
29
28
  // -- LESS CONSTANTS AND MIXINS
30
29
  @import "exports/exports.less";
@@ -37,13 +37,13 @@
37
37
  @import "components/post-summary.less";
38
38
  @import "components/progress-bars.less";
39
39
  @import "components/prose.less";
40
+ @import "components/sidebar-widgets.less";
40
41
  @import "components/spinner.less";
41
42
  @import "components/tables.less";
42
43
  @import "components/toggle-switches.less";
43
44
  @import "components/topbar.less";
44
45
  @import "components/uploader.less";
45
46
  @import "components/user-cards.less";
46
- @import "components/widget-static.less";
47
47
 
48
48
  // -- LESS CONSTANTS AND MIXINS
49
49
  @import "exports/exports.less";
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "type": "git",
6
6
  "url": "https://github.com/StackExchange/Stacks.git"
7
7
  },
8
- "version": "1.5.0",
8
+ "version": "1.6.0",
9
9
  "files": [
10
10
  "dist",
11
11
  "lib"
@@ -38,16 +38,16 @@
38
38
  "@highlightjs/cdn-assets": "^11.6.0",
39
39
  "@stackoverflow/stacks-editor": "^0.8.2",
40
40
  "@stackoverflow/stacks-icons": "^3.1.0",
41
- "@typescript-eslint/eslint-plugin": "^5.41.0",
42
- "@typescript-eslint/parser": "^5.40.1",
43
- "backstopjs": "^6.1.3",
41
+ "@typescript-eslint/eslint-plugin": "^5.42.0",
42
+ "@typescript-eslint/parser": "^5.44.0",
43
+ "backstopjs": "^6.1.4",
44
44
  "concurrently": "^7.5.0",
45
- "css-loader": "^6.7.1",
45
+ "css-loader": "^6.7.2",
46
46
  "cssnano": "^5.1.14",
47
47
  "docsearch.js": "^2.6.3",
48
48
  "eleventy-plugin-highlightjs": "^1.1.0",
49
49
  "eleventy-plugin-nesting-toc": "^1.3.0",
50
- "eslint": "^8.26.0",
50
+ "eslint": "^8.27.0",
51
51
  "eslint-config-prettier": "^8.5.0",
52
52
  "eslint-plugin-no-unsanitized": "^4.0.1",
53
53
  "jquery": "^3.6.1",
@@ -58,14 +58,14 @@
58
58
  "postcss-less": "^6.0.0",
59
59
  "postcss-loader": "^7.0.1",
60
60
  "prettier": "^2.7.1",
61
- "stylelint": "^14.13.0",
61
+ "stylelint": "^14.15.0",
62
62
  "stylelint-config-recommended": "^9.0.0",
63
63
  "stylelint-config-standard": "^29.0.0",
64
64
  "terser-webpack-plugin": "^5.3.6",
65
65
  "ts-loader": "^9.4.1",
66
66
  "typescript": "^4.8.4",
67
- "webpack": "^5.74.0",
68
- "webpack-cli": "^4.10.0",
67
+ "webpack": "^5.75.0",
68
+ "webpack-cli": "^5.0.0",
69
69
  "webpack-merge": "^5.8.0"
70
70
  },
71
71
  "browserslist": [
@@ -1,78 +0,0 @@
1
- // This is an example of the expected structure for component-specific styles
2
- // In some cases, deviations from this structure are warranted if we need to maintain a legacy structure
3
- .s-component-name {
4
- // BASE COMPONENT-SPECIFIC CUSTOM PROPERTIES
5
- // --_{component-abbreviation}-{property-shorthand}: {value};
6
- --_cn-bg: var(--blue-500);
7
- --_cn-h: var(--su-static16);
8
- --_cn-fd: row-reverse;
9
- // VARIANT CUSTOM PROPERTIES
10
- // --_{component-abbreviation}-{property-shorthand}-{variant-name}: {value};
11
- --_cn-fc-filled: var(--green-500);
12
- // CHILD COMPONENT CUSTOM PROPERTIES
13
- // --_{component-abreviation}-{child-component-name}-{property-shorthand}: {value};
14
- --_cn-image-bg: var(--red-500);
15
-
16
- // CONTEXTUAL STYLES
17
- // These may include themes/modes, responsive styles, or modifications based on parent containers
18
- .highcontrast-mode({
19
- --_cn-bg: var(--black-400);
20
-
21
- .s-avatar--letter {
22
- --_cn-image-bg: var(--white);
23
- }
24
- });
25
- .s-special-parent & {
26
- --_cn-bg: transparent;
27
- }
28
-
29
- // STATES
30
- // These are generally classes prefixed with `.is-` or `.has-`
31
- &.is-selected {
32
- --_cn-bg: var(--orange-200);
33
- }
34
-
35
- // MODIFIERS
36
- // Modifiers are considered to be classes that can be combined with other modifiers outside of their respective groupings without collisions
37
- // Sizes
38
- &&__xs {
39
- --_cn-h: var(--su-static2);
40
- }
41
- &&__sm {
42
- --_cn-h: var(--su-static12);
43
- }
44
- // Orientation
45
- &&__vertical {
46
- --_cn-fd: column;
47
- }
48
-
49
- // VARIANTS
50
- // Variants are expected to be used exclusive of one another. In other words, you should only use one variant class at a time
51
- &&__info {
52
- --_cn-bg: var(--yellow-100);
53
-
54
- &.s-component-name__filled {
55
- --_cn-bg-filled: var(--yellow-800);
56
- }
57
- }
58
-
59
- // CHILD ELEMENTS
60
- & &--image {
61
- background-color: var(--_cn-image-bg);
62
- }
63
-
64
- // INTERACTION
65
- &:hover {
66
- --_cn-bg: var(--_black-050);
67
- }
68
-
69
- // STYLES MODIFIED BY COMPONENT-SPECIFIC CUSTOM PROPERTIES
70
- background-color: var(--_cn-bg-filled, var(--_cn-bg));
71
- flex-direction: var(--_cn-fd);
72
- height: var(--_cn-h);
73
-
74
- // STATIC COMPONENT STYLES
75
- display: flex;
76
- position: relative;
77
- vertical-align: bottom;
78
- }
@@ -1,33 +0,0 @@
1
- //
2
- // STACK OVERFLOW
3
- // SIDEBAR WIDGET -- DYNAMIC PARTS
4
- //
5
- // This CSS comes from Stacks, our CSS & Pattern library for rapidly building
6
- // Stack Overflow. For documentation of all these classes and how to contribute,
7
- // visit https://stackoverflow.design/
8
- //
9
- // This file only sets the colors for the "current color" highlight when the
10
- // widget is used for navigation. This is the only part of the widget that is
11
- // dynamically configurable; the rest can be served in the static part of Stacks
12
- // and is in widget-static.less.
13
-
14
- .s-sidebarwidget--item {
15
- &,
16
- & > :first-child {
17
- &[aria-current="true"],
18
- &[aria-current="page"] {
19
- &:before {
20
- border-left-color: var(--theme-primary-color);
21
- }
22
- }
23
- }
24
- }
25
-
26
- .s-sidebarwidget--subnav {
27
- li {
28
- &[aria-current="true"],
29
- &[aria-current="page"] {
30
- #stacks-internals #bullet-arrow(var(--theme-primary-color));
31
- }
32
- }
33
- }