@codeforamerica/marcomms-design-system 1.0.0 → 1.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -1
- package/src/components/accordion.js +141 -0
- package/src/components/accordion.stories.js +56 -0
- package/src/components/avatar.js +62 -0
- package/src/components/avatar.stories.js +27 -0
- package/src/components/banner.js +152 -0
- package/src/components/banner.stories.js +115 -0
- package/src/components/bar.js +102 -0
- package/src/components/bar.stories.js +22 -0
- package/src/components/blob.js +119 -0
- package/src/components/blob.stories.js +64 -0
- package/src/components/box.js +55 -0
- package/src/components/box.stories.js +24 -0
- package/src/components/breadcrumbs.js +80 -0
- package/src/components/breadcrumbs.stories.js +27 -0
- package/src/components/button.js +167 -0
- package/src/components/button.scss +162 -0
- package/src/components/button.stories.js +49 -0
- package/src/components/callout.js +62 -0
- package/src/components/callout.stories.js +20 -0
- package/src/components/card.js +403 -0
- package/src/components/card.stories.js +170 -0
- package/src/components/carousel.js +182 -0
- package/src/components/carousel.stories.js +61 -0
- package/src/components/cta.js +99 -0
- package/src/components/cta.stories.js +22 -0
- package/src/components/details.scss +71 -0
- package/src/components/details.stories.js +27 -0
- package/src/components/flexible-layout.js +126 -0
- package/src/components/flexible-layout.stories.js +48 -0
- package/src/components/form-elements.scss +305 -0
- package/src/components/form-elements.stories.js +134 -0
- package/src/components/icon.js +41 -0
- package/src/components/icon.scss +31 -0
- package/src/components/icon.stories.js +16 -0
- package/src/components/label.js +63 -0
- package/src/components/label.stories.js +29 -0
- package/src/components/link-list.scss +80 -0
- package/src/components/link-list.stories.js +52 -0
- package/src/components/loader.scss +24 -0
- package/src/components/loader.stories.js +12 -0
- package/src/components/logo-card.js +93 -0
- package/src/components/logo-card.stories.js +48 -0
- package/src/components/nav.js +99 -0
- package/src/components/nav.stories.js +40 -0
- package/src/components/page-nav.js +171 -0
- package/src/components/page-nav.stories.js +112 -0
- package/src/components/pager.js +98 -0
- package/src/components/pager.stories.js +30 -0
- package/src/components/pagination.js +116 -0
- package/src/components/pagination.stories.js +30 -0
- package/src/components/person-card.js +240 -0
- package/src/components/person-card.stories.js +58 -0
- package/src/components/pill.js +33 -0
- package/src/components/pill.stories.js +23 -0
- package/src/components/promo.js +83 -0
- package/src/components/promo.stories.js +37 -0
- package/src/components/pullquote.js +42 -0
- package/src/components/pullquote.stories.js +16 -0
- package/src/components/quote.js +84 -0
- package/src/components/quote.stories.js +23 -0
- package/src/components/reveal.js +83 -0
- package/src/components/reveal.stories.js +40 -0
- package/src/components/slide.js +121 -0
- package/src/components/slide.stories.js +53 -0
- package/src/components/social-icon.js +233 -0
- package/src/components/social-icon.stories.js +36 -0
- package/src/components/stat.js +92 -0
- package/src/components/stat.stories.js +28 -0
- package/src/components/tab-list.js +114 -0
- package/src/components/tab-list.stories.js +18 -0
- package/src/components/tab.js +95 -0
- package/src/components/tab.stories.js +29 -0
- package/src/components/tile.js +150 -0
- package/src/components/tile.stories.js +41 -0
- package/src/components/transcript.js +44 -0
- package/src/components/transcript.stories.js +167 -0
- package/src/core/_base.scss +86 -0
- package/src/core/_grid.scss +295 -0
- package/src/core/_helpers.scss +111 -0
- package/src/core/_layout.scss +79 -0
- package/src/core/_reset.scss +53 -0
- package/src/core/_tokens.scss +251 -0
- package/src/core/_typography.scss +426 -0
- package/src/core/_wordpress.scss +27 -0
- package/src/core/colors.mdx +100 -0
- package/src/core/typography.mdx +66 -0
- package/src/shared/common.js +15 -0
- package/src/shared/layout.js +14 -0
- package/src/shared/typography.js +111 -0
- package/src/styles.scss +16 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@codeforamerica/marcomms-design-system",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"main": "src/index.js",
|
|
5
5
|
"devDependencies": {
|
|
6
6
|
"@babel/cli": "^7.26.4",
|
|
@@ -81,6 +81,7 @@
|
|
|
81
81
|
},
|
|
82
82
|
"files": [
|
|
83
83
|
"dist/",
|
|
84
|
+
"src/",
|
|
84
85
|
"README.md"
|
|
85
86
|
]
|
|
86
87
|
}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import { html, css, LitElement } from "lit";
|
|
2
|
+
import { commonStyles } from "../shared/common";
|
|
3
|
+
|
|
4
|
+
class AccordionItem extends LitElement {
|
|
5
|
+
static properties = {
|
|
6
|
+
open: { type: Boolean },
|
|
7
|
+
};
|
|
8
|
+
static styles = [
|
|
9
|
+
commonStyles,
|
|
10
|
+
css`
|
|
11
|
+
:host {
|
|
12
|
+
--color: var(--purple-60);
|
|
13
|
+
--hover-bg-color: var(--blue-20);
|
|
14
|
+
|
|
15
|
+
display: block;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.item {
|
|
19
|
+
border-bottom: var(--thin) solid var(--black-20);
|
|
20
|
+
max-width: var(--column-span-8);
|
|
21
|
+
margin-inline: auto;
|
|
22
|
+
background-color: var(--bg-color);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
.header {
|
|
26
|
+
align-items: center;
|
|
27
|
+
color: var(--color);
|
|
28
|
+
cursor: pointer;
|
|
29
|
+
display: flex;
|
|
30
|
+
flex-direction: row;
|
|
31
|
+
padding-block: var(--spacing-component-3);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.header:hover {
|
|
35
|
+
background-color: var(--hover-bg-color);
|
|
36
|
+
box-shadow:
|
|
37
|
+
var(--spacing-component-3) 0 var(--blue-20),
|
|
38
|
+
calc(-1 * var(--spacing-component-3)) 0 var(--blue-20);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
.header:focus {
|
|
42
|
+
outline: none;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.title {
|
|
46
|
+
flex: 1;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
.title ::slotted(*) {
|
|
50
|
+
font-family: var(--font-family-sans-serif) !important;
|
|
51
|
+
font-size: var(--base-font-size) !important;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.icon {
|
|
55
|
+
flex: 0;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.body {
|
|
59
|
+
opacity: 0;
|
|
60
|
+
max-height: 0;
|
|
61
|
+
overflow: hidden;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.body.open {
|
|
65
|
+
max-height: unset;
|
|
66
|
+
opacity: 1;
|
|
67
|
+
padding-block: var(--spacing-layout-half) var(--spacing-layout-1);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.body ::slotted(*) {
|
|
71
|
+
margin-block-start: 0 !important;
|
|
72
|
+
}
|
|
73
|
+
`,
|
|
74
|
+
];
|
|
75
|
+
constructor() {
|
|
76
|
+
super();
|
|
77
|
+
this.open = false;
|
|
78
|
+
}
|
|
79
|
+
toggle() {
|
|
80
|
+
this.open = !this.open;
|
|
81
|
+
}
|
|
82
|
+
handleKeyPress(event) {
|
|
83
|
+
if (event.key === "Enter" || event.key === " ") {
|
|
84
|
+
this.toggle();
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
render() {
|
|
88
|
+
return html`
|
|
89
|
+
<div class="item">
|
|
90
|
+
<div
|
|
91
|
+
class="header"
|
|
92
|
+
role="button"
|
|
93
|
+
aria-expanded=${this.open ? "true" : "false"}
|
|
94
|
+
tabindex="0"
|
|
95
|
+
@click=${this.toggle}
|
|
96
|
+
@keypress=${this.handleKeyPress}
|
|
97
|
+
>
|
|
98
|
+
<div class="title">
|
|
99
|
+
<slot name="title"></slot>
|
|
100
|
+
</div>
|
|
101
|
+
<span class="icon" aria-hidden="true">
|
|
102
|
+
${this.open
|
|
103
|
+
? html`<cfa-icon>expand_less</cfa-icon>`
|
|
104
|
+
: html`<cfa-icon>expand_more</cfa-icon>`}
|
|
105
|
+
</span>
|
|
106
|
+
</div>
|
|
107
|
+
<div
|
|
108
|
+
class="body ${this.open ? "open" : ""}"
|
|
109
|
+
role="region"
|
|
110
|
+
aria-hidden=${this.open ? "false" : "true"}
|
|
111
|
+
>
|
|
112
|
+
<slot></slot>
|
|
113
|
+
</div>
|
|
114
|
+
</div>
|
|
115
|
+
`;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
class Accordion extends LitElement {
|
|
120
|
+
static styles = css`
|
|
121
|
+
:host {
|
|
122
|
+
display: block;
|
|
123
|
+
}
|
|
124
|
+
`;
|
|
125
|
+
|
|
126
|
+
render() {
|
|
127
|
+
return html`
|
|
128
|
+
<div role="tablist">
|
|
129
|
+
<slot></slot>
|
|
130
|
+
</div>
|
|
131
|
+
`;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
if (!customElements.get("cfa-accordion-item")) {
|
|
136
|
+
customElements.define("cfa-accordion-item", AccordionItem);
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (!customElements.get("cfa-accordion")) {
|
|
140
|
+
customElements.define("cfa-accordion", Accordion);
|
|
141
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { html } from "lit-html";
|
|
2
|
+
import "./accordion";
|
|
3
|
+
import "./icon";
|
|
4
|
+
|
|
5
|
+
export default {
|
|
6
|
+
title: "Molecules/Accordion",
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
const Template = () => html`
|
|
10
|
+
<cfa-accordion>
|
|
11
|
+
<cfa-accordion-item>
|
|
12
|
+
<h3 slot="title">What is the desired skillset for these roles?</h3>
|
|
13
|
+
<div>
|
|
14
|
+
<p>
|
|
15
|
+
Even though the services being offered are tax-related, no previous
|
|
16
|
+
tax knowledge or tax preparation experience is required to volunteer.
|
|
17
|
+
</p>
|
|
18
|
+
<p>
|
|
19
|
+
Our training will give you all the info you need to succeed in
|
|
20
|
+
whichever role you choose. Much of the work is focused primarily on
|
|
21
|
+
customer service. We will provide training for any relevant tax law
|
|
22
|
+
needed to perform in your role.
|
|
23
|
+
</p>
|
|
24
|
+
</div>
|
|
25
|
+
</cfa-accordion-item>
|
|
26
|
+
<cfa-accordion-item>
|
|
27
|
+
<h3 slot="title">
|
|
28
|
+
What is the minimum number of hours a volunteer must serve?
|
|
29
|
+
</h3>
|
|
30
|
+
<div>
|
|
31
|
+
<p>
|
|
32
|
+
With customer service at the heart of our work, our volunteers are
|
|
33
|
+
asked to serve at least four to six hours per week to ensure they are
|
|
34
|
+
able to respond in a timely manner to the client they’re serving.
|
|
35
|
+
</p>
|
|
36
|
+
</div>
|
|
37
|
+
</cfa-accordion-item>
|
|
38
|
+
<cfa-accordion-item>
|
|
39
|
+
<h3 slot="title">
|
|
40
|
+
What is the Volunteer Income Tax Assistance program (VITA)?
|
|
41
|
+
</h3>
|
|
42
|
+
<div>
|
|
43
|
+
<a href="#">Volunteer Income Tax Assistance (VITA)</a> is a program that
|
|
44
|
+
came out of the IRS over 50 years ago and was designed to help taxpayers
|
|
45
|
+
with low income file their tax returns for free. The program has been
|
|
46
|
+
wildly successful and nonprofits all over the country offer VITA
|
|
47
|
+
services as a means to fight poverty and promote financial stability.
|
|
48
|
+
Since 2021, many VITA organizations across the country have begun to use
|
|
49
|
+
GetYourRefund to serve clients virtually.
|
|
50
|
+
</div>
|
|
51
|
+
</cfa-accordion-item>
|
|
52
|
+
</cfa-accordion>
|
|
53
|
+
`;
|
|
54
|
+
|
|
55
|
+
export const Default = Template.bind({});
|
|
56
|
+
Default.args = {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { LitElement, html, css, nothing } from "lit";
|
|
2
|
+
import { commonStyles } from "../shared/common";
|
|
3
|
+
|
|
4
|
+
class Avatar extends LitElement {
|
|
5
|
+
static properties = {
|
|
6
|
+
imageUrl: {},
|
|
7
|
+
altText: {},
|
|
8
|
+
size: {},
|
|
9
|
+
};
|
|
10
|
+
static styles = [
|
|
11
|
+
commonStyles,
|
|
12
|
+
css`
|
|
13
|
+
:host {
|
|
14
|
+
--bg-color: var(--blue-20);
|
|
15
|
+
|
|
16
|
+
display: inline-block;
|
|
17
|
+
max-width: 100%;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
picture {
|
|
21
|
+
aspect-ratio: 1 / 1;
|
|
22
|
+
background-color: var(--bg-color);
|
|
23
|
+
border-radius: 50%;
|
|
24
|
+
display: block;
|
|
25
|
+
max-width: 100%;
|
|
26
|
+
overflow: hidden;
|
|
27
|
+
width: var(--size);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
img {
|
|
31
|
+
display: block;
|
|
32
|
+
height: 100%;
|
|
33
|
+
object-fit: cover;
|
|
34
|
+
width: 100%;
|
|
35
|
+
}
|
|
36
|
+
`,
|
|
37
|
+
];
|
|
38
|
+
render() {
|
|
39
|
+
return html`
|
|
40
|
+
<style>
|
|
41
|
+
:host {
|
|
42
|
+
--size: var(--spacing-layout-${this.size || "4"}, 8rem);
|
|
43
|
+
}
|
|
44
|
+
</style>
|
|
45
|
+
<picture>
|
|
46
|
+
${this.imageUrl
|
|
47
|
+
? html`
|
|
48
|
+
<img
|
|
49
|
+
src="${this.imageUrl}"
|
|
50
|
+
loading="lazy"
|
|
51
|
+
alt="${this.altText}"
|
|
52
|
+
/>
|
|
53
|
+
`
|
|
54
|
+
: nothing}
|
|
55
|
+
</picture>
|
|
56
|
+
`;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
if (!customElements.get("cfa-avatar")) {
|
|
61
|
+
customElements.define("cfa-avatar", Avatar);
|
|
62
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { html } from "lit-html";
|
|
2
|
+
import "./avatar";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Atoms/Avatar",
|
|
6
|
+
argTypes: {
|
|
7
|
+
imageUrl: { type: "string" },
|
|
8
|
+
altText: { type: "string" },
|
|
9
|
+
size: { type: "number", control: { type: "range", min: 1, max: 8 } },
|
|
10
|
+
},
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const Template = ({ imageUrl, altText, size }) => html`
|
|
14
|
+
<cfa-avatar
|
|
15
|
+
imageUrl="${imageUrl}"
|
|
16
|
+
altText="${altText}"
|
|
17
|
+
size="${size}"
|
|
18
|
+
></cfa-avatar>
|
|
19
|
+
`;
|
|
20
|
+
|
|
21
|
+
export const Default = Template.bind({});
|
|
22
|
+
Default.args = {
|
|
23
|
+
imageUrl:
|
|
24
|
+
"https://files.codeforamerica.org/2021/02/13130320/Renteria.Turq_.Standing-scaled-e1678737908242-198x300.jpg",
|
|
25
|
+
altText: "Headshot photo of Amanda Renteria, Code for America CEO",
|
|
26
|
+
size: 4,
|
|
27
|
+
};
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import { LitElement, html, css } from "lit";
|
|
2
|
+
import { commonStyles } from "../shared/common";
|
|
3
|
+
|
|
4
|
+
class Banner extends LitElement {
|
|
5
|
+
static properties = {
|
|
6
|
+
accentColor: "",
|
|
7
|
+
backgroundColor: "",
|
|
8
|
+
linkUrl: "",
|
|
9
|
+
linkTarget: "",
|
|
10
|
+
visualType: "",
|
|
11
|
+
visualUrl: "",
|
|
12
|
+
visualThumbnailUrl: "",
|
|
13
|
+
visualAltText: "",
|
|
14
|
+
};
|
|
15
|
+
static styles = [
|
|
16
|
+
commonStyles,
|
|
17
|
+
css`
|
|
18
|
+
:host {
|
|
19
|
+
--accent-color: var(--white);
|
|
20
|
+
--background-color: var(--black);
|
|
21
|
+
--text-color: var(--white);
|
|
22
|
+
|
|
23
|
+
display: block;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
a {
|
|
27
|
+
align-items: center;
|
|
28
|
+
background-color: var(--background-color);
|
|
29
|
+
box-shadow: var(--shadow-medium);
|
|
30
|
+
color: var(--text-color);
|
|
31
|
+
display: grid;
|
|
32
|
+
grid-template-areas:
|
|
33
|
+
"visual"
|
|
34
|
+
"content";
|
|
35
|
+
grid-template-columns: auto;
|
|
36
|
+
grid-template-rows: var(--spacing-layout-8) auto;
|
|
37
|
+
text-decoration: none;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
.blob {
|
|
41
|
+
fill: var(--accent-color);
|
|
42
|
+
grid-area: visual;
|
|
43
|
+
height: 100%;
|
|
44
|
+
width: 100%;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
picture {
|
|
48
|
+
grid-area: visual;
|
|
49
|
+
height: 100%;
|
|
50
|
+
width: 100%;
|
|
51
|
+
z-index: 1;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
picture img {
|
|
55
|
+
object-fit: cover;
|
|
56
|
+
object-position: center center;
|
|
57
|
+
height: 100%;
|
|
58
|
+
width: 100%;
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
picture.illustration img {
|
|
62
|
+
object-fit: contain;
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
.content {
|
|
66
|
+
padding: var(--spacing-layout-1, 1rem) var(--outer-margin, 1rem);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
@media (min-width: 768px) {
|
|
70
|
+
a {
|
|
71
|
+
grid-template-columns: 33% minmax(50%, var(--column-span-6)) auto;
|
|
72
|
+
grid-template-rows: auto;
|
|
73
|
+
grid-template-areas: "visual" "content";
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.content {
|
|
77
|
+
text-align: start;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
picture {
|
|
81
|
+
max-height: calc(var(--spacing-layout-1) * 12);
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
@media (prefers-reduced-motion: no-preference) {
|
|
86
|
+
.blob path {
|
|
87
|
+
animation: float 10s ease-in-out infinite;
|
|
88
|
+
z-index: 0;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
@keyframes float {
|
|
93
|
+
0% {
|
|
94
|
+
transform: translatex(0) translatey(0) rotate(0);
|
|
95
|
+
}
|
|
96
|
+
50% {
|
|
97
|
+
transform: translatex(2px) translatey(-4px) rotate(4deg);
|
|
98
|
+
}
|
|
99
|
+
100% {
|
|
100
|
+
transform: translatex(0) translatey(0) rotate(0);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
`,
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
render() {
|
|
107
|
+
return html`
|
|
108
|
+
<a
|
|
109
|
+
href="${this.linkUrl ? this.linkUrl : "javascript:void(0)"}"
|
|
110
|
+
target="${this.linkTarget}"
|
|
111
|
+
style="
|
|
112
|
+
--accent-color: var(--${this.accentColor});
|
|
113
|
+
--background-color: var(--${this.backgroundColor});
|
|
114
|
+
"
|
|
115
|
+
>
|
|
116
|
+
${this.visualType == "illustration"
|
|
117
|
+
? html`
|
|
118
|
+
<svg
|
|
119
|
+
class="blob"
|
|
120
|
+
width="100%"
|
|
121
|
+
height="100%"
|
|
122
|
+
viewBox="0 400 991 404"
|
|
123
|
+
fill="none"
|
|
124
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
125
|
+
>
|
|
126
|
+
<path
|
|
127
|
+
fill-rule="evenodd"
|
|
128
|
+
clip-rule="evenodd"
|
|
129
|
+
d="M497.987 2.71228C593.074 -5.64211 690.176 4.03525 773.161 49.603C862.779 98.8136 944.454 170.47 976.005 265.197C1007.51 359.787 986.265 464.701 941.165 554.018C899.88 635.781 820.242 689.107 738.82 734.926C664.711 776.63 583.712 800.173 497.987 803.413C409.179 806.769 320.068 796.454 243.046 753.664C159.74 707.382 90.0067 640.005 51.1477 555.166C9.37056 463.956 -21.746 356.515 19.2012 264.956C59.2648 175.372 169.027 143.121 256.962 94.9565C334.013 52.7538 409.754 10.4645 497.987 2.71228Z"
|
|
130
|
+
/>
|
|
131
|
+
</svg>
|
|
132
|
+
`
|
|
133
|
+
: ""}
|
|
134
|
+
<picture class="${this.visualType}">
|
|
135
|
+
<source srcset="${this.visualUrl}" />
|
|
136
|
+
<img
|
|
137
|
+
src="${this.visualThumbnailUrl}"
|
|
138
|
+
alt="${this.visualAltText}"
|
|
139
|
+
loading="lazy"
|
|
140
|
+
/>
|
|
141
|
+
</picture>
|
|
142
|
+
<div class="content">
|
|
143
|
+
<slot></slot>
|
|
144
|
+
</div>
|
|
145
|
+
</a>
|
|
146
|
+
`;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
|
|
150
|
+
if (!customElements.get("cfa-banner")) {
|
|
151
|
+
customElements.define("cfa-banner", Banner);
|
|
152
|
+
}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { html } from "lit-html";
|
|
2
|
+
import "./banner";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Organisms/Banner",
|
|
6
|
+
argTypes: {
|
|
7
|
+
content: { type: "string" },
|
|
8
|
+
backgroundColor: {
|
|
9
|
+
defaultValue: "purple-80",
|
|
10
|
+
options: ["purple-80", "red-80", "green-80", "blue-80", "black"],
|
|
11
|
+
control: { type: "select" },
|
|
12
|
+
},
|
|
13
|
+
accentColor: {
|
|
14
|
+
defaultValue: "white",
|
|
15
|
+
options: [
|
|
16
|
+
"white",
|
|
17
|
+
"purple-40",
|
|
18
|
+
"red-40",
|
|
19
|
+
"blue-40",
|
|
20
|
+
"yelow-40",
|
|
21
|
+
"green-40",
|
|
22
|
+
],
|
|
23
|
+
control: { type: "select" },
|
|
24
|
+
},
|
|
25
|
+
linkUrl: { type: "string" },
|
|
26
|
+
linkTarget: {
|
|
27
|
+
defaultValue: "_self",
|
|
28
|
+
options: ["_self", "_blank"],
|
|
29
|
+
control: { type: "radio" },
|
|
30
|
+
},
|
|
31
|
+
visualType: {
|
|
32
|
+
defaultValue: "image",
|
|
33
|
+
options: ["image", "illustration"],
|
|
34
|
+
control: { type: "radio" },
|
|
35
|
+
},
|
|
36
|
+
visualUrl: { type: "string" },
|
|
37
|
+
visualAltText: { type: "string" },
|
|
38
|
+
},
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
const Template = ({
|
|
42
|
+
content,
|
|
43
|
+
backgroundColor,
|
|
44
|
+
accentColor,
|
|
45
|
+
linkUrl,
|
|
46
|
+
visualType,
|
|
47
|
+
visualUrl,
|
|
48
|
+
visualThumbnailUrl,
|
|
49
|
+
visualAltText,
|
|
50
|
+
}) => html`
|
|
51
|
+
<cfa-banner
|
|
52
|
+
.innerHTML="${content}"
|
|
53
|
+
backgroundColor="${backgroundColor}"
|
|
54
|
+
accentColor="${accentColor}"
|
|
55
|
+
linkUrl="${linkUrl}"
|
|
56
|
+
visualType="${visualType}"
|
|
57
|
+
visualUrl="${visualUrl}"
|
|
58
|
+
visualThumbnailUrl="${visualThumbnailUrl}"
|
|
59
|
+
visualAltText="${visualAltText}"
|
|
60
|
+
>
|
|
61
|
+
<a href="${linkUrl}"> ${content} </a>
|
|
62
|
+
</cfa-banner>
|
|
63
|
+
`;
|
|
64
|
+
|
|
65
|
+
export const BannerWithImage = Template.bind({});
|
|
66
|
+
BannerWithImage.args = {
|
|
67
|
+
content: `
|
|
68
|
+
<div class="stack" style="--spacing: var(--spacing-layout-half);">
|
|
69
|
+
<p class="h2">We’re showing what’s possible this holiday season</p>
|
|
70
|
+
<p>
|
|
71
|
+
But we can’t do it without you.<br>
|
|
72
|
+
Make your gift today for double the impact.
|
|
73
|
+
</p>
|
|
74
|
+
<span class="cfa-button cfa-button--primary">
|
|
75
|
+
Donate now
|
|
76
|
+
</span>
|
|
77
|
+
</div>
|
|
78
|
+
`,
|
|
79
|
+
backgroundColor: "purple-80",
|
|
80
|
+
accentColor: "white",
|
|
81
|
+
linkUrl:
|
|
82
|
+
"https://codeforamerica.org/programs/criminal-justice/automatic-record-clearance/",
|
|
83
|
+
visualType: "image",
|
|
84
|
+
visualUrl:
|
|
85
|
+
"https://files.codeforamerica.org/2022/06/28153627/Amanda_TED_3.png",
|
|
86
|
+
visualThumbnailUrl:
|
|
87
|
+
"https://files.codeforamerica.org/2022/06/28153627/Amanda_TED_3.png",
|
|
88
|
+
visualAltText: "Code for America CEO Amanda Renteria speaking at TED",
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const BannerWithIllustration = Template.bind({});
|
|
92
|
+
BannerWithIllustration.args = {
|
|
93
|
+
content: `
|
|
94
|
+
<div class="stack" style="--spacing: var(--spacing-layout-half);">
|
|
95
|
+
<p class="h2">We’re showing what’s possible this holiday season</p>
|
|
96
|
+
<p>
|
|
97
|
+
But we can’t do it without you.<br>
|
|
98
|
+
Make your gift today for double the impact.
|
|
99
|
+
</p>
|
|
100
|
+
<span class="cfa-button cfa-button--primary">
|
|
101
|
+
Donate now
|
|
102
|
+
</span>
|
|
103
|
+
</div>
|
|
104
|
+
`,
|
|
105
|
+
backgroundColor: "purple-80",
|
|
106
|
+
accentColor: "white",
|
|
107
|
+
linkUrl:
|
|
108
|
+
"https://codeforamerica.org/programs/criminal-justice/automatic-record-clearance/",
|
|
109
|
+
visualType: "illustration",
|
|
110
|
+
visualUrl:
|
|
111
|
+
"https://files.codeforamerica.org/2022/11/09191601/paperwork-with-laptop-1.png",
|
|
112
|
+
visualThumbnailUrl:
|
|
113
|
+
"https://files.codeforamerica.org/2022/11/09191601/paperwork-with-laptop-1.png",
|
|
114
|
+
visualAltText: "Illustration of hands, a laptop computer and paperwork",
|
|
115
|
+
};
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
import { LitElement, html, css } from "lit";
|
|
2
|
+
import { commonStyles } from "../shared/common";
|
|
3
|
+
|
|
4
|
+
class Bar extends LitElement {
|
|
5
|
+
static properties = {
|
|
6
|
+
theme: {},
|
|
7
|
+
};
|
|
8
|
+
static styles = [
|
|
9
|
+
commonStyles,
|
|
10
|
+
css`
|
|
11
|
+
:host {
|
|
12
|
+
--bg-color: var(--purple-80);
|
|
13
|
+
--text-color: var(--white);
|
|
14
|
+
--link-color: var(--white);
|
|
15
|
+
--link-hover-color: var(--white);
|
|
16
|
+
--scrollbar-color: var(--white);
|
|
17
|
+
--spacing: var(--spacing-layout-half);
|
|
18
|
+
|
|
19
|
+
display: block;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.bar {
|
|
23
|
+
background-color: var(--bg-color);
|
|
24
|
+
color: var(--text-color);
|
|
25
|
+
|
|
26
|
+
a {
|
|
27
|
+
color: var(--link-color);
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
a:hover {
|
|
31
|
+
color: var(--link-hover-color);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.content {
|
|
36
|
+
display: flex;
|
|
37
|
+
column-gap: var(--spacing);
|
|
38
|
+
justify-content: center;
|
|
39
|
+
overflow-x: auto;
|
|
40
|
+
overflow-y: hidden;
|
|
41
|
+
padding-bottom: var(--spacing-layout-half);
|
|
42
|
+
padding-top: var(--spacing-layout-half);
|
|
43
|
+
scrollbar-color: var(--scrollbar-color) var(--bg-color);
|
|
44
|
+
scrollbar-width: thin;
|
|
45
|
+
|
|
46
|
+
&::before,
|
|
47
|
+
&::after {
|
|
48
|
+
content: "";
|
|
49
|
+
flex-basis: calc(var(--outer-margin) - var(--spacing));
|
|
50
|
+
flex-shrink: 0;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.content.is-overflowing {
|
|
55
|
+
justify-content: start;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
::slotted(*) {
|
|
59
|
+
max-width: none !important;
|
|
60
|
+
white-space: nowrap !important;
|
|
61
|
+
}
|
|
62
|
+
`,
|
|
63
|
+
];
|
|
64
|
+
|
|
65
|
+
// Check if the content is overflowing and add a class
|
|
66
|
+
|
|
67
|
+
firstUpdated() {
|
|
68
|
+
const content = this.shadowRoot.querySelector('.content');
|
|
69
|
+
const toggleOverflowClass = elem => {
|
|
70
|
+
elem.classList.toggle('is-overflowing', elem.scrollWidth > elem.clientWidth);
|
|
71
|
+
};
|
|
72
|
+
|
|
73
|
+
if ('ResizeObserver' in window) {
|
|
74
|
+
new ResizeObserver(entries => {
|
|
75
|
+
toggleOverflowClass(entries[0].target);
|
|
76
|
+
}).observe(content);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
if ('MutationObserver' in window) {
|
|
80
|
+
new MutationObserver(() => {
|
|
81
|
+
toggleOverflowClass(content);
|
|
82
|
+
}).observe(content, { childList: true });
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
// Initial check
|
|
86
|
+
toggleOverflowClass(content);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
render() {
|
|
90
|
+
return html`
|
|
91
|
+
<div class="bar">
|
|
92
|
+
<div class="content">
|
|
93
|
+
<slot></slot>
|
|
94
|
+
</div>
|
|
95
|
+
</div>
|
|
96
|
+
`;
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if (!customElements.get("cfa-bar")) {
|
|
101
|
+
customElements.define("cfa-bar", Bar);
|
|
102
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { html } from "lit-html";
|
|
2
|
+
import "./bar";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Molecules/Bar",
|
|
6
|
+
argTypes: {
|
|
7
|
+
content: { type: "string" },
|
|
8
|
+
},
|
|
9
|
+
parameters: {
|
|
10
|
+
layout: "fullscreen",
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const Template = ({ content }) => html`
|
|
15
|
+
<cfa-bar .innerHTML="${content}"> </cfa-bar>
|
|
16
|
+
`;
|
|
17
|
+
|
|
18
|
+
export const Default = Template.bind({});
|
|
19
|
+
Default.args = {
|
|
20
|
+
content:
|
|
21
|
+
'<ul class="ul ul--inline small"><li class="strong">Find out about: </li><li><a href="#">Easy and Free State Filing for IRS Direct Filers</a></li><li><a href="#">Bloomberg: Texts can improve access to food assistance</a></li><li><a href="#">Benefits Enrollment Field Guide</a></li></ul>',
|
|
22
|
+
};
|