@stackoverflow/stacks 2.1.0 → 2.1.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.
@@ -412,7 +412,7 @@
412
412
  .focus-styles(true, true);
413
413
  }
414
414
 
415
- &:not(&__link):not(&__unset)&:not(&__facebook):not(&__github):not(&__google):not(.is-selected):focus-visible,
415
+ &:not(&__link):not(&__unset):not(&__facebook):not(&__github):not(&__google):not(.is-selected):focus-visible,
416
416
  &--radio:focus-visible + & {
417
417
  &,
418
418
  &.s-btn__filled {
@@ -425,17 +425,30 @@
425
425
  }
426
426
  }
427
427
 
428
- &:not(&__link):not(&__unset)&:not(&__facebook):not(&__github):not(&__google):not(.is-selected) {
428
+ &:not(&__link):not(&__unset):not(&__facebook):not(&__github):not(&__google):not(.is-selected) {
429
429
  &:hover {
430
430
  &.s-btn__filled {
431
431
  background-color: var(--_bu-filled-bg-hover);
432
432
  border-color: var(--_bu-filled-bc-hover);
433
433
  color: var(--_bu-filled-fc-hover);
434
434
  }
435
+
435
436
  &:not(.s-btn__outlined) {
436
437
  border-color: var(--_bu-bc-hover);
437
438
  }
438
439
 
440
+ &:visited:not(:hover):not(:focus) {
441
+ &.s-btn__filled {
442
+ background-color: var(--_bu-filled-bg);
443
+ border-color: var(--_bu-filled-bc);
444
+ color: var(--_bu-filled-fc);
445
+ }
446
+
447
+ background-color: var(--_bu-bg);
448
+ border-color: var(--_bu-bc);
449
+ color: var(--_bu-fc);
450
+ }
451
+
439
452
  background-color: var(--_bu-bg-hover);
440
453
  color: var(--_bu-fc-hover);
441
454
  }
@@ -453,19 +466,6 @@
453
466
  }
454
467
  }
455
468
 
456
-
457
- &:visited:not(:hover):not(:focus) {
458
- &.s-btn__filled {
459
- background-color: var(--_bu-filled-bg);
460
- border-color: var(--_bu-filled-bc);
461
- color: var(--_bu-filled-fc);
462
- }
463
-
464
- background-color: var(--_bu-bg);
465
- border-color: var(--_bu-bc);
466
- color: var(--_bu-fc);
467
- }
468
-
469
469
  background-color: var(--_bu-bg, inherit); // [1]
470
470
  border: var(--_bu-baw) solid var(--_bu-bc);
471
471
  border-radius: var(--_bu-br);
