@stackoverflow/stacks 1.7.1 → 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/README.md +1 -1
- 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 +1351 -1171
- 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/base/fieldset.less +5 -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} +7 -6
- 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/components/checkbox_radio/checkbox_radio.less +158 -0
- package/lib/components/description/description.less +9 -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/components/input_textarea/input_textarea.less +166 -0
- package/lib/{css/components/labels.less → components/label/label.less} +4 -4
- package/lib/{css/components → components/link}/link.less +9 -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 → components/post-summary}/post-summary.less +6 -2
- package/lib/components/select/select.less +148 -0
- 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/{css/components/tags.less → components/tag/tag.less} +3 -3
- 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/{css/components/toggle-switches.less → components/toggle-switch/toggle-switch.less} +8 -0
- package/lib/{ts/controllers/s-uploader.ts → components/uploader/uploader.ts} +1 -1
- package/lib/controllers.ts +33 -0
- package/lib/{css/exports → exports}/mixins.less +73 -11
- package/lib/{ts/index.ts → index.ts} +1 -1
- package/lib/input-utils.less +44 -0
- 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 +26 -25
- package/dist/controllers/index.d.ts +0 -9
- package/lib/css/components/inputs.less +0 -666
- package/lib/css/stacks-static.less +0 -97
- package/lib/test/s-avatar.test.ts +0 -74
- package/lib/test/s-banner.visual.test.ts +0 -61
- package/lib/test/s-button.visual.test.ts +0 -12
- 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/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/code-blocks.less → components/code-block/code-block.less} +0 -0
- /package/lib/{css/components/empty-states.less → components/empty-state/empty-state.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/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/spinner}/spinner.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/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
|
+
});
|
|
@@ -57,6 +57,7 @@
|
|
|
57
57
|
});
|
|
58
58
|
|
|
59
59
|
// STATES
|
|
60
|
+
fieldset[disabled] &,
|
|
60
61
|
&[disabled],
|
|
61
62
|
&[aria-disabled="true"] {
|
|
62
63
|
--_bu-bs: none !important;
|
|
@@ -141,8 +142,6 @@
|
|
|
141
142
|
&:focus-visible {
|
|
142
143
|
outline-style: auto;
|
|
143
144
|
}
|
|
144
|
-
|
|
145
|
-
outline: initial;
|
|
146
145
|
}
|
|
147
146
|
|
|
148
147
|
&&__link {
|
|
@@ -169,6 +168,7 @@
|
|
|
169
168
|
.s-link();
|
|
170
169
|
display: inline;
|
|
171
170
|
font: inherit;
|
|
171
|
+
outline: revert;
|
|
172
172
|
text-align: inherit;
|
|
173
173
|
}
|
|
174
174
|
|
|
@@ -190,6 +190,8 @@
|
|
|
190
190
|
font: unset;
|
|
191
191
|
user-select: auto;
|
|
192
192
|
}
|
|
193
|
+
|
|
194
|
+
outline: initial;
|
|
193
195
|
}
|
|
194
196
|
|
|
195
197
|
// Pseudo-elements and child-based modifiers
|
|
@@ -221,18 +223,17 @@
|
|
|
221
223
|
|
|
222
224
|
// Size
|
|
223
225
|
&&__xs {
|
|
226
|
+
.size-styles(xs; bu; @styles: fs);
|
|
224
227
|
--_bu-dropdown-bw: calc(var(--su-static4) - var(--su-static1));
|
|
225
|
-
--_bu-fs: var(--fs-fine);
|
|
226
228
|
--_bu-p: 0.6em;
|
|
227
229
|
}
|
|
228
230
|
|
|
229
231
|
&&__sm {
|
|
230
|
-
|
|
232
|
+
.size-styles(sm; bu; @styles: fs);
|
|
231
233
|
}
|
|
232
234
|
|
|
233
235
|
&&__md {
|
|
234
|
-
|
|
235
|
-
--_bu-fs: var(--fs-body3);
|
|
236
|
+
.size-styles(md; bu; @styles: br, fs);
|
|
236
237
|
--_bu-p: 0.7em;
|
|
237
238
|
}
|
|
238
239
|
|
|
@@ -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
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
.s-checkbox,
|
|
2
|
+
.s-radio {
|
|
3
|
+
--_ch-baw: var(--su-static1);
|
|
4
|
+
--_ch-bc: var(--bc-darker);
|
|
5
|
+
--_ch-bc-focus: var(--theme-secondary-300);
|
|
6
|
+
--_ch-bg: var(--white);
|
|
7
|
+
--_ch-bg-image: unset;
|
|
8
|
+
--_ch-bs-focus: 0 0 0 var(--su-static4) var(--focus-ring);
|
|
9
|
+
|
|
10
|
+
// CONTEXTUAL STYLES
|
|
11
|
+
fieldset[disabled] &,
|
|
12
|
+
&[disabled] {
|
|
13
|
+
cursor: not-allowed;
|
|
14
|
+
opacity: var(--_o-disabled-static);
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.s-check-control & {
|
|
18
|
+
&[disabled] + .s-label {
|
|
19
|
+
&:extend(.is-disabled .s-label);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.s-check-group & {
|
|
24
|
+
margin-top: calc(var(--su2) + var(--su1)); // 3px
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
input& {
|
|
28
|
+
flex-shrink: 0;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
// INTERACTION
|
|
32
|
+
&:focus {
|
|
33
|
+
box-shadow: var(--_ch-bs-focus);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
background-color: var(--_ch-bg);
|
|
37
|
+
border: var(--_ch-baw) solid var(--_ch-bc);
|
|
38
|
+
|
|
39
|
+
appearance: none;
|
|
40
|
+
cursor: pointer;
|
|
41
|
+
font-size: inherit;
|
|
42
|
+
height: 1em;
|
|
43
|
+
margin: 0; // A guard against Core's default margins
|
|
44
|
+
outline: 0;
|
|
45
|
+
vertical-align: middle;
|
|
46
|
+
width: 1em;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.s-checkbox {
|
|
50
|
+
|
|
51
|
+
// CONTEXTUAL STYLES
|
|
52
|
+
.highcontrast-dark-mode({
|
|
53
|
+
&:checked, &:indeterminate {
|
|
54
|
+
--_ch-bc: var(--blue-700) !important;
|
|
55
|
+
--_ch-bc-focus: var(--_ch-bc);
|
|
56
|
+
--_ch-bg: var(--blue-300);
|
|
57
|
+
}
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
// STATES
|
|
61
|
+
&:checked, &:indeterminate {
|
|
62
|
+
--_ch-bc: var(--theme-secondary-400) !important;
|
|
63
|
+
--_ch-bg: var(--theme-secondary-400);
|
|
64
|
+
|
|
65
|
+
&:focus {
|
|
66
|
+
--_ch-bc-focus: var(--theme-secondary-400);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
&:checked {
|
|
71
|
+
--_ch-bg-image: url("data:image/svg+xml,%3Csvg width='11' height='11' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M10 3.41L8.59 2 4 6.59 2.41 5 1 6.41l3 3z' fill='%23fff'/%3E%3C/svg%3E");
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
&:indeterminate {
|
|
75
|
+
--_ch-bg-image: url("data:image/svg+xml,%3Csvg width='11' height='11' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M2 4.5 h7 v2 h-7 z' fill='%23fff'/%3E%3C/svg%3E");
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// INTERACTION
|
|
79
|
+
&:focus {
|
|
80
|
+
border-color: var(--_ch-bc-focus);
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
background-image: var(--_ch-bg-image);
|
|
84
|
+
|
|
85
|
+
background-position: center center;
|
|
86
|
+
background-repeat: no-repeat;
|
|
87
|
+
background-size: contain;
|
|
88
|
+
border-radius: var(--br-sm);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
.s-radio {
|
|
92
|
+
|
|
93
|
+
// CONTEXTUAL STYLES
|
|
94
|
+
.highcontrast-dark-mode({
|
|
95
|
+
&:checked {
|
|
96
|
+
--_ch-bc: var(--blue-300);
|
|
97
|
+
outline: var(--su-static1) solid var(--black);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
|
|
101
|
+
.dark-mode({
|
|
102
|
+
&:checked {
|
|
103
|
+
--_ch-bg: var(--black);
|
|
104
|
+
}
|
|
105
|
+
});
|
|
106
|
+
|
|
107
|
+
// STATES
|
|
108
|
+
&:checked {
|
|
109
|
+
--_ch-baw: 0.30769231em;
|
|
110
|
+
--_ch-bc: var(--theme-secondary-400);
|
|
111
|
+
--_ch-bg: var(--white);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
border-radius: var(--br-circle);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
.s-checkbox,
|
|
118
|
+
.s-radio:not(:checked) {
|
|
119
|
+
.validation-states(ch);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
.s-check-control { // TODO would _love_ to use .s-check instead, with no class on the input itself
|
|
123
|
+
--_cc-ai: center;
|
|
124
|
+
|
|
125
|
+
// CONTEXTUAL STYLES
|
|
126
|
+
.s-check-group & {
|
|
127
|
+
--_cc-ai: flex-start; // manually align the checkboxes and radios to the top of the group
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
// CHILD ELEMENTS
|
|
131
|
+
.s-label {
|
|
132
|
+
font-weight: normal;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
align-items: var(--_cc-ai);
|
|
136
|
+
display: flex;
|
|
137
|
+
gap: var(--su8);
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
.s-check-group {
|
|
141
|
+
--_cg-fd: column;
|
|
142
|
+
|
|
143
|
+
// MODIFIERS
|
|
144
|
+
&&__horizontal {
|
|
145
|
+
--_cg-fd: row;
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// CHILD ELEMENTS
|
|
149
|
+
// TODO HACK? <legend> isn't respecting gap...
|
|
150
|
+
legend.s-label {
|
|
151
|
+
margin-bottom: var(--su8);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
flex-direction: var(--_cg-fd);
|
|
155
|
+
|
|
156
|
+
display: flex;
|
|
157
|
+
gap: var(--su8);
|
|
158
|
+
}
|