@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,233 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common";
3
+
4
+ class SocialIcon extends LitElement {
5
+ static properties = {
6
+ icon: "",
7
+ };
8
+
9
+ static styles = [
10
+ commonStyles,
11
+ css`
12
+ .social-icon {
13
+ -moz-osx-font-smoothing: grayscale;
14
+ -webkit-font-smoothing: antialiased;
15
+ }
16
+
17
+ svg {
18
+ fill: currentColor;
19
+ height: 1em;
20
+ vertical-align: -0.125em;
21
+ width: 1em;
22
+ }
23
+ `,
24
+ ];
25
+
26
+ constructor() {
27
+ super();
28
+ }
29
+
30
+ iconTemplate(icon) {
31
+ switch (icon) {
32
+ case "bluesky":
33
+ return html`
34
+ <svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" version="1.1" viewBox="0 0 568 501">
35
+ <path class="st0" d="M123.1,33.7c65.1,48.9,135.2,148,160.9,201.2,25.7-53.2,95.8-152.3,160.9-201.2,47-35.3,123.1-62.6,123.1,24.3s-9.9,145.7-15.8,166.6c-20.3,72.5-94.2,90.9-159.9,79.7,114.9,19.6,144.1,84.3,81,149.1-119.9,123-172.3-30.9-185.7-70.3-2.5-7.2-3.6-10.6-3.6-7.7,0-2.9-1.2.5-3.6,7.7-13.4,39.4-65.8,193.3-185.7,70.3-63.1-64.8-33.9-129.5,81-149.1-65.7,11.2-139.6-7.3-159.9-79.7C9.9,203.7,0,75.3,0,57.9,0-28.9,76.1-1.6,123.1,33.7Z"/>
36
+ </svg>
37
+ `;
38
+ case "dropbox":
39
+ return html`
40
+ <svg
41
+ xmlns="http://www.w3.org/2000/svg"
42
+ height="16"
43
+ width="16.5"
44
+ viewBox="0 0 528 512"
45
+ >
46
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
47
+ <path
48
+ d="M264.4 116.3l-132 84.3 132 84.3-132 84.3L0 284.1l132.3-84.3L0 116.3 132.3 32l132.1 84.3zM131.6 395.7l132-84.3 132 84.3-132 84.3-132-84.3zm132.8-111.6l132-84.3-132-83.6L395.7 32 528 116.3l-132.3 84.3L528 284.8l-132.3 84.3-131.3-85z"
49
+ />
50
+ </svg>
51
+ `;
52
+ case "facebook":
53
+ return html`
54
+ <svg
55
+ xmlns="http://www.w3.org/2000/svg"
56
+ height="16"
57
+ width="16"
58
+ viewBox="0 0 512 512"
59
+ >
60
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
61
+ <path
62
+ d="M512 256C512 114.6 397.4 0 256 0S0 114.6 0 256C0 376 82.7 476.8 194.2 504.5V334.2H141.4V256h52.8V222.3c0-87.1 39.4-127.5 125-127.5c16.2 0 44.2 3.2 55.7 6.4V172c-6-.6-16.5-1-29.6-1c-42 0-58.2 15.9-58.2 57.2V256h83.6l-14.4 78.2H287V510.1C413.8 494.8 512 386.9 512 256h0z"
63
+ />
64
+ </svg>
65
+ `;
66
+ case "github":
67
+ return html`
68
+ <svg
69
+ xmlns="http://www.w3.org/2000/svg"
70
+ height="16"
71
+ width="15.5"
72
+ viewBox="0 0 496 512"
73
+ >
74
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
75
+ <path
76
+ d="M165.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3 .3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6zm-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5 .3-6.2 2.3zm44.2-1.7c-2.9 .7-4.9 2.6-4.6 4.9 .3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9zM244.8 8C106.1 8 0 113.3 0 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C428.2 457.8 496 362.9 496 252 496 113.3 383.5 8 244.8 8zM97.2 352.9c-1.3 1-1 3.3 .7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1zm-10.8-8.1c-.7 1.3 .3 2.9 2.3 3.9 1.6 1 3.6 .7 4.3-.7 .7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3 .7zm32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3 .7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1zm-11.4-14.7c-1.6 1-1.6 3.6 0 5.9 1.6 2.3 4.3 3.3 5.6 2.3 1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2z"
77
+ />
78
+ </svg>
79
+ `;
80
+ case "google-drive":
81
+ return html`
82
+ <svg
83
+ xmlns="http://www.w3.org/2000/svg"
84
+ height="16"
85
+ width="16"
86
+ viewBox="0 0 512 512"
87
+ >
88
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
89
+ <path
90
+ d="M339 314.9L175.4 32h161.2l163.6 282.9H339zm-137.5 23.6L120.9 480h310.5L512 338.5H201.5zM154.1 67.4L0 338.5 80.6 480 237 208.8 154.1 67.4z"
91
+ />
92
+ </svg>
93
+ `;
94
+ case "google":
95
+ return html`
96
+ <svg
97
+ xmlns="http://www.w3.org/2000/svg"
98
+ height="16"
99
+ width="15.25"
100
+ viewBox="0 0 488 512"
101
+ >
102
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
103
+ <path
104
+ d="M488 261.8C488 403.3 391.1 504 248 504 110.8 504 0 393.2 0 256S110.8 8 248 8c66.8 0 123 24.5 166.3 64.9l-67.5 64.9C258.5 52.6 94.3 116.6 94.3 256c0 86.5 69.1 156.6 153.7 156.6 98.2 0 135-70.4 140.8-106.9H248v-85.3h236.1c2.3 12.7 3.9 24.9 3.9 41.4z"
105
+ />
106
+ </svg>
107
+ `;
108
+ case "instagram":
109
+ return html`
110
+ <svg
111
+ xmlns="http://www.w3.org/2000/svg"
112
+ height="16"
113
+ width="14"
114
+ viewBox="0 0 448 512"
115
+ >
116
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
117
+ <path
118
+ d="M224.1 141c-63.6 0-114.9 51.3-114.9 114.9s51.3 114.9 114.9 114.9S339 319.5 339 255.9 287.7 141 224.1 141zm0 189.6c-41.1 0-74.7-33.5-74.7-74.7s33.5-74.7 74.7-74.7 74.7 33.5 74.7 74.7-33.6 74.7-74.7 74.7zm146.4-194.3c0 14.9-12 26.8-26.8 26.8-14.9 0-26.8-12-26.8-26.8s12-26.8 26.8-26.8 26.8 12 26.8 26.8zm76.1 27.2c-1.7-35.9-9.9-67.7-36.2-93.9-26.2-26.2-58-34.4-93.9-36.2-37-2.1-147.9-2.1-184.9 0-35.8 1.7-67.6 9.9-93.9 36.1s-34.4 58-36.2 93.9c-2.1 37-2.1 147.9 0 184.9 1.7 35.9 9.9 67.7 36.2 93.9s58 34.4 93.9 36.2c37 2.1 147.9 2.1 184.9 0 35.9-1.7 67.7-9.9 93.9-36.2 26.2-26.2 34.4-58 36.2-93.9 2.1-37 2.1-147.8 0-184.8zM398.8 388c-7.8 19.6-22.9 34.7-42.6 42.6-29.5 11.7-99.5 9-132.1 9s-102.7 2.6-132.1-9c-19.6-7.8-34.7-22.9-42.6-42.6-11.7-29.5-9-99.5-9-132.1s-2.6-102.7 9-132.1c7.8-19.6 22.9-34.7 42.6-42.6 29.5-11.7 99.5-9 132.1-9s102.7-2.6 132.1 9c19.6 7.8 34.7 22.9 42.6 42.6 11.7 29.5 9 99.5 9 132.1s2.7 102.7-9 132.1z"
119
+ />
120
+ </svg>
121
+ `;
122
+ case "linkedin":
123
+ return html`
124
+ <svg
125
+ xmlns="http://www.w3.org/2000/svg"
126
+ height="16"
127
+ width="14"
128
+ viewBox="0 0 448 512"
129
+ >
130
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
131
+ <path
132
+ d="M416 32H31.9C14.3 32 0 46.5 0 64.3v383.4C0 465.5 14.3 480 31.9 480H416c17.6 0 32-14.5 32-32.3V64.3c0-17.8-14.4-32.3-32-32.3zM135.4 416H69V202.2h66.5V416zm-33.2-243c-21.3 0-38.5-17.3-38.5-38.5S80.9 96 102.2 96c21.2 0 38.5 17.3 38.5 38.5 0 21.3-17.2 38.5-38.5 38.5zm282.1 243h-66.4V312c0-24.8-.5-56.7-34.5-56.7-34.6 0-39.9 27-39.9 54.9V416h-66.4V202.2h63.7v29.2h.9c8.9-16.8 30.6-34.5 62.9-34.5 67.2 0 79.7 44.3 79.7 101.9V416z"
133
+ />
134
+ </svg>
135
+ `;
136
+ case "reddit":
137
+ return html`
138
+ <svg
139
+ xmlns="http://www.w3.org/2000/svg"
140
+ height="16"
141
+ width="16"
142
+ viewBox="0 0 512 512"
143
+ >
144
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
145
+ <path
146
+ d="M0 256C0 114.6 114.6 0 256 0S512 114.6 512 256s-114.6 256-256 256L37.1 512c-13.7 0-20.5-16.5-10.9-26.2L75 437C28.7 390.7 0 326.7 0 256zM349.6 153.6c23.6 0 42.7-19.1 42.7-42.7s-19.1-42.7-42.7-42.7c-20.6 0-37.8 14.6-41.8 34c-34.5 3.7-61.4 33-61.4 68.4l0 .2c-37.5 1.6-71.8 12.3-99 29.1c-10.1-7.8-22.8-12.5-36.5-12.5c-33 0-59.8 26.8-59.8 59.8c0 24 14.1 44.6 34.4 54.1c2 69.4 77.6 125.2 170.6 125.2s168.7-55.9 170.6-125.3c20.2-9.6 34.1-30.2 34.1-54c0-33-26.8-59.8-59.8-59.8c-13.7 0-26.3 4.6-36.4 12.4c-27.4-17-62.1-27.7-100-29.1l0-.2c0-25.4 18.9-46.5 43.4-49.9l0 0c4.4 18.8 21.3 32.8 41.5 32.8zM177.1 246.9c16.7 0 29.5 17.6 28.5 39.3s-13.5 29.6-30.3 29.6s-31.4-8.8-30.4-30.5s15.4-38.3 32.1-38.3zm190.1 38.3c1 21.7-13.7 30.5-30.4 30.5s-29.3-7.9-30.3-29.6c-1-21.7 11.8-39.3 28.5-39.3s31.2 16.6 32.1 38.3zm-48.1 56.7c-10.3 24.6-34.6 41.9-63 41.9s-52.7-17.3-63-41.9c-1.2-2.9 .8-6.2 3.9-6.5c18.4-1.9 38.3-2.9 59.1-2.9s40.7 1 59.1 2.9c3.1 .3 5.1 3.6 3.9 6.5z"
147
+ />
148
+ </svg>
149
+ `;
150
+ case "soundcloud":
151
+ return html`
152
+ <svg
153
+ xmlns="http://www.w3.org/2000/svg"
154
+ height="16"
155
+ width="20"
156
+ viewBox="0 0 640 512"
157
+ >
158
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
159
+ <path
160
+ d="M111.4 256.3l5.8 65-5.8 68.3c-.3 2.5-2.2 4.4-4.4 4.4s-4.2-1.9-4.2-4.4l-5.6-68.3 5.6-65c0-2.2 1.9-4.2 4.2-4.2 2.2 0 4.1 2 4.4 4.2zm21.4-45.6c-2.8 0-4.7 2.2-5 5l-5 105.6 5 68.3c.3 2.8 2.2 5 5 5 2.5 0 4.7-2.2 4.7-5l5.8-68.3-5.8-105.6c0-2.8-2.2-5-4.7-5zm25.5-24.1c-3.1 0-5.3 2.2-5.6 5.3l-4.4 130 4.4 67.8c.3 3.1 2.5 5.3 5.6 5.3 2.8 0 5.3-2.2 5.3-5.3l5.3-67.8-5.3-130c0-3.1-2.5-5.3-5.3-5.3zM7.2 283.2c-1.4 0-2.2 1.1-2.5 2.5L0 321.3l4.7 35c.3 1.4 1.1 2.5 2.5 2.5s2.2-1.1 2.5-2.5l5.6-35-5.6-35.6c-.3-1.4-1.1-2.5-2.5-2.5zm23.6-21.9c-1.4 0-2.5 1.1-2.5 2.5l-6.4 57.5 6.4 56.1c0 1.7 1.1 2.8 2.5 2.8s2.5-1.1 2.8-2.5l7.2-56.4-7.2-57.5c-.3-1.4-1.4-2.5-2.8-2.5zm25.3-11.4c-1.7 0-3.1 1.4-3.3 3.3L47 321.3l5.8 65.8c.3 1.7 1.7 3.1 3.3 3.1 1.7 0 3.1-1.4 3.1-3.1l6.9-65.8-6.9-68.1c0-1.9-1.4-3.3-3.1-3.3zm25.3-2.2c-1.9 0-3.6 1.4-3.6 3.6l-5.8 70 5.8 67.8c0 2.2 1.7 3.6 3.6 3.6s3.6-1.4 3.9-3.6l6.4-67.8-6.4-70c-.3-2.2-2-3.6-3.9-3.6zm241.4-110.9c-1.1-.8-2.8-1.4-4.2-1.4-2.2 0-4.2 .8-5.6 1.9-1.9 1.7-3.1 4.2-3.3 6.7v.8l-3.3 176.7 1.7 32.5 1.7 31.7c.3 4.7 4.2 8.6 8.9 8.6s8.6-3.9 8.6-8.6l3.9-64.2-3.9-177.5c-.4-3-2-5.8-4.5-7.2zm-26.7 15.3c-1.4-.8-2.8-1.4-4.4-1.4s-3.1 .6-4.4 1.4c-2.2 1.4-3.6 3.9-3.6 6.7l-.3 1.7-2.8 160.8s0 .3 3.1 65.6v.3c0 1.7 .6 3.3 1.7 4.7 1.7 1.9 3.9 3.1 6.4 3.1 2.2 0 4.2-1.1 5.6-2.5 1.7-1.4 2.5-3.3 2.5-5.6l.3-6.7 3.1-58.6-3.3-162.8c-.3-2.8-1.7-5.3-3.9-6.7zm-111.4 22.5c-3.1 0-5.8 2.8-5.8 6.1l-4.4 140.6 4.4 67.2c.3 3.3 2.8 5.8 5.8 5.8 3.3 0 5.8-2.5 6.1-5.8l5-67.2-5-140.6c-.2-3.3-2.7-6.1-6.1-6.1zm376.7 62.8c-10.8 0-21.1 2.2-30.6 6.1-6.4-70.8-65.8-126.4-138.3-126.4-17.8 0-35 3.3-50.3 9.4-6.1 2.2-7.8 4.4-7.8 9.2v249.7c0 5 3.9 8.6 8.6 9.2h218.3c43.3 0 78.6-35 78.6-78.3 .1-43.6-35.2-78.9-78.5-78.9zm-296.7-60.3c-4.2 0-7.5 3.3-7.8 7.8l-3.3 136.7 3.3 65.6c.3 4.2 3.6 7.5 7.8 7.5 4.2 0 7.5-3.3 7.5-7.5l3.9-65.6-3.9-136.7c-.3-4.5-3.3-7.8-7.5-7.8zm-53.6-7.8c-3.3 0-6.4 3.1-6.4 6.7l-3.9 145.3 3.9 66.9c.3 3.6 3.1 6.4 6.4 6.4 3.6 0 6.4-2.8 6.7-6.4l4.4-66.9-4.4-145.3c-.3-3.6-3.1-6.7-6.7-6.7zm26.7 3.4c-3.9 0-6.9 3.1-6.9 6.9L227 321.3l3.9 66.4c.3 3.9 3.1 6.9 6.9 6.9s6.9-3.1 6.9-6.9l4.2-66.4-4.2-141.7c0-3.9-3-6.9-6.9-6.9z"
161
+ />
162
+ </svg>
163
+ `;
164
+ case "threads":
165
+ return html`
166
+ <svg
167
+ xmlns="http://www.w3.org/2000/svg"
168
+ height="16"
169
+ width="14"
170
+ viewBox="0 0 448 512"
171
+ >
172
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
173
+ <path
174
+ d="M331.5 235.7c2.2 .9 4.2 1.9 6.3 2.8c29.2 14.1 50.6 35.2 61.8 61.4c15.7 36.5 17.2 95.8-30.3 143.2c-36.2 36.2-80.3 52.5-142.6 53h-.3c-70.2-.5-124.1-24.1-160.4-70.2c-32.3-41-48.9-98.1-49.5-169.6V256v-.2C17 184.3 33.6 127.2 65.9 86.2C102.2 40.1 156.2 16.5 226.4 16h.3c70.3 .5 124.9 24 162.3 69.9c18.4 22.7 32 50 40.6 81.7l-40.4 10.8c-7.1-25.8-17.8-47.8-32.2-65.4c-29.2-35.8-73-54.2-130.5-54.6c-57 .5-100.1 18.8-128.2 54.4C72.1 146.1 58.5 194.3 58 256c.5 61.7 14.1 109.9 40.3 143.3c28 35.6 71.2 53.9 128.2 54.4c51.4-.4 85.4-12.6 113.7-40.9c32.3-32.2 31.7-71.8 21.4-95.9c-6.1-14.2-17.1-26-31.9-34.9c-3.7 26.9-11.8 48.3-24.7 64.8c-17.1 21.8-41.4 33.6-72.7 35.3c-23.6 1.3-46.3-4.4-63.9-16c-20.8-13.8-33-34.8-34.3-59.3c-2.5-48.3 35.7-83 95.2-86.4c21.1-1.2 40.9-.3 59.2 2.8c-2.4-14.8-7.3-26.6-14.6-35.2c-10-11.7-25.6-17.7-46.2-17.8H227c-16.6 0-39 4.6-53.3 26.3l-34.4-23.6c19.2-29.1 50.3-45.1 87.8-45.1h.8c62.6 .4 99.9 39.5 103.7 107.7l-.2 .2zm-156 68.8c1.3 25.1 28.4 36.8 54.6 35.3c25.6-1.4 54.6-11.4 59.5-73.2c-13.2-2.9-27.8-4.4-43.4-4.4c-4.8 0-9.6 .1-14.4 .4c-42.9 2.4-57.2 23.2-56.2 41.8l-.1 .1z"
175
+ />
176
+ </svg>
177
+ `;
178
+ case "twitter":
179
+ return html`
180
+ <svg
181
+ xmlns="http://www.w3.org/2000/svg"
182
+ height="16"
183
+ width="16"
184
+ viewBox="0 0 512 512"
185
+ >
186
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
187
+ <path
188
+ d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"
189
+ />
190
+ </svg>
191
+ `;
192
+ case "wikipedia":
193
+ return html`
194
+ <svg
195
+ xmlns="http://www.w3.org/2000/svg"
196
+ height="16"
197
+ width="20"
198
+ viewBox="0 0 640 512"
199
+ >
200
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
201
+ <path
202
+ d="M640 51.2l-.3 12.2c-28.1 .8-45 15.8-55.8 40.3-25 57.8-103.3 240-155.3 358.6H415l-81.9-193.1c-32.5 63.6-68.3 130-99.2 193.1-.3 .3-15 0-15-.3C172 352.3 122.8 243.4 75.8 133.4 64.4 106.7 26.4 63.4 .2 63.7c0-3.1-.3-10-.3-14.2h161.9v13.9c-19.2 1.1-52.8 13.3-43.3 34.2 21.9 49.7 103.6 240.3 125.6 288.6 15-29.7 57.8-109.2 75.3-142.8-13.9-28.3-58.6-133.9-72.8-160-9.7-17.8-36.1-19.4-55.8-19.7V49.8l142.5 .3v13.1c-19.4 .6-38.1 7.8-29.4 26.1 18.9 40 30.6 68.1 48.1 104.7 5.6-10.8 34.7-69.4 48.1-100.8 8.9-20.6-3.9-28.6-38.6-29.4 .3-3.6 0-10.3 .3-13.6 44.4-.3 111.1-.3 123.1-.6v13.6c-22.5 .8-45.8 12.8-58.1 31.7l-59.2 122.8c6.4 16.1 63.3 142.8 69.2 156.7L559.2 91.8c-8.6-23.1-36.4-28.1-47.2-28.3V49.6l127.8 1.1 .2 .5z"
203
+ />
204
+ </svg>
205
+ `;
206
+ case "youtube":
207
+ return html`
208
+ <svg
209
+ xmlns="http://www.w3.org/2000/svg"
210
+ height="16"
211
+ width="18"
212
+ viewBox="0 0 576 512"
213
+ >
214
+ <!--!Font Awesome Free 6.5.1 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free Copyright 2024 Fonticons, Inc.-->
215
+ <path
216
+ d="M549.7 124.1c-6.3-23.7-24.8-42.3-48.3-48.6C458.8 64 288 64 288 64S117.2 64 74.6 75.5c-23.5 6.3-42 24.9-48.3 48.6-11.4 42.9-11.4 132.3-11.4 132.3s0 89.4 11.4 132.3c6.3 23.7 24.8 41.5 48.3 47.8C117.2 448 288 448 288 448s170.8 0 213.4-11.5c23.5-6.3 42-24.2 48.3-47.8 11.4-42.9 11.4-132.3 11.4-132.3s0-89.4-11.4-132.3zm-317.5 213.5V175.2l142.7 81.2-142.7 81.2z"
217
+ />
218
+ </svg>
219
+ `;
220
+ default:
221
+ return "";
222
+ }
223
+ }
224
+
225
+ render() {
226
+ return html`
227
+ <span class="social-icon ${this.icon}" aria-hidden="true">
228
+ ${this.iconTemplate(this.icon)}
229
+ </span>
230
+ `;
231
+ }
232
+ }
233
+ customElements.define("cfa-social-icon", SocialIcon);
@@ -0,0 +1,36 @@
1
+ import { html } from "lit-html";
2
+ import "./social-icon";
3
+
4
+ export default {
5
+ title: "Atoms/SocialIcon",
6
+ argTypes: {
7
+ icon: {
8
+ options: [
9
+ "bluesky",
10
+ "dropbox",
11
+ "facebook",
12
+ "github",
13
+ "google-drive",
14
+ "google",
15
+ "instagram",
16
+ "linkedin",
17
+ "reddit",
18
+ "soundcloud",
19
+ "threads",
20
+ "twitter",
21
+ "wikipedia",
22
+ "youtube",
23
+ ],
24
+ control: {
25
+ type: "select",
26
+ },
27
+ },
28
+ },
29
+ };
30
+
31
+ const Template = ({ icon }) => html` <cfa-social-icon icon="${icon}" /> `;
32
+
33
+ export const Default = Template.bind({});
34
+ Default.args = {
35
+ icon: "linkedin",
36
+ };
@@ -0,0 +1,92 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common.js";
3
+ import { typographyStyles } from "../shared/typography.js";
4
+
5
+ class Stat extends LitElement {
6
+ static properties = {
7
+ beforeLabel: {},
8
+ figure: {},
9
+ afterLabel: {},
10
+ animated: {},
11
+ };
12
+ static styles = [
13
+ commonStyles,
14
+ typographyStyles,
15
+ css`
16
+ :host {
17
+ --text-color: var(--text-dark);
18
+ --highlight-color: var(--purple-20);
19
+ --highlight-thickness: var(--spacing-layout-half);
20
+
21
+ align-self: center;
22
+ display: block;
23
+ margin-inline: auto;
24
+ }
25
+ .stat {
26
+ align-items: center;
27
+ color: var(--text-color);
28
+ display: flex;
29
+ flex-direction: column;
30
+ text-align: center;
31
+ }
32
+ .figure {
33
+ min-width: var(--spacing-layout-3);
34
+ padding-inline: var(--spacing-component-2);
35
+ }
36
+ .figure > span {
37
+ background-image: linear-gradient(
38
+ var(--highlight-color),
39
+ var(--highlight-color)
40
+ );
41
+ background-size: 100% var(--highlight-thickness);
42
+ background-position: bottom 0.15em left;
43
+ background-repeat: no-repeat;
44
+ padding-inline: 0.25em;
45
+ }
46
+ /* Animation */
47
+ @media (prefers-reduced-motion: no-preference) {
48
+ .stat.is-animated .figure > span {
49
+ background-size: 0% var(--highlight-thickness);
50
+ transition: background-size 1s ease;
51
+ }
52
+ .stat.is-animated.is-visible .figure > span {
53
+ background-size: 100% var(--highlight-thickness);
54
+ }
55
+ }
56
+ `,
57
+ ];
58
+ constructor() {
59
+ super();
60
+ this.animated = true;
61
+ }
62
+ firstUpdated() {
63
+ const stat = this.shadowRoot.querySelector(".stat");
64
+ const callback = (entries) => {
65
+ entries.forEach((entry) => {
66
+ if (entry.isIntersecting) {
67
+ entry.target.classList.add("is-visible");
68
+ }
69
+ });
70
+ };
71
+ const options = {
72
+ rootMargin: "0px 0px -20% 0px",
73
+ };
74
+ const myObserver = new IntersectionObserver(callback, options);
75
+ myObserver.observe(stat);
76
+ }
77
+ render() {
78
+ return html`
79
+ <div class="stat ${this.animated ? "is-animated" : ""}">
80
+ <div class="above-label strong">${this.beforeLabel}</div>
81
+ <div class="figure display-2">
82
+ <span>${this.figure}</span>
83
+ </div>
84
+ <div class="below-label strong">${this.afterLabel}</div>
85
+ </div>
86
+ `;
87
+ }
88
+ }
89
+
90
+ if (!customElements.get("cfa-stat")) {
91
+ customElements.define("cfa-stat", Stat);
92
+ }
@@ -0,0 +1,28 @@
1
+ import { html } from "lit-html";
2
+ import "./stat";
3
+
4
+ export default {
5
+ title: "Atoms/Stat",
6
+ argTypes: {
7
+ beforeLabel: { type: "string" },
8
+ figure: { type: "string" },
9
+ afterLabel: { type: "string" },
10
+ },
11
+ };
12
+
13
+ const Template = ({ beforeLabel, figure, afterLabel }) => html`
14
+ <cfa-stat
15
+ beforeLabel="${beforeLabel}"
16
+ figure="${figure}"
17
+ afterLabel="${afterLabel}"
18
+ >
19
+ ${beforeLabel} ${figure} ${afterLabel}
20
+ </cfa-stat>
21
+ `;
22
+
23
+ export const Default = Template.bind({});
24
+ Default.args = {
25
+ beforeLabel: "More than",
26
+ figure: "3.8 million",
27
+ afterLabel: "people helped",
28
+ };
@@ -0,0 +1,114 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common";
3
+ import { buttonStyles } from "./button";
4
+ import "./tab";
5
+
6
+ class TabList extends LitElement {
7
+ static properties = {};
8
+ static styles = [
9
+ commonStyles,
10
+ buttonStyles,
11
+ css`
12
+ :host {
13
+ display: block;
14
+ width: calc(100% + var(--outer-margin));
15
+ }
16
+
17
+ .tab-list {
18
+ display: flex;
19
+ flex-direction: row;
20
+ line-height: 1;
21
+ margin-inline-start: calc(-1 * var(--outer-margin));
22
+ overflow-x: auto;
23
+ overflow-y: hidden;
24
+ scrollbar-width: none;
25
+ white-space: nowrap;
26
+ }
27
+
28
+ .tab-list::before {
29
+ content: "";
30
+ min-width: var(--outer-margin);
31
+ }
32
+
33
+ .tab-list::after {
34
+ border-bottom: var(--hairline) solid var(--gray-40);
35
+ content: "";
36
+ flex-grow: 1;
37
+ margin-right: var(--outer-margin);
38
+ }
39
+
40
+ ::slotted(*) {
41
+ max-width: none !important;
42
+ white-space: nowrap !important;
43
+ }
44
+ `,
45
+ ];
46
+
47
+ constructor() {
48
+ super();
49
+ }
50
+
51
+ firstUpdated() {
52
+ this.addEventListener("click", this._onTabClick);
53
+ this.setAttribute("role", "tablist");
54
+ this._setInitialAriaAttributes();
55
+ }
56
+
57
+ _setInitialAriaAttributes() {
58
+ const tabs = this.querySelectorAll("cfa-tab");
59
+ tabs.forEach((tab, index) => {
60
+ tab.setAttribute("role", "tab");
61
+ tab.setAttribute("aria-selected", "false");
62
+ tab.setAttribute("tabindex", "-1");
63
+ if (index === 0) {
64
+ tab.setAttribute("aria-selected", "true");
65
+ tab.setAttribute("tabindex", "0");
66
+ }
67
+ });
68
+ }
69
+
70
+ _onTabClick(event) {
71
+ const tab = event.target.closest("cfa-tab");
72
+ if (tab) {
73
+ this._setActiveTab(tab);
74
+ }
75
+ }
76
+
77
+ _setActiveTab(activeTab) {
78
+ const tabs = this.querySelectorAll("cfa-tab");
79
+ tabs.forEach((tab) => {
80
+ tab.removeAttribute("active");
81
+ tab.setAttribute("aria-selected", "false");
82
+ tab.setAttribute("tabindex", "-1");
83
+ });
84
+ activeTab.setAttribute("active", "");
85
+ activeTab.setAttribute("aria-selected", "true");
86
+ activeTab.setAttribute("tabindex", "0");
87
+
88
+ // Trigger a custom event with the ID for the new tab
89
+ let tabId = activeTab.id;
90
+ if (tabId && tabId.startsWith("tab-")) {
91
+ tabId = tabId.substring(4);
92
+ }
93
+ console.log("Tab changed event dispatched with ID:", tabId);
94
+ this.dispatchEvent(
95
+ new CustomEvent("tab-changed", {
96
+ detail: { id: tabId },
97
+ bubbles: true,
98
+ composed: true,
99
+ }),
100
+ );
101
+ }
102
+
103
+ render() {
104
+ return html`
105
+ <div class="tab-list" role="tablist">
106
+ <slot></slot>
107
+ </div>
108
+ `;
109
+ }
110
+ }
111
+
112
+ if (!customElements.get("cfa-tab-list")) {
113
+ customElements.define("cfa-tab-list", TabList);
114
+ }
@@ -0,0 +1,18 @@
1
+ import { html } from "lit-html";
2
+ import "./tab-list.js";
3
+
4
+ export default {
5
+ title: "Molecules/Tabs/TabList",
6
+ };
7
+
8
+ const Template = () => html`
9
+ <cfa-tab-list>
10
+ <cfa-tab id="tab-show-all" active>Show all stories</cfa-tab>
11
+ <cfa-tab id="tab-announcements">Announcements</cfa-tab>
12
+ <cfa-tab id="tab-blog-posts">Blog posts</cfa-tab>
13
+ <cfa-tab id="tab-press-releases">Press releases</cfa-tab>
14
+ </cfa-tab-list>
15
+ `;
16
+
17
+ export const Default = Template.bind({});
18
+ Default.args = {};
@@ -0,0 +1,95 @@
1
+ import { LitElement, html, css } from "lit";
2
+ import { commonStyles } from "../shared/common.js";
3
+ import { typographyStyles } from "../shared/typography.js";
4
+
5
+ class Tab extends LitElement {
6
+ static properties = {
7
+ active: { type: Boolean },
8
+ panelId: { type: String },
9
+ };
10
+
11
+ static styles = [
12
+ commonStyles,
13
+ typographyStyles,
14
+ css`
15
+ button {
16
+ background: none;
17
+ border: 0;
18
+ box-shadow: inset 0 calc(-1 * var(--hairline)) 0 0 var(--gray-40);
19
+ color: var(--gray-80);
20
+ cursor: pointer;
21
+ font-family: var(--font-family-sans-serif);
22
+ font-size: var(--font-size-small);
23
+ font-weight: normal;
24
+ padding: var(--spacing-component-2) var(--spacing-component-3)
25
+ calc(var(--spacing-component-2) + var(--medium));
26
+ }
27
+ button:focus {
28
+ background-color: var(--focus-color);
29
+ outline: none;
30
+ }
31
+ button:not(.active):hover {
32
+ box-shadow: inset 0 calc(-1 * var(--medium)) 0 0 var(--purple-40);
33
+ color: var(--black);
34
+ }
35
+ button.active {
36
+ box-shadow: inset 0 calc(-1 * var(--medium)) 0 0 var(--purple-60);
37
+ color: var(--black);
38
+ font-weight: bold;
39
+ }
40
+ `,
41
+ ];
42
+
43
+ constructor() {
44
+ super();
45
+ this.active = false;
46
+ this.panelId = "";
47
+ }
48
+
49
+ firstUpdated() {
50
+ this.addEventListener("keydown", this._onKeyDown);
51
+ }
52
+
53
+ _onKeyDown(event) {
54
+ const tabs = Array.from(this.parentElement.querySelectorAll("cfa-tab"));
55
+ const currentIndex = tabs.indexOf(this);
56
+ let newIndex;
57
+
58
+ switch (event.key) {
59
+ case "ArrowLeft":
60
+ newIndex = (currentIndex - 1 + tabs.length) % tabs.length;
61
+ tabs[newIndex].shadowRoot.querySelector("button").focus();
62
+ break;
63
+ case "ArrowRight":
64
+ newIndex = (currentIndex + 1) % tabs.length;
65
+ tabs[newIndex].shadowRoot.querySelector("button").focus();
66
+ break;
67
+ case "Home":
68
+ tabs[0].shadowRoot.querySelector("button").focus();
69
+ break;
70
+ case "End":
71
+ tabs[tabs.length - 1].shadowRoot.querySelector("button").focus();
72
+ break;
73
+ default:
74
+ break;
75
+ }
76
+ }
77
+
78
+ render() {
79
+ return html`
80
+ <button
81
+ role="tab"
82
+ aria-selected="${this.active ? "true" : "false"}"
83
+ aria-controls="${this.panelId}"
84
+ class="${this.active ? "active" : ""}"
85
+ tabindex="${this.active ? "0" : "-1"}"
86
+ >
87
+ <slot></slot>
88
+ </button>
89
+ `;
90
+ }
91
+ }
92
+
93
+ if (!customElements.get("cfa-tab")) {
94
+ customElements.define("cfa-tab", Tab);
95
+ }
@@ -0,0 +1,29 @@
1
+ import { html } from "lit-html";
2
+ import "./tab";
3
+
4
+ export default {
5
+ title: "Molecules/Tabs/Tab",
6
+ argTypes: {
7
+ content: { type: "string" },
8
+ state: {
9
+ control: { type: "radio" },
10
+ options: ["default", "active"],
11
+ },
12
+ },
13
+ };
14
+
15
+ const Template = ({ content, state }) => html`
16
+ <cfa-tab ?active=${state === "active"}>${content}</cfa-tab>
17
+ `;
18
+
19
+ export const Default = Template.bind({});
20
+ Default.args = {
21
+ content: "Click me",
22
+ state: "default",
23
+ };
24
+
25
+ export const Active = Template.bind({});
26
+ Active.args = {
27
+ content: "Click me",
28
+ state: "active",
29
+ };