@stackoverflow/stacks 2.0.8 → 2.1.0-rc.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.
- package/LICENSE.MD +1 -1
- package/README.md +7 -9
- package/dist/css/stacks.css +234 -214
- package/dist/css/stacks.min.css +1 -1
- package/dist/js/stacks.js +1 -1
- package/lib/atomic/misc.less +1 -1
- package/lib/components/activity-indicator/activity-indicator.a11y.test.ts +2 -3
- package/lib/components/activity-indicator/activity-indicator.less +5 -5
- package/lib/components/activity-indicator/activity-indicator.visual.test.ts +2 -3
- package/lib/components/anchor/anchor.a11y.test.ts +2 -4
- package/lib/components/anchor/anchor.visual.test.ts +2 -4
- package/lib/components/avatar/avatar.a11y.test.ts +2 -3
- package/lib/components/avatar/avatar.visual.test.ts +2 -3
- package/lib/components/award-bling/award-bling.a11y.test.ts +2 -4
- package/lib/components/award-bling/award-bling.visual.test.ts +2 -4
- package/lib/components/badge/badge.a11y.test.ts +7 -16
- package/lib/components/badge/badge.visual.test.ts +8 -21
- package/lib/components/banner/banner.a11y.test.ts +2 -3
- package/lib/components/banner/banner.visual.test.ts +2 -3
- package/lib/components/block-link/block-link.a11y.test.ts +4 -9
- package/lib/components/block-link/block-link.less +7 -10
- package/lib/components/block-link/block-link.visual.test.ts +4 -9
- package/lib/components/breadcrumbs/breadcrumbs.a11y.test.ts +2 -3
- package/lib/components/breadcrumbs/breadcrumbs.visual.test.ts +2 -3
- package/lib/components/button/button.a11y.test.ts +2 -3
- package/lib/components/button/button.less +70 -35
- package/lib/components/button/button.visual.test.ts +2 -3
- package/lib/components/card/card.a11y.test.ts +2 -3
- package/lib/components/card/card.visual.test.ts +3 -6
- package/lib/components/check-control/check-control.a11y.test.ts +2 -4
- package/lib/components/check-control/check-control.visual.test.ts +2 -4
- package/lib/components/check-group/check-group.a11y.test.ts +2 -4
- package/lib/components/check-group/check-group.visual.test.ts +2 -4
- package/lib/components/checkbox_radio/checkbox_radio.a11y.test.ts +2 -4
- package/lib/components/checkbox_radio/checkbox_radio.less +1 -13
- package/lib/components/checkbox_radio/checkbox_radio.visual.test.ts +2 -4
- package/lib/components/code-block/code-block.a11y.test.ts +2 -4
- package/lib/components/code-block/code-block.visual.test.ts +2 -4
- package/lib/components/description/description.a11y.test.ts +2 -4
- package/lib/components/description/description.visual.test.ts +2 -4
- package/lib/components/empty-state/empty-state.a11y.test.ts +2 -3
- package/lib/components/empty-state/empty-state.visual.test.ts +2 -3
- package/lib/components/expandable/expandable.a11y.test.ts +2 -3
- package/lib/components/expandable/expandable.visual.test.ts +2 -3
- package/lib/components/input-fill/input-fill.a11y.test.ts +2 -3
- package/lib/components/input-fill/input-fill.visual.test.ts +2 -3
- package/lib/components/input-message/input-message.a11y.test.ts +2 -3
- package/lib/components/input-message/input-message.visual.test.ts +2 -3
- package/lib/components/input_textarea/input_textarea.a11y.test.ts +4 -7
- package/lib/components/input_textarea/input_textarea.less +2 -20
- package/lib/components/input_textarea/input_textarea.visual.test.ts +4 -7
- package/lib/components/label/label.a11y.test.ts +2 -3
- package/lib/components/label/label.visual.test.ts +2 -3
- package/lib/components/link/link.a11y.test.ts +2 -3
- package/lib/components/link/link.visual.test.ts +2 -3
- package/lib/components/link-preview/link-preview.a11y.test.ts +2 -3
- package/lib/components/link-preview/link-preview.visual.test.ts +3 -3
- package/lib/components/menu/menu.a11y.test.ts +2 -3
- package/lib/components/menu/menu.visual.test.ts +2 -3
- package/lib/components/modal/modal.a11y.test.ts +2 -3
- package/lib/components/modal/modal.visual.test.ts +2 -3
- package/lib/components/navigation/navigation.a11y.test.ts +2 -3
- package/lib/components/navigation/navigation.less +3 -1
- package/lib/components/navigation/navigation.visual.test.ts +3 -6
- package/lib/components/notice/notice.a11y.test.ts +2 -3
- package/lib/components/notice/notice.visual.test.ts +2 -3
- package/lib/components/page-title/page-title.a11y.test.ts +2 -3
- package/lib/components/page-title/page-title.visual.test.ts +2 -3
- package/lib/components/pagination/pagination.a11y.test.ts +2 -3
- package/lib/components/pagination/pagination.less +9 -0
- package/lib/components/pagination/pagination.visual.test.ts +2 -3
- package/lib/components/progress-bar/progress-bar.a11y.test.ts +7 -18
- package/lib/components/progress-bar/progress-bar.less +1 -1
- package/lib/components/progress-bar/progress-bar.visual.test.ts +7 -18
- package/lib/components/select/select.less +1 -15
- package/lib/components/spinner/spinner.a11y.test.ts +2 -3
- package/lib/components/spinner/spinner.visual.test.ts +4 -7
- package/lib/components/table/table.a11y.test.ts +3 -4
- package/lib/components/table/table.visual.test.ts +2 -3
- package/lib/components/tag/tag.a11y.test.ts +2 -3
- package/lib/components/tag/tag.less +27 -21
- package/lib/components/tag/tag.visual.test.ts +3 -6
- package/lib/components/toast/toast.a11y.test.ts +2 -3
- package/lib/components/toast/toast.visual.test.ts +2 -3
- package/lib/components/toggle-switch/toggle-switch.a11y.test.ts +3 -6
- package/lib/components/toggle-switch/toggle-switch.less +5 -16
- package/lib/components/toggle-switch/toggle-switch.visual.test.ts +3 -7
- package/lib/components/topbar/topbar.less +61 -39
- package/lib/components/topbar/topbar.visual.test.ts +188 -0
- package/lib/components/uploader/uploader.less +1 -1
- package/lib/exports/__snapshots__/color-mixins.less.test.ts.snap +12 -0
- package/lib/exports/__snapshots__/color.less.test.ts.snap +45 -0
- package/lib/exports/color-mixins.less +2 -0
- package/lib/exports/color-sets.less +44 -7
- package/lib/exports/mixins.less +33 -0
- package/lib/input-utils.less +0 -3
- package/lib/test/a11y-test-utils.ts +94 -0
- package/lib/test/assertions.ts +10 -3
- package/lib/test/test-utils.ts +152 -300
- package/lib/test/visual-test-utils.ts +58 -0
- package/lib/tsconfig.json +3 -3
- package/package.json +12 -13
- package/lib/components/popover/tooltip.visual.test.ts +0 -31
package/lib/exports/mixins.less
CHANGED
|
@@ -110,6 +110,39 @@
|
|
|
110
110
|
}
|
|
111
111
|
|
|
112
112
|
|
|
113
|
+
/**
|
|
114
|
+
* Focus styles for the given context.
|
|
115
|
+
*
|
|
116
|
+
* Usage example:
|
|
117
|
+
* .focus-styles(true, true);
|
|
118
|
+
*
|
|
119
|
+
* @inset: boolean - whether the focus style be placed inside the element.
|
|
120
|
+
* @border: boolean - whether the element's border color change to match the focus style.
|
|
121
|
+
*/
|
|
122
|
+
.focus-styles(@inset: false, @border: false) {
|
|
123
|
+
& when not (@inset) and not (@border) {
|
|
124
|
+
box-shadow: 0 0 0 var(--su-static2) var(--focus-neutral), 0 0 0 var(--su-static4) var(--focus-theme);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
& when not (@inset) and (@border) {
|
|
128
|
+
border-color: var(--focus-neutral) !important;
|
|
129
|
+
box-shadow: 0 0 0 var(--su-static1) var(--focus-neutral), 0 0 0 calc(var(--su-static4) - var(--su-static1)) var(--focus-theme);
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
& when (@inset) and not (@border) {
|
|
133
|
+
box-shadow: inset 0 0 0 var(--su-static2) var(--focus-theme), inset 0 0 0 var(--su-static4) var(--focus-neutral);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
& when (@inset) and (@border) {
|
|
137
|
+
border-color: var(--focus-theme) !important;
|
|
138
|
+
box-shadow: inset 0 0 0 var(--su-static1) var(--focus-theme), inset 0 0 0 calc(var(--su-static4) - var(--su-static1)) var(--focus-neutral);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// We include a 2px transparent outline to ensure Windows High Contrast Forced Color Mode
|
|
142
|
+
// includes outlines as expected See https://blogs.windows.com/msedgedev/2020/09/17/styling-for-windows-high-contrast-with-new-standards-for-forced-colors/
|
|
143
|
+
outline: var(--su-static2) solid transparent !important;
|
|
144
|
+
}
|
|
145
|
+
|
|
113
146
|
// =============================================================================
|
|
114
147
|
// -- COLORS
|
|
115
148
|
// The following mixins let us do color math on the browser. They take a
|
package/lib/input-utils.less
CHANGED
|
@@ -17,19 +17,16 @@
|
|
|
17
17
|
|
|
18
18
|
.has-error & {
|
|
19
19
|
--_@{prefix}-bc: var(--red-400);
|
|
20
|
-
--_@{prefix}-bs-focus: 0 0 0 var(--su-static4) var(--focus-ring-error);
|
|
21
20
|
@error();
|
|
22
21
|
}
|
|
23
22
|
|
|
24
23
|
.has-success & {
|
|
25
24
|
--_@{prefix}-bc: var(--green-400);
|
|
26
|
-
--_@{prefix}-bs-focus: 0 0 0 var(--su-static4) var(--focus-ring-success);
|
|
27
25
|
@success();
|
|
28
26
|
}
|
|
29
27
|
|
|
30
28
|
.has-warning & {
|
|
31
29
|
--_@{prefix}-bc: var(--yellow-500);
|
|
32
|
-
--_@{prefix}-bs-focus: 0 0 0 var(--su-static4) var(--focus-ring-warning);
|
|
33
30
|
@warning();
|
|
34
31
|
}
|
|
35
32
|
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import { html, fixture, expect } from "@open-wc/testing";
|
|
2
|
+
import { screen } from "@testing-library/dom";
|
|
3
|
+
import axe from "axe-core";
|
|
4
|
+
import registerAPCACheck from "apca-check";
|
|
5
|
+
import { generateTestVariations, type TestVariationArgs } from "./test-utils";
|
|
6
|
+
import type { AdditionalAssertion } from "./assertions";
|
|
7
|
+
|
|
8
|
+
type A11yTestArgs = TestVariationArgs & {
|
|
9
|
+
/**
|
|
10
|
+
* Additional assertions to run against the test element
|
|
11
|
+
*/
|
|
12
|
+
additionalAssertions?: AdditionalAssertion[];
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
// register Stack APCA conformance threshold function
|
|
16
|
+
// see also https://stackoverflow.design/product/base/color-fundamentals/#accessibility-standards
|
|
17
|
+
const customConformanceThresholdFn = (fontSize: string): number | null => {
|
|
18
|
+
// if the font size is 32px or larger, we use a 45Lc threshold
|
|
19
|
+
// otherwise, we use a 60Lc threshold
|
|
20
|
+
return parseFloat(fontSize) >= 32 ? 45 : 60;
|
|
21
|
+
};
|
|
22
|
+
registerAPCACheck("custom", customConformanceThresholdFn);
|
|
23
|
+
|
|
24
|
+
const scheduleA11yTest = ({
|
|
25
|
+
element,
|
|
26
|
+
testid,
|
|
27
|
+
theme,
|
|
28
|
+
additionalAssertions = [],
|
|
29
|
+
}: {
|
|
30
|
+
element: ReturnType<typeof html>;
|
|
31
|
+
testid: string;
|
|
32
|
+
theme: string[];
|
|
33
|
+
additionalAssertions?: AdditionalAssertion[];
|
|
34
|
+
}) => {
|
|
35
|
+
it(`a11y: ${testid} should be accessible`, async () => {
|
|
36
|
+
await fixture(element);
|
|
37
|
+
const el = screen.getByTestId(testid);
|
|
38
|
+
|
|
39
|
+
document.body.className = "";
|
|
40
|
+
|
|
41
|
+
if (theme?.length) {
|
|
42
|
+
const prefixedThemes = theme.map((t) => `theme-${t}`);
|
|
43
|
+
document.body.classList.add(...prefixedThemes);
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
const highcontrast = theme?.includes("highcontrast");
|
|
47
|
+
|
|
48
|
+
axe.configure({
|
|
49
|
+
rules: [
|
|
50
|
+
// for non-high contrast, we disable WCAG 2.1 AA (4.5:1)
|
|
51
|
+
// and use a Stacks-specific APCA custom level instead
|
|
52
|
+
{ id: "color-contrast", enabled: false },
|
|
53
|
+
{
|
|
54
|
+
id: "color-contrast-apca-custom",
|
|
55
|
+
enabled: !highcontrast,
|
|
56
|
+
},
|
|
57
|
+
// for high contrast, we check against WCAG 2.1 AAA (7:1)
|
|
58
|
+
{ id: "color-contrast-enhanced", enabled: highcontrast },
|
|
59
|
+
],
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
await expect(el).to.be.accessible();
|
|
63
|
+
el.remove();
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
additionalAssertions.forEach((assertion) => {
|
|
67
|
+
it(`a11y: ${testid} ${assertion.description}`, async () => {
|
|
68
|
+
await fixture(element);
|
|
69
|
+
const el = screen.getByTestId(testid);
|
|
70
|
+
await assertion.assertion(el);
|
|
71
|
+
el.remove();
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
};
|
|
75
|
+
|
|
76
|
+
const runA11yTests = (args: A11yTestArgs) => {
|
|
77
|
+
const testVariations = generateTestVariations(args);
|
|
78
|
+
testVariations.forEach((variation) => {
|
|
79
|
+
if (variation.skipped) {
|
|
80
|
+
it.skip(`a11y: ${variation.testid} (skipped)`, () => {
|
|
81
|
+
return;
|
|
82
|
+
});
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
scheduleA11yTest({
|
|
87
|
+
...variation,
|
|
88
|
+
additionalAssertions: args.additionalAssertions,
|
|
89
|
+
});
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
export type { AdditionalAssertion };
|
|
94
|
+
export { runA11yTests };
|
package/lib/test/assertions.ts
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
1
|
import { expect } from "@open-wc/testing";
|
|
2
2
|
import Color from "colorjs.io";
|
|
3
|
-
|
|
3
|
+
|
|
4
|
+
type AdditionalAssertion = {
|
|
5
|
+
description: string;
|
|
6
|
+
assertion: (node: HTMLElement) => Promise<void> | void;
|
|
7
|
+
};
|
|
4
8
|
|
|
5
9
|
// TODO: evaluate if we can do this check against all the components
|
|
6
10
|
// automatically instead of having to add the assertion manually
|
|
7
|
-
|
|
11
|
+
const WCAGNonTextContrast: AdditionalAssertion = {
|
|
8
12
|
description:
|
|
9
13
|
"should pass WCAG22 1.4.11 non-text-contrast success criterion (https://www.w3.org/TR/WCAG22/#non-text-contrast)",
|
|
10
14
|
assertion: (node) => {
|
|
@@ -18,7 +22,7 @@ export const WCAGNonTextContrast: AdditionalAssertion = {
|
|
|
18
22
|
selectedNodeStyles.getPropertyValue("background-color")
|
|
19
23
|
);
|
|
20
24
|
|
|
21
|
-
// we are
|
|
25
|
+
// we are specifing WCAG21 because of colorjs.io API
|
|
22
26
|
// WCAG21 and WCAG22 algoirthms are the same
|
|
23
27
|
const WCAGcontrast = bgSelectedNodeColor.contrast(
|
|
24
28
|
bgBodyColor,
|
|
@@ -27,3 +31,6 @@ export const WCAGNonTextContrast: AdditionalAssertion = {
|
|
|
27
31
|
expect(WCAGcontrast).to.be.at.least(3);
|
|
28
32
|
},
|
|
29
33
|
};
|
|
34
|
+
|
|
35
|
+
export type { AdditionalAssertion };
|
|
36
|
+
export { WCAGNonTextContrast };
|