@grantcodes/ui 2.0.2 → 2.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 (179) hide show
  1. package/CHANGELOG.md +7 -0
  2. package/custom-elements.json +1926 -191
  3. package/package.json +6 -5
  4. package/src/components/accordion/accordion.component.js +33 -0
  5. package/src/components/accordion/accordion.js +6 -0
  6. package/src/components/accordion/accordion.stories.js +88 -0
  7. package/src/components/accordion/accordion.styles.js +66 -0
  8. package/src/components/accordion/index.js +6 -0
  9. package/src/components/app-bar/app-bar.component.js +1 -3
  10. package/src/components/app-bar/app-bar.js +0 -2
  11. package/src/components/app-bar/app-bar.styles.js +222 -221
  12. package/src/components/app-bar/app-bar.test.js +58 -17
  13. package/src/components/app-bar/index.js +0 -2
  14. package/src/components/avatar/avatar.js +0 -12
  15. package/src/components/avatar/avatar.stories.js +0 -12
  16. package/src/components/avatar/avatar.styles.js +19 -19
  17. package/src/components/avatar/avatar.test.js +4 -4
  18. package/src/components/avatar/index.js +1 -13
  19. package/src/components/badge/badge.js +0 -2
  20. package/src/components/badge/badge.styles.js +78 -81
  21. package/src/components/badge/badge.test.js +18 -5
  22. package/src/components/badge/index.js +0 -2
  23. package/src/components/breadcrumb/breadcrumb.component.js +9 -10
  24. package/src/components/breadcrumb/breadcrumb.js +6 -4
  25. package/src/components/breadcrumb/breadcrumb.styles.js +86 -90
  26. package/src/components/breadcrumb/breadcrumb.test.js +15 -5
  27. package/src/components/breadcrumb/index.js +0 -2
  28. package/src/components/button/button.component.js +2 -2
  29. package/src/components/button/button.styles.js +58 -86
  30. package/src/components/button/button.test.js +8 -4
  31. package/src/components/button/index.js +1 -1
  32. package/src/components/button-group/button-group.test.js +0 -2
  33. package/src/components/button-group/index.js +1 -1
  34. package/src/components/card/card.component.js +40 -9
  35. package/src/components/card/card.js +3 -1
  36. package/src/components/card/card.stories.js +18 -5
  37. package/src/components/card/card.styles.js +46 -20
  38. package/src/components/card/card.test.js +0 -2
  39. package/src/components/card/index.js +1 -1
  40. package/src/components/code-preview/code-preview.component.js +9 -9
  41. package/src/components/code-preview/code-preview.js +0 -1
  42. package/src/components/code-preview/code-preview.styles.js +3 -3
  43. package/src/components/code-preview/code-preview.test.js +29 -8
  44. package/src/components/code-preview/index.js +1 -1
  45. package/src/components/container/container.component.js +1 -0
  46. package/src/components/container/container.js +0 -1
  47. package/src/components/container/container.stories.js +12 -4
  48. package/src/components/container/container.styles.js +37 -35
  49. package/src/components/container/container.test.js +0 -2
  50. package/src/components/container/index.js +1 -1
  51. package/src/components/cta/cta.component.js +108 -0
  52. package/src/components/cta/cta.js +6 -0
  53. package/src/components/cta/cta.stories.js +56 -0
  54. package/src/components/cta/cta.styles.js +64 -0
  55. package/src/components/cta/index.js +1 -0
  56. package/src/components/dialog/dialog.js +0 -1
  57. package/src/components/dialog/dialog.styles.js +8 -8
  58. package/src/components/dialog/dialog.test.js +11 -5
  59. package/src/components/dialog/index.js +1 -1
  60. package/src/components/dropdown/dropdown.component.js +5 -3
  61. package/src/components/dropdown/dropdown.js +6 -4
  62. package/src/components/dropdown/dropdown.styles.js +5 -5
  63. package/src/components/dropdown/dropdown.test.js +20 -4
  64. package/src/components/dropdown/index.js +0 -2
  65. package/src/components/dropzone/dropzone.component.js +7 -6
  66. package/src/components/dropzone/dropzone.styles.js +4 -4
  67. package/src/components/dropzone/dropzone.test.js +6 -4
  68. package/src/components/dropzone/index.js +1 -1
  69. package/src/components/feature-list/feature-list.component.js +130 -0
  70. package/src/components/feature-list/feature-list.js +6 -0
  71. package/src/components/feature-list/feature-list.stories.js +117 -0
  72. package/src/components/feature-list/feature-list.styles.js +82 -0
  73. package/src/components/feature-list/index.js +1 -0
  74. package/src/components/footer/footer-column.styles.js +46 -47
  75. package/src/components/footer/footer.js +6 -2
  76. package/src/components/footer/footer.styles.js +6 -6
  77. package/src/components/footer/footer.test.js +9 -4
  78. package/src/components/footer/index.js +1 -1
  79. package/src/components/form-field/form-field.component.js +1 -3
  80. package/src/components/form-field/form-field.js +0 -1
  81. package/src/components/form-field/form-field.styles.js +35 -37
  82. package/src/components/form-field/form-field.test.js +9 -4
  83. package/src/components/form-field/index.js +1 -1
  84. package/src/components/gallery/gallery-image.js +0 -1
  85. package/src/components/gallery/gallery.js +0 -1
  86. package/src/components/gallery/gallery.styles.js +1 -1
  87. package/src/components/gallery/gallery.test.js +5 -3
  88. package/src/components/gallery/index.js +2 -2
  89. package/src/components/hero/hero.component.js +66 -0
  90. package/src/components/hero/hero.js +6 -0
  91. package/src/components/hero/hero.stories.js +53 -0
  92. package/src/components/hero/hero.styles.js +46 -0
  93. package/src/components/hero/index.js +1 -0
  94. package/src/components/icon/icon.js +3 -2
  95. package/src/components/icon/icon.stories.js +2 -1
  96. package/src/components/icon/icon.styles.js +23 -21
  97. package/src/components/icon/icon.test.js +2 -3
  98. package/src/components/icon/index.js +1 -1
  99. package/src/components/loading/index.js +1 -1
  100. package/src/components/loading/loading.js +3 -2
  101. package/src/components/loading/loading.styles.js +1 -1
  102. package/src/components/loading/loading.test.js +0 -2
  103. package/src/components/logo-cloud/index.js +1 -0
  104. package/src/components/logo-cloud/logo-cloud.component.js +81 -0
  105. package/src/components/logo-cloud/logo-cloud.js +6 -0
  106. package/src/components/logo-cloud/logo-cloud.stories.js +107 -0
  107. package/src/components/logo-cloud/logo-cloud.styles.js +68 -0
  108. package/src/components/media-text/index.js +1 -0
  109. package/src/components/media-text/media-text.component.js +100 -0
  110. package/src/components/media-text/media-text.js +6 -0
  111. package/src/components/media-text/media-text.stories.js +69 -0
  112. package/src/components/media-text/media-text.styles.js +66 -0
  113. package/src/components/newsletter/index.js +1 -0
  114. package/src/components/newsletter/newsletter.component.js +101 -0
  115. package/src/components/newsletter/newsletter.js +6 -0
  116. package/src/components/newsletter/newsletter.stories.js +59 -0
  117. package/src/components/newsletter/newsletter.styles.js +89 -0
  118. package/src/components/notice/index.js +1 -1
  119. package/src/components/notice/notice.js +0 -1
  120. package/src/components/notice/notice.styles.js +7 -7
  121. package/src/components/notice/notice.test.js +15 -5
  122. package/src/components/pagination/index.js +1 -1
  123. package/src/components/pagination/pagination.stories.js +1 -3
  124. package/src/components/pagination/pagination.styles.js +1 -1
  125. package/src/components/pagination/pagination.test.js +9 -4
  126. package/src/components/pricing/index.js +1 -0
  127. package/src/components/pricing/pricing.component.js +119 -0
  128. package/src/components/pricing/pricing.js +6 -0
  129. package/src/components/pricing/pricing.stories.js +123 -0
  130. package/src/components/pricing/pricing.styles.js +135 -0
  131. package/src/components/sidebar/index.js +0 -2
  132. package/src/components/sidebar/sidebar.component.js +12 -10
  133. package/src/components/sidebar/sidebar.js +3 -3
  134. package/src/components/sidebar/sidebar.stories.js +0 -2
  135. package/src/components/sidebar/sidebar.styles.js +181 -186
  136. package/src/components/sidebar/sidebar.test.js +48 -13
  137. package/src/components/stats/index.js +1 -0
  138. package/src/components/stats/stats.component.js +73 -0
  139. package/src/components/stats/stats.js +6 -0
  140. package/src/components/stats/stats.stories.js +64 -0
  141. package/src/components/stats/stats.styles.js +66 -0
  142. package/src/components/tabs/index.js +2 -2
  143. package/src/components/tabs/internal/tabs-button.component.js +1 -1
  144. package/src/components/tabs/internal/tabs-button.js +0 -1
  145. package/src/components/tabs/tab.js +0 -1
  146. package/src/components/tabs/tabs.js +3 -2
  147. package/src/components/tabs/tabs.styles.js +84 -74
  148. package/src/components/testimonials/index.js +1 -0
  149. package/src/components/testimonials/testimonials.component.js +97 -0
  150. package/src/components/testimonials/testimonials.js +6 -0
  151. package/src/components/testimonials/testimonials.stories.js +78 -0
  152. package/src/components/testimonials/testimonials.styles.js +82 -0
  153. package/src/components/toast/index.js +0 -2
  154. package/src/components/toast/toast.component.js +1 -3
  155. package/src/components/toast/toast.js +10 -5
  156. package/src/components/toast/toast.stories.js +9 -5
  157. package/src/components/toast/toast.styles.js +199 -201
  158. package/src/components/toast/toast.test.js +38 -10
  159. package/src/components/tooltip/index.js +1 -1
  160. package/src/components/tooltip/tooltip.js +3 -2
  161. package/src/components/tooltip/tooltip.styles.js +3 -3
  162. package/src/components/tooltip/tooltip.test.js +10 -4
  163. package/src/css/base.css +8 -5
  164. package/src/css/colors.stories.js +27 -28
  165. package/src/css/elements/forms/input.css +9 -41
  166. package/src/css/elements/media/image.css +1 -1
  167. package/src/css/themes/todomap.css +1 -0
  168. package/src/css/tokens.stories.js +26 -21
  169. package/src/css/typography.css +1 -3
  170. package/src/css/util/focus-ring.css +30 -0
  171. package/src/css/util/index.css +1 -2
  172. package/src/lib/styles/focus-ring.styles.js +34 -0
  173. package/src/main.js +10 -1
  174. package/src/pages/agency.stories.js +164 -0
  175. package/src/pages/blog-post.stories.js +381 -0
  176. package/src/pages/saas-landing.stories.js +307 -0
  177. package/src/test-utils/assert-helpers.js +10 -8
  178. package/src/css/util/functions.css +0 -16
  179. package/src/css/util/mixins.css +0 -63
