@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,123 +1,123 @@
1
- import { getStorybookHelpers } from "@wc-toolkit/storybook-helpers";
2
- import "./pricing.js";
1
+ import { getStorybookHelpers } from '@wc-toolkit/storybook-helpers';
2
+ import './pricing.js';
3
3
 
4
- const { events, args, argTypes } = getStorybookHelpers("grantcodes-pricing");
4
+ const { events, args, argTypes } = getStorybookHelpers('grantcodes-pricing');
5
5
 
6
6
  const meta = {
7
- title: "Blocks/Pricing",
8
- component: "grantcodes-pricing",
9
- args,
10
- argTypes,
11
- parameters: {
12
- actions: {
13
- handles: events,
14
- },
15
- layout: "fullscreen",
16
- },
7
+ title: 'Blocks/Pricing',
8
+ component: 'grantcodes-pricing',
9
+ args,
10
+ argTypes,
11
+ parameters: {
12
+ actions: {
13
+ handles: events,
14
+ },
15
+ layout: 'fullscreen',
16
+ },
17
17
  };
18
18
 
19
19
  export default meta;
20
20
 
21
21
  const tiers = JSON.stringify([
22
- {
23
- name: "Starter",
24
- price: "$0",
25
- period: "month",
26
- description: "Perfect for side projects and open source.",
27
- features: [
28
- { text: "5 projects", included: true },
29
- { text: "Community support", included: true },
30
- { text: "Basic analytics", included: true },
31
- { text: "Custom domain", included: false },
32
- { text: "Priority support", included: false },
33
- ],
34
- cta: { label: "Get started free", href: "/signup" },
35
- highlighted: false,
36
- },
37
- {
38
- name: "Pro",
39
- price: "$19",
40
- period: "month",
41
- description: "Everything you need for a growing team.",
42
- features: [
43
- { text: "Unlimited projects", included: true },
44
- { text: "Priority support", included: true },
45
- { text: "Advanced analytics", included: true },
46
- { text: "Custom domain", included: true },
47
- { text: "SLA guarantee", included: false },
48
- ],
49
- cta: { label: "Start free trial", href: "/signup?plan=pro" },
50
- highlighted: true,
51
- },
52
- {
53
- name: "Enterprise",
54
- price: "$99",
55
- period: "month",
56
- description: "Dedicated support and compliance features.",
57
- features: [
58
- { text: "Unlimited projects", included: true },
59
- { text: "Dedicated support", included: true },
60
- { text: "Advanced analytics", included: true },
61
- { text: "Custom domain", included: true },
62
- { text: "SLA guarantee", included: true },
63
- ],
64
- cta: { label: "Contact sales", href: "/contact" },
65
- highlighted: false,
66
- },
22
+ {
23
+ name: 'Starter',
24
+ price: '$0',
25
+ period: 'month',
26
+ description: 'Perfect for side projects and open source.',
27
+ features: [
28
+ { text: '5 projects', included: true },
29
+ { text: 'Community support', included: true },
30
+ { text: 'Basic analytics', included: true },
31
+ { text: 'Custom domain', included: false },
32
+ { text: 'Priority support', included: false },
33
+ ],
34
+ cta: { label: 'Get started free', href: '/signup' },
35
+ highlighted: false,
36
+ },
37
+ {
38
+ name: 'Pro',
39
+ price: '$19',
40
+ period: 'month',
41
+ description: 'Everything you need for a growing team.',
42
+ features: [
43
+ { text: 'Unlimited projects', included: true },
44
+ { text: 'Priority support', included: true },
45
+ { text: 'Advanced analytics', included: true },
46
+ { text: 'Custom domain', included: true },
47
+ { text: 'SLA guarantee', included: false },
48
+ ],
49
+ cta: { label: 'Start free trial', href: '/signup?plan=pro' },
50
+ highlighted: true,
51
+ },
52
+ {
53
+ name: 'Enterprise',
54
+ price: '$99',
55
+ period: 'month',
56
+ description: 'Dedicated support and compliance features.',
57
+ features: [
58
+ { text: 'Unlimited projects', included: true },
59
+ { text: 'Dedicated support', included: true },
60
+ { text: 'Advanced analytics', included: true },
61
+ { text: 'Custom domain', included: true },
62
+ { text: 'SLA guarantee', included: true },
63
+ ],
64
+ cta: { label: 'Contact sales', href: '/contact' },
65
+ highlighted: false,
66
+ },
67
67
  ]);
68
68
 
69
69
  /**
70
70
  * Three-tier pricing with one highlighted plan.
71
71
  */