@@ -0,0 +1,81 @@
1
+ import { html } from "@open-wc/testing";
2
+ import { runA11yTests } from "../../test/a11y-test-utils";
3
+ import "../../index";
4
+
5
+ const modifiers = [
6
+ {
7
+ name: "error",
8
+ parentClasses: "has-error",
9
+ },
10
+ {
11
+ name: "success",
12
+ parentClasses: "has-success",
13
+ },
14
+ {
15
+ name: "warning",
16
+ parentClasses: "has-warning",
17
+ },
18
+ {
19
+ name: "disabled",
20
+ parentClasses: "is-disabled",
21
+ },
22
+ {
23
+ name: "readonly",
24
+ parentClasses: "is-readonly",
25
+ },
26
+ {
27
+ name: "creditcard",
28
+ modifier: "creditcard",
29
+ inputClasses: "s-input__creditcard",
30
+ },
31
+ {
32
+ name: "search",
33
+ modifier: "search",
34
+ inputClasses: "s-input__search",
35
+ },
36
+ ];
37
+
38
+ const getSvgPath = (name: string) => {
39
+ switch (name) {
40
+ case "creditcard":
41
+ return '<path d="M3 3h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2Zm0 6v4h12V9H3Zm0-3h12V5H3v1Z"></path>';
42
+ case "search":
43
+ return '<path d="m18 16.5-5.14-5.18h-.35a7 7 0 1 0-1.19 1.19v.35L16.5 18l1.5-1.5ZM12 7A5 5 0 1 1 2 7a5 5 0 0 1 10 0Z"></path>';
44
+ default:
45
+ return '<path d="M9.06 3C4 3 1 9 1 9s3 6 8.06 6C14 15 17 9 17 9s-3-6-7.94-6ZM9 13a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm0-2a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2 2 2 0 0 0 2 2Z"></path>'; // eye icon path
46
+ }
47
+ };
48
+
49
+ describe("input-icon", () => {
50
+ modifiers.forEach(({ name, parentClasses, modifier }) => {
51
+ runA11yTests({
52
+ baseClass: `s-input-icon`,
53
+ tag: "svg",
54
+ children: {
55
+ [name]: getSvgPath(name), // IconSearch
56
+ },
57
+ modifiers: {
58
+ standalone: modifier ? [`${modifier}`] : [],
59
+ global: parentClasses ? [`parent-${parentClasses}`] : [],
60
+ },
61
+ attributes: {
62
+ "aria-hidden": "true",
63
+ "width": "18",
64
+ "height": "18",
65
+ "viewBox": "0 0 18 18",
66
+ },
67
+ template: ({ component, testid }) => html`
68
+ <div
69
+ data-testid="${testid}"
70
+ class="d-flex fd-column g4 fc-black ps-relative wmx2 p8 ${parentClasses ??
71
+ ""}"
72
+ >
73
+ <div class="d-flex ps-relative svg-icon">${component}</div>
74
+ </div>
75
+ `,
76
+ options: {
77
+ includeNullModifier: false,
78
+ },
79
+ });
80
+ });
81
+ });
@@ -0,0 +1,92 @@
1
+ import { html } from "@open-wc/testing";
2
+ import { runVisualTests } from "../../test/visual-test-utils";
3
+ import "../../index";
4
+
5
+ const modifiers = [
6
+ {
7
+ name: "error",
8
+ parentClasses: "has-error",
9
+ },
10
+ {
11
+ name: "success",
12
+ parentClasses: "has-success",
13
+ },
14
+ {
15
+ name: "warning",
16
+ parentClasses: "has-warning",
17
+ },
18
+ {
19
+ name: "disabled",
20
+ parentClasses: "is-disabled",
21
+ },
22
+ {
23
+ name: "readonly",
24
+ parentClasses: "is-readonly",
25
+ },
26
+ {
27
+ name: "creditcard",
28
+ modifier: "creditcard",
29
+ inputClasses: "s-input__creditcard",
30
+ },
31
+ {
32
+ name: "search",
33
+ modifier: "search",
34
+ inputClasses: "s-input__search",
35
+ },
36
+ ];
37
+
38
+ const getSvgPath = (name: string) => {
39
+ switch (name) {
40
+ case "creditcard":
41
+ return '<path d="M3 3h12a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2H3a2 2 0 0 1-2-2V5c0-1.1.9-2 2-2Zm0 6v4h12V9H3Zm0-3h12V5H3v1Z"></path>';
42
+ case "search":
43
+ return '<path d="m18 16.5-5.14-5.18h-.35a7 7 0 1 0-1.19 1.19v.35L16.5 18l1.5-1.5ZM12 7A5 5 0 1 1 2 7a5 5 0 0 1 10 0Z"></path>';
44
+ default:
45
+ return '<path d="M9.06 3C4 3 1 9 1 9s3 6 8.06 6C14 15 17 9 17 9s-3-6-7.94-6ZM9 13a4 4 0 1 1 0-8 4 4 0 0 1 0 8Zm0-2a2 2 0 0 0 2-2 2 2 0 0 0-2-2 2 2 0 0 0-2 2 2 2 0 0 0 2 2Z"></path>'; // eye icon path
46
+ }
47
+ };
48
+
49
+ describe("input-icon", () => {
50
+ modifiers.forEach(({ name, parentClasses, modifier, inputClasses }) => {
51
+ runVisualTests({
52
+ baseClass: `s-input-icon`,
53
+ tag: "svg",
54
+ children: {
55
+ [name]: getSvgPath(name), // IconSearch
56
+ },
57
+ modifiers: {
58
+ standalone: modifier ? [`${modifier}`] : [],
59
+ global: parentClasses ? [`parent-${parentClasses}`] : [],
60
+ },
61
+ attributes: {
62
+ "aria-hidden": "true",
63
+ "width": "18",
64
+ "height": "18",
65
+ "viewBox": "0 0 18 18",
66
+ },
67
+ template: ({ component, testid }) => html`
68
+ <div
69
+ data-testid="${testid}"
70
+ class="d-flex fd-column g4 fc-black ps-relative wmx2 p8 ${parentClasses ??
71
+ ""}"
72
+ >
73
+ <label class="s-label v-visible-sr" for="ex-input"
74
+ >Input</label
75
+ >
76
+ <div class="d-flex ps-relative svg-icon">
77
+ <input
78
+ id="ex-input"
79
+ type="text"
80
+ class="s-input ${inputClasses ?? ""}"
81
+ placeholder="${name} input…"
82
+ />
83
+ ${component}
84
+ </div>
85
+ </div>
86
+ `,
87
+ options: {
88
+ includeNullModifier: false,
89
+ },
90
+ });
91
+ });
92
+ });
@@ -0,0 +1,72 @@
1
+ import { html } from "@open-wc/testing";
2
+ import { runA11yTests } from "../../test/a11y-test-utils";
3
+ import "../../index";
4
+
5
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
+ const template = ({ component, testid, className }: any) => html`
7
+ <div class="d-inline-flex p8 ${className}" data-testid="${testid}">
8
+ ${component}
9
+ </div>
10
+ `;
11
+
12
+ const child = (attr?: string): string => {
13
+ return `
14
+ <label for="select-menu">Transportation method</label>
15
+ <select id="select-menu" ${attr}>
16
+ <option value="" selected>Please select one…</option>
17
+ <option value="walk">Walk</option>
18
+ <option value="bike">Bicycle</option>
19
+ <option value="car">Automobile</option>
20
+ <option value="rail">Train</option>
21
+ <option value="fly">Plane</option>
22
+ </select>`;
23
+ };
24
+
25
+ describe("select", () => {
26
+ // default, sizes
27
+ runA11yTests({
28
+ baseClass: "s-select",
29
+ modifiers: {
30
+ primary: ["sm", "md", "lg", "xl"],
31
+ },
32
+ children: {
33
+ default: child(),
34
+ },
35
+ template,
36
+ });
37
+
38
+ // modifier classes
39
+ [
40
+ {
41
+ class: "is-disabled",
42
+ attr: 'disabled=""',
43
+ },
44
+ {
45
+ class: "is-readonly",
46
+ attr: 'readonly=""',
47
+ },
48
+ {
49
+ class: "has-success",
50
+ },
51
+ {
52
+ class: "has-error",
53
+ },
54
+ {
55
+ class: "has-warning",
56
+ },
57
+ ].forEach((state) => {
58
+ runA11yTests({
59
+ baseClass: `s-select state-${state.class}`,
60
+ children: {
61
+ default: child(state.attr),
62
+ },
63
+ template: ({ component, testid }) =>
64
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
65
+ template({ component, testid, className: state.class }),
66
+ options: {
67
+ includeNullModifier: false,
68
+ },
69
+ skippedTestids: [/readonly/], // Skipping readonly since it doesn't need to meet APCA contrast minimums
70
+ });
71
+ });
72
+ });
@@ -0,0 +1,72 @@
1
+ import { html } from "@open-wc/testing";
2
+ import { runVisualTests } from "../../test/visual-test-utils";
3
+ import "../../index";
4
+
5
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
6
+ const template = ({ component, testid, className }: any) => html`
7
+ <div class="d-inline-flex p8 ${className}" data-testid="${testid}">
8
+ ${component}
9
+ </div>
10
+ `;
11
+
12
+ const child = (attr?: string): string => {
13
+ return `<select id="select-menu" ${attr}>
14
+ <option value="" selected>Please select one…</option>
15
+ <option value="walk">Walk</option>
16
+ <option value="bike">Bicycle</option>
17
+ <option value="car">Automobile</option>
18
+ <option value="rail">Train</option>
19
+ <option value="fly">Plane</option>
20
+ </select>`;
21
+ };
22
+
23
+ describe("select", () => {
24
+ // default, sizes
25
+ runVisualTests({
26
+ baseClass: "s-select",
27
+ modifiers: {
28
+ primary: ["sm", "md", "lg", "xl"],
29
+ },
30
+ children: {
31
+ default: child(),
32
+ },
33
+ template,
34
+ });
35
+
36
+ // modifier classes
37
+ [
38
+ {
39
+ class: "is-disabled",
40
+ attr: 'disabled=""',
41
+ },
42
+ {
43
+ class: "is-readonly",
44
+ attr: 'readonly=""',
45
+ },
46
+ {
47
+ class: "has-success",
48
+ },
49
+ {
50
+ class: "has-error",
51
+ },
52
+ {
53
+ class: "has-warning",
54
+ },
55
+ ].forEach((state) => {
56
+ runVisualTests({
57
+ baseClass: "s-select",
58
+ modifiers: {
59
+ global: [`state-${state.class}`],
60
+ },
61
+ children: {
62
+ selected: child(state.attr),
63
+ },
64
+ template: ({ component, testid }) =>
65
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
66
+ template({ component, testid, className: state.class }),
67
+ options: {
68
+ includeNullModifier: false,
69
+ },
70
+ });
71
+ });
72
+ });
@@ -215,10 +215,14 @@ const generatePrimitiveVariations = ({
215
215
  : modifiers.primary
216
216
  : [""];
217
217
  const secondaryModifiers = modifiers?.secondary
218
- ? ["", ...(<[]>modifiers.secondary)]
218
+ ? opts.includeNullModifier
219
+ ? ["", ...(<[]>modifiers.secondary)]
220
+ : modifiers.secondary
219
221
  : [""];
220
222
  const globalModifiers = modifiers?.global
221
- ? ["", ...(<[]>modifiers.global)]
223
+ ? opts.includeNullModifier
224
+ ? ["", ...(<[]>modifiers.global)]
225
+ : modifiers.global
222
226
  : [""];
223
227
 
224
228
  primaryModifiers.forEach((primaryModifier) => {
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": "2.1.0",
8
+ "version": "2.1.1",
9
9
  "files": [
10
10
  "dist",
11
11
  "lib"
@@ -47,7 +47,7 @@
47
47
  "@open-wc/testing": "^4.0.0",
48
48
  "@rollup/plugin-commonjs": "^25.0.7",
49
49
  "@rollup/plugin-replace": "^5.0.5",
50
- "@stackoverflow/stacks-editor": "^0.9.1",
50
+ "@stackoverflow/stacks-editor": "^0.10.0",
51
51
  "@stackoverflow/stacks-icons": "^6.0.0",
52
52
  "@testing-library/dom": "^9.3.4",
53
53
  "@testing-library/user-event": "^14.5.2",
@@ -56,7 +56,7 @@
56
56
  "@types/mocha": "^10.0.6",
57
57
  "@typescript-eslint/eslint-plugin": "^6.20.0",
58
58
  "@typescript-eslint/parser": "^6.21.0",
59
- "@web/dev-server-esbuild": "^1.0.1",
59
+ "@web/dev-server-esbuild": "^1.0.2",
60
60
  "@web/dev-server-rollup": "^0.6.1",
61
61
  "@web/test-runner": "^0.18.0",
62
62
  "@web/test-runner-playwright": "^0.11.0",
@@ -77,12 +77,12 @@
77
77
  "less-loader": "^12.2.0",
78
78
  "list.js": "^2.3.1",
79
79
  "markdown-it": "^14.0.0",
80
- "mini-css-extract-plugin": "^2.7.7",
80
+ "mini-css-extract-plugin": "^2.8.0",
81
81
  "postcss-less": "^6.0.0",
82
82
  "postcss-loader": "^8.0.0",
83
83
  "prettier": "^3.2.4",
84
84
  "rollup-plugin-postcss": "^4.0.2",
85
- "stylelint": "^16.2.0",
85
+ "stylelint": "^16.2.1",
86
86
  "stylelint-config-recommended": "^14.0.0",
87
87
  "stylelint-config-standard": "^36.0.0",
88
88
  "terser-webpack-plugin": "^5.3.10",