@@ -1,43 +1,45 @@
1
1
  import { css } from "lit";
2
2
 
3
3
  export const containerStyles = css`
4
+ .container {
5
+ display: flex;
6
+ flex-direction: column;
7
+ justify-content: flex-start;
8
+ align-items: stretch;
9
+ inline-size: 1200px;
10
+ max-inline-size: 100%;
11
+ padding-inline: var(--g-theme-spacing-md);
12
+ margin-inline: auto;
13
+ background-color: inherit;
14
+ }
4
15
 
5
- .container {
6
- display: flex;
7
- flex-direction: column;
8
- justify-content: flex-start;
9
- align-items: stretch;
10
- inline-size: 1200px;
11
- max-inline-size: 100%;
12
- padding-inline: 1rem;
13
- margin-inline: auto;
14
- background-color: inherit;
15
- }
16
+ .container--prose {
17
+ max-inline-size: 65ch;
18
+ }
16
19
 
17
- .container--wide {
18
- inline-size: 1400px;
19
- }
20
+ .container--wide {
21
+ inline-size: 1400px;
22
+ }
20
23
 
21
- .container--full {
22
- inline-size: 100%;
23
- }
24
+ .container--full {
25
+ inline-size: 100%;
26
+ }
24
27
 
25
- .container--viewport {
26
- inset-inline-start: 50%;
27
- position: relative;
28
- inset-inline-end: 50%;
29
- margin-inline-start: -50vw;
30
- margin-inline-end: -50vw;
31
- max-inline-size: 100vw;
32
- inline-size: 100vw;
33
- margin-inline-start: -50dvw;
34
- margin-inline-end: -50dvw;
35
- max-inline-size: 100dvw;
36
- inline-size: 100dvw;
37
- }
28
+ .container--viewport {
29
+ inset-inline-start: 50%;
30
+ position: relative;
31
+ inset-inline-end: 50%;
32
+ margin-inline-start: -50vw;
33
+ margin-inline-end: -50vw;
34
+ max-inline-size: 100vw;
35
+ inline-size: 100vw;
36
+ margin-inline-start: -50dvw;
37
+ margin-inline-end: -50dvw;
38
+ max-inline-size: 100dvw;
39
+ inline-size: 100dvw;
40
+ }
38
41
 
39
- .container--nopad {
40
- padding-inline: 0;
41
- }
42
-
43
- `;
42
+ .container--nopad {
43
+ padding-inline: 0;
44
+ }
45
+ `;
@@ -80,5 +80,3 @@ describe("Container Component", () => {
80
80
  assert.ok(slot, "Slot should exist");
81
81
  });
82
82
  });
83
-
84
-
@@ -1 +1 @@
1
- export * from "./container";
1
+ export * from "./container.js";
@@ -0,0 +1,108 @@
1
+ import { LitElement, html } from "lit";
2
+ import { ctaStyles } from "./cta.styles.js";
3
+ import "../button/button.js";
4
+
5
+ export class GrantCodesCta extends LitElement {
6
+ static styles = [ctaStyles];
7
+
8
+ static properties = {
9
+ /**
10
+ * Small label shown above the title.
11
+ * @type {string}
12
+ */
13
+ eyebrow: { type: String },
14
+ /**
15
+ * Main heading text.
16
+ * @type {string}
17
+ */
18
+ title: { type: String },
19
+ /**
20
+ * Supporting paragraph text.
21
+ * @type {string}
22
+ */
23
+ text: { type: String },
24
+ /**
25
+ * Primary CTA as a JSON string: `{"label":"...","href":"..."}`.
26
+ * @type {string}
27
+ */
28
+ primaryAction: { type: String, attribute: "primary-action" },
29
+ /**
30
+ * Secondary CTA as a JSON string: `{"label":"...","href":"..."}`.
31
+ * @type {string}
32
+ */
33
+ secondaryAction: { type: String, attribute: "secondary-action" },
34
+ /**
35
+ * Text alignment of the block.
36
+ * @type {'left' | 'center'}
37
+ */
38
+ align: { type: String, reflect: true },
39
+ };
40
+
41
+ constructor() {
42
+ super();
43
+ this.eyebrow = "";
44
+ this.title = "";
45
+ this.text = "";
46
+ this.primaryAction = "";
47
+ this.secondaryAction = "";
48
+ this.align = "center";
49
+ }
50
+
51
+ get _primaryAction() {
52
+ try {
53
+ return this.primaryAction ? JSON.parse(this.primaryAction) : null;
54
+ } catch {
55
+ return null;
56
+ }
57
+ }
58
+
59
+ get _secondaryAction() {
60
+ try {
61
+ return this.secondaryAction ? JSON.parse(this.secondaryAction) : null;
62
+ } catch {
63
+ return null;
64
+ }
65
+ }
66
+
67
+ render() {
68
+ const primary = this._primaryAction;
69
+ const secondary = this._secondaryAction;
70
+ return html`
71
+ <section class="cta">
72
+ <div class="cta__container">
73
+ ${
74
+ this.eyebrow
75
+ ? html`<p class="cta__eyebrow">${this.eyebrow}</p>`
76
+ : null
77
+ }
78
+ <h2 class="cta__title">${this.title}</h2>
79
+ ${this.text ? html`<p class="cta__text">${this.text}</p>` : null}
80
+ ${
81
+ primary || secondary
82
+ ? html`
83
+ <div class="cta__actions">
84
+ ${
85
+ primary
86
+ ? html`<grantcodes-button href=${primary.href}
87
+ >${primary.label}</grantcodes-button
88
+ >`
89
+ : null
90
+ }
91
+ ${
92
+ secondary
93
+ ? html`<a
94
+ href=${secondary.href}
95
+ class="cta__secondary-link"
96
+ >${secondary.label}</a
97
+ >`
98
+ : null
99
+ }
100
+ </div>
101
+ `
102
+ : null
103
+ }
104
+ </div>
105
+ </section>
106
+ `;
107
+ }
108
+ }
@@ -0,0 +1,6 @@
1
+ import { GrantCodesCta } from "./cta.component.js";
2
+
3
+ export * from "./cta.component.js";
4
+ export default GrantCodesCta;
5
+
6
+ customElements.define("grantcodes-cta", GrantCodesCta);
@@ -0,0 +1,56 @@
1
+ import { getStorybookHelpers } from "@wc-toolkit/storybook-helpers";
2
+ import "./cta.js";
3
+
4
+ const { events, args, argTypes } = getStorybookHelpers("grantcodes-cta");
5
+
6
+ const meta = {
7
+ title: "Blocks/CTA",
8
+ component: "grantcodes-cta",
9
+ args,
10
+ argTypes,
11
+ parameters: {
12
+ actions: {
13
+ handles: events,
14
+ },
15
+ layout: "fullscreen",
16
+ },
17
+ };
18
+
19
+ export default meta;
20
+
21
+ /**
22
+ * Default centered CTA with primary and secondary actions.
23
+ */
24
+ export const Default = {
25
+ args: {
26
+ eyebrow: "Get started today",
27
+ title: "Build something remarkable",
28
+ text: "A personal web component library with a custom design system, ready for your next project.",
29
+ "primary-action": JSON.stringify({ label: "Get started", href: "/docs" }),
30
+ "secondary-action": JSON.stringify({ label: "Learn more", href: "/about" }),
31
+ align: "center",
32
+ },
33
+ };
34
+
35
+ /**
36
+ * Left-aligned CTA, no secondary action.
37
+ */
38
+ export const LeftAligned = {
39
+ args: {
40
+ title: "Ready to ship?",
41
+ text: "Deploy your components today with zero configuration.",
42
+ "primary-action": JSON.stringify({ label: "Deploy now", href: "/deploy" }),
43
+ align: "left",
44
+ },
45
+ };
46
+
47
+ /**
48
+ * Minimal CTA — title only with a single action.
49
+ */
50
+ export const Minimal = {
51
+ args: {
52
+ title: "Join the community",
53
+ "primary-action": JSON.stringify({ label: "Sign up", href: "/signup" }),
54
+ align: "center",
55
+ },
56
+ };
@@ -0,0 +1,64 @@
1
+ import { css } from "lit";
2
+
3
+ export const ctaStyles = css`
4
+ :host {
5
+ display: block;
6
+ }
7
+
8
+ .cta {
9
+ padding-block: var(--g-theme-spacing-3xl);
10
+ padding-inline: var(--g-theme-spacing-md);
11
+ background: var(--g-theme-color-background-subtle);
12
+ }
13
+
14
+ .cta__container {
15
+ max-width: 65ch;
16
+ margin: 0 auto;
17
+ }
18
+
19
+ :host([align="center"]) .cta {
20
+ text-align: center;
21
+ }
22
+
23
+ :host([align="center"]) .cta__actions {
24
+ justify-content: center;
25
+ }
26
+
27
+ .cta__eyebrow {
28
+ margin: 0 0 var(--g-theme-spacing-sm);
29
+ font-size: var(--g-theme-typography-meta-default-font-size);
30
+ font-weight: var(--g-theme-typography-meta-default-font-weight);
31
+ letter-spacing: var(--g-theme-typography-meta-default-letter-spacing);
32
+ text-transform: uppercase;
33
+ color: var(--g-theme-color-content-brand, #7c3aed);
34
+ }
35
+
36
+ .cta__title {
37
+ margin: 0 0 var(--g-theme-spacing-md);
38
+ font: var(--g-theme-typography-headline-lg);
39
+ color: var(--g-theme-color-content-default);
40
+ }
41
+
42
+ .cta__text {
43
+ margin: 0 0 var(--g-theme-spacing-xl);
44
+ font: var(--g-theme-typography-body-lg);
45
+ color: var(--g-theme-color-content-secondary);
46
+ }
47
+
48
+ .cta__actions {
49
+ display: flex;
50
+ flex-wrap: wrap;
51
+ gap: var(--g-theme-spacing-md);
52
+ align-items: center;
53
+ }
54
+
55
+ .cta__secondary-link {
56
+ font-size: var(--g-theme-typography-body-default-font-size);
57
+ font-weight: var(--g-typography-font-weight-500);
58
+ color: var(--g-theme-color-content-default);
59
+ }
60
+
61
+ .cta__secondary-link:hover {
62
+ color: var(--g-theme-color-content-brand, #7c3aed);
63
+ }
64
+ `;
@@ -0,0 +1 @@
1
+ export * from "./cta.js";
@@ -4,4 +4,3 @@ export * from "./dialog.component.js";
4
4
  export default GrantCodesDialog;
5
5
 
6
6
  customElements.define("grantcodes-dialog", GrantCodesDialog);
7
-
@@ -26,17 +26,17 @@ export const dialogStyles = css`
26
26
  position: absolute;
27
27
  border: none;
28
28
  line-height: 1;
29
- font-size: 1.4rem;
29
+ font-size: var(--g-theme-typography-title-lg-font-size);
30
30
  cursor: pointer;
31
31
  background: transparent;
32
- inset-block-start: 1rem;
33
- inset-inline-end: 1rem;
32
+ inset-block-start: var(--g-theme-spacing-md);
33
+ inset-inline-end: var(--g-theme-spacing-md);
34
34
  margin-block-start: -0.25rem;
35
35
  margin-inline-end: -0.25rem;
36
36
  border-radius: 50%;
37
37
  width: 2rem;
38
38
  height: 2rem;
39
- padding: 0.25rem;
39
+ padding: var(--g-theme-spacing-xs);
40
40
  justify-content: center;
41
41
  align-items: center;
42
42
  }
@@ -45,8 +45,8 @@ export const dialogStyles = css`
45
45
  display: flex;
46
46
  flex-direction: column;
47
47
  justify-content: flex-start;
48
- gap: 1rem;
49
- padding: 1rem;
48
+ gap: var(--g-theme-spacing-md);
49
+ padding: var(--g-theme-spacing-md);
50
50
  }
51
51
 
52
52
  .dialog__header,
@@ -62,7 +62,7 @@ export const dialogStyles = css`
62
62
  flex-direction: row;
63
63
  justify-content: space-between;
64
64
  align-items: center;
65
- padding: 1rem;
65
+ padding: var(--g-theme-spacing-md);
66
66
  border-bottom: var(--g-theme-border-width-sm) solid
67
67
  var(--g-theme-color-border-default);
68
68
  }