72
72
  export const Default = {
73
- args: {
74
- title: "Simple, transparent pricing",
75
- subtitle: "No hidden fees. Cancel any time.",
76
- tiers,
77
- },
73
+ args: {
74
+ title: 'Simple, transparent pricing',
75
+ subtitle: 'No hidden fees. Cancel any time.',
76
+ tiers,
77
+ },
78
78
  };
79
79
 
80
80
  /**
81
81
  * Pricing without the section heading.
82
82
  */
83
83
  export const NoHeading = {
84
- args: {
85
- tiers,
86
- },
84
+ args: {
85
+ tiers,
86
+ },
87
87
  };
88
88
 
89
89
  /**
90
90
  * Two-tier pricing — free vs paid.
91
91
  */
92
92
  export const TwoTiers = {
93
- args: {
94
- title: "Choose a plan",
95
- tiers: JSON.stringify([
96
- {
97
- name: "Free",
98
- price: "$0",
99
- description: "Get started at no cost.",
100
- features: [
101
- { text: "3 projects", included: true },
102
- { text: "Community support", included: true },
103
- { text: "Custom domain", included: false },
104
- ],
105
- cta: { label: "Sign up free", href: "/signup" },
106
- highlighted: false,
107
- },
108
- {
109
- name: "Paid",
110
- price: "$9",
111
- period: "month",
112
- description: "Unlock the full platform.",
113
- features: [
114
- { text: "Unlimited projects", included: true },
115
- { text: "Email support", included: true },
116
- { text: "Custom domain", included: true },
117
- ],
118
- cta: { label: "Upgrade", href: "/upgrade" },
119
- highlighted: true,
120
- },
121
- ]),
122
- },
93
+ args: {
94
+ title: 'Choose a plan',
95
+ tiers: JSON.stringify([
96
+ {
97
+ name: 'Free',
98
+ price: '$0',
99
+ description: 'Get started at no cost.',
100
+ features: [
101
+ { text: '3 projects', included: true },
102
+ { text: 'Community support', included: true },
103
+ { text: 'Custom domain', included: false },
104
+ ],
105
+ cta: { label: 'Sign up free', href: '/signup' },
106
+ highlighted: false,
107
+ },
108
+ {
109
+ name: 'Paid',
110
+ price: '$9',
111
+ period: 'month',
112
+ description: 'Unlock the full platform.',
113
+ features: [
114
+ { text: 'Unlimited projects', included: true },
115
+ { text: 'Email support', included: true },
116
+ { text: 'Custom domain', included: true },
117
+ ],
118
+ cta: { label: 'Upgrade', href: '/upgrade' },
119
+ highlighted: true,
120
+ },
121
+ ]),
122
+ },
123
123
  };
@@ -1 +1 @@
1
- export * from "./sidebar.js";
1
+ export * from './sidebar.js';
@@ -1,143 +1,170 @@
1
- import { html, LitElement } from "lit";
2
- import { classMap } from "lit/directives/class-map.js";
3
- import focusRingStyles from "../../lib/styles/focus-ring.css" with {
4
- type: "css",
5
- };
6
- import sidebarStyles from "./sidebar.css" with { type: "css" };
1
+ import { html, LitElement } from 'lit';
2
+ import { classMap } from 'lit/directives/class-map.js';
3
+ import { generateId } from '../../lib/generate-id.js';
4
+ import focusRingStyles from '../../lib/styles/focus-ring.css' with { type: 'css' };
5
+ import { startViewTransition } from '../../lib/view-transition.js';
6
+ import sidebarStyles from './sidebar.css' with { type: 'css' };
7
7
 
