@grantcodes/ui 2.15.6 → 2.16.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 (300) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/custom-elements.json +476 -346
  3. package/package.json +23 -23
  4. package/src/components/accordion/accordion-item.component.js +17 -19
  5. package/src/components/accordion/accordion-item.css +40 -44
  6. package/src/components/accordion/accordion.component.js +7 -7
  7. package/src/components/accordion/accordion.css +5 -5
  8. package/src/components/accordion/accordion.js +6 -6
  9. package/src/components/accordion/accordion.react.js +6 -6
  10. package/src/components/accordion/accordion.stories.js +10 -10
  11. package/src/components/accordion/accordion.test.js +100 -100
  12. package/src/components/accordion/index.js +6 -6
  13. package/src/components/app-bar/app-bar.component.js +86 -92
  14. package/src/components/app-bar/app-bar.css +187 -203
  15. package/src/components/app-bar/app-bar.js +3 -3
  16. package/src/components/app-bar/app-bar.react.js +9 -9
  17. package/src/components/app-bar/app-bar.stories.js +20 -20
  18. package/src/components/app-bar/app-bar.test.js +190 -237
  19. package/src/components/app-bar/index.js +1 -1
  20. package/src/components/app-bar/nav-link.component.js +7 -9
  21. package/src/components/app-bar/nav-link.css +23 -28
  22. package/src/components/app-bar/nav-link.js +3 -3
  23. package/src/components/app-bar/nav-link.react.js +6 -6
  24. package/src/components/avatar/avatar.component.js +79 -68
  25. package/src/components/avatar/avatar.css +18 -18
  26. package/src/components/avatar/avatar.js +3 -3
  27. package/src/components/avatar/avatar.react.js +6 -6
  28. package/src/components/avatar/avatar.stories.js +24 -23
  29. package/src/components/avatar/avatar.test.js +128 -84
  30. package/src/components/avatar/index.js +1 -1
  31. package/src/components/badge/badge.component.js +23 -23
  32. package/src/components/badge/badge.css +39 -52
  33. package/src/components/badge/badge.js +3 -3
  34. package/src/components/badge/badge.react.js +6 -6
  35. package/src/components/badge/badge.stories.js +23 -23
  36. package/src/components/badge/badge.test.js +53 -68
  37. package/src/components/badge/index.js +1 -1
  38. package/src/components/breadcrumb/breadcrumb.component.js +95 -96
  39. package/src/components/breadcrumb/breadcrumb.css +42 -44
  40. package/src/components/breadcrumb/breadcrumb.js +6 -9
  41. package/src/components/breadcrumb/breadcrumb.react.js +9 -12
  42. package/src/components/breadcrumb/breadcrumb.stories.js +5 -5
  43. package/src/components/breadcrumb/breadcrumb.test.js +139 -151
  44. package/src/components/breadcrumb/index.js +1 -1
  45. package/src/components/button/button.component.js +101 -103
  46. package/src/components/button/button.css +90 -94
  47. package/src/components/button/button.js +3 -3
  48. package/src/components/button/button.react.js +6 -6
  49. package/src/components/button/button.stories.js +25 -25
  50. package/src/components/button/button.test.js +324 -344
  51. package/src/components/button/index.js +1 -1
  52. package/src/components/button-group/button-group.component.js +18 -18
  53. package/src/components/button-group/button-group.css +16 -16
  54. package/src/components/button-group/button-group.js +3 -3
  55. package/src/components/button-group/button-group.react.js +6 -6
  56. package/src/components/button-group/button-group.stories.js +23 -23
  57. package/src/components/button-group/button-group.test.js +54 -54
  58. package/src/components/button-group/index.js +1 -1
  59. package/src/components/card/card.component.js +31 -33
  60. package/src/components/card/card.css +85 -85
  61. package/src/components/card/card.js +4 -4
  62. package/src/components/card/card.react.js +6 -6
  63. package/src/components/card/card.stories.js +27 -26
  64. package/src/components/card/card.test.js +56 -56
  65. package/src/components/card/index.js +1 -1
  66. package/src/components/code-preview/code-preview.component.js +47 -48
  67. package/src/components/code-preview/code-preview.css +11 -11
  68. package/src/components/code-preview/code-preview.js +3 -3
  69. package/src/components/code-preview/code-preview.react.js +6 -6
  70. package/src/components/code-preview/code-preview.stories.js +29 -29
  71. package/src/components/code-preview/code-preview.test.js +112 -135
  72. package/src/components/code-preview/index.js +1 -1
  73. package/src/components/container/container.component.js +27 -27
  74. package/src/components/container/container.css +22 -22
  75. package/src/components/container/container.js +3 -3
  76. package/src/components/container/container.react.js +6 -6
  77. package/src/components/container/container.stories.js +44 -44
  78. package/src/components/container/container.test.js +54 -66
  79. package/src/components/container/index.js +1 -1
  80. package/src/components/countdown/countdown.component.js +160 -162
  81. package/src/components/countdown/countdown.css +50 -34
  82. package/src/components/countdown/countdown.js +3 -3
  83. package/src/components/countdown/countdown.react.js +6 -6
  84. package/src/components/countdown/countdown.stories.js +34 -34
  85. package/src/components/countdown/index.js +1 -1
  86. package/src/components/cta/cta.component.js +77 -81
  87. package/src/components/cta/cta.css +24 -24
  88. package/src/components/cta/cta.js +3 -3
  89. package/src/components/cta/cta.react.js +6 -6
  90. package/src/components/cta/cta.stories.js +32 -32
  91. package/src/components/cta/index.js +1 -1
  92. package/src/components/dialog/dialog.component.js +95 -58
  93. package/src/components/dialog/dialog.css +45 -50
  94. package/src/components/dialog/dialog.js +3 -3
  95. package/src/components/dialog/dialog.react.js +6 -6
  96. package/src/components/dialog/dialog.stories.js +38 -29
  97. package/src/components/dialog/dialog.test.js +188 -102
  98. package/src/components/dialog/index.js +1 -1
  99. package/src/components/dropdown/dropdown.component.js +220 -201
  100. package/src/components/dropdown/dropdown.css +60 -84
  101. package/src/components/dropdown/dropdown.js +6 -9
  102. package/src/components/dropdown/dropdown.react.js +15 -15
  103. package/src/components/dropdown/dropdown.stories.js +10 -10
  104. package/src/components/dropdown/dropdown.test.js +211 -157
  105. package/src/components/dropdown/index.js +1 -1
  106. package/src/components/dropzone/dropzone.component.js +126 -129
  107. package/src/components/dropzone/dropzone.css +35 -37
  108. package/src/components/dropzone/dropzone.js +3 -3
  109. package/src/components/dropzone/dropzone.react.js +6 -6
  110. package/src/components/dropzone/dropzone.stories.js +28 -28
  111. package/src/components/dropzone/dropzone.test.js +91 -99
  112. package/src/components/dropzone/index.js +1 -1
  113. package/src/components/feature-list/feature-list.component.js +78 -86
  114. package/src/components/feature-list/feature-list.css +37 -37
  115. package/src/components/feature-list/feature-list.js +3 -3
  116. package/src/components/feature-list/feature-list.react.js +6 -6
  117. package/src/components/feature-list/feature-list.stories.js +86 -90
  118. package/src/components/feature-list/index.js +1 -1
  119. package/src/components/footer/footer-column.component.js +7 -7
  120. package/src/components/footer/footer-column.css +22 -22
  121. package/src/components/footer/footer.component.js +19 -19
  122. package/src/components/footer/footer.css +38 -38
  123. package/src/components/footer/footer.js +8 -8
  124. package/src/components/footer/footer.react.js +9 -9
  125. package/src/components/footer/footer.stories.js +9 -9
  126. package/src/components/footer/footer.test.js +101 -111
  127. package/src/components/footer/index.js +2 -2
  128. package/src/components/form-field/form-field.component.js +167 -125
  129. package/src/components/form-field/form-field.css +24 -24
  130. package/src/components/form-field/form-field.js +3 -3
  131. package/src/components/form-field/form-field.react.js +6 -6
  132. package/src/components/form-field/form-field.stories.js +53 -44
  133. package/src/components/form-field/form-field.test.js +280 -134
  134. package/src/components/form-field/index.js +1 -1
  135. package/src/components/gallery/gallery-image.component.js +30 -30
  136. package/src/components/gallery/gallery-image.js +3 -3
  137. package/src/components/gallery/gallery-image.react.js +6 -6
  138. package/src/components/gallery/gallery.component.js +24 -17
  139. package/src/components/gallery/gallery.css +79 -72
  140. package/src/components/gallery/gallery.js +3 -3
  141. package/src/components/gallery/gallery.react.js +6 -6
  142. package/src/components/gallery/gallery.stories.js +69 -68
  143. package/src/components/gallery/gallery.test.js +95 -88
  144. package/src/components/gallery/index.js +2 -2
  145. package/src/components/hero/hero.component.js +53 -57
  146. package/src/components/hero/hero.css +27 -27
  147. package/src/components/hero/hero.js +3 -3
  148. package/src/components/hero/hero.react.js +6 -6
  149. package/src/components/hero/hero.stories.js +39 -39
  150. package/src/components/hero/index.js +1 -1
  151. package/src/components/icon/icon.component.js +10 -10
  152. package/src/components/icon/icon.css +13 -13
  153. package/src/components/icon/icon.js +4 -4
  154. package/src/components/icon/icon.react.js +6 -6
  155. package/src/components/icon/icon.stories.js +8 -9
  156. package/src/components/icon/icon.test.js +54 -55
  157. package/src/components/icon/index.js +1 -1
  158. package/src/components/loading/index.js +1 -1
  159. package/src/components/loading/loading.component.js +41 -14
  160. package/src/components/loading/loading.css +47 -30
  161. package/src/components/loading/loading.js +4 -4
  162. package/src/components/loading/loading.react.js +6 -6
  163. package/src/components/loading/loading.stories.js +19 -18
  164. package/src/components/loading/loading.test.js +77 -54
  165. package/src/components/logo-cloud/index.js +1 -1
  166. package/src/components/logo-cloud/logo-cloud.component.js +39 -43
  167. package/src/components/logo-cloud/logo-cloud.css +31 -31
  168. package/src/components/logo-cloud/logo-cloud.js +3 -3
  169. package/src/components/logo-cloud/logo-cloud.react.js +6 -6
  170. package/src/components/logo-cloud/logo-cloud.stories.js +80 -80
  171. package/src/components/map/index.js +1 -1
  172. package/src/components/map/map.component.js +103 -107
  173. package/src/components/map/map.css +22 -22
  174. package/src/components/map/map.js +3 -3
  175. package/src/components/map/map.react.js +6 -6
  176. package/src/components/map/map.stories.js +38 -38
  177. package/src/components/media-text/index.js +1 -1
  178. package/src/components/media-text/media-text.component.js +76 -70
  179. package/src/components/media-text/media-text.css +32 -32
  180. package/src/components/media-text/media-text.js +3 -3
  181. package/src/components/media-text/media-text.react.js +6 -6
  182. package/src/components/media-text/media-text.stories.js +45 -45
  183. package/src/components/media-text/media-text.test.js +72 -0
  184. package/src/components/newsletter/index.js +1 -1
  185. package/src/components/newsletter/newsletter.component.js +56 -64
  186. package/src/components/newsletter/newsletter.css +48 -48
  187. package/src/components/newsletter/newsletter.js +3 -3
  188. package/src/components/newsletter/newsletter.react.js +6 -6
  189. package/src/components/newsletter/newsletter.stories.js +35 -35
  190. package/src/components/notice/index.js +1 -1
  191. package/src/components/notice/notice.component.js +66 -55
  192. package/src/components/notice/notice.css +37 -38
  193. package/src/components/notice/notice.js +3 -3
  194. package/src/components/notice/notice.react.js +6 -6
  195. package/src/components/notice/notice.stories.js +54 -53
  196. package/src/components/notice/notice.test.js +210 -156
  197. package/src/components/pagination/index.js +1 -1
  198. package/src/components/pagination/pagination.component.js +44 -44
  199. package/src/components/pagination/pagination.css +6 -6
  200. package/src/components/pagination/pagination.js +4 -4
  201. package/src/components/pagination/pagination.react.js +6 -6
  202. package/src/components/pagination/pagination.stories.js +20 -18
  203. package/src/components/pagination/pagination.test.js +95 -102
  204. package/src/components/person/index.js +1 -1
  205. package/src/components/person/person.component.js +29 -29
  206. package/src/components/person/person.css +17 -17
  207. package/src/components/person/person.js +4 -4
  208. package/src/components/person/person.react.js +6 -6
  209. package/src/components/person/person.stories.js +34 -33
  210. package/src/components/person/person.test.js +55 -68
  211. package/src/components/pricing/index.js +1 -1
  212. package/src/components/pricing/pricing.component.js +58 -70
  213. package/src/components/pricing/pricing.css +65 -65
  214. package/src/components/pricing/pricing.js +3 -3
  215. package/src/components/pricing/pricing.react.js +6 -6
  216. package/src/components/pricing/pricing.stories.js +96 -96
  217. package/src/components/sidebar/index.js +1 -1
  218. package/src/components/sidebar/sidebar.component.js +157 -130
  219. package/src/components/sidebar/sidebar.css +118 -115
  220. package/src/components/sidebar/sidebar.js +4 -4
  221. package/src/components/sidebar/sidebar.react.js +10 -10
  222. package/src/components/sidebar/sidebar.stories.js +10 -10
  223. package/src/components/sidebar/sidebar.test.js +250 -230
  224. package/src/components/stats/index.js +1 -1
  225. package/src/components/stats/stats.component.js +42 -50
  226. package/src/components/stats/stats.css +29 -29
  227. package/src/components/stats/stats.js +3 -3
  228. package/src/components/stats/stats.react.js +6 -6
  229. package/src/components/stats/stats.stories.js +40 -40
  230. package/src/components/tabs/index.js +2 -2
  231. package/src/components/tabs/internal/tabs-button.component.js +16 -27
  232. package/src/components/tabs/internal/tabs-button.js +3 -3
  233. package/src/components/tabs/internal/tabs-button.react.js +6 -6
  234. package/src/components/tabs/internal/tabs-item.component.js +30 -30
  235. package/src/components/tabs/tab.component.js +9 -11
  236. package/src/components/tabs/tab.js +3 -3
  237. package/src/components/tabs/tab.react.js +6 -6
  238. package/src/components/tabs/tabs.component.js +107 -109
  239. package/src/components/tabs/tabs.css +50 -59
  240. package/src/components/tabs/tabs.js +4 -4
  241. package/src/components/tabs/tabs.react.js +6 -6
  242. package/src/components/tabs/tabs.stories.js +23 -22
  243. package/src/components/tabs/tabs.test.js +201 -147
  244. package/src/components/testimonials/index.js +1 -1
  245. package/src/components/testimonials/testimonials.component.js +47 -51
  246. package/src/components/testimonials/testimonials.css +31 -31
  247. package/src/components/testimonials/testimonials.js +3 -3
  248. package/src/components/testimonials/testimonials.react.js +6 -6
  249. package/src/components/testimonials/testimonials.stories.js +49 -51
  250. package/src/components/toast/index.js +1 -1
  251. package/src/components/toast/toast.component.js +217 -148
  252. package/src/components/toast/toast.css +101 -99
  253. package/src/components/toast/toast.js +6 -9
  254. package/src/components/toast/toast.react.js +12 -12
  255. package/src/components/toast/toast.stories.js +75 -49
  256. package/src/components/toast/toast.test.js +260 -221
  257. package/src/components/tooltip/index.js +1 -1
  258. package/src/components/tooltip/tooltip.component.js +56 -49
  259. package/src/components/tooltip/tooltip.css +61 -50
  260. package/src/components/tooltip/tooltip.js +4 -4
  261. package/src/components/tooltip/tooltip.react.js +6 -6
  262. package/src/components/tooltip/tooltip.stories.js +24 -23
  263. package/src/components/tooltip/tooltip.test.js +143 -155
  264. package/src/constructor.test.js +31 -0
  265. package/src/css/base.css +1 -0
  266. package/src/css/colors.stories.js +120 -122
  267. package/src/css/elements/a.css +28 -28
  268. package/src/css/elements/forms/button.css +1 -1
  269. package/src/css/elements/forms/input.css +80 -80
  270. package/src/css/elements/forms/label.css +3 -3
  271. package/src/css/elements/media/image.css +2 -2
  272. package/src/css/elements.stories.js +48 -49
  273. package/src/css/helpers.css +8 -8
  274. package/src/css/layers.stories.js +5 -5
  275. package/src/css/reset.css +102 -102
  276. package/src/css/themes/todomap.css +1 -1
  277. package/src/css/tokens.stories.js +50 -53
  278. package/src/css/typography.css +30 -32
  279. package/src/css/typography.stories.js +92 -92
  280. package/src/css/util/focus-ring.css +12 -20
  281. package/src/css/view-transitions.css +16 -0
  282. package/src/exports.test.js +89 -105
  283. package/src/icons.js +1 -1
  284. package/src/lib/generate-id.js +1 -1
  285. package/src/lib/slot-presence-controller.js +48 -0
  286. package/src/lib/styles/all.css +38 -37
  287. package/src/lib/styles/focus-ring.css +12 -20
  288. package/src/lib/view-transition.js +42 -0
  289. package/src/lib/view-transition.test.js +105 -0
  290. package/src/main.js +29 -29
  291. package/src/pages/agency.stories.js +59 -59
  292. package/src/pages/blog-post.stories.js +48 -48
  293. package/src/pages/saas-landing.stories.js +180 -180
  294. package/src/react.js +44 -44
  295. package/src/react.test.js +42 -51
  296. package/src/test-utils/assert-helpers.js +39 -58
  297. package/src/test-utils/events.js +32 -34
  298. package/src/test-utils/fixture.js +31 -31
  299. package/src/test-utils/index.js +3 -3
  300. package/src/types.d.ts +3 -3