@@ -71,4 +71,4 @@ export const dialogStyles = css`
71
71
  --g-theme-border-radius-md: 0;
72
72
  }
73
73
 
74
- `;
74
+ `;
@@ -18,7 +18,11 @@ describe("Dialog Component", () => {
18
18
 
19
19
  it("should be closed by default", async () => {
20
20
  element = await fixture("grantcodes-dialog");
21
- assert.strictEqual(element.open, false, "Dialog should be closed by default");
21
+ assert.strictEqual(
22
+ element.open,
23
+ false,
24
+ "Dialog should be closed by default",
25
+ );
22
26
  });
23
27
 
24
28
  it("should render dialog element", async () => {
@@ -40,7 +44,11 @@ describe("Dialog Component", () => {
40
44
 
41
45
  it("should be dismissible by default", async () => {
42
46
  element = await fixture("grantcodes-dialog");
43
- assert.strictEqual(element.dismissible, true, "Should be dismissible by default");
47
+ assert.strictEqual(
48
+ element.dismissible,
49
+ true,
50
+ "Should be dismissible by default",
51
+ );
44
52
  });
45
53
 
46
54
  it("should render dismiss button when dismissible", async () => {
@@ -75,7 +83,7 @@ describe("Dialog Component", () => {
75
83
 
76
84
  it("should have default content slot", async () => {
77
85
  element = await fixture("grantcodes-dialog");
78
- const slot = element.shadowRoot.querySelector('slot.dialog__content');
86
+ const slot = element.shadowRoot.querySelector("slot.dialog__content");
79
87
  assert.ok(slot, "Content slot should exist");
80
88
  });
81
89
 
@@ -93,5 +101,3 @@ describe("Dialog Component", () => {
93
101
  assert.strictEqual(element.open, false, "Dialog should be closed");
94
102
  });
95
103
  });
96
-
97
-
@@ -1 +1 @@
1
- export * from "./dialog";
1
+ export * from "./dialog.js";
@@ -121,7 +121,7 @@ export class GrantCodesDropdown extends LitElement {
121
121
  detail: { open: this.open },
122
122
  bubbles: true,
123
123
  composed: true,
124
- })
124
+ }),
125
125
  );
126
126
  }
127
127
 
@@ -155,7 +155,9 @@ export class GrantCodesDropdown extends LitElement {
155
155
  }
156
156
 
157
157
  render() {
158
- const placementClass = this.placement ? `dropdown__menu--${this.placement}` : "";
158
+ const placementClass = this.placement
159
+ ? `dropdown__menu--${this.placement}`
160
+ : "";
159
161
  const openClass = this.open ? "dropdown__menu--open" : "";
160
162
  return html`