8
8
  export class GrantCodesSidebar extends LitElement {
9
- static styles = [focusRingStyles, sidebarStyles];
10
-
11
- static properties = {
12
- position: { type: String },
13
- collapsed: { type: Boolean, reflect: true },
14
- collapsible: { type: Boolean },
15
- width: { type: String },
16
- _drawerOpen: { type: Boolean, state: true },
17
- };
18
-
19
- constructor() {
20
- super();
21
-
22
- /**
23
- * Position of the sidebar
24
- * @type {'left' | 'right'}
25
- */
26
- this.position = "left";
27
-
28
- /**
29
- * Whether the sidebar is collapsed on desktop
30
- * @type {boolean}
31
- */
32
- this.collapsed = false;
33
-
34
- /**
35
- * Whether the sidebar can be collapsed
36
- * @type {boolean}
37
- */
38
- this.collapsible = true;
39
-
40
- /**
41
- * Custom width of the sidebar
42
- * @type {string}
43
- */
44
- this.width = "280px";
45
-
46
- /**
47
- * Whether mobile drawer is open
48
- * @type {boolean}
49
- */
50
- this._drawerOpen = false;
51
-
52
- this._handleDocumentClick = this._handleDocumentClick.bind(this);
53
- this._handleEscape = this._handleEscape.bind(this);
54
- }
55
-
56
- connectedCallback() {
57
- super.connectedCallback();
58
- if (typeof document === "undefined") return;
59
- document.addEventListener("click", this._handleDocumentClick);
60
- document.addEventListener("keydown", this._handleEscape);
61
- }
62
-
63
- disconnectedCallback() {
64
- document.removeEventListener("click", this._handleDocumentClick);
65
- document.removeEventListener("keydown", this._handleEscape);
66
- super.disconnectedCallback();
67
- }
68
-
69
- _handleDocumentClick(e) {
70
- // Close mobile drawer if clicking outside
71
- if (this._drawerOpen) {
72
- const path = e.composedPath();
73
- if (!path.includes(this)) {
74
- this._drawerOpen = false;
75
- }
76
- }
77
- }
78
-
79
- _handleEscape(e) {
80
- if (e.key === "Escape" && this._drawerOpen) {
81
- this._drawerOpen = false;
82
- }
83
- }
84
-
85
- _toggleCollapsed() {
86
- if (!this.collapsible) return;
87
-
88
- this.collapsed = !this.collapsed;
89
- this.dispatchEvent(
90
- new CustomEvent("toggle", {
91
- detail: { collapsed: this.collapsed },
92
- bubbles: true,
93
- composed: true,
94
- }),
95
- );
96
- }
97
-
98
- _toggleDrawer() {
99
- this._drawerOpen = !this._drawerOpen;
100
- this.dispatchEvent(
101
- new CustomEvent("drawer-toggle", {
102
- detail: { open: this._drawerOpen },
103
- bubbles: true,
104
- composed: true,
105
- }),
106
- );
107
- }
108
-
109
- render() {
110
- const sidebarClasses = classMap({
111
- sidebar: true,
112
- "sidebar--collapsed": this.collapsed,
113
- [`sidebar--${this.position}`]: true,
114
- "sidebar--drawer-open": this._drawerOpen,
115
- });
116
-
117
- return html`
9
+ static styles = [focusRingStyles, sidebarStyles];
10
+
11
+ static properties = {
12
+ position: { type: String },
13
+ collapsed: { type: Boolean, reflect: true },
14
+ collapsible: { type: Boolean },
15
+ width: { type: String },
16
+ _drawerOpen: { type: Boolean, state: true },
17
+ };
18
+
19
+ constructor() {
20
+ super();
21
+
22
+ /**
23
+ * Position of the sidebar
24
+ * @type {'left' | 'right'}
25
+ */
26
+ this.position = 'left';
27
+
28
+ /**
29
+ * Whether the sidebar is collapsed on desktop
30
+ * @type {boolean}
31
+ */
32
+ this.collapsed = false;
33
+
34
+ /**
35
+ * Whether the sidebar can be collapsed
36
+ * @type {boolean}
37
+ */
38
+ this.collapsible = true;
39
+
40
+ /**
41
+ * Custom width of the sidebar
42
+ * @type {string}
43
+ */
44
+ this.width = '280px';
45
+
46
+ /**
47
+ * Whether mobile drawer is open
48
+ * @type {boolean}
49
+ */
50
+ this._drawerOpen = false;
51
+
52
+ // Per-instance, so two sidebars cannot abort each other's view transition.
53
+ this._viewTransitionName = generateId('sidebar-vt');
54
+ this._pendingState = {};
55
+ this._transitionScheduled = false;
56
+
57
+ this._handleDocumentClick = this._handleDocumentClick.bind(this);
58
+ this._handleEscape = this._handleEscape.bind(this);
59
+ }
60
+
61
+ connectedCallback() {
62
+ super.connectedCallback();
63
+ this.style.setProperty('--sidebar-vt-name', this._viewTransitionName);
64
+ if (typeof document === 'undefined') return;
65
+ document.addEventListener('click', this._handleDocumentClick);
66
+ document.addEventListener('keydown', this._handleEscape);
67
+ }
68
+
69
+ disconnectedCallback() {
70
+ document.removeEventListener('click', this._handleDocumentClick);
71
+ document.removeEventListener('keydown', this._handleEscape);
72
+ super.disconnectedCallback();
73
+ }
74
+
75
+ _handleDocumentClick(e) {
76
+ // Close mobile drawer if clicking outside
77
+ if (this._pendingState._drawerOpen ?? this._drawerOpen) {
78
+ const path = e.composedPath();
79
+ if (!path.includes(this)) {
80
+ this._closeDrawer();
81
+ }
82
+ }
83
+ }
84
+
85
+ _handleEscape(e) {
86
+ if (e.key === 'Escape' && (this._pendingState._drawerOpen ?? this._drawerOpen)) {
87
+ this._closeDrawer();
88
+ }
89
+ }
90
+
91
+ _scheduleTransition() {
92
+ if (this._transitionScheduled) return;
93
+ this._transitionScheduled = true;
94
+ startViewTransition(() => {
95
+ const pending = this._pendingState;
96
+ this._pendingState = {};
97
+ this._transitionScheduled = false;
98
+ if ('collapsed' in pending) this.collapsed = pending.collapsed;
99
+ if ('_drawerOpen' in pending) this._drawerOpen = pending._drawerOpen;
100
+ return this.updateComplete;
101
+ });
102
+ }
103
+
104
+ _closeDrawer() {
105
+ if (!(this._pendingState._drawerOpen ?? this._drawerOpen)) return;
106
+ this._pendingState._drawerOpen = false;
107
+ this._scheduleTransition();
108
+ }
109
+
110
+ _toggleCollapsed() {
111
+ if (!this.collapsible) return;
112
+
113
+ const collapsed = !(this._pendingState.collapsed ?? this.collapsed);
114
+ this._pendingState.collapsed = collapsed;
115
+ this._scheduleTransition();
116
+ this.dispatchEvent(
117
+ new CustomEvent('toggle', {
118
+ detail: { collapsed },
119
+ bubbles: true,
120
+ composed: true,
121
+ }),
122
+ );
123
+ }
124
+
125
+ _toggleDrawer() {
126
+ const open = !(this._pendingState._drawerOpen ?? this._drawerOpen);
127
+ this._pendingState._drawerOpen = open;
128
+ this._scheduleTransition();
129
+ this.dispatchEvent(
130
+ new CustomEvent('drawer-toggle', {
131
+ detail: { open },
132
+ bubbles: true,
133
+ composed: true,
134
+ }),
135
+ );
136
+ }
137
+
138
+ render() {
139
+ const sidebarClasses = classMap({
140
+ sidebar: true,
141
+ 'sidebar--collapsed': this.collapsed,
142
+ [`sidebar--${this.position}`]: true,
143
+ 'sidebar--drawer-open': this._drawerOpen,
144
+ });
145
+
146
+ return html`
118
147
  <!-- Mobile Toggle Button -->
119
148
  <button
120
149
  type="button"
121
150
  class="sidebar__mobile-toggle focus-ring"
122
151
  @click=${this._toggleDrawer}
123
- aria-label="${this._drawerOpen ? "Close sidebar" : "Open sidebar"}"
152
+ aria-label="${this._drawerOpen ? 'Close sidebar' : 'Open sidebar'}"
124
153
  >
125
154
  ☰
126
155
  </button>
127
156
 
128
157
  <!-- Overlay for mobile -->
129
158
  ${
130
- this._drawerOpen
131
- ? html`
159
+ this._drawerOpen
160
+ ? html`
132
161
  <div
133
162
  class="sidebar__overlay"
134
- @click=${() => {
135
- this._drawerOpen = false;
136
- }}
163
+ @click=${this._closeDrawer}
137
164
  ></div>
138
165
  `
139
- : ""
140
- }
166
+ : ''
167
+ }
141
168
 
142
169
  <!-- Sidebar -->
143
170
  <aside
@@ -146,20 +173,20 @@ export class GrantCodesSidebar extends LitElement {
146
173
  >
147
174
  <!-- Collapse Toggle (Desktop) -->
148
175
  ${
149
- this.collapsible
150
- ? html`
176
+ this.collapsible
177
+ ? html`
151
178
  <button
152
179
  type="button"
153
180
  class="sidebar__toggle focus-ring"
154
181
  @click=${this._toggleCollapsed}
155
- aria-label="${this.collapsed ? "Expand sidebar" : "Collapse sidebar"}"
182
+ aria-label="${this.collapsed ? 'Expand sidebar' : 'Collapse sidebar'}"
156
183
  aria-expanded="${!this.collapsed}"
157
184
  >
158
- ${this.position === "left" ? (this.collapsed ? "→" : "←") : this.collapsed ? "←" : "→"}
185
+ ${this.position === 'left' ? (this.collapsed ? '→' : '←') : this.collapsed ? '←' : '→'}
159
186
  </button>
160
187
  `
161
- : ""
162
- }
188
+ : ''
189
+ }
163
190
 
164
191
  <!-- Content -->
165
192
  <div class="sidebar__content">
@@ -167,5 +194,5 @@ export class GrantCodesSidebar extends LitElement {
167
194
  </div>
168
195
  </aside>
169
196
  `;
170
- }
197
+ }
171
198
  }