@codeforamerica/marcomms-design-system 1.19.0 → 1.19.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/bar.js +102 -0
- package/src/components/bar.stories.js +22 -0
- package/src/components/blob.js +128 -0
- package/src/components/blob.stories.js +73 -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 +163 -0
- package/src/components/button.scss +157 -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 +456 -0
- package/src/components/card.stories.js +227 -0
- package/src/components/carousel.js +662 -0
- package/src/components/carousel.stories.js +165 -0
- package/src/components/details.scss +71 -0
- package/src/components/details.stories.js +27 -0
- package/src/components/form-elements.scss +304 -0
- package/src/components/form-elements.stories.js +134 -0
- package/src/components/icon.js +44 -0
- package/src/components/icon.scss +32 -0
- package/src/components/icon.stories.js +38 -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 +98 -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 +25 -0
- package/src/components/placeholder.js +25 -0
- package/src/components/placeholder.stories.js +10 -0
- package/src/components/promo.js +82 -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 +111 -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 +122 -0
- package/src/components/slide.stories.js +49 -0
- package/src/components/social-icon.js +236 -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 +149 -0
- package/src/components/tile.stories.js +41 -0
- package/src/components/transcript.js +44 -0
- package/src/components/transcript.stories.js +103 -0
- package/src/core/base.scss +86 -0
- package/src/core/colors.mdx +100 -0
- package/src/core/grid.mdx +244 -0
- package/src/core/grid.scss +394 -0
- package/src/core/helpers.scss +111 -0
- package/src/core/layout.scss +103 -0
- package/src/core/layout.stories.js +145 -0
- package/src/core/reset.scss +53 -0
- package/src/core/shadows.mdx +108 -0
- package/src/core/tokens.scss +261 -0
- package/src/core/typography.mdx +79 -0
- package/src/core/typography.scss +411 -0
- package/src/core.js +10 -0
- package/src/index.js +43 -0
- package/src/shared/common.js +65 -0
- package/src/shared/layout.js +14 -0
- package/src/shared/typography.js +397 -0
- package/src/styles.scss +15 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
import { LitElement, html, css } from "lit";
|
|
2
|
+
import { commonStyles } from "../shared/common";
|
|
3
|
+
|
|
4
|
+
class PageNav extends LitElement {
|
|
5
|
+
static properties = {
|
|
6
|
+
fontSize: {},
|
|
7
|
+
};
|
|
8
|
+
|
|
9
|
+
static styles = [
|
|
10
|
+
commonStyles,
|
|
11
|
+
css`
|
|
12
|
+
:host {
|
|
13
|
+
--bg-color: var(--white);
|
|
14
|
+
--link-color: var(--purple-80);
|
|
15
|
+
--link-hover-color: var(--purple-80);
|
|
16
|
+
|
|
17
|
+
background-color: var(--bg-color);
|
|
18
|
+
display: block;
|
|
19
|
+
padding-block: var(--spacing-layout-1);
|
|
20
|
+
display: block;
|
|
21
|
+
font-family: var(--font-family-sans-serif);
|
|
22
|
+
font-size: var(--font-size-small);
|
|
23
|
+
line-height: var(--font-size-small);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
slot {
|
|
27
|
+
display: none;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
nav {
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
ul {
|
|
34
|
+
display: flex;
|
|
35
|
+
flex-direction: column;
|
|
36
|
+
gap: var(--spacing-layout-half);
|
|
37
|
+
margin: 0;
|
|
38
|
+
padding: 0 var(--outer-margin);
|
|
39
|
+
min-height: var(--spacing-layout-2);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
li {
|
|
43
|
+
display: block;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
a {
|
|
47
|
+
background-color: var(--purple-10);
|
|
48
|
+
border-radius: var(--rounded-corners);
|
|
49
|
+
color: var(--link-color);
|
|
50
|
+
display: block;
|
|
51
|
+
position: relative;
|
|
52
|
+
padding: var(--spacing-layout-half);
|
|
53
|
+
text-decoration: none;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
a:hover {
|
|
57
|
+
background-color: var(--blue-20);
|
|
58
|
+
color: var(--link-hover-color);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
a:active {
|
|
62
|
+
background-color: var(--blue-40);
|
|
63
|
+
color: var(--link-color);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
@media (min-width: 768px) {
|
|
67
|
+
:host {
|
|
68
|
+
box-shadow: var(--shadow-small);
|
|
69
|
+
padding-block: var(--spacing-component-2);
|
|
70
|
+
position: sticky;
|
|
71
|
+
top: 0;
|
|
72
|
+
z-index: 3;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
nav {
|
|
76
|
+
align-items: center;
|
|
77
|
+
display: flex;
|
|
78
|
+
flex-direction: row;
|
|
79
|
+
margin-inline: auto;
|
|
80
|
+
max-width: var(--grid-max-width);
|
|
81
|
+
overflow-x: auto;
|
|
82
|
+
overflow-y: hidden;
|
|
83
|
+
scrollbar-width: none;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
ul {
|
|
87
|
+
align-items: center;
|
|
88
|
+
display: flex;
|
|
89
|
+
flex-direction: row;
|
|
90
|
+
gap: var(--spacing-component-2);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
a,
|
|
94
|
+
li {
|
|
95
|
+
max-width: none;
|
|
96
|
+
white-space: nowrap;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
a.is-active {
|
|
100
|
+
background-color: var(--blue-40);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
`,
|
|
104
|
+
];
|
|
105
|
+
|
|
106
|
+
handleSlotchange(event) {
|
|
107
|
+
const slot = event.target;
|
|
108
|
+
const assignedNodes = slot.assignedNodes({ flatten: true });
|
|
109
|
+
const breadcrumbContainer = this.shadowRoot.querySelector("ul");
|
|
110
|
+
|
|
111
|
+
// Create an array to hold the IDs of all the anchor links in the nav
|
|
112
|
+
const navItemIds = [];
|
|
113
|
+
|
|
114
|
+
assignedNodes.forEach((node) => {
|
|
115
|
+
if (node.tagName === "UL") {
|
|
116
|
+
const liElements = node.querySelectorAll("li");
|
|
117
|
+
liElements.forEach((li) => {
|
|
118
|
+
breadcrumbContainer.appendChild(li.cloneNode(true));
|
|
119
|
+
// If it's an anchor link (starting with '#') add the anchor ID to the navItemIds array
|
|
120
|
+
const linkUrl = li.querySelector("a")?.getAttribute("href");
|
|
121
|
+
if (linkUrl && linkUrl.startsWith("#")) {
|
|
122
|
+
navItemIds.push(linkUrl.substring(1));
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
});
|
|
127
|
+
|
|
128
|
+
// Add a scroll event listener to highlight the active nav
|
|
129
|
+
window.addEventListener("scroll", () => this.updateActiveNav(navItemIds));
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
updateActiveNav(navItemIds) {
|
|
133
|
+
const scrollPosition = window.scrollY;
|
|
134
|
+
let activeSectionId = null;
|
|
135
|
+
|
|
136
|
+
navItemIds.forEach((id) => {
|
|
137
|
+
const section = document.getElementById(id);
|
|
138
|
+
if (section && section.offsetTop <= scrollPosition + 256) {
|
|
139
|
+
activeSectionId = id;
|
|
140
|
+
}
|
|
141
|
+
});
|
|
142
|
+
|
|
143
|
+
this.shadowRoot.querySelectorAll("li a").forEach((item) => {
|
|
144
|
+
item.classList.remove("is-active");
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
if (activeSectionId) {
|
|
148
|
+
const activeNavItem = this.shadowRoot.querySelector(
|
|
149
|
+
`li a[href*="#${activeSectionId}"]`,
|
|
150
|
+
);
|
|
151
|
+
if (activeNavItem) {
|
|
152
|
+
activeNavItem.classList.add("is-active");
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
render() {
|
|
158
|
+
return html`
|
|
159
|
+
<slot @slotchange=${this.handleSlotchange}></slot>
|
|
160
|
+
<nav>
|
|
161
|
+
<ul>
|
|
162
|
+
<li><strong>On this page:  </strong></li>
|
|
163
|
+
</ul>
|
|
164
|
+
</nav>
|
|
165
|
+
`;
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
if (!customElements.get("cfa-page-nav")) {
|
|
170
|
+
customElements.define("cfa-page-nav", PageNav);
|
|
171
|
+
}
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
import { html } from "lit-html";
|
|
2
|
+
import "./page-nav.js";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Molecules/PageNav",
|
|
6
|
+
parameters: {
|
|
7
|
+
layout: "fullscreen",
|
|
8
|
+
},
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const Template = () => html`
|
|
12
|
+
<cfa-page-nav>
|
|
13
|
+
<ul>
|
|
14
|
+
<li>
|
|
15
|
+
<a href="#actions" target="_self"> Actions </a>
|
|
16
|
+
</li>
|
|
17
|
+
<li>
|
|
18
|
+
<a href="#participate" target="_self"> How to participate </a>
|
|
19
|
+
</li>
|
|
20
|
+
<li>
|
|
21
|
+
<a href="#faq" target="_self"> FAQs </a>
|
|
22
|
+
</li>
|
|
23
|
+
</ul>
|
|
24
|
+
</cfa-page-nav>
|
|
25
|
+
|
|
26
|
+
<section id="actions" class="section">
|
|
27
|
+
<div class="container-fluid wrapper">
|
|
28
|
+
<h2>Take action</h2>
|
|
29
|
+
<p>
|
|
30
|
+
We’re organizing a few types of actions and activities that volunteers
|
|
31
|
+
can participate in.
|
|
32
|
+
</p>
|
|
33
|
+
<p>
|
|
34
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Eveniet
|
|
35
|
+
deserunt hic, perspiciatis eligendi doloremque vero ipsa, voluptatum
|
|
36
|
+
nihil aut dolorem praesentium dolor temporibus nemo? Neque et voluptate
|
|
37
|
+
asperiores dignissimos maiores. Lorem ipsum dolor, sit amet consectetur
|
|
38
|
+
adipisicing elit. Quidem, dicta adipisci aut ad delectus, iure sint
|
|
39
|
+
exercitationem tenetur illum voluptates officia at incidunt numquam
|
|
40
|
+
corporis, non pariatur quod magnam quasi. Lorem, ipsum dolor sit amet
|
|
41
|
+
consectetur adipisicing elit. Eveniet vitae, aliquam accusantium maiores
|
|
42
|
+
animi nobis tenetur, et pariatur amet provident libero exercitationem
|
|
43
|
+
commodi tempore est ex. Excepturi modi ea ipsam.
|
|
44
|
+
</p>
|
|
45
|
+
<p>
|
|
46
|
+
Lorem ipsum dolor sit amet consectetur adipisicing elit. Doloribus, eum
|
|
47
|
+
at ipsa cumque, fugiat suscipit veritatis vero ab minus quaerat ipsam
|
|
48
|
+
enim mollitia dolor! Aperiam, optio ipsum. Est, explicabo quod?
|
|
49
|
+
</p>
|
|
50
|
+
</div>
|
|
51
|
+
</section>
|
|
52
|
+
<section id="participate" class="section">
|
|
53
|
+
<div class="container-fluid wrapper">
|
|
54
|
+
<h2>Participate</h2>
|
|
55
|
+
<p>
|
|
56
|
+
In the spirit of collective action (and to reduce weekend Zoom fatigue!)
|
|
57
|
+
we will be hosting this year’s National Day of Civic Hacking on Gather,
|
|
58
|
+
where participants will have the opportunity to virtually mingle and
|
|
59
|
+
make connections. Prepare yourself for the day by reading our Gather
|
|
60
|
+
Guidelines document or view the Gather Guidelines video. For more
|
|
61
|
+
information about the platform, please see our FAQs.
|
|
62
|
+
</p>
|
|
63
|
+
<p>
|
|
64
|
+
On the day of the event, we will provide step-by-step guidance for
|
|
65
|
+
participating in your chosen action(s). You will need a laptop,
|
|
66
|
+
Wi-Fi/internet access, and should be prepared to use Gather, Zoom,
|
|
67
|
+
Slack, and Google Docs/Google Sheets; we suggest downloading these
|
|
68
|
+
applications and becoming familiar with them ahead of time.
|
|
69
|
+
</p>
|
|
70
|
+
<p>
|
|
71
|
+
Interested in organizing an event with your local Brigade or a team of
|
|
72
|
+
people locally for National Day of Civic Hacking? View this year’s
|
|
73
|
+
toolkit to learn how you can start preparing for your event.
|
|
74
|
+
</p>
|
|
75
|
+
</div>
|
|
76
|
+
</section>
|
|
77
|
+
<section id="faq" class="section">
|
|
78
|
+
<div class="container-fluid wrapper">
|
|
79
|
+
<h2>Frequently Asked Questions</h2>
|
|
80
|
+
<h3>Why do we take collective action?</h3>
|
|
81
|
+
<p>
|
|
82
|
+
Over the years, common themes have emerged from our Brigade Network on
|
|
83
|
+
challenges they face locally and opportunities for addressing those
|
|
84
|
+
challenges. Brigade leaders identified various pain points in addressing
|
|
85
|
+
these challenges. One Brigade leader commented, “We’re not as powerful
|
|
86
|
+
as our numbers should make us. We have talented people; we need to give
|
|
87
|
+
them ways to channel that but we don’t know how to do it.”
|
|
88
|
+
</p>
|
|
89
|
+
<p>
|
|
90
|
+
The National Advisory Council (NAC), an elected group of 10 Brigade
|
|
91
|
+
members, the Network team, and Brigade leaders from across the country
|
|
92
|
+
came together—in person and online—to strategize around these challenges
|
|
93
|
+
and opportunities to support our diverse and growing network across the
|
|
94
|
+
county. National Day of Civic Hacking emerged as a clear opportunity to
|
|
95
|
+
come together as a network, focus our efforts, provide dedicated
|
|
96
|
+
resources to volunteers, amplify actions across the country, and
|
|
97
|
+
leverage the collective power of all of Code for America’s resources.
|
|
98
|
+
</p>
|
|
99
|
+
<h3>Who can participate in National Day of Civic Hacking?</h3>
|
|
100
|
+
<p>
|
|
101
|
+
Anyone who wants to volunteer is welcome to participate. While “hacking”
|
|
102
|
+
is in the name, you don’t need to know how to code to contribute. We
|
|
103
|
+
welcome people with all kinds of backgrounds—like marketing, community
|
|
104
|
+
organizing, logistics, engineering, and project management skills, just
|
|
105
|
+
to name a few!
|
|
106
|
+
</p>
|
|
107
|
+
</div>
|
|
108
|
+
</section>
|
|
109
|
+
`;
|
|
110
|
+
|
|
111
|
+
export const Default = Template.bind({});
|
|
112
|
+
Default.args = {};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { LitElement, html, css } from "lit";
|
|
2
|
+
import { commonStyles } from "../shared/common.js";
|
|
3
|
+
import { typographyStyles } from "../shared/typography.js";
|
|
4
|
+
import { buttonStyles } from "./button";
|
|
5
|
+
import "./icon";
|
|
6
|
+
|
|
7
|
+
class Pager extends LitElement {
|
|
8
|
+
static properties = {
|
|
9
|
+
previousTitle: {},
|
|
10
|
+
previousUrl: {},
|
|
11
|
+
nextTitle: {},
|
|
12
|
+
nextUrl: {},
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
static styles = [
|
|
16
|
+
commonStyles,
|
|
17
|
+
typographyStyles,
|
|
18
|
+
buttonStyles,
|
|
19
|
+
css`
|
|
20
|
+
:host {
|
|
21
|
+
display: block;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
* {
|
|
25
|
+
box-sizing: border-box;
|
|
26
|
+
text-wrap: comfortable;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
nav {
|
|
30
|
+
display: flex;
|
|
31
|
+
flex-direction: column;
|
|
32
|
+
column-gap: var(--gutter-width);
|
|
33
|
+
row-gap: var(--spacing-layout-half);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
nav > * > * {
|
|
37
|
+
width: 100%;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@media (min-width: 768px) {
|
|
41
|
+
nav {
|
|
42
|
+
flex-direction: row-reverse;
|
|
43
|
+
justify-content: space-between;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
a {
|
|
47
|
+
min-width: var(--column-span-4);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.next a {
|
|
51
|
+
text-align: end;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
.previous a {
|
|
55
|
+
text-align: start;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
`,
|
|
59
|
+
];
|
|
60
|
+
|
|
61
|
+
render() {
|
|
62
|
+
return html`
|
|
63
|
+
<nav>
|
|
64
|
+
<div class="next">
|
|
65
|
+
${this.nextUrl
|
|
66
|
+
? html`
|
|
67
|
+
<a href="${this.nextUrl}" class="cfa-button">
|
|
68
|
+
<span class="small label"
|
|
69
|
+
>Next <cfa-icon>arrow_forward</cfa-icon></span
|
|
70
|
+
><br />
|
|
71
|
+
<span class="title normal">${this.nextTitle}</span>
|
|
72
|
+
</a>
|
|
73
|
+
`
|
|
74
|
+
: ""}
|
|
75
|
+
</div>
|
|
76
|
+
<div class="previous">
|
|
77
|
+
${this.previousUrl
|
|
78
|
+
? html`
|
|
79
|
+
<a
|
|
80
|
+
href="${this.previousUrl}"
|
|
81
|
+
class="cfa-button cfa-button--outline"
|
|
82
|
+
>
|
|
83
|
+
<span class="small label"
|
|
84
|
+
><cfa-icon>arrow_back</cfa-icon> Previous</span
|
|
85
|
+
><br />
|
|
86
|
+
<span class="title normal">${this.previousTitle}</span>
|
|
87
|
+
</a>
|
|
88
|
+
`
|
|
89
|
+
: ""}
|
|
90
|
+
</div>
|
|
91
|
+
</nav>
|
|
92
|
+
`;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
if (!customElements.get("cfa-pager")) {
|
|
97
|
+
customElements.define("cfa-pager", Pager);
|
|
98
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { html } from "lit-html";
|
|
2
|
+
import "./pager";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Molecules/Pager",
|
|
6
|
+
argTypes: {
|
|
7
|
+
previousTitle: { type: "string" },
|
|
8
|
+
previousUrl: { type: "string" },
|
|
9
|
+
nextTitle: { type: "string" },
|
|
10
|
+
nextUrl: { type: "string" },
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const Template = ({ previousTitle, previousUrl, nextTitle, nextUrl }) => html`
|
|
15
|
+
<cfa-pager
|
|
16
|
+
previousTitle="${previousTitle}"
|
|
17
|
+
previousUrl="${previousUrl}"
|
|
18
|
+
nextTitle="${nextTitle}"
|
|
19
|
+
nextUrl="${nextUrl}"
|
|
20
|
+
>
|
|
21
|
+
</cfa-pager>
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
export const Default = Template.bind({});
|
|
25
|
+
Default.args = {
|
|
26
|
+
previousTitle: "How should we measure Safety Net delivery?",
|
|
27
|
+
previousUrl: "#",
|
|
28
|
+
nextTitle: "The National Safety Net Scorecard",
|
|
29
|
+
nextUrl: "#",
|
|
30
|
+
};
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import { LitElement, html, css } from "lit";
|
|
2
|
+
import { commonStyles } from "../shared/common";
|
|
3
|
+
import { buttonStyles } from "./button";
|
|
4
|
+
import "./icon";
|
|
5
|
+
|
|
6
|
+
class Pagination extends LitElement {
|
|
7
|
+
static properties = {
|
|
8
|
+
page: { type: Number },
|
|
9
|
+
totalPages: { type: Number },
|
|
10
|
+
previousLabel: {},
|
|
11
|
+
nextLabel: {},
|
|
12
|
+
};
|
|
13
|
+
static styles = [
|
|
14
|
+
commonStyles,
|
|
15
|
+
buttonStyles,
|
|
16
|
+
css`
|
|
17
|
+
:host {
|
|
18
|
+
display: block;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.pagination {
|
|
22
|
+
align-items: center;
|
|
23
|
+
display: flex;
|
|
24
|
+
flex-direction: row;
|
|
25
|
+
gap: var(--gutter-width);
|
|
26
|
+
justify-content: space-between;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
.pagination > * {
|
|
30
|
+
flex: 1;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
.status {
|
|
34
|
+
font-size: var(--font-size-small);
|
|
35
|
+
line-height: var(-line-height-small);
|
|
36
|
+
color: var(--gray-60);
|
|
37
|
+
text-align: center;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
@media (max-width: 768px) {
|
|
41
|
+
.status {
|
|
42
|
+
display: none;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
.previous {
|
|
47
|
+
text-align: left;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
.next {
|
|
51
|
+
text-align: right;
|
|
52
|
+
}
|
|
53
|
+
`,
|
|
54
|
+
];
|
|
55
|
+
constructor() {
|
|
56
|
+
super();
|
|
57
|
+
this.previousLabel = "Previous";
|
|
58
|
+
this.nextLabel = "Next";
|
|
59
|
+
this.page = 1;
|
|
60
|
+
this.totalPages = 1;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
render() {
|
|
64
|
+
return html`
|
|
65
|
+
<div class="pagination">
|
|
66
|
+
<div class="previous">
|
|
67
|
+
${this.page > 1
|
|
68
|
+
? html`
|
|
69
|
+
<button class="cfa-button" @click="${this.handlePreviousPage}">
|
|
70
|
+
<cfa-icon>arrow_back</cfa-icon> ${this.previousLabel}
|
|
71
|
+
</button>
|
|
72
|
+
`
|
|
73
|
+
: ""}
|
|
74
|
+
</div>
|
|
75
|
+
<div class="status">Page ${this.page} of ${this.totalPages}</div>
|
|
76
|
+
<div class="next">
|
|
77
|
+
${this.page < this.totalPages
|
|
78
|
+
? html`
|
|
79
|
+
<button class="cfa-button" @click="${this.handleNextPage}">
|
|
80
|
+
${this.nextLabel} <cfa-icon>arrow_forward</cfa-icon>
|
|
81
|
+
</button>
|
|
82
|
+
`
|
|
83
|
+
: ""}
|
|
84
|
+
</div>
|
|
85
|
+
</div>
|
|
86
|
+
`;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
handleNextPage() {
|
|
90
|
+
if (this.page < this.totalPages) {
|
|
91
|
+
this.page++;
|
|
92
|
+
const pageChangeEvent = new CustomEvent("page-change", {
|
|
93
|
+
bubbles: true,
|
|
94
|
+
cancelable: true,
|
|
95
|
+
detail: this.page,
|
|
96
|
+
});
|
|
97
|
+
this.dispatchEvent(pageChangeEvent);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
handlePreviousPage() {
|
|
102
|
+
if (this.page > 1) {
|
|
103
|
+
this.page--;
|
|
104
|
+
const pageChangeEvent = new CustomEvent("page-change", {
|
|
105
|
+
bubbles: true,
|
|
106
|
+
cancelable: true,
|
|
107
|
+
detail: this.page,
|
|
108
|
+
});
|
|
109
|
+
this.dispatchEvent(pageChangeEvent);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
if (!customElements.get("cfa-pagination")) {
|
|
115
|
+
customElements.define("cfa-pagination", Pagination);
|
|
116
|
+
}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { html } from "lit-html";
|
|
2
|
+
import "./pagination.js";
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
title: "Molecules/Pagination",
|
|
6
|
+
argTypes: {
|
|
7
|
+
page: { type: "number", min: 1, max: 100 },
|
|
8
|
+
totalPages: { type: "number", min: 1, max: 100 },
|
|
9
|
+
previousLabel: { type: "string" },
|
|
10
|
+
nextLabel: { type: "string" },
|
|
11
|
+
},
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const Template = ({ page, totalPages, previousLabel, nextLabel }) => html`
|
|
15
|
+
<cfa-pagination
|
|
16
|
+
page="${page}"
|
|
17
|
+
totalPages="${totalPages}"
|
|
18
|
+
previousLabel="${previousLabel}"
|
|
19
|
+
nextLabel="${nextLabel}"
|
|
20
|
+
>
|
|
21
|
+
</cfa-pagination>
|
|
22
|
+
`;
|
|
23
|
+
|
|
24
|
+
export const Default = Template.bind({});
|
|
25
|
+
Default.args = {
|
|
26
|
+
page: 1,
|
|
27
|
+
totalPages: 3,
|
|
28
|
+
previousLabel: "Previous",
|
|
29
|
+
nextLabel: "Next",
|
|
30
|
+
};
|