161
163
  <div class="dropdown">
@@ -202,7 +204,7 @@ export class GrantCodesDropdownItem extends LitElement {
202
204
  new CustomEvent("select", {
203
205
  bubbles: true,
204
206
  composed: true,
205
- })
207
+ }),
206
208
  );
207
209
 
208
210
  // Close the dropdown
@@ -6,7 +6,9 @@ import {
6
6
  export * from "./dropdown.component.js";
7
7
  export default GrantCodesDropdown;
8
8
 
9
- customElements.define("grantcodes-dropdown", GrantCodesDropdown);
10
- customElements.define("grantcodes-dropdown-item", GrantCodesDropdownItem);
11
-
12
-
9
+ if (!customElements.get("grantcodes-dropdown")) {
10
+ customElements.define("grantcodes-dropdown", GrantCodesDropdown);
11
+ }
12
+ if (!customElements.get("grantcodes-dropdown-item")) {
13
+ customElements.define("grantcodes-dropdown-item", GrantCodesDropdownItem);
14
+ }
@@ -23,8 +23,8 @@ export const dropdownStyles = css`
23
23
  anchor-name: --dropdown-trigger;
24
24
  z-index: 1000;
25
25
  min-inline-size: 12rem;
26
- margin-block: 0.25rem;
27
- padding-block: 0.5rem;
26
+ margin-block: var(--g-theme-spacing-xs);
27
+ padding-block: var(--g-theme-spacing-sm);
28
28
  background-color: var(--g-theme-color-background-default);
29
29
  border: 1px solid var(--g-theme-color-border-default);
30
30
  border-radius: var(--g-theme-border-radius-md);
@@ -53,9 +53,9 @@ export const dropdownStyles = css`
53
53
  display: flex;
54
54
  width: 100%;
55
55
  align-items: center;
56
- gap: 0.5rem;
57
- padding-block: 0.5rem;
58
- padding-inline: 1rem;
56
+ gap: var(--g-theme-spacing-sm);
57
+ padding-block: var(--g-theme-spacing-sm);
58
+ padding-inline: var(--g-theme-spacing-md);
59
59
  font-size: var(--g-typography-font-size-16);
60
60
  color: var(--g-theme-color-content-default);
61
61
  cursor: pointer;
@@ -23,7 +23,11 @@ describe("Dropdown Component", () => {
23
23
 
24
24
  it("should have bottom-start placement by default", async () => {
25
25
  element = await fixture("grantcodes-dropdown");
26
- assert.strictEqual(element.placement, "bottom-start", "Default placement should be bottom-start");
26
+ assert.strictEqual(
27
+ element.placement,
28
+ "bottom-start",
29
+ "Default placement should be bottom-start",
30
+ );
27
31
  });
28
32
 
29
33
  it("should have trigger slot", async () => {
@@ -47,7 +51,11 @@ describe("Dropdown Component", () => {
47
51
  it("should have role=menu on menu", async () => {
48
52
  element = await fixture("grantcodes-dropdown");
49
53
  const menu = element.shadowRoot.querySelector(".dropdown__menu");
50
- assert.strictEqual(menu.getAttribute("role"), "menu", "Menu should have role");
54
+ assert.strictEqual(
55
+ menu.getAttribute("role"),
56
+ "menu",
57
+ "Menu should have role",
58
+ );
51
59
  });
52
60
 
53
61
  it("should apply placement class to menu", async () => {
@@ -85,7 +93,11 @@ describe("Dropdown Item Component", () => {
85
93
 
86
94
  it("should not be disabled by default", async () => {
87
95
  element = await fixture("grantcodes-dropdown-item");
88
- assert.strictEqual(element.disabled, false, "Should not be disabled by default");
96
+ assert.strictEqual(
97
+ element.disabled,
98
+ false,
99
+ "Should not be disabled by default",
100
+ );
89
101
  });
90
102
 
91
103
  it("should render with disabled class when disabled", async () => {
@@ -133,7 +145,11 @@ describe("Dropdown Item Component", () => {
133
145
 
134
146
  await element.updateComplete;
135
147
 
136
- assert.strictEqual(element.textContent, "Menu Item", "Slotted content should be rendered");
148
+ assert.strictEqual(
149
+ element.textContent,
150
+ "Menu Item",
151
+ "Slotted content should be rendered",
152
+ );
137
153
  });
138
154
 
139
155
  it("should have dropdown-item wrapper", async () => {
@@ -1,3 +1 @@
1
1
  export * from "./dropdown.js";
2
-
3
-
@@ -97,7 +97,7 @@ export class GrantCodesDropzone extends LitElement {
97
97
  super.disconnectedCallback();
98
98
  }
99
99
 
100
- firstUpdated() {
100
+ firstUpdated() {
101
101
  // Find input elements in the slot
102
102
  const slot = this.renderRoot.querySelector("slot");
103
103
  if (slot) {
@@ -108,11 +108,12 @@ export class GrantCodesDropzone extends LitElement {
108
108
  }
109
109
 
110
110
  if (this._input.length === 0) {
111
- // In unit tests, allow rendering without an input to reduce friction
112
- const isTestEnv = typeof process !== "undefined" && process?.env?.NODE_ENV === "test";
113
- if (!isTestEnv) {
114
- throw new Error("No file input found");
115
- }
111
+ // In unit tests, allow rendering without an input to reduce friction
112
+ const isTestEnv =
113
+ typeof process !== "undefined" && process?.env?.NODE_ENV === "test";
114
+ if (!isTestEnv) {
115
+ throw new Error("No file input found");
116
+ }
116
117
  this._placeholder = "";
117
118
  return;
118
119
  }
@@ -17,7 +17,7 @@ export const dropzoneStyles = css`
17
17
  flex-direction: column;
18
18
  align-items: center;
19
19
  justify-content: center;
20
- padding: 2rem;
20
+ padding: var(--g-theme-spacing-xl);
21
21
  border: max(var(--g-theme-border-width-md), 0.2rem) dashed var(--g-theme-color-border-default);
22
22
  border-radius: var(--g-theme-border-radius-md);
23
23
  background-color: var(--g-theme-color-background-subtle);
@@ -34,14 +34,14 @@ export const dropzoneStyles = css`
34
34
  content: '';
35
35
  display: flex;
36
36
  position: fixed;
37
- inset: 2rem;
37
+ inset: var(--g-theme-spacing-xl);
38
38
  justify-content: center;
39
39
  align-items: center;
40
- padding: 2rem;
40
+ padding: var(--g-theme-spacing-xl);
41
41
  border: max(calc(var(--g-theme-border-width-md) * 2), 0.4rem) dashed var(--g-theme-color-border-default);
42
42
  border-radius: calc(var(--g-theme-border-radius-md) * 2);
43
43
  z-index: 11;
44
- font-weight: bold;
44
+ font-weight: var(--g-typography-font-weight-700);
45
45
  color: inherit;
46
46
  }
47
47
 
@@ -52,7 +52,9 @@ describe("Dropzone Component", () => {
52
52
  input.placeholder = "Drop files here";
53
53
  element.appendChild(input);
54
54
  await element.updateComplete;
55
- const placeholder = element.shadowRoot.querySelector(".dropzone__placeholder");
55
+ const placeholder = element.shadowRoot.querySelector(
56
+ ".dropzone__placeholder",
57
+ );
56
58
  assert.ok(placeholder, "Placeholder element should exist");
57
59
  });
58
60
 
@@ -103,10 +105,10 @@ describe("Dropzone Component", () => {
103
105
 
104
106
  await element.updateComplete;
105
107
 
106
- const placeholder = element.shadowRoot.querySelector(".dropzone__placeholder");
108
+ const placeholder = element.shadowRoot.querySelector(
109
+ ".dropzone__placeholder",
110
+ );
107
111
  // The placeholder text is set from the input's placeholder in firstUpdated
108
112
  assert.ok(placeholder, "Placeholder should exist");
109
113
  });
110
114
  });
111
-
112
-
@@ -1 +1 @@
1
- export * from "./dropzone";
1
+ export * from "./dropzone.js";