@stackoverflow/stacks 1.6.1 → 1.6.3

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.
@@ -609,34 +609,18 @@ fieldset {
609
609
  font-size: var(--fs-caption);
610
610
  }
611
611
 
612
- // $$ SIZES
612
+ // $$ PADDING ADJUSTMENTS AND SIZES
613
613
  // ----------------------------------------------------------------------------
614
614
  .s-input__sm,
615
615
  .s-textarea__sm,
616
616
  .s-select__sm > select {
617
617
  font-size: var(--fs-caption);
618
618
  }
619
- .s-input__md,
620
- .s-textarea__md,
621
- .s-select__md > select {
622
- font-size: var(--fs-body3);
623
- }
624
- .s-input__lg,
625
- .s-textarea__lg,
626
- .s-select__lg > select {
627
- font-size: var(--fs-title);
628
- }
629
- .s-input__xl,
630
- .s-textarea__xl,
631
- .s-select__xl > select {
632
- font-size: var(--fs-headline1);
633
- }
634
619
 
635
- // $$ PADDING ADJUSTMENTS WITHIN SIZES
636
- // ----------------------------------------------------------------------------
637
620
  .s-input__md,
638
621
  .s-textarea__md,
639
622
  .s-select__md > select {
623
+ font-size: var(--fs-body3);
640
624
  padding-top: 0.5em;
641
625
  padding-bottom: 0.5em;
642
626
  border-radius: calc(var(--br-sm) + 1px);
@@ -650,6 +634,7 @@ fieldset {
650
634
  .s-input__lg,
651
635
  .s-textarea__lg,
652
636
  .s-select__lg > select {
637
+ font-size: var(--fs-title);
653
638
  padding: 0.45em 0.6em;
654
639
  border-radius: calc(var(--br-sm) + 1px);
655
640
  }
@@ -657,6 +642,7 @@ fieldset {
657
642
  .s-input__xl,
658
643
  .s-textarea__xl,
659
644
  .s-select__xl > select {
645
+ font-size: var(--fs-headline1);
660
646
  padding: 0.4em 0.5em;
661
647
  border-radius: var(--br-md);
662
648
  }
@@ -152,6 +152,10 @@
152
152
  background: var(--_no-code-bg, transparent);
153
153
  }
154
154
  & &--btn {
155
+ // TODO: decouple .s-notice--btn from .s-btn
156
+ &:not(:focus) {
157
+ box-shadow: none; // This will prevent default .s-btn box-shadow from showing
158
+ }
155
159
  &:focus,
156
160
  &:hover {
157
161
  background: var(--_no-btn-bg-focus);
@@ -1,5 +1,5 @@
1
1
  .s-pagination {
2
- & &--item {
2
+ & &--item {
3
3
  --_pa-item-bg: transparent;
4
4
  --_pa-item-bc: var(--bc-medium);
5
5
  --_pa-item-fc: var(--fc-medium);
@@ -17,7 +17,7 @@
17
17
  --_po-arrow-after-r: unset;
18
18
  --_po-arrow-after-t: unset;
19
19
  --_po-arrow-after-bs: unset;
20
-
20
+
21
21
  // CONTEXTUAL STYLES
22
22
  .dark-mode({
23
23
  --_po-bg: var(--black-075);
@@ -25,7 +25,7 @@
25
25
  --_po-bs: var(--bs-lg);
26
26
  --_po-arrow-fc: var(--black-075);
27
27
  });
28
-
28
+
29
29
  // MODIFIERS
30
30
  &.is-visible {
31
31
  --_po-d: block;
@@ -34,7 +34,7 @@
34
34
  --_po-wmn: unset;
35
35
  --_po-w: auto;
36
36
  }
37
-
37
+
38
38
  // CHILD ELEMENTS
39
39
  // Arrow
40
40
  &[data-popper-placement^="top"] > &--arrow,
@@ -128,14 +128,14 @@
128
128
  right: calc(var(--su8) * -1); // Compensate for s-popover's padding
129
129
  padding: var(--su8) !important;
130
130
  }
131
-
131
+
132
132
  background-color: var(--_po-bg);
133
133
  border: 1px solid var(--_po-bc);
134
134
  box-shadow: var(--_po-bs);
135
135
  display: var(--_po-d);
136
136
  min-width: var(--_po-wmn);
137
137
  width: var(--_po-w);
138
-
138
+
139
139
  border-radius: var(--br-md);
140
140
  color: var(--fc-dark);
141
141
  font-size: var(--fs-body1);
@@ -144,5 +144,4 @@
144
144
  position: absolute;
145
145
  white-space: normal; // Guard against popovers being in a container with white-space: nowrap. Without this, the content pops *out* of the popover.
146
146
  z-index: var(--zi-popovers);
147
- }
148
-
147
+ }
@@ -24,6 +24,9 @@
24
24
  --_pr-spacing: 1.1em;
25
25
  --_pr-spacing-condensed: calc(var(--_pr-spacing) / 2); // Reduce the base spacing by half in the context of lists, etc.
26
26
  --_pr-spoiler-transition: opacity 0.1s ease-in-out;
27
+ // TEMP HOT FIX FOR .s-editor [1]
28
+ --s-prose-spacing: var(--_pr-spacing); // TODO remove once addressed in StackExchange/Stacks-Editor
29
+ --s-prose-spacing-condensed: var(--_pr-spacing-condensed); // TODO remove once addressed in StackExchange/Stacks-Editor
27
30
 
28
31
  // CONDITIONAL STYLES
29
32
  .dark-mode({
@@ -164,6 +167,7 @@
164
167
  quotes: none;
165
168
  }
166
169
  dd,
170
+ div,
167
171
  dl,
168
172
  .s-table-container,
169
173
  .s-link-preview {
@@ -371,7 +375,7 @@
371
375
  color: var(--black-800);
372
376
  min-height: var(--su-static48); // TODO: Let's find a solution that doesn't have a magic number
373
377
  }
374
- .youtube-embed { // [1]
378
+ .youtube-embed { // [2]
375
379
  > div {
376
380
  iframe {
377
381
  height: 100%;
@@ -395,7 +399,10 @@
395
399
  overflow-wrap: break-word;
396
400
  }
397
401
 
398
- // [1] The outer div enforces a max-width of 640px. The inner div has a height of 35 pixels, and a
402
+ // [1] StackExchange/Stacks-Editor references `--s-prose-spacing` and `--s-prose-spacing-condensed`.
403
+ // Going forward, it shouldn't but for now, I've introduced a hotfix to define those custom properties.
404
+
405
+ // [2] The outer div enforces a max-width of 640px. The inner div has a height of 35 pixels, and a
399
406
  // padding-bottom of 56.25%. Padding percentages, even for top/bottom, are always relative
400
407
  // to the *width*, so the padding always has an aspect ratio of 1/0.5625, or 16/9. Thus in total,
401
408
  // the iframe has a height of 35 + width * 9/16. 35 pixels is the height of youtube's player controls,
@@ -1,8 +1,15 @@
1
1
  // export all controllers *with helpers* so they can be bulk re-exported by the package entry point
2
- export { ExpandableController } from './s-expandable-control';
3
- export { hideModal, ModalController, showModal } from './s-modal';
4
- export { TabListController } from './s-navigation-tablist';
5
- export { attachPopover, detachPopover, hidePopover, BasePopoverController, PopoverController, showPopover } from './s-popover';
6
- export { TableController } from './s-table';
7
- export { setTooltipHtml, setTooltipText, TooltipController } from './s-tooltip';
8
- export { UploaderController } from './s-uploader';
2
+ export { ExpandableController } from "./s-expandable-control";
3
+ export { hideModal, ModalController, showModal } from "./s-modal";
4
+ export { TabListController } from "./s-navigation-tablist";
5
+ export {
6
+ attachPopover,
7
+ detachPopover,
8
+ hidePopover,
9
+ BasePopoverController,
10
+ PopoverController,
11
+ showPopover,
12
+ } from "./s-popover";
13
+ export { TableController } from "./s-table";
14
+ export { setTooltipHtml, setTooltipText, TooltipController } from "./s-tooltip";
15
+ export { UploaderController } from "./s-uploader";
@@ -1,4 +1,4 @@
1
- import * as Stacks from '../stacks';
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
4
  // they're *unchecked*. Therefore, if we have an active `s-expandable-control` in
@@ -12,10 +12,15 @@ const RADIO_OFF_EVENT = "s-expandable-control:radio-off";
12
12
 
13
13
  function globalChangeListener(e: UIEvent) {
14
14
  const target = e.target;
15
- if (!(target instanceof HTMLInputElement) || target.nodeName !== "INPUT" || target.type !== "radio") {
15
+ if (
16
+ !(target instanceof HTMLInputElement) ||
17
+ target.nodeName !== "INPUT" ||
18
+ target.type !== "radio"
19
+ ) {
16
20
  return;
17
21
  }
18
- document.querySelectorAll('input[type="radio"][name="' + target.name + '"]')
22
+ document
23
+ .querySelectorAll('input[type="radio"][name="' + target.name + '"]')
19
24
  .forEach(function (other) {
20
25
  if (other === e.target) {
21
26
  return;
@@ -37,12 +42,18 @@ function globalChangeListenerRequired(required: boolean) {
37
42
  if (required) {
38
43
  refCount++;
39
44
  if (refCount === 1) {
40
- document.body.addEventListener("change", globalChangeListener as EventListener);
45
+ document.body.addEventListener(
46
+ "change",
47
+ globalChangeListener as EventListener
48
+ );
41
49
  }
42
50
  } else {
43
51
  refCount--;
44
52
  if (refCount === 0) {
45
- document.body.removeEventListener("change", globalChangeListener as EventListener);
53
+ document.body.removeEventListener(
54
+ "change",
55
+ globalChangeListener as EventListener
56
+ );
46
57
  }
47
58
  }
48
59
  }
@@ -55,7 +66,12 @@ export class ExpandableController extends Stacks.StacksController {
55
66
  private lastKeydownClickTimestamp = 0;
56
67
 
57
68
  initialize() {
58
- if (this.element.nodeName === "INPUT" && ["radio", "checkbox"].indexOf((<HTMLInputElement>this.element).type) >= 0) {
69
+ if (
70
+ this.element.nodeName === "INPUT" &&
71
+ ["radio", "checkbox"].indexOf(
72
+ (<HTMLInputElement>this.element).type
73
+ ) >= 0
74
+ ) {
59
75
  this.isCollapsed = this._isCollapsedForCheckable.bind(this);
60
76
  this.events = ["change", RADIO_OFF_EVENT];
61
77
  this.isCheckable = true;
@@ -65,40 +81,41 @@ export class ExpandableController extends Stacks.StacksController {
65
81
  this.events = ["click", "keydown"];
66
82
  }
67
83
  this.listener = this.listener.bind(this);
68
- };
69
-
84
+ }
70
85
 
71
86
  // for non-checkable elements, the initial source of truth is the collapsed/expanded
72
87
  // state of the controlled element (unless the element doesn't exist)
73
88
  _isCollapsedForClickable() {
74
89
  const cc = this.controlledExpandables;
75
90
  // the element is considered collapsed if *any* target element is collapsed
76
- return cc.length > 0 ? !cc.every(element => element.classList.contains("is-expanded")) : this.element.getAttribute("aria-expanded") === "false";
77
- };
91
+ return cc.length > 0
92
+ ? !cc.every((element) => element.classList.contains("is-expanded"))
93
+ : this.element.getAttribute("aria-expanded") === "false";
94
+ }
78
95
 
79
96
  // for checkable elements, the initial source of truth is the checked state
80
97
  _isCollapsedForCheckable() {
81
98
  return !(<HTMLInputElement>this.element).checked;
82
- };
83
-
99
+ }
84
100
 
85
101
  get controlledExpandables() {
86
102
  const attr = this.element.getAttribute("aria-controls");
87
103
  if (!attr) {
88
104
  throw `[aria-controls="targetId1 ... targetIdN"] attribute required`;
89
105
  }
90
- const result = attr.split(/\s+/g)
91
- .map(s => document.getElementById(s))
106
+ const result = attr
107
+ .split(/\s+/g)
108
+ .map((s) => document.getElementById(s))
92
109
  .filter((e): e is HTMLElement => !!e);
93
110
  if (!result.length) {
94
- throw "couldn't find controls"
111
+ throw "couldn't find controls";
95
112
  }
96
113
  return result;
97
- };
114
+ }
98
115
 
99
116
  _dispatchShowHideEvent(isShow: boolean) {
100
117
  this.triggerEvent(isShow ? "show" : "hide");
101
- };
118
+ }
102
119
 
103
120
  _toggleClass(doAdd: boolean) {
104
121
  if (!this.data.has("toggle-class")) {
@@ -107,22 +124,30 @@ export class ExpandableController extends Stacks.StacksController {
107
124
  const cl = this.element.classList;
108
125
  const toggleClass = this.data.get("toggle-class");
109
126
  if (!toggleClass) {
110
- throw "couldn't find toggle class"
127
+ throw "couldn't find toggle class";
111
128
  }
112
129
  toggleClass.split(/\s+/).forEach(function (cls) {
113
130
  cl.toggle(cls, !!doAdd);
114
131
  });
115
- };
132
+ }
116
133
 
117
134
  listener(e: Event) {
118
135
  let newCollapsed;
119
136
  if (this.isCheckable) {
120
137
  newCollapsed = !(<HTMLInputElement>this.element).checked;
121
138
  } else {
122
- if (e.type == "keydown" && (e instanceof KeyboardEvent && e.keyCode != 13 && e.keyCode != 32)) {
139
+ if (
140
+ e.type == "keydown" &&
141
+ e instanceof KeyboardEvent &&
142
+ e.keyCode != 13 &&
143
+ e.keyCode != 32
144
+ ) {
123
145
  return;
124
146
  }
125
- if (e.target !== e.currentTarget && ["A", "BUTTON"].indexOf((<HTMLElement>e.target).nodeName) >= 0) {
147
+ if (
148
+ e.target !== e.currentTarget &&
149
+ ["A", "BUTTON"].indexOf((<HTMLElement>e.target).nodeName) >= 0
150
+ ) {
126
151
  return;
127
152
  }
128
153
 
@@ -133,24 +158,31 @@ export class ExpandableController extends Stacks.StacksController {
133
158
  // doesn't guarantee it.
134
159
  if (e.type == "keydown") {
135
160
  this.lastKeydownClickTimestamp = Date.now();
136
- } else if (e.type == "click" && Date.now() - this.lastKeydownClickTimestamp < 300) {
161
+ } else if (
162
+ e.type == "click" &&
163
+ Date.now() - this.lastKeydownClickTimestamp < 300
164
+ ) {
137
165
  return;
138
166
  }
139
- newCollapsed = this.element.getAttribute("aria-expanded") === "true";
167
+ newCollapsed =
168
+ this.element.getAttribute("aria-expanded") === "true";
140
169
  if (e.type === "click") {
141
170
  (<HTMLInputElement>this.element).blur();
142
171
  }
143
172
  }
144
- this.element.setAttribute("aria-expanded", newCollapsed ? "false" : "true");
173
+ this.element.setAttribute(
174
+ "aria-expanded",
175
+ newCollapsed ? "false" : "true"
176
+ );
145
177
  for (const controlledElement of this.controlledExpandables) {
146
178
  controlledElement.classList.toggle("is-expanded", !newCollapsed);
147
179
  }
148
180
  this._dispatchShowHideEvent(!newCollapsed);
149
181
  this._toggleClass(!newCollapsed);
150
- };
182
+ }
151
183
 
152
184
  connect() {
153
- this.events.forEach(e => {
185
+ this.events.forEach((e) => {
154
186
  this.element.addEventListener(e, this.listener.bind(this));
155
187
  }, this);
156
188
 
@@ -163,31 +195,44 @@ export class ExpandableController extends Stacks.StacksController {
163
195
  // Note: aria-expanded is currently an invalid attribute on radio elements
164
196
  // Support for aria-expanded is being debated by the W3C https://github.com/w3c/aria/issues/1404 as recently as June 2022
165
197
  if (!this.isRadio) {
166
- this.element.setAttribute("aria-expanded", this.isCollapsed() ? "false" : "true");
198
+ this.element.setAttribute(
199
+ "aria-expanded",
200
+ this.isCollapsed() ? "false" : "true"
201
+ );
167
202
  }
168
203
  if (this.isCheckable) {
169
204
  const cc = this.controlledExpandables;
170
205
  if (cc.length) {
171
206
  const expected = !this.isCollapsed();
172
207
  // if any element does not match the expected state, set them all to the expected state
173
- if (cc.some(element => element.classList.contains("is-expanded") !== expected)) {
174
- for (const controlledElement of this.controlledExpandables) {
175
- controlledElement.classList.toggle("is-expanded", expected);
208
+ if (
209
+ cc.some(
210
+ (element) =>
211
+ element.classList.contains("is-expanded") !==
212
+ expected
213
+ )
214
+ ) {
215
+ for (const controlledElement of this
216
+ .controlledExpandables) {
217
+ controlledElement.classList.toggle(
218
+ "is-expanded",
219
+ expected
220
+ );
176
221
  }
177
222
  this._dispatchShowHideEvent(expected);
178
223
  this._toggleClass(expected);
179
224
  }
180
225
  }
181
226
  }
182
- };
227
+ }
183
228
 
184
229
  disconnect() {
185
- this.events.forEach(e => {
230
+ this.events.forEach((e) => {
186
231
  this.element.removeEventListener(e, this.listener.bind(this));
187
232
  }, this);
188
233
 
189
234
  if (this.isRadio) {
190
235
  globalChangeListenerRequired(false);
191
236
  }
192
- };
193
- }
237
+ }
238
+ }