@stackoverflow/stacks 1.8.0 → 1.9.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/dist/components/activity-indicator/activity-indicator.a11y.test.d.ts +1 -0
- package/dist/components/activity-indicator/activity-indicator.visual.test.d.ts +1 -0
- package/dist/components/avatar/avatar.a11y.test.d.ts +1 -0
- package/dist/components/avatar/avatar.visual.test.d.ts +1 -0
- package/dist/{controllers/s-banner.d.ts → components/banner/banner.d.ts} +1 -1
- package/dist/components/banner/banner.test.d.ts +1 -0
- package/dist/components/banner/banner.visual.test.d.ts +1 -0
- package/dist/components/button/button.a11y.test.d.ts +1 -0
- package/dist/components/button/button.visual.test.d.ts +1 -0
- package/dist/{controllers/s-expandable-control.d.ts → components/expandable/expandable.d.ts} +1 -1
- package/dist/components/expandable/expandable.test.d.ts +1 -0
- package/dist/{controllers/s-modal.d.ts → components/modal/modal.d.ts} +1 -1
- package/dist/{controllers/s-navigation-tablist.d.ts → components/navigation/navigation.d.ts} +1 -1
- package/dist/{controllers/s-popover.d.ts → components/popover/popover.d.ts} +1 -1
- package/dist/{controllers/s-tooltip.d.ts → components/popover/tooltip.d.ts} +1 -1
- package/dist/components/popover/tooltip.test.d.ts +1 -0
- package/dist/components/popover/tooltip.visual.test.d.ts +1 -0
- package/dist/{controllers/s-table.d.ts → components/table/table.d.ts} +1 -1
- package/dist/{controllers/s-toast.d.ts → components/toast/toast.d.ts} +1 -1
- package/dist/components/toast/toast.test.d.ts +1 -0
- package/dist/components/toast/toast.visual.test.d.ts +1 -0
- package/dist/{controllers/s-uploader.d.ts → components/uploader/uploader.d.ts} +1 -1
- package/dist/controllers.d.ts +9 -0
- package/dist/css/stacks.css +2043 -1989
- package/dist/css/stacks.min.css +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/js/stacks.js +545 -545
- package/dist/js/stacks.min.js +1 -1
- package/dist/test/test-utils.d.ts +136 -0
- package/lib/{css/atomic/borders.less → atomic/border.less} +18 -0
- package/lib/{css/base/icons.less → base/icon.less} +0 -9
- package/lib/components/activity-indicator/activity-indicator.a11y.test.ts +21 -0
- package/lib/components/activity-indicator/activity-indicator.visual.test.ts +23 -0
- package/lib/components/avatar/avatar.a11y.test.ts +36 -0
- package/lib/components/avatar/avatar.visual.test.ts +54 -0
- package/lib/components/banner/banner.less +51 -0
- package/lib/{test/s-banner.test.ts → components/banner/banner.test.ts} +7 -3
- package/lib/{ts/controllers/s-banner.ts → components/banner/banner.ts} +1 -1
- package/lib/components/banner/banner.visual.test.ts +36 -0
- package/lib/components/button/button.a11y.test.ts +32 -0
- package/lib/{css/components/buttons.less → components/button/button.less} +3 -2
- package/lib/components/button/button.visual.test.ts +52 -0
- package/lib/{css/components/cards.less → components/card/card.less} +1 -1
- package/lib/components/check-control/check-control.less +17 -0
- package/lib/components/check-group/check-group.less +19 -0
- package/lib/{css/components → components/expandable}/expandable.less +3 -0
- package/lib/components/expandable/expandable.test.ts +53 -0
- package/lib/{ts/controllers/s-expandable-control.ts → components/expandable/expandable.ts} +1 -1
- package/lib/components/input-fill/input-fill.less +35 -0
- package/lib/components/input-icon/input-icon.less +45 -0
- package/lib/components/input-message/input-message.less +48 -0
- package/lib/{css/components/inputs.less → components/input_textarea/input_textarea.less} +0 -131
- package/lib/{css/components → components/link}/link.less +2 -2
- package/lib/{ts/controllers/s-modal.ts → components/modal/modal.ts} +1 -1
- package/lib/{ts/controllers/s-navigation-tablist.ts → components/navigation/navigation.ts} +1 -1
- package/lib/{css/components/notices.less → components/notice/notice.less} +0 -89
- package/lib/{css/components/popovers.less → components/popover/popover.less} +1 -0
- package/lib/{ts/controllers/s-popover.ts → components/popover/popover.ts} +1 -1
- package/lib/{test/s-tooltip.test.ts → components/popover/tooltip.test.ts} +6 -2
- package/lib/{ts/controllers/s-tooltip.ts → components/popover/tooltip.ts} +2 -2
- package/lib/{test/s-tooltip.visual.test.ts → components/popover/tooltip.visual.test.ts} +2 -2
- package/lib/{css/components/sidebar-widgets.less → components/sidebar-widget/sidebar-widget.less} +0 -1
- package/lib/{css/components → components/table}/table.less +0 -5
- package/lib/{ts/controllers/s-table.ts → components/table/table.ts} +1 -1
- package/lib/components/table-container/table-container.less +4 -0
- package/lib/components/toast/toast.less +35 -0
- package/lib/{test/s-toast.test.ts → components/toast/toast.test.ts} +7 -3
- package/lib/{ts/controllers/s-toast.ts → components/toast/toast.ts} +1 -1
- package/lib/components/toast/toast.visual.test.ts +27 -0
- package/lib/{ts/controllers/s-uploader.ts → components/uploader/uploader.ts} +1 -1
- package/lib/controllers.ts +33 -0
- package/lib/{ts/index.ts → index.ts} +1 -1
- package/lib/{css/stacks-dynamic.less → stacks-dynamic.less} +1 -2
- package/lib/stacks-static.less +93 -0
- package/lib/test/test-utils.ts +444 -0
- package/lib/tsconfig.json +1 -1
- package/package.json +17 -17
- package/dist/controllers/index.d.ts +0 -9
- package/lib/css/stacks-static.less +0 -87
- package/lib/test/s-avatar.a11y.test.ts +0 -77
- package/lib/test/s-banner.visual.test.ts +0 -61
- package/lib/test/s-btn.a11y.test.ts +0 -123
- package/lib/test/s-btn.visual.test.ts +0 -16
- package/lib/test/s-toast.visual.test.ts +0 -48
- package/lib/ts/controllers/index.ts +0 -17
- /package/lib/{css/atomic/colors.less → atomic/color.less} +0 -0
- /package/lib/{css/atomic → atomic}/flex.less +0 -0
- /package/lib/{css/atomic → atomic}/gap.less +0 -0
- /package/lib/{css/atomic → atomic}/grid.less +0 -0
- /package/lib/{css/atomic → atomic}/misc.less +0 -0
- /package/lib/{css/atomic → atomic}/spacing.less +0 -0
- /package/lib/{css/atomic → atomic}/typography.less +0 -0
- /package/lib/{css/atomic → atomic}/width-height.less +0 -0
- /package/lib/{css/base → base}/body.less +0 -0
- /package/lib/{css/base → base}/configuration-static.less +0 -0
- /package/lib/{css/base → base}/fieldset.less +0 -0
- /package/lib/{css/base/internals.less → base/internal.less} +0 -0
- /package/lib/{css/base → base}/reset-meyer.less +0 -0
- /package/lib/{css/base → base}/reset-normalize.less +0 -0
- /package/lib/{css/base → base}/reset.less +0 -0
- /package/lib/{css/components → components/activity-indicator}/activity-indicator.less +0 -0
- /package/lib/{css/components/anchors.less → components/anchor/anchor.less} +0 -0
- /package/lib/{css/components/avatars.less → components/avatar/avatar.less} +0 -0
- /package/lib/{css/components → components/award-bling}/award-bling.less +0 -0
- /package/lib/{css/components/badges.less → components/badge/badge.less} +0 -0
- /package/lib/{css/components → components/block-link}/block-link.less +0 -0
- /package/lib/{css/components → components/breadcrumbs}/breadcrumbs.less +0 -0
- /package/lib/{css/components/button-groups.less → components/button-group/button-group.less} +0 -0
- /package/lib/{css/components/checkboxes-radios.less → components/checkbox_radio/checkbox_radio.less} +0 -0
- /package/lib/{css/components/code-blocks.less → components/code-block/code-block.less} +0 -0
- /package/lib/{css/components → components/description}/description.less +0 -0
- /package/lib/{css/components/empty-states.less → components/empty-state/empty-state.less} +0 -0
- /package/lib/{css/components/labels.less → components/label/label.less} +0 -0
- /package/lib/{css/components/link-previews.less → components/link-preview/link-preview.less} +0 -0
- /package/lib/{css/components → components/menu}/menu.less +0 -0
- /package/lib/{css/components/modals.less → components/modal/modal.less} +0 -0
- /package/lib/{css/components → components/navigation}/navigation.less +0 -0
- /package/lib/{css/components/page-titles.less → components/page-title/page-title.less} +0 -0
- /package/lib/{css/components → components/pagination}/pagination.less +0 -0
- /package/lib/{css/components → components/post-summary}/post-summary.less +0 -0
- /package/lib/{css/components/progress-bars.less → components/progress-bar/progress-bar.less} +0 -0
- /package/lib/{css/components → components/prose}/prose.less +0 -0
- /package/lib/{css/components → components/select}/select.less +0 -0
- /package/lib/{css/components → components/spinner}/spinner.less +0 -0
- /package/lib/{css/components/tags.less → components/tag/tag.less} +0 -0
- /package/lib/{css/components/toggle-switches.less → components/toggle-switch/toggle-switch.less} +0 -0
- /package/lib/{css/components → components/topbar}/topbar.less +0 -0
- /package/lib/{css/components → components/uploader}/uploader.less +0 -0
- /package/lib/{css/components/user-cards.less → components/user-card/user-card.less} +0 -0
- /package/lib/{css/exports → exports}/constants-colors.less +0 -0
- /package/lib/{css/exports → exports}/constants-helpers.less +0 -0
- /package/lib/{css/exports → exports}/constants-type.less +0 -0
- /package/lib/{css/exports → exports}/exports.less +0 -0
- /package/lib/{css/exports → exports}/mixins.less +0 -0
- /package/lib/{css/input-utils.less → input-utils.less} +0 -0
- /package/lib/{css/stacks.less → stacks.less} +0 -0
- /package/lib/{ts/stacks.ts → stacks.ts} +0 -0
|
@@ -335,6 +335,24 @@
|
|
|
335
335
|
.bc-yellow-800 { border-color: var(--yellow-800) !important; }
|
|
336
336
|
.bc-yellow-900 { border-color: var(--yellow-900) !important; }
|
|
337
337
|
|
|
338
|
+
// $$ GOLD
|
|
339
|
+
// ----------------------------------------------------------------------------
|
|
340
|
+
.bc-gold-lighter { border-color: var(--gold-lighter) !important; }
|
|
341
|
+
.bc-gold { border-color: var(--gold) !important; }
|
|
342
|
+
.bc-gold-darker { border-color: var(--gold-darker) !important; }
|
|
343
|
+
|
|
344
|
+
// $$ SILVER
|
|
345
|
+
// ----------------------------------------------------------------------------
|
|
346
|
+
.bc-silver-lighter { border-color: var(--silver-lighter) !important; }
|
|
347
|
+
.bc-silver { border-color: var(--silver) !important; }
|
|
348
|
+
.bc-silver-darker { border-color: var(--silver-darker) !important; }
|
|
349
|
+
|
|
350
|
+
// $$ BRONZE
|
|
351
|
+
// ----------------------------------------------------------------------------
|
|
352
|
+
.bc-bronze-lighter { border-color: var(--bronze-lighter) !important; }
|
|
353
|
+
.bc-bronze { border-color: var(--bronze) !important; }
|
|
354
|
+
.bc-bronze-darker { border-color: var(--bronze-darker) !important; }
|
|
355
|
+
|
|
338
356
|
// $$ PRIMARY
|
|
339
357
|
// ----------------------------------------------------------------------------
|
|
340
358
|
.bc-theme-primary-025 { border-color: var(--theme-primary-025) !important; }
|
|
@@ -1,12 +1,3 @@
|
|
|
1
|
-
//
|
|
2
|
-
// STACK OVERFLOW
|
|
3
|
-
// ICON STYLES
|
|
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
1
|
.svg-icon,
|
|
11
2
|
.svg-spot {
|
|
12
3
|
vertical-align: bottom; // Make SVG play nicely while inline with text by default
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { runComponentTests } from "../../test/test-utils";
|
|
2
|
+
import "../../index";
|
|
3
|
+
|
|
4
|
+
describe("activity-indicator", () => {
|
|
5
|
+
runComponentTests({
|
|
6
|
+
type: "a11y",
|
|
7
|
+
baseClass: "s-activity-indicator",
|
|
8
|
+
variants: ["danger", "success", "warning"],
|
|
9
|
+
children: {
|
|
10
|
+
default: `<div class="v-visible-sr">New activity</div>`,
|
|
11
|
+
new: `new<div class="v-visible-sr">New activity</div>`,
|
|
12
|
+
},
|
|
13
|
+
skippedTestids: [
|
|
14
|
+
"s-activity-indicator-dark-new", // TODO fix contrast issue
|
|
15
|
+
"s-activity-indicator-dark-success-new", // TODO fix contrast issue
|
|
16
|
+
"s-activity-indicator-dark-warning-new", // TODO fix contrast issue
|
|
17
|
+
"s-activity-indicator-light-success-new", // TODO fix contrast issue
|
|
18
|
+
"s-activity-indicator-light-warning-new", // TODO fix contrast issue
|
|
19
|
+
],
|
|
20
|
+
});
|
|
21
|
+
});
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { html } from "@open-wc/testing";
|
|
2
|
+
import { runComponentTests } from "../../test/test-utils";
|
|
3
|
+
import "../../index";
|
|
4
|
+
|
|
5
|
+
describe("activity-indicator", () => {
|
|
6
|
+
runComponentTests({
|
|
7
|
+
type: "visual",
|
|
8
|
+
baseClass: "s-activity-indicator",
|
|
9
|
+
variants: ["danger", "success", "warning"],
|
|
10
|
+
children: {
|
|
11
|
+
default: `<div class="v-visible-sr">New activity</div>`,
|
|
12
|
+
new: `new<div class="v-visible-sr">New activity</div>`,
|
|
13
|
+
},
|
|
14
|
+
template: ({ component, testid }) => html`
|
|
15
|
+
<div
|
|
16
|
+
class="d-inline-flex ai-center jc-center hs1 ws1 p8"
|
|
17
|
+
data-testid="${testid}"
|
|
18
|
+
>
|
|
19
|
+
${component}
|
|
20
|
+
</div>
|
|
21
|
+
`,
|
|
22
|
+
});
|
|
23
|
+
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { runComponentTests } from "../../test/test-utils";
|
|
2
|
+
import "../../index";
|
|
3
|
+
|
|
4
|
+
const getChild = (child?: string): string => {
|
|
5
|
+
const srEl = `<span class="v-visible-sr">Stack Overflow</span>`;
|
|
6
|
+
switch (child) {
|
|
7
|
+
case "image":
|
|
8
|
+
return `<img
|
|
9
|
+
class="s-avatar--image"
|
|
10
|
+
src="https://picsum.photos/id/1/48"
|
|
11
|
+
alt="team logo"
|
|
12
|
+
/>${srEl}`;
|
|
13
|
+
case "letter":
|
|
14
|
+
return `<div
|
|
15
|
+
class="s-avatar--letter"
|
|
16
|
+
aria-hidden="true">
|
|
17
|
+
S
|
|
18
|
+
</div>${srEl}`;
|
|
19
|
+
default:
|
|
20
|
+
return srEl;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
describe("avatar", () => {
|
|
25
|
+
runComponentTests({
|
|
26
|
+
type: "a11y",
|
|
27
|
+
baseClass: "s-avatar",
|
|
28
|
+
variants: ["24", "32", "48", "64", "96", "128"],
|
|
29
|
+
children: {
|
|
30
|
+
default: getChild(),
|
|
31
|
+
image: getChild("image"),
|
|
32
|
+
letter: getChild("letter"),
|
|
33
|
+
},
|
|
34
|
+
tag: "span",
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { html } from "@open-wc/testing";
|
|
2
|
+
import { runComponentTests } from "../../test/test-utils";
|
|
3
|
+
import "../../index";
|
|
4
|
+
|
|
5
|
+
const base64Image =
|
|
6
|
+
"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAATwAAAE8CAMAAABq2/00AAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAABhQTFRF/3IA/////44y/8OS/+fU//Xs/6tn/9e2EhvbMQAABH9JREFUeNrs3e1y2ygAhWELJHH/d7zuJpN1XAnxoe408Ly/6xnnHXEOIEwfDwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/gbAGEhrZl2VloY20PIk8tAzZbfkXA7eeuHyysVfdFMsXiY66ptiWF8Re05BdxF7HkBV7PUNW7FVx4E7sVSwrDjBw2+pC7NWwHtkTe3ULM7En9v6O2ONF7Ik9sSf2IPbEntgTexB7t8feTsynniD2Oh6tXex1hFoUe02kaxVi72JMZs+Rib0LLdkXFGLvaECWjkOxdxVmUex1rB6S2Kss2lcytSH2LnVkakPsXQ7E8xwTe5fuMrUh9vKj8CP4xN7lNOXc3mnwib1M2X7Z28VeS93mg0/sFZTG6WCMVSE51fqsYL4s9jpqQ+yV1caxErHXUxtir6c2xF5HbYRF7LXXhtjrqQ2x11MbYu9tLG4VtSH2empD7BUNxpPaSGKvPPh2sdcxX45i78baEHs18+X32hB7NfPl99oQex21MVHsxViaR8W1MU3s/XpMSvWF0tqYJfY+BmMq01dcG+scP6/6enTK9BW+1J0j9l5aYN0rP5BzM0XsbSUnAlpqY4LYezexFeRSbpslH3uDXdF64OG6est258PohXE8BK+7o6g29rJTQsPt1F3qK9qdTwMP2Wz2X1Vv0UvdbeQ53nl2Xesr2Z0Pww7Zs5lsafWW1MY+6JDNxv5/+kLb5/fXfzLirRdhKSGnr6A2tkGvJoxLGZnqva6NkAbdgA+pUN9a+QuWYYPu+98ee/W1/PJgoMG7lek7nW3UHiEdbKpcqu+kO2L9b4aG0rcWjt5jfWf2Z7kCeE891XtSG/O86A5d+tbZj1h0VW+c/ja90FG9uxMCFdWb/+SkZ1Oaq/d1vjzvXfvF+tLp+aiZT5S1Vm90lrFj02B3bW1d9X7T92u+7Aq9qk2D+Fob/v/Myu7YostC76xe9K966evfr5+7ekuXHVy1V6+R275pEMd3kPbGB+Syeod/8D7Sf41NBvPdMf7a4uXpaTGY0zd+4r0vDlKtwdPqHf/BOzzf8zQYqvRtcz54mXfUNUVyUL0T7AhcrBbKY/C36p1geVEy1y00+F3fBA9eKFxnlRXJa/XOcKxnqeF6Pv1VvTPc7RuXai6K5LN6Z9hQSUsb2Rh86pviUultaScTg/sMD15YeqmcT8/bFx1Foi/umk9P3hcMfqTenrabBT5j8DGTwHivwelOCTwNrnfJm/Ol2U0GZ74WdE+dBn9+Z/z2J9UZ7IjB7dZv8gPl9RRJIq89BiN57QZ38trn04G8k62E6xjcHuQ1D+JEXrvBnbz2+XQgr30+/SCveT69ktceg4m8doOBvDG/CXnkkTezvOXPQB555JFHHnnkkUceeeSRRx555JFHHnnkkWcnmTzyyCOPPPLII4888sgjjzzfhDzyyCOPPPL+9Ff+eyCPPPLII4888sgjjzzyyCOPPPLII4888sgDAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPy//CPAAPiZOI3BPDFQAAAAAElFTkSuQmCC";
|
|
7
|
+
|
|
8
|
+
const getChild = (child?: string): string => {
|
|
9
|
+
const srEl = `<span class="v-visible-sr">Stack Overflow</span>`;
|
|
10
|
+
switch (child) {
|
|
11
|
+
case "image":
|
|
12
|
+
return `<img
|
|
13
|
+
class="s-avatar--image"
|
|
14
|
+
src="${base64Image}"
|
|
15
|
+
alt="team logo"
|
|
16
|
+
/>${srEl}`;
|
|
17
|
+
case "letter":
|
|
18
|
+
return `<div
|
|
19
|
+
class="s-avatar--letter"
|
|
20
|
+
aria-hidden="true">
|
|
21
|
+
S
|
|
22
|
+
</div>${srEl}`;
|
|
23
|
+
default:
|
|
24
|
+
return srEl;
|
|
25
|
+
}
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
describe("avatar", () => {
|
|
29
|
+
runComponentTests({
|
|
30
|
+
type: "visual",
|
|
31
|
+
baseClass: "s-avatar",
|
|
32
|
+
variants: ["24", "32", "48", "64", "96", "128"],
|
|
33
|
+
children: {
|
|
34
|
+
default: getChild(),
|
|
35
|
+
image: getChild("image"),
|
|
36
|
+
letter: getChild("letter"),
|
|
37
|
+
},
|
|
38
|
+
attributes: {
|
|
39
|
+
href: "#",
|
|
40
|
+
},
|
|
41
|
+
tag: "a",
|
|
42
|
+
template: ({ component, testid }) => html`
|
|
43
|
+
<div
|
|
44
|
+
data-testid="${testid}"
|
|
45
|
+
class="d-inline-flex ai-center jc-center hmn1 wmn1 p8"
|
|
46
|
+
>
|
|
47
|
+
${component}
|
|
48
|
+
</div>
|
|
49
|
+
`,
|
|
50
|
+
skippedTestids: [
|
|
51
|
+
/-letter/, // TODO: resolve font-family thrashing issues
|
|
52
|
+
],
|
|
53
|
+
});
|
|
54
|
+
});
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
// See also ./lib/components/notice/notice.less
|
|
2
|
+
// TODO deprecate .s-banner (by turning it into a modifier on .s-notice)
|
|
3
|
+
// This would reduce the amount of CSS we ship to the client and simplify our codebase
|
|
4
|
+
.s-banner {
|
|
5
|
+
--_no-x-offset: 0; // [1]
|
|
6
|
+
.construct-notice-component(s-banner);
|
|
7
|
+
|
|
8
|
+
&[aria-hidden="true"] { // If you want to hide and reveal the banner
|
|
9
|
+
--_no-x-offset: calc(var(--su48) + var(--su2) * -1); // -50px
|
|
10
|
+
opacity: 0;
|
|
11
|
+
visibility: hidden;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&[aria-hidden="false"] {
|
|
15
|
+
--_no-x-offset: calc(var(--su48) + var(--su1)); // 49px
|
|
16
|
+
opacity: 1;
|
|
17
|
+
visibility: visible;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
&.is-pinned { // If you want to put the banner above the topbar
|
|
21
|
+
z-index: calc(var(--zi-navigation-fixed) + 1);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
&__body-pt {
|
|
25
|
+
padding-top: 93px;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
& &--container { // When we want to keep hero content capped
|
|
29
|
+
margin: 0 auto;
|
|
30
|
+
max-width: calc(var(--s-step) * 10);
|
|
31
|
+
position: relative;
|
|
32
|
+
width: 100%;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
border-width: var(--su-static1) 0;
|
|
36
|
+
inset: 0 0 auto 0;
|
|
37
|
+
padding: var(--su12);
|
|
38
|
+
position: fixed;
|
|
39
|
+
-webkit-transform: translate3d(0, var(--_no-x-offset), 0);
|
|
40
|
+
transform: translate3d(0, var(--_no-x-offset), 0);
|
|
41
|
+
width: 100%;
|
|
42
|
+
z-index: calc(var(--zi-navigation-fixed) - 1); // Tuck below topbar
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
// [1] When we use .s-banner, we need to adjust the padding-top on
|
|
46
|
+
// the body tag. This class correctly adjusts the body padding ONLY if
|
|
47
|
+
// the notice is one line. If it wraps to multiple lines, more classes or
|
|
48
|
+
// (ideally) JS will need to be used to determine the notice's height
|
|
49
|
+
// at the time of render. The padding value is determined like so:
|
|
50
|
+
// 50px (top bar) + 44px (notice height) - 1px (bottom border)
|
|
51
|
+
// The borders subtraction are necessary to neatly tuck everything together.
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { html, fixture, expect } from "@open-wc/testing";
|
|
2
2
|
import { screen } from "@testing-library/dom";
|
|
3
3
|
import userEvent from "@testing-library/user-event";
|
|
4
|
-
import "
|
|
5
|
-
import { showBanner, hideBanner } from "
|
|
4
|
+
import "../../index";
|
|
5
|
+
import { showBanner, hideBanner } from "../../controllers";
|
|
6
6
|
|
|
7
7
|
const user = userEvent.setup();
|
|
8
8
|
|
|
9
|
-
describe("
|
|
9
|
+
describe("banner", () => {
|
|
10
10
|
it("trigger should make banner visible", async () => {
|
|
11
11
|
await fixture(html`
|
|
12
12
|
<button data-toggle="s-banner" data-target="#test-banner">
|
|
@@ -29,10 +29,12 @@ describe("s-banner", () => {
|
|
|
29
29
|
const button = screen.getByRole("button");
|
|
30
30
|
const banner = screen.getByTestId("test-banner");
|
|
31
31
|
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
32
33
|
expect(banner).to.have.attribute("aria-hidden", "true");
|
|
33
34
|
button.addEventListener("click", () => showBanner(banner));
|
|
34
35
|
|
|
35
36
|
await user.click(button);
|
|
37
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
36
38
|
expect(banner).to.have.attribute("aria-hidden", "false");
|
|
37
39
|
});
|
|
38
40
|
|
|
@@ -64,10 +66,12 @@ describe("s-banner", () => {
|
|
|
64
66
|
const button = screen.getByRole("button");
|
|
65
67
|
const banner = screen.getByTestId("test-banner");
|
|
66
68
|
|
|
69
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
67
70
|
expect(banner).to.have.attribute("aria-hidden", "false");
|
|
68
71
|
button.addEventListener("click", () => hideBanner(banner));
|
|
69
72
|
|
|
70
73
|
await user.click(button);
|
|
74
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
71
75
|
expect(banner).to.have.attribute("aria-hidden", "true");
|
|
72
76
|
});
|
|
73
77
|
});
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { runComponentTests } from "../../test/test-utils";
|
|
2
|
+
import "../../index";
|
|
3
|
+
|
|
4
|
+
const bannerChild = `
|
|
5
|
+
<div
|
|
6
|
+
class="d-flex flex__center jc-space-between s-banner--container"
|
|
7
|
+
role="alertdialog"
|
|
8
|
+
aria-describedby="banner-message"
|
|
9
|
+
>
|
|
10
|
+
<div aria-label="banner message">
|
|
11
|
+
Test Banner
|
|
12
|
+
</div>
|
|
13
|
+
<div class="ml-auto myn8">
|
|
14
|
+
<span class="s-btn s-banner--btn">Close</span>
|
|
15
|
+
</div>
|
|
16
|
+
</div>
|
|
17
|
+
`;
|
|
18
|
+
|
|
19
|
+
describe("banner", () => {
|
|
20
|
+
runComponentTests({
|
|
21
|
+
type: "visual",
|
|
22
|
+
baseClass: "s-banner",
|
|
23
|
+
variants: ["info", "success", "warning", "danger"],
|
|
24
|
+
modifiers: {
|
|
25
|
+
primary: ["important"],
|
|
26
|
+
},
|
|
27
|
+
attributes: {
|
|
28
|
+
role: "alert",
|
|
29
|
+
ariaHidden: "false",
|
|
30
|
+
},
|
|
31
|
+
children: {
|
|
32
|
+
default: bannerChild,
|
|
33
|
+
},
|
|
34
|
+
tag: "aside",
|
|
35
|
+
});
|
|
36
|
+
});
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { runComponentTests } from "../../test/test-utils";
|
|
2
|
+
import "../../index";
|
|
3
|
+
|
|
4
|
+
describe("button", () => {
|
|
5
|
+
runComponentTests({
|
|
6
|
+
type: "a11y",
|
|
7
|
+
baseClass: "s-btn",
|
|
8
|
+
variants: ["danger", "muted", "primary"],
|
|
9
|
+
modifiers: {
|
|
10
|
+
primary: ["filled", "outlined"],
|
|
11
|
+
secondary: [...["xs", "sm", "md"], ...["dropdown", "icon"]],
|
|
12
|
+
global: ["is-loading"],
|
|
13
|
+
standalone: [
|
|
14
|
+
...["link", "unset"],
|
|
15
|
+
...["facebook", "github", "google"],
|
|
16
|
+
],
|
|
17
|
+
},
|
|
18
|
+
attributes: {
|
|
19
|
+
type: "button",
|
|
20
|
+
},
|
|
21
|
+
children: {
|
|
22
|
+
default: "Ask question",
|
|
23
|
+
},
|
|
24
|
+
tag: "button",
|
|
25
|
+
excludedTestids: [
|
|
26
|
+
/primary-outlined/, // This combination is not supported
|
|
27
|
+
],
|
|
28
|
+
skippedTestids: [
|
|
29
|
+
/s-btn-dark/, // TODO remove when contrast bugs are fixed
|
|
30
|
+
],
|
|
31
|
+
});
|
|
32
|
+
});
|
|
@@ -142,8 +142,6 @@
|
|
|
142
142
|
&:focus-visible {
|
|
143
143
|
outline-style: auto;
|
|
144
144
|
}
|
|
145
|
-
|
|
146
|
-
outline: initial;
|
|
147
145
|
}
|
|
148
146
|
|
|
149
147
|
&&__link {
|
|
@@ -170,6 +168,7 @@
|
|
|
170
168
|
.s-link();
|
|
171
169
|
display: inline;
|
|
172
170
|
font: inherit;
|
|
171
|
+
outline: revert;
|
|
173
172
|
text-align: inherit;
|
|
174
173
|
}
|
|
175
174
|
|
|
@@ -191,6 +190,8 @@
|
|
|
191
190
|
font: unset;
|
|
192
191
|
user-select: auto;
|
|
193
192
|
}
|
|
193
|
+
|
|
194
|
+
outline: initial;
|
|
194
195
|
}
|
|
195
196
|
|
|
196
197
|
// Pseudo-elements and child-based modifiers
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { html } from "@open-wc/testing";
|
|
2
|
+
import { runComponentTests } from "../../test/test-utils";
|
|
3
|
+
import "../../index";
|
|
4
|
+
|
|
5
|
+
const getChild = (child?: string): string => {
|
|
6
|
+
switch (child) {
|
|
7
|
+
case "badge":
|
|
8
|
+
return `Ask question
|
|
9
|
+
<span class="s-btn--badge">
|
|
10
|
+
<span class="s-btn--number">198</span>
|
|
11
|
+
</span>`;
|
|
12
|
+
default:
|
|
13
|
+
return "Ask question";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
describe("button", () => {
|
|
18
|
+
// TODO test disabled states, interaction pseudo-classes
|
|
19
|
+
runComponentTests({
|
|
20
|
+
type: "visual",
|
|
21
|
+
baseClass: "s-btn",
|
|
22
|
+
variants: ["danger", "muted", "primary"],
|
|
23
|
+
modifiers: {
|
|
24
|
+
primary: ["filled", "outlined"],
|
|
25
|
+
secondary: [...["xs", "sm", "md"], ...["dropdown", "icon"]],
|
|
26
|
+
global: ["is-loading"],
|
|
27
|
+
standalone: [
|
|
28
|
+
...["link", "unset"],
|
|
29
|
+
...["facebook", "github", "google"],
|
|
30
|
+
],
|
|
31
|
+
},
|
|
32
|
+
attributes: {
|
|
33
|
+
type: "button",
|
|
34
|
+
},
|
|
35
|
+
children: {
|
|
36
|
+
default: getChild(),
|
|
37
|
+
badge: getChild("badge"),
|
|
38
|
+
},
|
|
39
|
+
tag: "button",
|
|
40
|
+
template: ({ component, testid }) => html`
|
|
41
|
+
<div
|
|
42
|
+
class="bg-black-100 d-inline-flex ai-center jc-center hs1 ws2 p8"
|
|
43
|
+
data-testid="${testid}"
|
|
44
|
+
>
|
|
45
|
+
${component}
|
|
46
|
+
</div>
|
|
47
|
+
`,
|
|
48
|
+
excludedTestids: [
|
|
49
|
+
/primary-outlined/, // This combination is not supported
|
|
50
|
+
],
|
|
51
|
+
});
|
|
52
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.s-check-control { // TODO would _love_ to use .s-check instead, with no class on the input itself
|
|
2
|
+
--_cc-ai: center;
|
|
3
|
+
|
|
4
|
+
// CONTEXTUAL STYLES
|
|
5
|
+
.s-check-group & {
|
|
6
|
+
--_cc-ai: flex-start; // manually align the checkboxes and radios to the top of the group
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// CHILD ELEMENTS
|
|
10
|
+
.s-label {
|
|
11
|
+
font-weight: normal;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
align-items: var(--_cc-ai);
|
|
15
|
+
display: flex;
|
|
16
|
+
gap: var(--su8);
|
|
17
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
.s-check-group {
|
|
2
|
+
--_cg-fd: column;
|
|
3
|
+
|
|
4
|
+
// MODIFIERS
|
|
5
|
+
&&__horizontal {
|
|
6
|
+
--_cg-fd: row;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
// CHILD ELEMENTS
|
|
10
|
+
// TODO HACK? <legend> isn't respecting gap...
|
|
11
|
+
legend.s-label {
|
|
12
|
+
margin-bottom: var(--su8);
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
flex-direction: var(--_cg-fd);
|
|
16
|
+
|
|
17
|
+
display: flex;
|
|
18
|
+
gap: var(--su8);
|
|
19
|
+
}
|
|
@@ -17,6 +17,7 @@
|
|
|
17
17
|
margin-bottom @ex-transition-duration cubic-bezier(0, 0, 0, 1),
|
|
18
18
|
transform @ex-transition-duration cubic-bezier(1, 0, 1, 1),
|
|
19
19
|
opacity @ex-transition-duration cubic-bezier(1, 0, 1, 1);
|
|
20
|
+
--_ex-content-v: unset;
|
|
20
21
|
|
|
21
22
|
&:not(.is-expanded) {
|
|
22
23
|
--_ex-after-h: 0;
|
|
@@ -32,6 +33,7 @@
|
|
|
32
33
|
max-height 0s @ex-transition-duration,
|
|
33
34
|
transform @ex-transition-duration cubic-bezier(0, 1, 1, 1),
|
|
34
35
|
opacity @ex-transition-duration cubic-bezier(0, 1, 1, 1);
|
|
36
|
+
--_ex-content-v: hidden;
|
|
35
37
|
|
|
36
38
|
& .s-expandable--content {
|
|
37
39
|
@supports ((-webkit-clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%)) or (clip-path: polygon(0% 0%, 100% 0%, 100% 100%, 0% 100%))) {
|
|
@@ -62,6 +64,7 @@
|
|
|
62
64
|
opacity: var(--_ex-content-o);
|
|
63
65
|
-webkit-transform: var(--_ex-content-transform);
|
|
64
66
|
transform: var(--_ex-content-transform);
|
|
67
|
+
visibility: var(--_ex-content-v);
|
|
65
68
|
|
|
66
69
|
-ms-flex-preferred-size: 100%;
|
|
67
70
|
flex-basis: 100%;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { html, fixture, expect } from "@open-wc/testing";
|
|
2
|
+
import { screen } from "@testing-library/dom";
|
|
3
|
+
import userEvent from "@testing-library/user-event";
|
|
4
|
+
import "../../index";
|
|
5
|
+
|
|
6
|
+
const user = userEvent.setup();
|
|
7
|
+
|
|
8
|
+
describe("expandable-control", () => {
|
|
9
|
+
it("should focus on expandable content only when expanded", async () => {
|
|
10
|
+
const trigger = await fixture(html`
|
|
11
|
+
<button
|
|
12
|
+
data-controller="s-expandable-control"
|
|
13
|
+
aria-expanded="false"
|
|
14
|
+
aria-controls="expandable-example"
|
|
15
|
+
>
|
|
16
|
+
expandable trigger
|
|
17
|
+
</button>
|
|
18
|
+
<div class="s-expandable" id="expandable-example">
|
|
19
|
+
<div class="s-expandable--content">
|
|
20
|
+
<button>inside expandable</button>
|
|
21
|
+
</div>
|
|
22
|
+
</div>
|
|
23
|
+
`);
|
|
24
|
+
|
|
25
|
+
// expandable is not expanded
|
|
26
|
+
let expandableTrigger = screen.getByRole("button", {
|
|
27
|
+
name: "expandable trigger",
|
|
28
|
+
expanded: false,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
32
|
+
expect(
|
|
33
|
+
screen.queryByRole("button", {
|
|
34
|
+
name: "inside expandable",
|
|
35
|
+
})
|
|
36
|
+
).to.be.null;
|
|
37
|
+
|
|
38
|
+
await userEvent.click(expandableTrigger);
|
|
39
|
+
|
|
40
|
+
// expandable is now expanded
|
|
41
|
+
expandableTrigger = screen.getByRole("button", {
|
|
42
|
+
name: "expandable trigger",
|
|
43
|
+
expanded: true,
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-call
|
|
47
|
+
expect(
|
|
48
|
+
screen.getByRole("button", {
|
|
49
|
+
name: "inside expandable",
|
|
50
|
+
})
|
|
51
|
+
).to.be.visible;
|
|
52
|
+
});
|
|
53
|
+
});
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
.s-input-fill {
|
|
2
|
+
--_if-bc: var(--bc-darker);
|
|
3
|
+
--_if-bg: var(--black-050);
|
|
4
|
+
--_if-blw: 0;
|
|
5
|
+
--_if-blr: 0;
|
|
6
|
+
--_if-brr: 0;
|
|
7
|
+
--_if-brw: 0;
|
|
8
|
+
|
|
9
|
+
&&__clear {
|
|
10
|
+
--_if-bc: transparent;
|
|
11
|
+
--_if-bg: transparent;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
&.order-first {
|
|
15
|
+
--_if-blw: var(--su-static1);
|
|
16
|
+
--_if-blr: var(--br-sm);
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
&.order-last {
|
|
20
|
+
--_if-brw: var(--su-static1);
|
|
21
|
+
--_if-brr: var(--br-sm);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
background-color: var(--_if-bg);
|
|
25
|
+
border: var(--su-static1) solid var(--_if-bc);
|
|
26
|
+
border-left-width: var(--_if-blw);
|
|
27
|
+
border-right-width: var(--_if-brw);
|
|
28
|
+
border-radius: var(--_if-blr) var(--_if-brr) var(--_if-brr) var(--_if-blr);
|
|
29
|
+
|
|
30
|
+
color: var(--fc-medium);
|
|
31
|
+
font-family: inherit;
|
|
32
|
+
line-height: var(--lh-sm);
|
|
33
|
+
padding: 0.6em 0.7em;
|
|
34
|
+
white-space: nowrap;
|
|
35
|
+
}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
.s-input-icon {
|
|
2
|
+
--_ii-fc: unset;
|
|
3
|
+
--_ii-r: 0.7em;
|
|
4
|
+
|
|
5
|
+
// MODIFIERS
|
|
6
|
+
.has-error & {
|
|
7
|
+
--_ii-fc: var(--red-400);
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
.has-success & {
|
|
11
|
+
--_ii-fc: var(--green-400);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
.has-warning & {
|
|
15
|
+
--_ii-fc: var(--yellow-600);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.is-disabled & {
|
|
19
|
+
--_ii-fc: var(--black-400);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.is-readonly & {
|
|
23
|
+
--_ii-fc: var(--black-200);
|
|
24
|
+
|
|
25
|
+
.highcontrast-mode({
|
|
26
|
+
--_ii-fc: var(--fc-light);
|
|
27
|
+
});
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
&&__creditcard,
|
|
31
|
+
&&__search {
|
|
32
|
+
--_ii-r: auto;
|
|
33
|
+
|
|
34
|
+
color: var(--black-400);
|
|
35
|
+
left: 0.7em;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
color: var(--_ii-fc);
|
|
39
|
+
right: var(--_ii-r);
|
|
40
|
+
|
|
41
|
+
margin-top: -9px; // Half the icon's height at 18px for centering;
|
|
42
|
+
pointer-events: none;
|
|
43
|
+
position: absolute;
|
|
44
|
+
top: 50%;
|
|
45
|
+
}
|