@stackoverflow/stacks 2.3.3 → 2.5.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.
Files changed (120) hide show
  1. package/dist/css/stacks.css +37 -4884
  2. package/dist/css/stacks.min.css +1 -1
  3. package/lib/components/button/button.less +0 -18
  4. package/lib/components/tag/tag.less +16 -68
  5. package/lib/components/topbar/topbar.less +33 -3
  6. package/lib/exports/color-mixins.less +0 -2
  7. package/lib/exports/exports.less +0 -1
  8. package/lib/stacks-static.less +0 -5
  9. package/package.json +12 -11
  10. package/lib/atomic/__snapshots__/color-new.less.test.ts.snap +0 -3015
  11. package/lib/atomic/__snapshots__/color.less.test.ts.snap +0 -3132
  12. package/lib/atomic/__snapshots__/misc.less.test.ts.snap +0 -893
  13. package/lib/atomic/__snapshots__/spacing.less.test.ts.snap +0 -1928
  14. package/lib/atomic/color.less.test.ts +0 -12
  15. package/lib/atomic/misc.less.test.ts +0 -12
  16. package/lib/atomic/spacing.less.test.ts +0 -12
  17. package/lib/atomic/v1/__snapshots__/border.less.test.ts.snap +0 -546
  18. package/lib/atomic/v1/__snapshots__/color.less.test.ts.snap +0 -6750
  19. package/lib/atomic/v1/__snapshots__/typography.less.test.ts.snap +0 -16
  20. package/lib/atomic/v1/border.less +0 -210
  21. package/lib/atomic/v1/border.less.test.ts +0 -14
  22. package/lib/atomic/v1/color.less +0 -183
  23. package/lib/atomic/v1/color.less.test.ts +0 -14
  24. package/lib/atomic/v1/typography.less +0 -8
  25. package/lib/atomic/v1/typography.less.test.ts +0 -14
  26. package/lib/components/activity-indicator/activity-indicator.a11y.test.ts +0 -13
  27. package/lib/components/activity-indicator/activity-indicator.visual.test.ts +0 -22
  28. package/lib/components/anchor/anchor.a11y.test.ts +0 -35
  29. package/lib/components/anchor/anchor.visual.test.ts +0 -47
  30. package/lib/components/avatar/avatar.a11y.test.ts +0 -35
  31. package/lib/components/avatar/avatar.visual.test.ts +0 -50
  32. package/lib/components/award-bling/award-bling.a11y.test.ts +0 -15
  33. package/lib/components/award-bling/award-bling.visual.test.ts +0 -24
  34. package/lib/components/badge/badge.a11y.test.ts +0 -143
  35. package/lib/components/badge/badge.visual.test.ts +0 -165
  36. package/lib/components/banner/banner.a11y.test.ts +0 -36
  37. package/lib/components/banner/banner.test.ts +0 -73
  38. package/lib/components/banner/banner.visual.test.ts +0 -36
  39. package/lib/components/block-link/block-link.a11y.test.ts +0 -57
  40. package/lib/components/block-link/block-link.visual.test.ts +0 -57
  41. package/lib/components/breadcrumbs/breadcrumbs.a11y.test.ts +0 -36
  42. package/lib/components/breadcrumbs/breadcrumbs.visual.test.ts +0 -36
  43. package/lib/components/button/button.a11y.test.ts +0 -21
  44. package/lib/components/button/button.test.setup.ts +0 -36
  45. package/lib/components/button/button.visual.test.ts +0 -18
  46. package/lib/components/button-group/button-group.a11y.test.ts +0 -12
  47. package/lib/components/button-group/button-group.test.setup.ts +0 -77
  48. package/lib/components/button-group/button-group.visual.test.ts +0 -7
  49. package/lib/components/card/card.a11y.test.ts +0 -12
  50. package/lib/components/card/card.visual.test.ts +0 -52
  51. package/lib/components/check-control/check-control.a11y.test.ts +0 -33
  52. package/lib/components/check-control/check-control.visual.test.ts +0 -36
  53. package/lib/components/check-group/check-group.a11y.test.ts +0 -49
  54. package/lib/components/check-group/check-group.visual.test.ts +0 -56
  55. package/lib/components/checkbox_radio/checkbox_radio.a11y.test.ts +0 -37
  56. package/lib/components/checkbox_radio/checkbox_radio.visual.test.ts +0 -33
  57. package/lib/components/code-block/code-block.a11y.test.ts +0 -27
  58. package/lib/components/code-block/code-block.visual.test.ts +0 -18
  59. package/lib/components/description/description.a11y.test.ts +0 -28
  60. package/lib/components/description/description.visual.test.ts +0 -28
  61. package/lib/components/empty-state/empty-state.a11y.test.ts +0 -16
  62. package/lib/components/empty-state/empty-state.visual.test.ts +0 -16
  63. package/lib/components/expandable/expandable.a11y.test.ts +0 -26
  64. package/lib/components/expandable/expandable.test.ts +0 -51
  65. package/lib/components/expandable/expandable.visual.test.ts +0 -26
  66. package/lib/components/input-fill/input-fill.a11y.test.ts +0 -21
  67. package/lib/components/input-fill/input-fill.visual.test.ts +0 -21
  68. package/lib/components/input-icon/input-icon.a11y.test.ts +0 -81
  69. package/lib/components/input-icon/input-icon.visual.test.ts +0 -92
  70. package/lib/components/input-message/input-message.a11y.test.ts +0 -57
  71. package/lib/components/input-message/input-message.visual.test.ts +0 -58
  72. package/lib/components/input_textarea/input_textarea.a11y.test.ts +0 -109
  73. package/lib/components/input_textarea/input_textarea.visual.test.ts +0 -95
  74. package/lib/components/label/label.a11y.test.ts +0 -47
  75. package/lib/components/label/label.visual.test.ts +0 -65
  76. package/lib/components/link/link.a11y.test.ts +0 -27
  77. package/lib/components/link/link.visual.test.ts +0 -31
  78. package/lib/components/link-preview/link-preview.a11y.test.ts +0 -47
  79. package/lib/components/link-preview/link-preview.visual.test.ts +0 -52
  80. package/lib/components/menu/menu.a11y.test.ts +0 -39
  81. package/lib/components/menu/menu.visual.test.ts +0 -39
  82. package/lib/components/modal/modal.a11y.test.ts +0 -41
  83. package/lib/components/modal/modal.test.ts +0 -155
  84. package/lib/components/modal/modal.visual.test.ts +0 -41
  85. package/lib/components/navigation/navigation.a11y.test.ts +0 -81
  86. package/lib/components/navigation/navigation.visual.test.ts +0 -98
  87. package/lib/components/notice/notice.a11y.test.ts +0 -16
  88. package/lib/components/notice/notice.visual.test.ts +0 -25
  89. package/lib/components/page-title/page-title.a11y.test.ts +0 -28
  90. package/lib/components/page-title/page-title.visual.test.ts +0 -58
  91. package/lib/components/pagination/pagination.a11y.test.ts +0 -21
  92. package/lib/components/pagination/pagination.visual.test.ts +0 -25
  93. package/lib/components/popover/tooltip.test.ts +0 -62
  94. package/lib/components/post-summary/post-summary.a11y.test.ts +0 -25
  95. package/lib/components/post-summary/post-summary.test.setup.ts +0 -435
  96. package/lib/components/post-summary/post-summary.visual.test.ts +0 -17
  97. package/lib/components/progress-bar/progress-bar.a11y.test.ts +0 -189
  98. package/lib/components/progress-bar/progress-bar.visual.test.ts +0 -188
  99. package/lib/components/select/select.a11y.test.ts +0 -72
  100. package/lib/components/select/select.visual.test.ts +0 -72
  101. package/lib/components/spinner/spinner.a11y.test.ts +0 -14
  102. package/lib/components/spinner/spinner.visual.test.ts +0 -40
  103. package/lib/components/table/table.a11y.test.ts +0 -112
  104. package/lib/components/table/table.test.ts +0 -366
  105. package/lib/components/table/table.visual.test.ts +0 -104
  106. package/lib/components/tag/tag.a11y.test.ts +0 -28
  107. package/lib/components/tag/tag.visual.test.ts +0 -43
  108. package/lib/components/toast/toast.a11y.test.ts +0 -29
  109. package/lib/components/toast/toast.test.ts +0 -64
  110. package/lib/components/toast/toast.visual.test.ts +0 -30
  111. package/lib/components/toggle-switch/toggle-switch.a11y.test.ts +0 -66
  112. package/lib/components/toggle-switch/toggle-switch.visual.test.ts +0 -70
  113. package/lib/components/topbar/topbar.visual.test.ts +0 -216
  114. package/lib/exports/__snapshots__/color-mixins.less.test.ts.snap +0 -558
  115. package/lib/exports/__snapshots__/color.less.test.ts.snap +0 -819
  116. package/lib/exports/color-mixins.less.test.ts +0 -150
  117. package/lib/exports/color.less.test.ts +0 -12
  118. package/lib/exports/v1/__snapshots__/constants-colors.less.test.ts.snap +0 -902
  119. package/lib/exports/v1/constants-colors.less +0 -893
  120. package/lib/exports/v1/constants-colors.less.test.ts +0 -12
