@codeforamerica/marcomms-design-system 1.0.0 → 1.1.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.
Files changed (92) hide show
  1. package/dist/styles.css +1 -1
  2. package/package.json +2 -1
  3. package/src/components/accordion.js +141 -0
  4. package/src/components/accordion.stories.js +56 -0
  5. package/src/components/avatar.js +62 -0
  6. package/src/components/avatar.stories.js +27 -0
  7. package/src/components/banner.js +152 -0
  8. package/src/components/banner.stories.js +115 -0
  9. package/src/components/bar.js +102 -0
  10. package/src/components/bar.stories.js +22 -0
  11. package/src/components/blob.js +119 -0
  12. package/src/components/blob.stories.js +64 -0
  13. package/src/components/box.js +55 -0
  14. package/src/components/box.stories.js +24 -0
  15. package/src/components/breadcrumbs.js +80 -0
  16. package/src/components/breadcrumbs.stories.js +27 -0
  17. package/src/components/button.js +167 -0
  18. package/src/components/button.scss +162 -0
  19. package/src/components/button.stories.js +49 -0
  20. package/src/components/callout.js +62 -0
  21. package/src/components/callout.stories.js +20 -0
  22. package/src/components/card.js +403 -0
  23. package/src/components/card.stories.js +170 -0
  24. package/src/components/carousel.js +182 -0
  25. package/src/components/carousel.stories.js +61 -0
  26. package/src/components/cta.js +99 -0
  27. package/src/components/cta.stories.js +22 -0
  28. package/src/components/details.scss +71 -0
  29. package/src/components/details.stories.js +27 -0
  30. package/src/components/flexible-layout.js +126 -0
  31. package/src/components/flexible-layout.stories.js +48 -0
  32. package/src/components/form-elements.scss +305 -0
  33. package/src/components/form-elements.stories.js +134 -0
  34. package/src/components/icon.js +41 -0
  35. package/src/components/icon.scss +31 -0
  36. package/src/components/icon.stories.js +16 -0
  37. package/src/components/label.js +63 -0
  38. package/src/components/label.stories.js +29 -0
  39. package/src/components/link-list.scss +80 -0
  40. package/src/components/link-list.stories.js +52 -0
  41. package/src/components/loader.scss +24 -0
  42. package/src/components/loader.stories.js +12 -0
  43. package/src/components/logo-card.js +93 -0
  44. package/src/components/logo-card.stories.js +48 -0
  45. package/src/components/nav.js +99 -0
  46. package/src/components/nav.stories.js +40 -0
  47. package/src/components/page-nav.js +171 -0
  48. package/src/components/page-nav.stories.js +112 -0
  49. package/src/components/pager.js +98 -0
  50. package/src/components/pager.stories.js +30 -0
  51. package/src/components/pagination.js +116 -0
  52. package/src/components/pagination.stories.js +30 -0
  53. package/src/components/person-card.js +240 -0
  54. package/src/components/person-card.stories.js +58 -0
  55. package/src/components/pill.js +33 -0
  56. package/src/components/pill.stories.js +23 -0
  57. package/src/components/promo.js +83 -0
  58. package/src/components/promo.stories.js +37 -0
  59. package/src/components/pullquote.js +42 -0
  60. package/src/components/pullquote.stories.js +16 -0
  61. package/src/components/quote.js +84 -0
  62. package/src/components/quote.stories.js +23 -0
  63. package/src/components/reveal.js +83 -0
  64. package/src/components/reveal.stories.js +40 -0
  65. package/src/components/slide.js +121 -0
  66. package/src/components/slide.stories.js +53 -0
  67. package/src/components/social-icon.js +233 -0
  68. package/src/components/social-icon.stories.js +36 -0
  69. package/src/components/stat.js +92 -0
  70. package/src/components/stat.stories.js +28 -0
  71. package/src/components/tab-list.js +114 -0
  72. package/src/components/tab-list.stories.js +18 -0
  73. package/src/components/tab.js +95 -0
  74. package/src/components/tab.stories.js +29 -0
  75. package/src/components/tile.js +150 -0
  76. package/src/components/tile.stories.js +41 -0
  77. package/src/components/transcript.js +44 -0
  78. package/src/components/transcript.stories.js +167 -0
  79. package/src/core/base.scss +86 -0
  80. package/src/core/colors.mdx +100 -0
  81. package/src/core/grid.mdx +14 -0
  82. package/src/core/grid.scss +295 -0
  83. package/src/core/helpers.scss +111 -0
  84. package/src/core/layout.scss +79 -0
  85. package/src/core/reset.scss +53 -0
  86. package/src/core/tokens.scss +251 -0
  87. package/src/core/typography.mdx +66 -0
  88. package/src/core/typography.scss +426 -0
  89. package/src/shared/common.js +15 -0
  90. package/src/shared/layout.js +14 -0
  91. package/src/shared/typography.js +111 -0
  92. package/src/styles.scss +15 -0