@@ -1,114 +1,106 @@
1
- import { describe, it, afterEach } from "node:test";
2
- import { strict as assert } from "node:assert";
3
- import { fixture, cleanup } from "../../test-utils/index.js";
4
- import "./dropzone.js";
1
+ import { strict as assert } from 'node:assert';
2
+ import { afterEach, describe, it } from 'node:test';
3
+ import { cleanup, fixture } from '../../test-utils/index.js';
4
+ import './dropzone.js';
5
5
 
6
- describe("Dropzone Component", () => {
7
- let element;
6
+ describe('Dropzone Component', () => {
7
+ let element;
8
8
 
9
- afterEach(() => {
10
- cleanup(element);
11
- });
9
+ afterEach(() => {
10
+ cleanup(element);
11
+ });
12
12
 
13
- it("should render with default properties", async () => {
14
- element = await fixture("grantcodes-dropzone");
15
- // Add required file input after fixture (component allows missing input in tests)
16
- const input = document.createElement("input");
17
- input.type = "file";
18
- input.placeholder = "Drop files here";
19
- element.appendChild(input);
20
- await element.updateComplete;
21
- assert.ok(element, "Element should be created");
22
- assert.ok(element.shadowRoot, "Element should have shadow root");
23
- });
13
+ it('should render with default properties', async () => {
14
+ element = await fixture('grantcodes-dropzone');
15
+ // Add required file input after fixture (component allows missing input in tests)
16
+ const input = document.createElement('input');
17
+ input.type = 'file';
18
+ input.placeholder = 'Drop files here';
19
+ element.appendChild(input);
20
+ await element.updateComplete;
21
+ assert.ok(element, 'Element should be created');
22
+ assert.ok(element.shadowRoot, 'Element should have shadow root');
23
+ });
24
24
 
25
- it("should have fullscreenOnDrag property set to false by default", async () => {
26
- element = await fixture("grantcodes-dropzone");
27
- const input = document.createElement("input");
28
- input.type = "file";
29
- element.appendChild(input);
30
- await element.updateComplete;
31
- assert.strictEqual(
32
- element.fullscreenOnDrag,
33
- false,
34
- "fullscreenOnDrag should be false by default",
35
- );
36
- });
25
+ it('should have fullscreenOnDrag property set to false by default', async () => {
26
+ element = await fixture('grantcodes-dropzone');
27
+ const input = document.createElement('input');
28
+ input.type = 'file';
29
+ element.appendChild(input);
30
+ await element.updateComplete;
31
+ assert.strictEqual(
32
+ element.fullscreenOnDrag,
33
+ false,
34
+ 'fullscreenOnDrag should be false by default',
35
+ );
36
+ });
37
37
 
38
- it("should render dropzone wrapper", async () => {
39
- element = await fixture("grantcodes-dropzone");
40
- const input = document.createElement("input");
41
- input.type = "file";
42
- element.appendChild(input);
43
- await element.updateComplete;
44
- const dropzone = element.shadowRoot.querySelector(".dropzone");
45
- assert.ok(dropzone, "Dropzone element should exist");
46
- });
38
+ it('should render dropzone wrapper', async () => {
39
+ element = await fixture('grantcodes-dropzone');
40
+ const input = document.createElement('input');
41
+ input.type = 'file';
42
+ element.appendChild(input);
43
+ await element.updateComplete;
44
+ const dropzone = element.shadowRoot.querySelector('.dropzone');
45
+ assert.ok(dropzone, 'Dropzone element should exist');
46
+ });
47
47
 
48
- it("should render placeholder span", async () => {
49
- element = await fixture("grantcodes-dropzone");
50
- const input = document.createElement("input");
51
- input.type = "file";
52
- input.placeholder = "Drop files here";
53
- element.appendChild(input);
54
- await element.updateComplete;
55
- const placeholder = element.shadowRoot.querySelector(
56
- ".dropzone__placeholder",
57
- );
58
- assert.ok(placeholder, "Placeholder element should exist");
59
- });
48
+ it('should render placeholder span', async () => {
49
+ element = await fixture('grantcodes-dropzone');
50
+ const input = document.createElement('input');
51
+ input.type = 'file';
52
+ input.placeholder = 'Drop files here';
53
+ element.appendChild(input);
54
+ await element.updateComplete;
55
+ const placeholder = element.shadowRoot.querySelector('.dropzone__placeholder');
56
+ assert.ok(placeholder, 'Placeholder element should exist');
57
+ });
60
58
 
61
- it("should have slot for file input", async () => {
62
- element = await fixture("grantcodes-dropzone");
63
- const input = document.createElement("input");
64
- input.type = "file";
65
- element.appendChild(input);
66
- await element.updateComplete;
67
- const slot = element.shadowRoot.querySelector("slot");
68
- assert.ok(slot, "Slot should exist");
69
- });
59
+ it('should have slot for file input', async () => {
60
+ element = await fixture('grantcodes-dropzone');
61
+ const input = document.createElement('input');
62
+ input.type = 'file';
63
+ element.appendChild(input);
64
+ await element.updateComplete;
65
+ const slot = element.shadowRoot.querySelector('slot');
66
+ assert.ok(slot, 'Slot should exist');
67
+ });
70
68
 
71
- it("should support fullscreenOnDrag property", async () => {
72
- element = await fixture("grantcodes-dropzone", {
73
- fullscreenOnDrag: true,
74
- });
75
- const input = document.createElement("input");
76
- input.type = "file";
77
- element.appendChild(input);
78
- await element.updateComplete;
69
+ it('should support fullscreenOnDrag property', async () => {
70
+ element = await fixture('grantcodes-dropzone', {
71
+ fullscreenOnDrag: true,
72
+ });
73
+ const input = document.createElement('input');
74
+ input.type = 'file';
75
+ element.appendChild(input);
76
+ await element.updateComplete;
79
77
 
80
- assert.strictEqual(
81
- element.fullscreenOnDrag,
82
- true,
83
- "fullscreenOnDrag should be true",
84
- );
85
- });
78
+ assert.strictEqual(element.fullscreenOnDrag, true, 'fullscreenOnDrag should be true');
79
+ });
86
80
 
87
- it("should have drag event handlers", async () => {
88
- element = await fixture("grantcodes-dropzone");
89
- const input = document.createElement("input");
90
- input.type = "file";
91
- element.appendChild(input);
92
- await element.updateComplete;
93
- const dropzone = element.shadowRoot.querySelector(".dropzone");
81
+ it('should have drag event handlers', async () => {
82
+ element = await fixture('grantcodes-dropzone');
83
+ const input = document.createElement('input');
84
+ input.type = 'file';
85
+ element.appendChild(input);
86
+ await element.updateComplete;
87
+ const dropzone = element.shadowRoot.querySelector('.dropzone');
94
88
 
95
- // Check that the element has the event listener attributes
96
- assert.ok(dropzone, "Dropzone should exist to attach handlers");
97
- });
89
+ // Check that the element has the event listener attributes
90
+ assert.ok(dropzone, 'Dropzone should exist to attach handlers');
91
+ });
98
92
 
99
- it("should handle file input placeholder", async () => {
100
- element = await fixture("grantcodes-dropzone");
101
- const input = document.createElement("input");
102
- input.type = "file";
103
- input.placeholder = "Drop files here";
104
- element.appendChild(input);
93
+ it('should handle file input placeholder', async () => {
94
+ element = await fixture('grantcodes-dropzone');
95
+ const input = document.createElement('input');
96
+ input.type = 'file';
97
+ input.placeholder = 'Drop files here';
98
+ element.appendChild(input);
105
99
 
106
- await element.updateComplete;
100
+ await element.updateComplete;
107
101
 
108
- const placeholder = element.shadowRoot.querySelector(
109
- ".dropzone__placeholder",
110
- );
111
- // The placeholder text is set from the input's placeholder in firstUpdated
112
- assert.ok(placeholder, "Placeholder should exist");
113
- });
102
+ const placeholder = element.shadowRoot.querySelector('.dropzone__placeholder');
103
+ // The placeholder text is set from the input's placeholder in firstUpdated
104
+ assert.ok(placeholder, 'Placeholder should exist');
105
+ });
114
106
  });
@@ -1 +1 @@
1
- export * from "./dropzone.js";
1
+ export * from './dropzone.js';
@@ -1,131 +1,123 @@
1
- import { LitElement, html } from "lit";
2
- import { unsafeHTML } from "lit/directives/unsafe-html.js";
3
- import * as icons from "lucide-static";
4
- import featureListStyles from "./feature-list.css" with { type: "css" };
5
- import "../icon/icon.js";
6
- import "../container/container.js";
1
+ import { html, LitElement } from 'lit';
2
+ import { unsafeHTML } from 'lit/directives/unsafe-html.js';
3
+ import * as icons from 'lucide-static';
4
+ import featureListStyles from './feature-list.css' with { type: 'css' };
5
+ import '../icon/icon.js';
6
+ import '../container/container.js';
7
7
 
8
8
  export class GrantCodesFeatureList extends LitElement {
9
- static styles = [featureListStyles];
9
+ static styles = [featureListStyles];
10
10
 
11
- static properties = {
12
- /**
13
- * Optional section heading.
14
- * @type {string}
15
- */
16
- title: { type: String },
17
- /**
18
- * Optional supporting text below the heading.
19
- * @type {string}
20
- */
21
- subtitle: { type: String },
22
- /**
23
- * Feature items as a JSON string array: `[{"title":"...","description":"...","icon":"...","href":"..."}]`.
24
- * @type {string}
25
- */
26
- items: { type: String },
27
- /**
28
- * Number of columns in the grid (1–4).
29
- * @type {number}
30
- */
31
- columns: { type: Number },
32
- };
11
+ static properties = {
12
+ /**
13
+ * Optional section heading.
14
+ * @type {string}
15
+ */
16
+ title: { type: String },
17
+ /**
18
+ * Optional supporting text below the heading.
19
+ * @type {string}
20
+ */
21
+ subtitle: { type: String },
22
+ /**
23
+ * Feature items as a JSON string array: `[{"title":"...","description":"...","icon":"...","href":"..."}]`.
24
+ * @type {string}
25
+ */
26
+ items: { type: String },
27
+ /**
28
+ * Number of columns in the grid (1–4).
29
+ * @type {number}
30
+ */
31
+ columns: { type: Number },
32
+ };
33
33
 
34
- constructor() {
35
- super();
36
- this.title = "";
37
- this.subtitle = "";
38
- this.items = "[]";
39
- this.columns = 3;
40
- }
34
+ constructor() {
35
+ super();
36
+ this.title = '';
37
+ this.subtitle = '';
38
+ this.items = '[]';
39
+ this.columns = 3;
40
+ }
41
41
 
42
- get _items() {
43
- try {
44
- return JSON.parse(this.items);
45
- } catch {
46
- return [];
47
- }
48
- }
42
+ get _items() {
43
+ try {
44
+ return JSON.parse(this.items);
45
+ } catch {
46
+ return [];
47
+ }
48
+ }
49
49
 
50
- _iconSvg(name) {
51
- if (!name) return null;
52
- // Convert kebab-case to PascalCase for lucide-static lookup
53
- const key = name
54
- .split("-")
55
- .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
56
- .join("");
57
- // biome-ignore lint/performance/noDynamicNamespaceImportAccess: icon names are runtime strings; static imports are not feasible here
58
- return icons[key] ?? null;
59
- }
50
+ _iconSvg(name) {
51
+ if (!name) return null;
52
+ // Convert kebab-case to PascalCase for lucide-static lookup
53
+ const key = name
54
+ .split('-')
55
+ .map((part) => part.charAt(0).toUpperCase() + part.slice(1))
56
+ .join('');
57
+ // biome-ignore lint/performance/noDynamicNamespaceImportAccess: icon names are runtime strings; static imports are not feasible here
58
+ return icons[key] ?? null;
59
+ }
60
60
 
61
- _renderIcon(name) {
62
- const svg = this._iconSvg(name);
63
- if (!svg) return null;
64
- return html`<grantcodes-icon class="feature-list__icon" aria-hidden="true">${unsafeHTML(svg)}</grantcodes-icon>`;
65
- }
61
+ _renderIcon(name) {
62
+ const svg = this._iconSvg(name);
63
+ if (!svg) return null;
64
+ return html`<grantcodes-icon class="feature-list__icon" aria-hidden="true">${unsafeHTML(svg)}</grantcodes-icon>`;
65
+ }
66
66
 
67
- render() {
68
- const items = this._items;
69
- return html`
67
+ render() {
68
+ const items = this._items;
69
+ return html`
70
70
  <section class="feature-list">
71
71
  <grantcodes-container>
72
- ${
73
- this.title
74
- ? html`<h2 class="feature-list__title">${this.title}</h2>`
75
- : null
76
- }
77
- ${
78
- this.subtitle
79
- ? html`<p class="feature-list__subtitle">${this.subtitle}</p>`
80
- : null
81
- }
72
+ ${this.title ? html`<h2 class="feature-list__title">${this.title}</h2>` : null}
73
+ ${this.subtitle ? html`<p class="feature-list__subtitle">${this.subtitle}</p>` : null}
82
74
  <ul
83
75
  class="feature-list__grid"
84
76
  style="--columns: ${this.columns}"
85
77
  role="list"
86
78
  >
87
79
  ${items.map(
88
- (item) => html`
80
+ (item) => html`
89
81
  <li class="feature-list__item">
90
82
  ${
91
- item.href
92
- ? html`
83
+ item.href
84
+ ? html`
93
85
  <a href=${item.href} class="feature-list__link">
94
86
  ${this._renderIcon(item.icon)}
95
87
  <h3 class="feature-list__item-title">
96
88
  ${item.title}
97
89
  </h3>
98
90
  ${
99
- item.description
100
- ? html`<p class="feature-list__item-desc">
91
+ item.description
92
+ ? html`<p class="feature-list__item-desc">
101
93
  ${item.description}
102
94
  </p>`
103
- : null
104
- }
95
+ : null
96
+ }
105
97
  </a>
106
98
  `
107
- : html`
99
+ : html`
108
100
  <div class="feature-list__content">
109
101
  ${this._renderIcon(item.icon)}
110
102
  <h3 class="feature-list__item-title">
111
103
  ${item.title}
112
104
  </h3>
113
105
  ${
114
- item.description
115
- ? html`<p class="feature-list__item-desc">
106
+ item.description
107
+ ? html`<p class="feature-list__item-desc">
116
108
  ${item.description}
117
109
  </p>`
118
- : null
119
- }
110
+ : null
111
+ }
120
112
  </div>
121
113
  `
122
- }
114
+ }
123
115
  </li>
124
116
  `,
125
- )}
117
+ )}
126
118
  </ul>
127
119
  </grantcodes-container>
128
120
  </section>
129
121
  `;
130
- }
122
+ }
131
123
  }
@@ -1,78 +1,78 @@
1
1
  *,
2
2
  *::before,
3
3
  *::after {
4
- box-sizing: border-box;
4
+ box-sizing: border-box;
5
5
  }
6
6
 
7
7
  :host {
8
- display: block;
8
+ display: block;
9
9
  }
10
10
 
11
11
  .feature-list {
12
- padding-block: var(--g-spacing-3xl);
12
+ padding-block: var(--g-spacing-3xl);
13
13
  }
14
14
 
15
15
  .feature-list__title {
16
- margin: 0 0 var(--g-spacing-sm);
17
- font: var(--g-typography-h3-font);
18
- text-align: center;
19
- color: var(--g-color-content-default);
16
+ margin: 0 0 var(--g-spacing-sm);
17
+ font: var(--g-typography-h3-font);
18
+ text-align: center;
19
+ color: var(--g-color-content-default);
20
20
  }
21
21
 
22
22
  .feature-list__subtitle {
23
- margin: 0 auto var(--g-spacing-2xl);
24
- font: var(--g-typography-body-lg-font);
25
- text-align: center;
26
- color: var(--g-color-content-subtle);
27
- max-width: 55ch;
23
+ margin: 0 auto var(--g-spacing-2xl);
24
+ font: var(--g-typography-body-lg-font);
25
+ text-align: center;
26
+ color: var(--g-color-content-subtle);
27
+ max-width: 55ch;
28
28
  }
29
29
 
30
30
  .feature-list__grid {
31
- display: grid;
32
- grid-template-columns: repeat(var(--columns, 3), 1fr);
33
- gap: var(--g-spacing-xl);
34
- padding: 0;
35
- margin: 0;
36
- list-style: none;
31
+ display: grid;
32
+ grid-template-columns: repeat(var(--columns, 3), 1fr);
33
+ gap: var(--g-spacing-xl);
34
+ padding: 0;
35
+ margin: 0;
36
+ list-style: none;
37
37
  }
38
38
 
39
39
  @media (max-width: 768px) {
40
- .feature-list__grid {
41
- grid-template-columns: 1fr;
42
- }
40
+ .feature-list__grid {
41
+ grid-template-columns: 1fr;
42
+ }
43
43
  }
44
44
 
45
45
  @media (min-width: 769px) and (max-width: 1024px) {
46
- .feature-list__grid {
47
- grid-template-columns: repeat(min(var(--columns, 3), 2), 1fr);
48
- }
46
+ .feature-list__grid {
47
+ grid-template-columns: repeat(min(var(--columns, 3), 2), 1fr);
48
+ }
49
49
  }
50
50
 
51
51
  .feature-list__link,
52
52
  .feature-list__content {
53
- display: block;
54
- text-decoration: none;
55
- color: inherit;
53
+ display: block;
54
+ text-decoration: none;
55
+ color: inherit;
56
56
  }
57
57
 
58
58
  .feature-list__link:hover .feature-list__item-title {
59
- color: var(--g-color-content-primary, #7c3aed);
59
+ color: var(--g-color-content-primary, #7c3aed);
60
60
  }
61
61
 
62
62
  .feature-list__icon {
63
- display: block;
64
- padding: var(--g-spacing-md);
65
- border-radius: 50%;
66
- inline-size: fit-content;
67
- margin-block-end: var(--g-spacing-md);
68
- color: var(--g-color-content-primary, currentColor);
69
- background-color: var(--g-color-background-primary);
63
+ display: block;
64
+ padding: var(--g-spacing-md);
65
+ border-radius: 50%;
66
+ inline-size: fit-content;
67
+ margin-block-end: var(--g-spacing-md);
68
+ color: var(--g-color-content-primary, currentColor);
69
+ background-color: var(--g-color-background-primary);
70
70
  }
71
71
 
72
72
  .feature-list__item-title {
73
- font: var(--g-typography-h5-font);
73
+ font: var(--g-typography-h5-font);
74
74
  }
75
75
 
76
76
  .feature-list__item-desc {
77
- color: var(--g-color-content-subtle);
77
+ color: var(--g-color-content-subtle);
78
78
  }
@@ -1,6 +1,6 @@
1
- import { GrantCodesFeatureList } from "./feature-list.component.js";
1
+ import { GrantCodesFeatureList } from './feature-list.component.js';
2
2
 
3
- export * from "./feature-list.component.js";
3
+ export * from './feature-list.component.js';
4
4
  export default GrantCodesFeatureList;
5
5
 
6
- customElements.define("grantcodes-feature-list", GrantCodesFeatureList);
6
+ customElements.define('grantcodes-feature-list', GrantCodesFeatureList);
@@ -1,9 +1,9 @@
1
- import React from "react";
2
- import { createComponent } from "@lit/react";
3
- import { GrantCodesFeatureList } from "./feature-list.js";
1
+ import { createComponent } from '@lit/react';
2
+ import React from 'react';
3
+ import { GrantCodesFeatureList } from './feature-list.js';
4
4
 
5
5
  export const FeatureList = createComponent({
6
- tagName: "grantcodes-feature-list",
7
- elementClass: GrantCodesFeatureList,
8
- react: React,
6
+ tagName: 'grantcodes-feature-list',
7
+ elementClass: GrantCodesFeatureList,
8
+ react: React,
9
9
  });