@@ -1,65 +0,0 @@
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 labelTemplate = ({ component, testid, isDisabled }: any) => {
7
- return html`
8
- <fieldset
9
- data-testid="${testid}"
10
- class="p8 ws3"
11
- ?disabled="${isDisabled}"
12
- >
13
- ${component}
14
- </fieldset>
15
- `;
16
- };
17
-
18
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
19
- const getChildren = (text: string, status?: any) => {
20
- const typeClass =
21
- status && status !== "base" ? `s-label--status__${status}` : "";
22
- return `
23
- ${text}
24
- ${
25
- status
26
- ? `
27
- <span class="s-label--status ${typeClass}">${
28
- status ?? "no type"
29
- }</span>
30
- `
31
- : ""
32
- }
33
- `;
34
- };
35
-
36
- describe("label", () => {
37
- [true, false].forEach((isDisabled) => {
38
- const text = isDisabled ? "Disabled label" : "Example label";
39
-
40
- runVisualTests({
41
- baseClass: `s-label`,
42
- modifiers: {
43
- primary: ["sm", "md", "lg", "xl"],
44
- },
45
- children: isDisabled
46
- ? {
47
- "disabled": getChildren(text),
48
- "disabled-status": getChildren(text, "base"),
49
- "disabled-status-beta": getChildren(text, "beta"),
50
- "disabled-status-new": getChildren(text, "new"),
51
- "disabled-status-required": getChildren(text, "required"),
52
- }
53
- : {
54
- "default": getChildren(text),
55
- "status": getChildren(text, "base"),
56
- "status-beta": getChildren(text, "beta"),
57
- "status-new": getChildren(text, "new"),
58
- "status-required": getChildren(text, "required"),
59
- },
60
- tag: "label",
61
- template: ({ component, testid }) =>
62
- labelTemplate({ component, testid, isDisabled }),
63
- });
64
- });
65
- });
@@ -1,27 +0,0 @@
1
- import { runA11yTests } from "../../test/a11y-test-utils";
2
- import "../../index";
3
-
4
- describe("link", () => {
5
- // TODO check for visited styling
6
- runA11yTests({
7
- baseClass: "s-link",
8
- modifiers: {
9
- primary: [
10
- "grayscale",
11
- "muted",
12
- "danger",
13
- "inherit",
14
- "underlined",
15
- "visited",
16
- ],
17
- secondary: ["dropdown"],
18
- },
19
- children: {
20
- default: "s-link",
21
- },
22
- tag: "a",
23
- attributes: {
24
- href: "#",
25
- },
26
- });
27
- });
@@ -1,31 +0,0 @@
1
- import { html } from "@open-wc/testing";
2
- import { runVisualTests } from "../../test/visual-test-utils";
3
- import "../../index";
4
-
5
- describe("link", () => {
6
- // TODO check for visited styling
7
- runVisualTests({
8
- baseClass: "s-link",
9
- modifiers: {
10
- primary: [
11
- "grayscale",
12
- "muted",
13
- "danger",
14
- "inherit",
15
- "underlined",
16
- "visited",
17
- ],
18
- secondary: ["dropdown"],
19
- },
20
- children: {
21
- default: "s-link",
22
- },
23
- tag: "a",
24
- attributes: {
25
- href: "#",
26
- },
27
- template: ({ component, testid }) => html`
28
- <div data-testid="${testid}" class="p4 ws1">${component}</div>
29
- `,
30
- });
31
- });
@@ -1,47 +0,0 @@
1
- import { runA11yTests } from "../../test/a11y-test-utils";
2
- import "../../index";
3
-
4
- const getChild = (child?: string): string => {
5
- return `
6
- <div class="s-link-preview--header">
7
- <div class="s-link-preview--icon">👋</div>
8
- <div>
9
- <a href="#" class="s-link-preview--title">
10
- Using hooks for a simple fetch request and breaking the rules of hooks, unsure how?
11
- </a>
12
- <div class="s-link-preview--details">
13
- Issue submitted by Ricky Otero on <relative-time datetime="2019-08-12T04:05:22Z" title="Aug 12, 2019, 12:05 AM EDT">Aug 12, 2019</relative-time> • <strong>RESOLVED</strong>
14
- </div>
15
- </div>
16
- </div>
17
- ${
18
- child
19
- ? child
20
- : `
21
- <div class="s-link-preview--body">
22
- <p>I'm trying to create a simple fetch with hooks from an AWS database. At the moment it errors out and the only reason I can see is because it breaks the rules of hooks but I'm not sure how. It's at the top level of this functional component and it's not called inside an event handler.</p>
23
- <p>The result of this call (an array of user data), needs to be exported as a function and called in another file.</p>
24
- <p>If anyone can spot something I have missed and can highlighted how I'm breaking the rules of hooks I'd be grateful!</p>
25
- <p>Thanks!</p>
26
- </div>
27
- `
28
- }
29
- <div class="s-link-preview--footer">
30
- <a href="#" class="s-link-preview--url">https://stackoverflow.atlassian.net/projects/SREREQ/queues/custom/1</a>
31
- <a href="#" class="s-link-preview--misc">Privacy notice</a>
32
- </div>
33
- `;
34
- };
35
- describe("link preview", () => {
36
- runA11yTests({
37
- baseClass: "s-link-preview",
38
- children: {
39
- default: getChild(),
40
- code: getChild(`
41
- <div class="s-link-preview--code">
42
- <pre class="language-js s-code-block" tabindex="0"><code class="language-js s-code-block"><span class="hljs-meta">'use strict'</span>;</code></pre>
43
- </div>
44
- `),
45
- },
46
- });
47
- });
@@ -1,52 +0,0 @@
1
- import { html } from "@open-wc/testing";
2
- import { runVisualTests } from "../../test/visual-test-utils";
3
- import "../../index";
4
-
5
- const getChild = (child?: string): string => {
6
- return `
7
- <div class="s-link-preview--header">
8
- <div class="s-link-preview--icon">👋</div>
9
- <div>
10
- <a href="#" class="s-link-preview--title">
11
- Using hooks for a simple fetch request and breaking the rules of hooks, unsure how?
12
- </a>
13
- <div class="s-link-preview--details">
14
- Issue submitted by Ricky Otero on <relative-time datetime="2019-08-12T04:05:22Z" title="Aug 12, 2019, 12:05 AM EDT">Aug 12, 2019</relative-time> • <strong>RESOLVED</strong>
15
- </div>
16
- </div>
17
- </div>
18
- ${
19
- child
20
- ? child
21
- : `
22
- <div class="s-link-preview--body">
23
- <p>I'm trying to create a simple fetch with hooks from an AWS database. At the moment it errors out and the only reason I can see is because it breaks the rules of hooks but I'm not sure how. It's at the top level of this functional component and it's not called inside an event handler.</p>
24
- <p>The result of this call (an array of user data), needs to be exported as a function and called in another file.</p>
25
- <p>If anyone can spot something I have missed and can highlighted how I'm breaking the rules of hooks I'd be grateful!</p>
26
- <p>Thanks!</p>
27
- </div>
28
- `
29
- }
30
- <div class="s-link-preview--footer">
31
- <a href="#" class="s-link-preview--url">https://stackoverflow.atlassian.net/projects/SREREQ/queues/custom/1</a>
32
- <a href="#" class="s-link-preview--misc">Privacy notice</a>
33
- </div>
34
- `;
35
- };
36
-
37
- describe("link preview", () => {
38
- runVisualTests({
39
- baseClass: "s-link-preview",
40
- children: {
41
- default: getChild(),
42
- code: getChild(`
43
- <div class="s-link-preview--code">
44
- <pre class="language-js s-code-block" tabindex="0"><code class="language-js s-code-block"><span class="hljs-meta">'use strict'</span>;</code></pre>
45
- </div>
46
- `),
47
- },
48
- template: ({ component, testid }) => html`
49
- <div class="ws8 p8" data-testid="${testid}">${component}</div>
50
- `,
51
- });
52
- });
@@ -1,39 +0,0 @@
1
- import { html } from "@open-wc/testing";
2
- import { runA11yTests } from "../../test/a11y-test-utils";
3
- import "../../index";
4
-
5
- describe("menu", () => {
6
- runA11yTests({
7
- baseClass: `s-menu`,
8
- children: {
9
- default: `
10
- <li class="s-menu--title" role="separator">Title 1</li>
11
- <li role="menuitem">
12
- <a href="#" class="s-block-link">Example li</a>
13
- </li>
14
- <li class="s-menu--title" role="separator">Title 2</li>
15
- <li role="menuitem">
16
- <a href="#" class="s-block-link s-block-link__left is-selected">Selected link</a>
17
- </li>
18
- <li role="menuitem">
19
- <a href="#" class="s-block-link">Example li</a>
20
- </li>
21
- <li role="menuitem" class="s-menu--label">Example label</li>
22
- <li role="menuitem">
23
- <a href="#" class="s-block-link">Block link</a>
24
- </li>
25
- <li class="s-menu--divider" role="separator"></li>
26
- <li role="menuitem">
27
- <a href="…" class="s-block-link s-block-link__danger">Danger link</a>
28
- </li>
29
- `,
30
- },
31
- tag: "ul",
32
- attributes: {
33
- role: "menu",
34
- },
35
- template: ({ component, testid }) => html`
36
- <div class="ws2" data-testid="${testid}">${component}</div>
37
- `,
38
- });
39
- });
@@ -1,39 +0,0 @@
1
- import { html } from "@open-wc/testing";
2
- import { runVisualTests } from "../../test/visual-test-utils";
3
- import "../../index";
4
-
5
- describe("menu", () => {
6
- runVisualTests({
7
- baseClass: `s-menu`,
8
- children: {
9
- default: `
10
- <li class="s-menu--title" role="separator">Title 1</li>
11
- <li role="menuitem">
12
- <a href="#" class="s-block-link">Example li</a>
13
- </li>
14
- <li class="s-menu--title" role="separator">Title 2</li>
15
- <li role="menuitem">
16
- <a href="#" class="s-block-link s-block-link__left is-selected">Selected link</a>
17
- </li>
18
- <li role="menuitem">
19
- <a href="#" class="s-block-link">Example li</a>
20
- </li>
21
- <li role="menuitem" class="s-menu--label">Example label</li>
22
- <li role="menuitem">
23
- <a href="#" class="s-block-link">Block link</a>
24
- </li>
25
- <li class="s-menu--divider" role="separator"></li>
26
- <li role="menuitem">
27
- <a href="…" class="s-block-link s-block-link__danger">Danger link</a>
28
- </li>
29
- `,
30
- },
31
- tag: "ul",
32
- attributes: {
33
- role: "menu",
34
- },
35
- template: ({ component, testid }) => html`
36
- <div class="ws2" data-testid="${testid}">${component}</div>
37
- `,
38
- });
39
- });
@@ -1,41 +0,0 @@
1
- import { html } from "@open-wc/testing";
2
- import { runA11yTests } from "../../test/a11y-test-utils";
3
- import { IconClearSm } from "@stackoverflow/stacks-icons/icons";
4
- import "../../index";
5
-
6
- describe("modal", () => {
7
- runA11yTests({
8
- baseClass: `s-modal`,
9
- variants: ["danger"],
10
- modifiers: {
11
- primary: ["celebration"],
12
- secondary: ["full"],
13
- },
14
- children: {
15
- default: `
16
- <div class="s-modal--dialog" role="document">
17
- <h1 class="s-modal--header" id="modal-title">Modal header</h1>
18
- <p class="s-modal--body" id="modal-description">Modal body. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.</p>
19
- <div class="d-flex gx8 s-modal--footer">
20
- <button class="s-btn s-btn__filled" type="button">Confirm</button>
21
- <button class="s-btn s-btn__muted" type="button">Cancel</button>
22
- </div>
23
- <button class="s-modal--close s-btn s-btn__muted" type="button" aria-label="Close">
24
- ${IconClearSm}
25
- </button>
26
- </div>
27
- `,
28
- },
29
- tag: "aside",
30
- attributes: {
31
- "id": "example-modal",
32
- "tabindex": "-1",
33
- "aria-hidden": "false",
34
- "aria-labelledby": "modal-title",
35
- "class": "ps-relative p32",
36
- },
37
- template: ({ component, testid }) => html`
38
- <div class="m8 ws6" data-testid="${testid}">${component}</div>
39
- `,
40
- });
41
- });
@@ -1,155 +0,0 @@
1
- import { html, fixture, expect } from "@open-wc/testing";
2
- import { screen, waitFor } from "@testing-library/dom";
3
- import userEvent from "@testing-library/user-event";
4
- import "../../index";
5
-
6
- const user = userEvent.setup();
7
-
8
- const createModal = ({
9
- hidden = true,
10
- initialFocusEl,
11
- }: { hidden?: boolean; initialFocusEl?: ReturnType<typeof html> } = {}) => html`
12
- <div data-controller="s-modal">
13
- <button
14
- class="s-btn"
15
- data-action="s-modal#show"
16
- data-testid="trigger">
17
- Show Modal
18
- </button>
19
-
20
- <aside
21
- class="s-modal"
22
- id="modal-base"
23
- tabindex="-1"
24
- role="dialog"
25
- aria-labelledby="modal-base-title"
26
- aria-describedby="modal-base-description"
27
- aria-hidden="${hidden}"
28
- data-s-modal-target="modal"
29
- data-testid="modal">
30
- <div class="s-modal--dialog" role="document">
31
- <h1 class="s-modal--header" id="modal-base-title">Title</h1>
32
-
33
- <p class="s-modal--body">
34
- <span id="modal-base-description">Description</span>
35
- <form>
36
- <input type="text" data-testid="first-focusable-element" />
37
- ${initialFocusEl}
38
- </form>
39
- </p>
40
-
41
- <div class="d-flex gx8 s-modal--footer">
42
- <button class="flex--item s-btn s-btn__primary" type="button">Save changes</button>
43
- <button class="flex--item s-btn" type="button" data-action="s-modal#hide">Cancel</button>
44
- </div>
45
-
46
- <button
47
- class="s-btn s-btn__muted s-modal--close"
48
- type="button"
49
- aria-label="Close"
50
- data-action="s-modal#hide"
51
- data-testid="close-btn">
52
- Close
53
- </button>
54
- </div>
55
- </aside>
56
- </div>
57
- `;
58
-
59
- describe("modal", () => {
60
- it("should make the modal visible when toggle button is clicked", async () => {
61
- await fixture(createModal());
62
-
63
- const modal = await screen.findByTestId("modal");
64
- const trigger = await screen.findByTestId("trigger");
65
-
66
- expect(modal).not.to.be.visible;
67
-
68
- await user.click(trigger);
69
-
70
- expect(modal).to.be.visible;
71
- });
72
-
73
- it("should hide the modal when the close button is clicked", async () => {
74
- await fixture(createModal({ hidden: false }));
75
-
76
- const modal = await screen.findByTestId("modal");
77
- const closeBtn = await screen.findByTestId("close-btn");
78
-
79
- expect(modal).to.be.visible;
80
-
81
- await user.click(closeBtn);
82
-
83
- await waitFor(() => expect(modal).not.to.be.visible);
84
- });
85
-
86
- it('should focus on the first element with `data-s-modal-target"initialFocus"` when modal is shown', async () => {
87
- await fixture(
88
- createModal({
89
- initialFocusEl: html`<input
90
- type="text"
91
- data-testid="initialFocus"
92
- data-s-modal-target="initialFocus"
93
- />`,
94
- })
95
- );
96
-
97
- const modal = await screen.findByTestId("modal");
98
- const trigger = await screen.findByTestId("trigger");
99
- const initialFocusEl = await screen.findByTestId("initialFocus");
100
-
101
- expect(modal).not.to.be.visible;
102
-
103
- await user.click(trigger);
104
- expect(modal).to.be.visible;
105
-
106
- await waitFor(() => expect(initialFocusEl).to.have.focus);
107
- });
108
-
109
- it("should focus on the first focusable element when modal is shown and no initialFocus is specified", async () => {
110
- await fixture(createModal());
111
-
112
- const modal = await screen.findByTestId("modal");
113
- const trigger = await screen.findByTestId("trigger");
114
- const focusableEl = await screen.findByTestId(
115
- "first-focusable-element"
116
- );
117
-
118
- expect(modal).not.to.be.visible;
119
- expect(focusableEl).not.to.have.focus;
120
-
121
- await user.click(trigger);
122
- expect(modal).to.be.visible;
123
-
124
- await waitFor(() => expect(focusableEl).to.have.focus);
125
- });
126
-
127
- it("should not change set focus when an element within the modal is already focused", async () => {
128
- await fixture(createModal());
129
-
130
- const modal = await screen.findByTestId("modal");
131
- const trigger = await screen.findByTestId("trigger");
132
- const firstFocusableEl = await screen.findByTestId(
133
- "first-focusable-element"
134
- );
135
- const closeButton = await screen.findByTestId("close-btn");
136
-
137
- expect(modal).not.to.be.visible;
138
- expect(firstFocusableEl).not.to.have.focus;
139
-
140
- await user.click(trigger);
141
- expect(modal).to.be.visible;
142
-
143
- // manually focus on an element within the modal
144
- closeButton.focus();
145
-
146
- // wait for s-modal:shown css transition to complete
147
- await new Promise((resolve) =>
148
- modal.addEventListener("s-modal:shown", resolve)
149
- );
150
-
151
- // check that focus stayed on the manually focused element and
152
- // has not changed to the first focusable element
153
- expect(closeButton).to.have.focus;
154
- });
155
- });
@@ -1,41 +0,0 @@
1
- import { html } from "@open-wc/testing";
2
- import { runVisualTests } from "../../test/visual-test-utils";
3
- import { IconClearSm } from "@stackoverflow/stacks-icons/icons";
4
- import "../../index";
5
-
6
- describe("modal", () => {
7
- runVisualTests({
8
- baseClass: `s-modal`,
9
- variants: ["danger"],
10
- modifiers: {
11
- primary: ["celebration"],
12
- secondary: ["full"],
13
- },
14
- children: {
15
- default: `
16
- <div class="s-modal--dialog" role="document">
17
- <h1 class="s-modal--header" id="modal-title">Modal header</h1>
18
- <p class="s-modal--body" id="modal-description">Modal body. Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam.</p>
19
- <div class="d-flex gx8 s-modal--footer">
20
- <button class="s-btn s-btn__filled" type="button">Confirm</button>
21
- <button class="s-btn s-btn__muted" type="button">Cancel</button>
22
- </div>
23
- <button class="s-modal--close s-btn s-btn__muted" type="button" aria-label="Close">
24
- ${IconClearSm}
25
- </button>
26
- </div>
27
- `,
28
- },
29
- tag: "aside",
30
- attributes: {
31
- "id": "example-modal",
32
- "tabindex": "-1",
33
- "aria-hidden": "false",
34
- "aria-labelledby": "modal-title",
35
- "class": "ps-relative p32",
36
- },
37
- template: ({ component, testid }) => html`
38
- <div class="m8 ws6" data-testid="${testid}">${component}</div>
39
- `,
40
- });
41
- });
@@ -1,81 +0,0 @@
1
- import { html } from "@open-wc/testing";
2
- import { runA11yTests } from "../../test/a11y-test-utils";
3
- import { WCAGNonTextContrast } from "../../test/assertions";
4
- import "../../index";
5
-
6
- const items = [
7
- {
8
- label: "Group 1",
9
- title: true,
10
- },
11
- {
12
- label: "Product",
13
- selected: true,
14
- },
15
- {
16
- label: "Email",
17
- },
18
- {
19
- label: "Group 2",
20
- title: true,
21
- },
22
- {
23
- label: "Content",
24
- },
25
- {
26
- label: "Brand",
27
- },
28
- {
29
- label: "Marketing",
30
- },
31
- {
32
- label: "More selected",
33
- dropdown: true,
34
- selected: true,
35
- },
36
- {
37
- label: "More",
38
- dropdown: true,
39
- },
40
- ];
41
-
42
- const getChildren = (includeTitles = false): string =>
43
- items
44
- .map((item) => {
45
- if (item.title) {
46
- return includeTitles
47
- ? `<li class="s-navigation--title">${item.label}</li>`
48
- : "";
49
- }
50
- const classes = `s-navigation--item${
51
- item.selected ? " is-selected" : ""
52
- }${item.dropdown ? " s-navigation--item__dropdown" : ""}`;
53
- return `<li><a href="#" class="${classes}">${item.label}</a></li>`;
54
- })
55
- .join("");
56
-
57
- describe("navigation", () => {
58
- runA11yTests({
59
- baseClass: "s-navigation",
60
- variants: ["vertical", "muted"],
61
- modifiers: {
62
- primary: ["scroll", "sm"],
63
- },
64
- tag: "ul",
65
- children: {
66
- default: getChildren(true),
67
- },
68
- template: ({ component, testid }) => html`
69
- <nav
70
- class="d-inline-block p8 wmx3"
71
- aria-label="example-navigation"
72
- data-testid="${testid}"
73
- >
74
- ${component}
75
- </nav>
76
- `,
77
- additionalAssertions: [WCAGNonTextContrast],
78
- // TODO: fix non-text-contrast SC for s-navigation__muted
79
- skippedTestids: [/s-navigation-(light|dark)-muted/],
80
- });
81
- });