@@ -0,0 +1,80 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common";
3
+
4
+ class Breadcrumbs extends LitElement {
5
+ static properties = {};
6
+ static styles = [
7
+ commonStyles,
8
+ css`
9
+ slot {
10
+ display: none;
11
+ }
12
+
13
+ :host {
14
+ display: block;
15
+ }
16
+
17
+ .breadcrumbs {
18
+ margin: 0;
19
+ margin-inline: calc(-1 * var(--outer-margin));
20
+ overflow-x: auto;
21
+ overflow-y: hidden;
22
+ padding: 0;
23
+ scrollbar-width: none;
24
+ white-space: nowrap;
25
+ }
26
+
27
+ .breadcrumbs::before,
28
+ .breadcrumbs::after {
29
+ content: "";
30
+ display: inline-block;
31
+ width: var(--outer-margin);
32
+ }
33
+
34
+ .breadcrumbs > * {
35
+ display: inline-block;
36
+ font-size: var(--font-size-small);
37
+ font-weight: 600;
38
+ line-height: var(--line-height-small);
39
+ margin: 0;
40
+ padding: 0;
41
+ }
42
+
43
+ .breadcrumbs > *:not(:last-child)::after {
44
+ content: "/";
45
+ opacity: 0.5;
46
+ padding-inline: 0.75em;
47
+ }
48
+
49
+ .breadcrumbs a {
50
+ color: var(--link-color);
51
+ text-decoration: none;
52
+ }
53
+ `,
54
+ ];
55
+ handleSlotchange(event) {
56
+ const slot = event.target;
57
+ const assignedNodes = slot.assignedNodes({ flatten: true });
58
+ console.log(assignedNodes);
59
+ const breadcrumbContainer = this.shadowRoot.querySelector(".breadcrumbs");
60
+ breadcrumbContainer.innerHTML = ""; // Clear the existing content
61
+ assignedNodes.forEach((node) => {
62
+ if (node.tagName === "UL") {
63
+ const liElements = node.querySelectorAll("li");
64
+ liElements.forEach((li) => {
65
+ breadcrumbContainer.appendChild(li.cloneNode(true));
66
+ });
67
+ }
68
+ });
69
+ }
70
+ render() {
71
+ return html`
72
+ <slot @slotchange=${this.handleSlotchange}></slot>
73
+ <ul class="breadcrumbs"></ul>
74
+ `;
75
+ }
76
+ }
77
+
78
+ if (!customElements.get("cfa-breadcrumbs")) {
79
+ customElements.define("cfa-breadcrumbs", Breadcrumbs);
80
+ }
@@ -0,0 +1,27 @@
1
+ import { html } from "lit-html";
2
+ import "./breadcrumbs";
3
+
4
+ export default {
5
+ title: "Molecules/Breadcrumbs",
6
+ argTypes: {},
7
+ };
8
+
9
+ const Template = () => html`
10
+ <cfa-breadcrumbs>
11
+ <ul>
12
+ <li>
13
+ <a href="#">Home</a>
14
+ </li>
15
+ <li>
16
+ <a href="#">Programs</a>
17
+ </li>
18
+ <li>
19
+ <a href="#">Safety Net</a>
20
+ </li>
21
+ <li>Food benefits</li>
22
+ </ul>
23
+ </cfa-breadcrumbs>
24
+ `;
25
+
26
+ export const Default = Template.bind({});
27
+ Default.args = {};
@@ -0,0 +1,167 @@
1
+ // These are some shared button styles we can use when we need a button in a component
2
+ // NB: make sure the styles in here match those in button.scss
3
+
4
+ import { css } from "lit";
5
+
6
+ export const buttonStyles = css`
7
+ .cfa-button,
8
+ a.cfa-button,
9
+ .cfa-button > a,
10
+ .wp-block-button > * {
11
+ --bg-color: var(--white);
12
+ --border-color: transparent;
13
+ --font-family: var(--font-family-sans-serif);
14
+ --font-size: var(--font-size-base);
15
+ --hover-bg-color: var(--blue-20);
16
+ --hover-border-color: var(--border-color);
17
+ --line-height: var(--line-height-base);
18
+ --text-color: var(--purple-80);
19
+
20
+ background-color: var(--bg-color);
21
+ border: var(--hairline) solid var(--border-color);
22
+ border-radius: var(--rounded-corners);
23
+ box-shadow: var(--shadow-small);
24
+ color: var(--text-color);
25
+ cursor: pointer;
26
+ display: block;
27
+ font-family: var(--font-family);
28
+ font-size: var(--font-size);
29
+ font-weight: bold;
30
+ padding: var(--spacing-component-2) var(--spacing-component-3);
31
+ text-align: center;
32
+ text-decoration: none;
33
+ transition: background-color 0.5s, box-shadow 0.5s;
34
+
35
+ &:hover {
36
+ background-color: var(--hover-bg-color);
37
+ border-color: var(--hover-border-color);
38
+ box-shadow: var(--shadow-medium);
39
+ color: var(--text-color);
40
+ }
41
+
42
+ & cfa-icon {
43
+ line-height: 1em;
44
+ }
45
+ }
46
+
47
+ @media (max-width: 768px) {
48
+ .cfa-button,
49
+ a.cfa-button,
50
+ .cfa-button > a,
51
+ .wp-block-button > * {
52
+ width: 100%;
53
+
54
+ & + & {
55
+ margin-block-start: var(--spacing-layout-half);
56
+ }
57
+ }
58
+
59
+ .wp-block-button {
60
+ width: 100%;
61
+ }
62
+ }
63
+
64
+ @media (min-width: 768px) {
65
+ .cfa-button,
66
+ a.cfa-button,
67
+ .cfa-button > a,
68
+ .wp-block-button > * {
69
+ display: inline-block;
70
+
71
+ & {
72
+ margin-block: var(--spacing-component-2);
73
+ margin-inline-end: var(--spacing-component-2);
74
+ }
75
+ }
76
+ }
77
+
78
+ // Themes / variants
79
+
80
+ .cfa-button--primary,
81
+ a.cfa-button--primary,
82
+ .cfa-button--primary > a,
83
+ .wp-block-button.is-style-primary > * {
84
+ --bg-color: var(--red-60);
85
+ --hover-bg-color: var(--red-80);
86
+ --text-color: var(--white,);
87
+ }
88
+
89
+ .cfa-button--outline,
90
+ a.cfa-button--outline,
91
+ .cfa-button--outline > a,
92
+ .wp-block-button.is-style-outline > * {
93
+ --border-color: var(--black-20);
94
+ --bg-color: transparent;
95
+ }
96
+
97
+ .cfa-button--outline-white,
98
+ a.cfa-button--outline-white,
99
+ .cfa-button--outline-white > a,
100
+ .wp-block-button.is-style-outline-white > * {
101
+ --border-color: var(--white);
102
+ --bg-color: transparent;
103
+ --hover-bg-color: var(--black-20);
104
+ --shadow-color: var(--white-20);
105
+ --text-color: var(--white);
106
+ }
107
+
108
+ .cfa-button--prominent-link,
109
+ a.cfa-button--prominent-link,
110
+ .cfa-button--prominent-link > a,
111
+ .wp-block-button.is-style-prominent-link > * {
112
+ --accent-color: var(--purple-60);
113
+
114
+ background: unset;
115
+ box-shadow: unset;
116
+ color: inherit;
117
+ font-weight: bold;
118
+ padding: 0;
119
+ text-decoration: underline;
120
+ text-decoration-color: var(--accent-color);
121
+ text-decoration-thickness: var(--medium);
122
+ text-underline-offset: 0.4em;
123
+ transition: color 0.2s ease-in-out, border-color 0.2s ease-in-out;
124
+
125
+ &:hover {
126
+ --accent-color: var(--red-60);
127
+
128
+ background: unset;
129
+ box-shadow: unset;
130
+ }
131
+
132
+ &::after {
133
+ @include icon.icon;
134
+
135
+ content: "arrow_right_alt";
136
+ display: inline-block;
137
+ padding-inline-start: 0.1em;
138
+ text-decoration: none;
139
+ transition: transform 0.2s ease-in-out;
140
+ width: 1em;
141
+ }
142
+
143
+ &:hover::after {
144
+ transform: translateX(0.3em);
145
+ }
146
+
147
+ cfa-icon {
148
+ text-decoration: none;
149
+ }
150
+ }
151
+
152
+ // Sizes
153
+
154
+ .cfa-button--sm,
155
+ a.cfa-button--sm,
156
+ .cfa-button--sm > a {
157
+ --font-size: var(--font-size-small);
158
+ --line-height: var(--line-height-small);
159
+ }
160
+
161
+ .cfa-button--md,
162
+ a.cfa-button--md,
163
+ .cfa-button--md > a {
164
+ --font-size: var(--font-size-base);
165
+ --line-height: var(--line-height-base);
166
+ }
167
+ `;
@@ -0,0 +1,162 @@
1
+ @use '../components/icon';
2
+
3
+ .cfa-button,
4
+ a.cfa-button,
5
+ .cfa-button > a,
6
+ .wp-block-button > * {
7
+ --bg-color: var(--white);
8
+ --border-color: transparent;
9
+ --font-family: var(--font-family-sans-serif);
10
+ --font-size: var(--font-size-base);
11
+ --hover-bg-color: var(--blue-20);
12
+ --hover-border-color: var(--border-color);
13
+ --line-height: var(--line-height-base);
14
+ --text-color: var(--purple-80);
15
+
16
+ background-color: var(--bg-color);
17
+ border: var(--hairline) solid var(--border-color);
18
+ border-radius: var(--rounded-corners);
19
+ box-shadow: var(--shadow-small);
20
+ color: var(--text-color);
21
+ cursor: pointer;
22
+ display: block;
23
+ font-family: var(--font-family);
24
+ font-size: var(--font-size);
25
+ font-weight: bold;
26
+ padding: var(--spacing-component-2) var(--spacing-component-3);
27
+ text-align: center;
28
+ text-decoration: none;
29
+ transition: background-color 0.5s, box-shadow 0.5s;
30
+
31
+ &:hover {
32
+ background-color: var(--hover-bg-color);
33
+ border-color: var(--hover-border-color);
34
+ box-shadow: var(--shadow-medium);
35
+ color: var(--text-color);
36
+ }
37
+
38
+ & cfa-icon {
39
+ line-height: 1em;
40
+ }
41
+ }
42
+
43
+ @media (max-width: 768px) {
44
+ .cfa-button,
45
+ a.cfa-button,
46
+ .cfa-button > a,
47
+ .wp-block-button > * {
48
+ width: 100%;
49
+
50
+ & + & {
51
+ margin-block-start: var(--spacing-layout-half);
52
+ }
53
+ }
54
+
55
+ .wp-block-button {
56
+ width: 100%;
57
+ }
58
+ }
59
+
60
+ @media (min-width: 768px) {
61
+ .cfa-button,
62
+ a.cfa-button,
63
+ .cfa-button > a,
64
+ .wp-block-button > * {
65
+ display: inline-block;
66
+
67
+ & {
68
+ margin-block: var(--spacing-component-2);
69
+ margin-inline-end: var(--spacing-component-2);
70
+ }
71
+ }
72
+ }
73
+
74
+ // Themes / variants
75
+
76
+ .cfa-button--primary,
77
+ a.cfa-button--primary,
78
+ .cfa-button--primary > a,
79
+ .wp-block-button.is-style-primary > * {
80
+ --bg-color: var(--red-60);
81
+ --hover-bg-color: var(--red-80);
82
+ --text-color: var(--white,);
83
+ }
84
+
85
+ .cfa-button--outline,
86
+ a.cfa-button--outline,
87
+ .cfa-button--outline > a,
88
+ .wp-block-button.is-style-outline > * {
89
+ --border-color: var(--black-20);
90
+ --bg-color: transparent;
91
+ }
92
+
93
+ .cfa-button--outline-white,
94
+ a.cfa-button--outline-white,
95
+ .cfa-button--outline-white > a,
96
+ .wp-block-button.is-style-outline-white > * {
97
+ --border-color: var(--white);
98
+ --bg-color: transparent;
99
+ --hover-bg-color: var(--black-20);
100
+ --shadow-color: var(--white-20);
101
+ --text-color: var(--white);
102
+ }
103
+
104
+ .cfa-button--prominent-link,
105
+ a.cfa-button--prominent-link,
106
+ .cfa-button--prominent-link > a,
107
+ .wp-block-button.is-style-prominent-link > * {
108
+ --accent-color: var(--purple-60);
109
+
110
+ background: unset;
111
+ box-shadow: unset;
112
+ color: inherit;
113
+ font-weight: bold;
114
+ padding: 0;
115
+ text-decoration: underline;
116
+ text-decoration-color: var(--accent-color);
117
+ text-decoration-thickness: var(--medium);
118
+ text-underline-offset: 0.4em;
119
+ transition: color 0.2s ease-in-out, border-color 0.2s ease-in-out;
120
+
121
+ &:hover {
122
+ --accent-color: var(--red-60);
123
+
124
+ background: unset;
125
+ box-shadow: unset;
126
+ }
127
+
128
+ &::after {
129
+ @include icon.icon;
130
+
131
+ content: "arrow_right_alt";
132
+ display: inline-block;
133
+ padding-inline-start: 0.1em;
134
+ text-decoration: none;
135
+ transition: transform 0.2s ease-in-out;
136
+ width: 1em;
137
+ }
138
+
139
+ &:hover::after {
140
+ transform: translateX(0.3em);
141
+ }
142
+
143
+ cfa-icon {
144
+ text-decoration: none;
145
+ }
146
+ }
147
+
148
+ // Sizes
149
+
150
+ .cfa-button--sm,
151
+ a.cfa-button--sm,
152
+ .cfa-button--sm > a {
153
+ --font-size: var(--font-size-small);
154
+ --line-height: var(--line-height-small);
155
+ }
156
+
157
+ .cfa-button--md,
158
+ a.cfa-button--md,
159
+ .cfa-button--md > a {
160
+ --font-size: var(--font-size-base);
161
+ --line-height: var(--line-height-base);
162
+ }
@@ -0,0 +1,49 @@
1
+ import { html } from "lit-html";
2
+ import "./button.scss";
3
+
4
+ export default {
5
+ title: "Atoms/Button",
6
+ argTypes: {
7
+ theme: {
8
+ options: ["default", "primary", "outline", "outline-white", "prominent-link"],
9
+ control: { type: "inline-radio" },
10
+ },
11
+ size: {
12
+ options: ["sm", "md"],
13
+ control: { type: "inline-radio" },
14
+ defaultValue: "md",
15
+ },
16
+ },
17
+ };
18
+
19
+ const Template = ({ theme, size }) => html`
20
+ <div class="cfa-button cfa-button--${theme} cfa-button--${size}">Submit</div>
21
+ `;
22
+
23
+ export const Default = Template.bind({});
24
+ Default.args = {
25
+ theme: "default",
26
+ };
27
+
28
+ export const Primary = Template.bind({});
29
+ Primary.args = {
30
+ theme: "primary",
31
+ };
32
+
33
+ export const Outline = Template.bind({});
34
+ Outline.args = {
35
+ theme: "outline",
36
+ };
37
+
38
+ export const OutlineWhite = Template.bind({});
39
+ OutlineWhite.args = {
40
+ theme: "outline-white",
41
+ };
42
+ OutlineWhite.parameters = {
43
+ backgrounds: { default: "purple" },
44
+ };
45
+
46
+ export const ProminentLink = Template.bind({});
47
+ ProminentLink.args = {
48
+ theme: "prominent-link",
49
+ };
@@ -0,0 +1,62 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common";
3
+ import "./icon";
4
+
5
+ class CallOut extends LitElement {
6
+ static styles = [
7
+ commonStyles,
8
+ css`
9
+ :host {
10
+ --background: var(--white);
11
+ --icon-color: var(--purple-80);
12
+ --link-color: var(--base-link-color);
13
+ --link-hover-color: var(--base-link-hover-color);
14
+ --text-color: var(--black);
15
+
16
+ display: block;
17
+ }
18
+
19
+ .callout {
20
+ align-items: flex-start;
21
+ background: var(--background);
22
+ box-shadow: var(--shadow-medium);
23
+ color: var(--text-color);
24
+ display: flex;
25
+ flex-direction: row;
26
+ gap: var(--spacing-component-2);
27
+ padding: var(--spacing-component-3);
28
+ }
29
+
30
+ .icon {
31
+ color: var(--icon-color);
32
+ flex-direction: column;
33
+ flex-grow: 0;
34
+ font-size: var(--font-size-h3);
35
+ height: 100%;
36
+ margin-block-start: -0.075em;
37
+ margin-inline-end: var(--spacing-component-2);
38
+ }
39
+
40
+ .callout + .callout {
41
+ margin-top: var(--spacing-layout-half);
42
+ }
43
+ `,
44
+ ];
45
+
46
+ render() {
47
+ return html`
48
+ <div class="callout">
49
+ <div class="icon">
50
+ <cfa-icon>info</cfa-icon>
51
+ </div>
52
+ <div class="text">
53
+ <slot></slot>
54
+ </div>
55
+ </div>
56
+ `;
57
+ }
58
+ }
59
+
60
+ if (!customElements.get("cfa-callout")) {
61
+ customElements.define("cfa-callout", CallOut);
62
+ }
@@ -0,0 +1,20 @@
1
+ import { html } from "lit-html";
2
+ import "./callout";
3
+
4
+ export default {
5
+ title: "Molecules/CallOut",
6
+ argTypes: {
7
+ text: { type: "string" },
8
+ },
9
+ };
10
+
11
+ const Template = ({ text }) => html`
12
+ <cfa-callout>
13
+ <div .innerHTML="${text}"></div>
14
+ </cfa-callout>
15
+ `;
16
+
17
+ export const Default = Template.bind({});
18
+ Default.args = {
19
+ text: 'It’s not time to go back to “normal,” but to reimagine the status quo. <a href="#">Learn more</a>',
20
+ };