@getmicdrop/svelte-components 5.5.1 → 5.5.5

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 (472) hide show
  1. package/dist/calendar/AboutShow/AboutShow.spec.d.ts +2 -0
  2. package/dist/calendar/AboutShow/AboutShow.spec.d.ts.map +1 -0
  3. package/dist/calendar/AboutShow/AboutShow.spec.js +791 -0
  4. package/dist/calendar/AboutShow/AboutShow.svelte +172 -172
  5. package/dist/calendar/Calendar/MiniMonthCalendar.spec.d.ts +2 -0
  6. package/dist/calendar/Calendar/MiniMonthCalendar.spec.d.ts.map +1 -0
  7. package/dist/calendar/Calendar/MiniMonthCalendar.spec.js +1191 -0
  8. package/dist/calendar/Calendar/MiniMonthCalendar.svelte +782 -782
  9. package/dist/calendar/FAQs/FAQs.spec.d.ts +2 -0
  10. package/dist/calendar/FAQs/FAQs.spec.d.ts.map +1 -0
  11. package/dist/calendar/FAQs/FAQs.spec.js +238 -0
  12. package/dist/calendar/FAQs/FAQs.svelte +75 -75
  13. package/dist/calendar/MonthSwitcher/MonthSwitcher.spec.d.ts +2 -0
  14. package/dist/calendar/MonthSwitcher/MonthSwitcher.spec.d.ts.map +1 -0
  15. package/dist/calendar/MonthSwitcher/MonthSwitcher.spec.js +420 -0
  16. package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +126 -126
  17. package/dist/calendar/OrderSummary/OrderSummary.spec.d.ts +2 -0
  18. package/dist/calendar/OrderSummary/OrderSummary.spec.d.ts.map +1 -0
  19. package/dist/calendar/OrderSummary/OrderSummary.spec.js +808 -0
  20. package/dist/calendar/OrderSummary/OrderSummary.svelte +367 -367
  21. package/dist/calendar/PublicCard/PublicCard.spec.d.ts +2 -0
  22. package/dist/calendar/PublicCard/PublicCard.spec.d.ts.map +1 -0
  23. package/dist/calendar/PublicCard/PublicCard.spec.js +301 -0
  24. package/dist/calendar/PublicCard/PublicCard.svelte +134 -134
  25. package/dist/calendar/ShowCard/ShowCard.spec.d.ts +2 -0
  26. package/dist/calendar/ShowCard/ShowCard.spec.d.ts.map +1 -0
  27. package/dist/calendar/ShowCard/ShowCard.spec.js +714 -0
  28. package/dist/calendar/ShowCard/ShowCard.svelte +157 -157
  29. package/dist/calendar/ShowTimeCard/ShowTimeCard.spec.d.ts +2 -0
  30. package/dist/calendar/ShowTimeCard/ShowTimeCard.spec.d.ts.map +1 -0
  31. package/dist/calendar/ShowTimeCard/ShowTimeCard.spec.js +241 -0
  32. package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +61 -61
  33. package/dist/components/Layout/Grid.svelte +4 -4
  34. package/dist/components/Layout/Section.spec.d.ts +2 -0
  35. package/dist/components/Layout/Section.spec.d.ts.map +1 -0
  36. package/dist/components/Layout/Section.spec.js +149 -0
  37. package/dist/components/Layout/Section.svelte +80 -80
  38. package/dist/components/Layout/Sidebar.spec.d.ts +2 -0
  39. package/dist/components/Layout/Sidebar.spec.d.ts.map +1 -0
  40. package/dist/components/Layout/Sidebar.spec.js +186 -0
  41. package/dist/components/Layout/Sidebar.svelte +108 -108
  42. package/dist/components/Layout/Stack.spec.js +3 -3
  43. package/dist/components/Layout/Stack.svelte +6 -6
  44. package/dist/constants/formOptions.spec.js +9 -5
  45. package/dist/constants/validation.js +91 -91
  46. package/dist/constants/validation.spec.js +64 -64
  47. package/dist/datetime/__tests__/format.test.js +1 -1
  48. package/dist/datetime/__tests__/parse.test.js +1 -1
  49. package/dist/datetime/__tests__/timezone.test.js +124 -2
  50. package/dist/datetime/parse.js +1 -1
  51. package/dist/forms/createFieldTracker.spec.d.ts +2 -0
  52. package/dist/forms/createFieldTracker.spec.d.ts.map +1 -0
  53. package/dist/forms/createFieldTracker.spec.js +343 -0
  54. package/dist/forms/createFormStore.spec.d.ts +2 -0
  55. package/dist/forms/createFormStore.spec.d.ts.map +1 -0
  56. package/dist/forms/createFormStore.spec.js +689 -0
  57. package/dist/forms/createFormStore.svelte.js +0 -1
  58. package/dist/index.d.ts +5 -112
  59. package/dist/index.js +40 -225
  60. package/dist/patterns/data/DataGrid.spec.d.ts +2 -0
  61. package/dist/patterns/data/DataGrid.spec.d.ts.map +1 -0
  62. package/dist/patterns/data/DataGrid.spec.js +159 -0
  63. package/dist/patterns/data/DataGrid.svelte +45 -45
  64. package/dist/patterns/data/DataList.spec.d.ts +2 -0
  65. package/dist/patterns/data/DataList.spec.d.ts.map +1 -0
  66. package/dist/patterns/data/DataList.spec.js +158 -0
  67. package/dist/patterns/data/DataList.svelte +24 -24
  68. package/dist/patterns/data/DataTable.spec.d.ts +2 -0
  69. package/dist/patterns/data/DataTable.spec.d.ts.map +1 -0
  70. package/dist/patterns/data/DataTable.spec.js +196 -0
  71. package/dist/patterns/data/DataTable.svelte +36 -36
  72. package/dist/patterns/forms/FormActions.spec.js +95 -88
  73. package/dist/patterns/forms/FormActions.stories.svelte +97 -97
  74. package/dist/patterns/forms/FormActions.svelte +46 -46
  75. package/dist/patterns/forms/FormGrid.spec.d.ts +2 -0
  76. package/dist/patterns/forms/FormGrid.spec.d.ts.map +1 -0
  77. package/dist/patterns/forms/FormGrid.spec.js +125 -0
  78. package/dist/patterns/forms/FormGrid.svelte +33 -33
  79. package/dist/patterns/forms/FormSection.spec.d.ts +2 -0
  80. package/dist/patterns/forms/FormSection.spec.d.ts.map +1 -0
  81. package/dist/patterns/forms/FormSection.spec.js +153 -0
  82. package/dist/patterns/forms/FormSection.svelte +32 -32
  83. package/dist/patterns/forms/FormValidationSummary.stories.svelte +83 -83
  84. package/dist/patterns/forms/FormValidationSummary.svelte +33 -33
  85. package/dist/patterns/layout/Sidebar.spec.d.ts +2 -0
  86. package/dist/patterns/layout/Sidebar.spec.d.ts.map +1 -0
  87. package/dist/patterns/layout/Sidebar.spec.js +159 -0
  88. package/dist/patterns/layout/Sidebar.svelte +39 -39
  89. package/dist/patterns/navigation/BottomNav.stories.svelte +117 -117
  90. package/dist/patterns/navigation/BottomNav.svelte +20 -20
  91. package/dist/patterns/navigation/Header.spec.js +33 -24
  92. package/dist/patterns/navigation/Header.stories.svelte +77 -77
  93. package/dist/patterns/navigation/Header.svelte +193 -193
  94. package/dist/patterns/page/PageHeader.spec.d.ts +2 -0
  95. package/dist/patterns/page/PageHeader.spec.d.ts.map +1 -0
  96. package/dist/patterns/page/PageHeader.spec.js +167 -0
  97. package/dist/patterns/page/PageHeader.svelte +18 -18
  98. package/dist/patterns/page/PageLayout.spec.d.ts +2 -0
  99. package/dist/patterns/page/PageLayout.spec.d.ts.map +1 -0
  100. package/dist/patterns/page/PageLayout.spec.js +145 -0
  101. package/dist/patterns/page/PageLayout.svelte +40 -40
  102. package/dist/patterns/page/PageLoader.spec.js +57 -54
  103. package/dist/patterns/page/PageLoader.stories.svelte +137 -137
  104. package/dist/patterns/page/PageLoader.svelte +24 -24
  105. package/dist/patterns/page/SectionHeader.spec.d.ts +2 -0
  106. package/dist/patterns/page/SectionHeader.spec.d.ts.map +1 -0
  107. package/dist/patterns/page/SectionHeader.spec.js +197 -0
  108. package/dist/patterns/page/SectionHeader.svelte +29 -29
  109. package/dist/presets/badges.js +112 -112
  110. package/dist/presets/badges.spec.d.ts +2 -0
  111. package/dist/presets/badges.spec.d.ts.map +1 -0
  112. package/dist/presets/badges.spec.js +172 -0
  113. package/dist/presets/buttons.js +76 -76
  114. package/dist/presets/buttons.spec.d.ts +2 -0
  115. package/dist/presets/buttons.spec.d.ts.map +1 -0
  116. package/dist/presets/buttons.spec.js +135 -0
  117. package/dist/presets/index.js +9 -9
  118. package/dist/primitives/Accordion/Accordion.spec.d.ts +2 -0
  119. package/dist/primitives/Accordion/Accordion.spec.d.ts.map +1 -0
  120. package/dist/primitives/Accordion/Accordion.spec.js +83 -0
  121. package/dist/primitives/Accordion/Accordion.stories.svelte +75 -75
  122. package/dist/primitives/Accordion/Accordion.svelte +42 -42
  123. package/dist/primitives/Accordion/AccordionItem.spec.d.ts +2 -0
  124. package/dist/primitives/Accordion/AccordionItem.spec.d.ts.map +1 -0
  125. package/dist/primitives/Accordion/AccordionItem.spec.js +661 -0
  126. package/dist/primitives/Accordion/AccordionItem.svelte +95 -95
  127. package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte +107 -0
  128. package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte.d.ts +35 -0
  129. package/dist/primitives/Accordion/AccordionItemWrapper.test.svelte.d.ts.map +1 -0
  130. package/dist/primitives/Alert/Alert.spec.js +173 -170
  131. package/dist/primitives/Alert/Alert.stories.svelte +88 -88
  132. package/dist/primitives/Alert/Alert.svelte +27 -27
  133. package/dist/primitives/Avatar/Avatar.spec.d.ts +2 -0
  134. package/dist/primitives/Avatar/Avatar.spec.d.ts.map +1 -0
  135. package/dist/primitives/Avatar/Avatar.spec.js +211 -0
  136. package/dist/primitives/Avatar/Avatar.stories.svelte +94 -94
  137. package/dist/primitives/Avatar/Avatar.svelte +66 -66
  138. package/dist/primitives/Badges/Badge.spec.js +144 -103
  139. package/dist/primitives/Badges/Badge.stories.svelte +86 -86
  140. package/dist/primitives/Badges/Badge.svelte +79 -79
  141. package/dist/primitives/BottomSheet/BottomSheet.spec.js +136 -127
  142. package/dist/primitives/BottomSheet/BottomSheet.stories.svelte +83 -83
  143. package/dist/primitives/BottomSheet/BottomSheet.svelte +100 -100
  144. package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte +13 -0
  145. package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte.d.ts +7 -0
  146. package/dist/primitives/BottomSheet/BottomSheetWrapper.test.svelte.d.ts.map +1 -0
  147. package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +122 -120
  148. package/dist/primitives/Breadcrumb/Breadcrumb.stories.svelte +23 -23
  149. package/dist/primitives/Breadcrumb/Breadcrumb.svelte +89 -89
  150. package/dist/primitives/Button/Button.spec.js +223 -211
  151. package/dist/primitives/Button/Button.stories.svelte +76 -76
  152. package/dist/primitives/Button/Button.svelte +270 -270
  153. package/dist/primitives/Button/ButtonSaveDemo.spec.js +146 -48
  154. package/dist/primitives/Button/ButtonSaveDemo.svelte +25 -25
  155. package/dist/primitives/Button/ButtonVariantShowcase.spec.d.ts +2 -0
  156. package/dist/primitives/Button/ButtonVariantShowcase.spec.d.ts.map +1 -0
  157. package/dist/primitives/Button/ButtonVariantShowcase.spec.js +202 -0
  158. package/dist/primitives/Button/ButtonVariantShowcase.svelte +129 -129
  159. package/dist/primitives/Card.spec.js +49 -49
  160. package/dist/primitives/Card.stories.svelte +22 -22
  161. package/dist/primitives/Card.svelte +28 -28
  162. package/dist/primitives/Checkbox/Checkbox.spec.d.ts +2 -0
  163. package/dist/primitives/Checkbox/Checkbox.spec.d.ts.map +1 -0
  164. package/dist/primitives/Checkbox/Checkbox.spec.js +252 -0
  165. package/dist/primitives/Checkbox/Checkbox.stories.svelte +84 -84
  166. package/dist/primitives/Checkbox/Checkbox.svelte +88 -88
  167. package/dist/primitives/DarkModeToggle.spec.js +390 -357
  168. package/dist/primitives/DarkModeToggle.stories.svelte +57 -57
  169. package/dist/primitives/DarkModeToggle.svelte +136 -136
  170. package/dist/primitives/Drawer/Drawer.spec.d.ts +2 -0
  171. package/dist/primitives/Drawer/Drawer.spec.d.ts.map +1 -0
  172. package/dist/primitives/Drawer/Drawer.spec.js +212 -0
  173. package/dist/primitives/Drawer/Drawer.stories.svelte +80 -80
  174. package/dist/primitives/Drawer/Drawer.svelte +120 -120
  175. package/dist/primitives/Dropdown/Dropdown.spec.d.ts +2 -0
  176. package/dist/primitives/Dropdown/Dropdown.spec.d.ts.map +1 -0
  177. package/dist/primitives/Dropdown/Dropdown.spec.js +366 -0
  178. package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -137
  179. package/dist/primitives/Dropdown/Dropdown.svelte +14 -14
  180. package/dist/primitives/Dropdown/DropdownItem.spec.d.ts +2 -0
  181. package/dist/primitives/Dropdown/DropdownItem.spec.d.ts.map +1 -0
  182. package/dist/primitives/Dropdown/DropdownItem.spec.js +182 -0
  183. package/dist/primitives/Dropdown/DropdownItem.svelte +80 -80
  184. package/dist/primitives/Icons/ArrowLeft.svelte +8 -8
  185. package/dist/primitives/Icons/ArrowRight.svelte +8 -8
  186. package/dist/primitives/Icons/Availability.svelte +14 -14
  187. package/dist/primitives/Icons/Back.svelte +14 -14
  188. package/dist/primitives/Icons/CheckCircle.svelte +6 -6
  189. package/dist/primitives/Icons/CheckCircleOutline.svelte +15 -15
  190. package/dist/primitives/Icons/ChevronLeft.svelte +4 -4
  191. package/dist/primitives/Icons/ChevronRight.svelte +4 -4
  192. package/dist/primitives/Icons/Copy.svelte +15 -15
  193. package/dist/primitives/Icons/Cross.svelte +5 -5
  194. package/dist/primitives/Icons/DownArrow.svelte +8 -8
  195. package/dist/primitives/Icons/ErrorCircle.svelte +6 -6
  196. package/dist/primitives/Icons/FacebookIcon.svelte +2 -2
  197. package/dist/primitives/Icons/Home.svelte +15 -15
  198. package/dist/primitives/Icons/Icon.spec.js +169 -169
  199. package/dist/primitives/Icons/Icon.stories.svelte +100 -100
  200. package/dist/primitives/Icons/Icon.svelte +52 -52
  201. package/dist/primitives/Icons/IconGallery.stories.svelte +235 -235
  202. package/dist/primitives/Icons/Info.svelte +7 -7
  203. package/dist/primitives/Icons/InstagramIcon.svelte +4 -4
  204. package/dist/primitives/Icons/LogoInstagram.svelte +2 -2
  205. package/dist/primitives/Icons/Message.svelte +15 -15
  206. package/dist/primitives/Icons/MoonIcon.svelte +5 -5
  207. package/dist/primitives/Icons/More.svelte +21 -21
  208. package/dist/primitives/Icons/MoreHori.spec.js +61 -61
  209. package/dist/primitives/Icons/MoreHori.svelte +22 -22
  210. package/dist/primitives/Icons/Notification.svelte +14 -14
  211. package/dist/primitives/Icons/Payment.svelte +14 -14
  212. package/dist/primitives/Icons/Profile.svelte +21 -21
  213. package/dist/primitives/Icons/Reload.svelte +29 -29
  214. package/dist/primitives/Icons/Shows.svelte +21 -21
  215. package/dist/primitives/Icons/Signout.svelte +21 -21
  216. package/dist/primitives/Icons/SunIcon.svelte +8 -8
  217. package/dist/primitives/Icons/TiktokIcon.svelte +2 -2
  218. package/dist/primitives/Icons/TwitterIcon.svelte +2 -2
  219. package/dist/primitives/Icons/WarningIcon.spec.js +18 -18
  220. package/dist/primitives/Icons/WarningIcon.svelte +5 -5
  221. package/dist/primitives/Icons/iconTestUtils.spec.d.ts +2 -0
  222. package/dist/primitives/Icons/iconTestUtils.spec.d.ts.map +1 -0
  223. package/dist/primitives/Icons/iconTestUtils.spec.js +235 -0
  224. package/dist/primitives/Input/Input.spec.js +573 -573
  225. package/dist/primitives/Input/Input.stories.svelte +139 -139
  226. package/dist/primitives/Input/Input.svelte +384 -397
  227. package/dist/primitives/Input/Input.svelte.d.ts.map +1 -1
  228. package/dist/primitives/Input/Select.spec.js +212 -218
  229. package/dist/primitives/Input/Select.stories.svelte +112 -112
  230. package/dist/primitives/Input/Select.svelte +128 -128
  231. package/dist/primitives/Input/Textarea.spec.d.ts +2 -0
  232. package/dist/primitives/Input/Textarea.spec.d.ts.map +1 -0
  233. package/dist/primitives/Input/Textarea.spec.js +255 -0
  234. package/dist/primitives/Input/Textarea.stories.svelte +137 -137
  235. package/dist/primitives/Input/Textarea.svelte +35 -35
  236. package/dist/primitives/Label/Label.spec.d.ts +2 -0
  237. package/dist/primitives/Label/Label.spec.d.ts.map +1 -0
  238. package/dist/primitives/Label/Label.spec.js +157 -0
  239. package/dist/primitives/Label/Label.svelte +37 -37
  240. package/dist/primitives/Modal/Modal.spec.js +99 -95
  241. package/dist/primitives/Modal/Modal.stories.svelte +86 -86
  242. package/dist/primitives/Modal/Modal.svelte +158 -158
  243. package/dist/primitives/Modal/ModalTestWrapper.svelte +65 -0
  244. package/dist/primitives/Modal/ModalTestWrapper.svelte.d.ts +23 -0
  245. package/dist/primitives/Modal/ModalTestWrapper.svelte.d.ts.map +1 -0
  246. package/dist/primitives/NumberInput/NumberInput.spec.d.ts +2 -0
  247. package/dist/primitives/NumberInput/NumberInput.spec.d.ts.map +1 -0
  248. package/dist/primitives/NumberInput/NumberInput.spec.js +235 -0
  249. package/dist/primitives/NumberInput/NumberInput.svelte +106 -106
  250. package/dist/primitives/Pagination/Pagination.spec.d.ts +2 -0
  251. package/dist/primitives/Pagination/Pagination.spec.d.ts.map +1 -0
  252. package/dist/primitives/Pagination/Pagination.spec.js +266 -0
  253. package/dist/primitives/Pagination/Pagination.stories.svelte +76 -76
  254. package/dist/primitives/Pagination/Pagination.svelte +261 -261
  255. package/dist/primitives/Radio/Radio.spec.d.ts +2 -0
  256. package/dist/primitives/Radio/Radio.spec.d.ts.map +1 -0
  257. package/dist/primitives/Radio/Radio.spec.js +206 -0
  258. package/dist/primitives/Radio/Radio.stories.svelte +80 -80
  259. package/dist/primitives/Radio/Radio.svelte +67 -67
  260. package/dist/primitives/Skeleton/CardPlaceholder.spec.d.ts +2 -0
  261. package/dist/primitives/Skeleton/CardPlaceholder.spec.d.ts.map +1 -0
  262. package/dist/primitives/Skeleton/CardPlaceholder.spec.js +156 -0
  263. package/dist/primitives/Skeleton/CardPlaceholder.svelte +87 -87
  264. package/dist/primitives/Skeleton/ImagePlaceholder.spec.d.ts +2 -0
  265. package/dist/primitives/Skeleton/ImagePlaceholder.spec.d.ts.map +1 -0
  266. package/dist/primitives/Skeleton/ImagePlaceholder.spec.js +120 -0
  267. package/dist/primitives/Skeleton/ImagePlaceholder.svelte +59 -59
  268. package/dist/primitives/Skeleton/ListPlaceholder.spec.d.ts +2 -0
  269. package/dist/primitives/Skeleton/ListPlaceholder.spec.d.ts.map +1 -0
  270. package/dist/primitives/Skeleton/ListPlaceholder.spec.js +220 -0
  271. package/dist/primitives/Skeleton/ListPlaceholder.svelte +76 -76
  272. package/dist/primitives/Skeleton/Skeleton.spec.d.ts +2 -0
  273. package/dist/primitives/Skeleton/Skeleton.spec.d.ts.map +1 -0
  274. package/dist/primitives/Skeleton/Skeleton.spec.js +173 -0
  275. package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -151
  276. package/dist/primitives/Skeleton/Skeleton.svelte +26 -26
  277. package/dist/primitives/Spinner/Spinner.spec.js +71 -75
  278. package/dist/primitives/Spinner/Spinner.stories.svelte +29 -29
  279. package/dist/primitives/Spinner/Spinner.svelte +20 -20
  280. package/dist/primitives/Tabs/TabItem.spec.d.ts +2 -0
  281. package/dist/primitives/Tabs/TabItem.spec.d.ts.map +1 -0
  282. package/dist/primitives/Tabs/TabItem.spec.js +130 -0
  283. package/dist/primitives/Tabs/TabItem.svelte +49 -49
  284. package/dist/primitives/Tabs/Tabs.spec.d.ts +2 -0
  285. package/dist/primitives/Tabs/Tabs.spec.d.ts.map +1 -0
  286. package/dist/primitives/Tabs/Tabs.spec.js +295 -0
  287. package/dist/primitives/Tabs/Tabs.stories.svelte +112 -112
  288. package/dist/primitives/Tabs/Tabs.svelte +123 -123
  289. package/dist/primitives/Tabs/TabsWithItems.test.svelte +18 -0
  290. package/dist/primitives/Tabs/TabsWithItems.test.svelte.d.ts +16 -0
  291. package/dist/primitives/Tabs/TabsWithItems.test.svelte.d.ts.map +1 -0
  292. package/dist/primitives/Toggle.spec.js +143 -127
  293. package/dist/primitives/Toggle.stories.svelte +92 -92
  294. package/dist/primitives/Toggle.svelte +71 -71
  295. package/dist/primitives/Typography/Typography.spec.d.ts +2 -0
  296. package/dist/primitives/Typography/Typography.spec.d.ts.map +1 -0
  297. package/dist/primitives/Typography/Typography.spec.js +183 -0
  298. package/dist/primitives/Typography/Typography.svelte +53 -53
  299. package/dist/primitives/ValidationError.spec.js +103 -103
  300. package/dist/primitives/ValidationError.stories.svelte +69 -69
  301. package/dist/primitives/ValidationError.svelte +29 -29
  302. package/dist/primitives/index.d.ts +1 -0
  303. package/dist/primitives/index.js +3 -0
  304. package/dist/recipes/CropImage/CropImage.spec.js +208 -216
  305. package/dist/recipes/CropImage/CropImage.stories.svelte +104 -104
  306. package/dist/recipes/CropImage/CropImage.svelte +238 -238
  307. package/dist/recipes/ImageUploader/ImageUploader.spec.d.ts +2 -0
  308. package/dist/recipes/ImageUploader/ImageUploader.spec.d.ts.map +1 -0
  309. package/dist/recipes/ImageUploader/ImageUploader.spec.js +1351 -0
  310. package/dist/recipes/ImageUploader/ImageUploader.stories.svelte +125 -125
  311. package/dist/recipes/ImageUploader/ImageUploader.svelte +804 -804
  312. package/dist/recipes/SuperLogin/SuperLogin.spec.d.ts +2 -0
  313. package/dist/recipes/SuperLogin/SuperLogin.spec.d.ts.map +1 -0
  314. package/dist/recipes/SuperLogin/SuperLogin.spec.js +1436 -0
  315. package/dist/recipes/SuperLogin/SuperLogin.svelte +7 -6
  316. package/dist/recipes/SuperLogin/SuperLogin.svelte.d.ts.map +1 -1
  317. package/dist/recipes/Toaster/Toaster.stories.svelte +62 -62
  318. package/dist/recipes/feedback/EmptyState/EmptyState.spec.d.ts +2 -0
  319. package/dist/recipes/feedback/EmptyState/EmptyState.spec.d.ts.map +1 -0
  320. package/dist/recipes/feedback/EmptyState/EmptyState.spec.js +202 -0
  321. package/dist/recipes/feedback/EmptyState/EmptyState.svelte +1 -1
  322. package/dist/recipes/feedback/ErrorDisplay.spec.js +69 -69
  323. package/dist/recipes/feedback/ErrorDisplay.stories.svelte +101 -101
  324. package/dist/recipes/feedback/ErrorDisplay.svelte +1 -1
  325. package/dist/recipes/feedback/StatusIndicator/StatusIndicator.spec.js +133 -129
  326. package/dist/recipes/feedback/StatusIndicator/StatusIndicator.svelte +157 -157
  327. package/dist/recipes/fields/CheckboxField.spec.d.ts +2 -0
  328. package/dist/recipes/fields/CheckboxField.spec.d.ts.map +1 -0
  329. package/dist/recipes/fields/CheckboxField.spec.js +135 -0
  330. package/dist/recipes/fields/CheckboxField.svelte +85 -85
  331. package/dist/recipes/fields/FormField.spec.d.ts +2 -0
  332. package/dist/recipes/fields/FormField.spec.d.ts.map +1 -0
  333. package/dist/recipes/fields/FormField.spec.js +159 -0
  334. package/dist/recipes/fields/FormField.svelte +58 -58
  335. package/dist/recipes/fields/RadioGroup.spec.d.ts +2 -0
  336. package/dist/recipes/fields/RadioGroup.spec.d.ts.map +1 -0
  337. package/dist/recipes/fields/RadioGroup.spec.js +199 -0
  338. package/dist/recipes/fields/RadioGroup.svelte +95 -95
  339. package/dist/recipes/fields/SelectField.spec.d.ts +2 -0
  340. package/dist/recipes/fields/SelectField.spec.d.ts.map +1 -0
  341. package/dist/recipes/fields/SelectField.spec.js +188 -0
  342. package/dist/recipes/fields/SelectField.svelte +80 -80
  343. package/dist/recipes/fields/TextareaField.spec.d.ts +2 -0
  344. package/dist/recipes/fields/TextareaField.spec.d.ts.map +1 -0
  345. package/dist/recipes/fields/TextareaField.spec.js +205 -0
  346. package/dist/recipes/fields/TextareaField.svelte +97 -97
  347. package/dist/recipes/fields/ToggleField.spec.d.ts +2 -0
  348. package/dist/recipes/fields/ToggleField.spec.d.ts.map +1 -0
  349. package/dist/recipes/fields/ToggleField.spec.js +153 -0
  350. package/dist/recipes/fields/ToggleField.svelte +60 -60
  351. package/dist/recipes/fields/index.js +7 -7
  352. package/dist/recipes/inputs/MultiSelect.spec.js +258 -257
  353. package/dist/recipes/inputs/MultiSelect.stories.svelte +133 -133
  354. package/dist/recipes/inputs/MultiSelect.svelte +256 -249
  355. package/dist/recipes/inputs/MultiSelect.svelte.d.ts +2 -0
  356. package/dist/recipes/inputs/MultiSelect.svelte.d.ts.map +1 -1
  357. package/dist/recipes/inputs/OTPInput.spec.js +251 -238
  358. package/dist/recipes/inputs/OTPInput.stories.svelte +162 -162
  359. package/dist/recipes/inputs/OTPInput.svelte +29 -29
  360. package/dist/recipes/inputs/PasswordInput.spec.d.ts +2 -0
  361. package/dist/recipes/inputs/PasswordInput.spec.d.ts.map +1 -0
  362. package/dist/recipes/inputs/PasswordInput.spec.js +410 -0
  363. package/dist/recipes/inputs/PasswordInput.svelte +22 -22
  364. package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.spec.js +245 -165
  365. package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte +43 -43
  366. package/dist/recipes/inputs/PasswordStrengthIndicator/TestWrapper.svelte +71 -0
  367. package/dist/recipes/inputs/PasswordStrengthIndicator/TestWrapper.svelte.d.ts +9 -0
  368. package/dist/recipes/inputs/PasswordStrengthIndicator/TestWrapper.svelte.d.ts.map +1 -0
  369. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.spec.js +1139 -193
  370. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +123 -123
  371. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +326 -326
  372. package/dist/recipes/inputs/Search.spec.d.ts +2 -0
  373. package/dist/recipes/inputs/Search.spec.d.ts.map +1 -0
  374. package/dist/recipes/inputs/Search.spec.js +177 -0
  375. package/dist/recipes/inputs/Search.svelte +37 -37
  376. package/dist/recipes/inputs/SelectDropdown.spec.d.ts +2 -0
  377. package/dist/recipes/inputs/SelectDropdown.spec.d.ts.map +1 -0
  378. package/dist/recipes/inputs/SelectDropdown.spec.js +512 -0
  379. package/dist/recipes/inputs/SelectDropdown.svelte +57 -57
  380. package/dist/recipes/modals/AlertModal.spec.d.ts +2 -0
  381. package/dist/recipes/modals/AlertModal.spec.d.ts.map +1 -0
  382. package/dist/recipes/modals/AlertModal.spec.js +432 -0
  383. package/dist/recipes/modals/AlertModal.svelte +130 -130
  384. package/dist/recipes/modals/ConfirmationModal.spec.js +206 -191
  385. package/dist/recipes/modals/ConfirmationModal.stories.svelte +119 -119
  386. package/dist/recipes/modals/ConfirmationModal.svelte +152 -152
  387. package/dist/recipes/modals/InputModal.spec.d.ts +2 -0
  388. package/dist/recipes/modals/InputModal.spec.d.ts.map +1 -0
  389. package/dist/recipes/modals/InputModal.spec.js +872 -0
  390. package/dist/recipes/modals/InputModal.svelte +182 -182
  391. package/dist/recipes/modals/ModalStateManager.spec.js +100 -100
  392. package/dist/recipes/modals/ModalStateManager.svelte +77 -77
  393. package/dist/recipes/modals/ModalTestWrapper.spec.d.ts +2 -0
  394. package/dist/recipes/modals/ModalTestWrapper.spec.d.ts.map +1 -0
  395. package/dist/recipes/modals/ModalTestWrapper.spec.js +502 -0
  396. package/dist/recipes/modals/ModalTestWrapper.svelte +65 -65
  397. package/dist/recipes/modals/StatusModal.spec.d.ts +2 -0
  398. package/dist/recipes/modals/StatusModal.spec.d.ts.map +1 -0
  399. package/dist/recipes/modals/StatusModal.spec.js +599 -0
  400. package/dist/recipes/modals/StatusModal.svelte +206 -206
  401. package/dist/services/EventService.js +75 -75
  402. package/dist/services/EventService.spec.js +217 -217
  403. package/dist/services/ShowService.spec.js +345 -342
  404. package/dist/stores/auth.js +36 -36
  405. package/dist/stores/auth.spec.js +139 -139
  406. package/dist/stores/toaster.js +13 -13
  407. package/dist/stories/ButtonAuditDashboard.spec.d.ts +2 -0
  408. package/dist/stories/ButtonAuditDashboard.spec.d.ts.map +1 -0
  409. package/dist/stories/ButtonAuditDashboard.spec.js +913 -0
  410. package/dist/stories/ButtonAuditReview.spec.d.ts +2 -0
  411. package/dist/stories/ButtonAuditReview.spec.d.ts.map +1 -0
  412. package/dist/stories/ButtonAuditReview.spec.js +422 -0
  413. package/dist/stories/ButtonAuditReview.stories.svelte +14 -14
  414. package/dist/stories/ButtonAuditReview.svelte +427 -427
  415. package/dist/stories/ButtonGridView.spec.d.ts +2 -0
  416. package/dist/stories/ButtonGridView.spec.d.ts.map +1 -0
  417. package/dist/stories/ButtonGridView.spec.js +667 -0
  418. package/dist/stories/ButtonShowcase.spec.d.ts +2 -0
  419. package/dist/stories/ButtonShowcase.spec.d.ts.map +1 -0
  420. package/dist/stories/ButtonShowcase.spec.js +499 -0
  421. package/dist/stories/PatternsGallery.spec.d.ts +2 -0
  422. package/dist/stories/PatternsGallery.spec.d.ts.map +1 -0
  423. package/dist/stories/PatternsGallery.spec.js +514 -0
  424. package/dist/stories/PatternsGallery.stories.svelte +19 -19
  425. package/dist/stories/PatternsGallery.svelte +206 -206
  426. package/dist/stories/PrimitivesGallery.spec.d.ts +2 -0
  427. package/dist/stories/PrimitivesGallery.spec.d.ts.map +1 -0
  428. package/dist/stories/PrimitivesGallery.spec.js +813 -0
  429. package/dist/stories/PrimitivesGallery.stories.svelte +19 -19
  430. package/dist/stories/PrimitivesGallery.svelte +725 -725
  431. package/dist/stories/RecipesGallery.spec.d.ts +2 -0
  432. package/dist/stories/RecipesGallery.spec.d.ts.map +1 -0
  433. package/dist/stories/RecipesGallery.spec.js +299 -0
  434. package/dist/stories/RecipesGallery.stories.svelte +19 -19
  435. package/dist/stories/RecipesGallery.svelte +271 -271
  436. package/dist/stories/button-audit-manifest.json +11186 -11186
  437. package/dist/stripe/useStripeTheme.spec.d.ts +2 -0
  438. package/dist/stripe/useStripeTheme.spec.d.ts.map +1 -0
  439. package/dist/stripe/useStripeTheme.spec.js +793 -0
  440. package/dist/tailwind/preset.cjs +82 -82
  441. package/dist/telemetry.d.ts.map +1 -1
  442. package/dist/telemetry.js +6 -5
  443. package/dist/telemetry.spec.js +495 -12
  444. package/dist/tokens/__tests__/colors.test.d.ts +2 -0
  445. package/dist/tokens/__tests__/colors.test.d.ts.map +1 -0
  446. package/dist/tokens/__tests__/colors.test.js +152 -0
  447. package/dist/tokens/__tests__/radius.test.d.ts +2 -0
  448. package/dist/tokens/__tests__/radius.test.d.ts.map +1 -0
  449. package/dist/tokens/__tests__/radius.test.js +118 -0
  450. package/dist/tokens/__tests__/shadows.test.d.ts +2 -0
  451. package/dist/tokens/__tests__/shadows.test.d.ts.map +1 -0
  452. package/dist/tokens/__tests__/shadows.test.js +105 -0
  453. package/dist/tokens/__tests__/spacing.test.js +11 -8
  454. package/dist/tokens/__tests__/typography.test.d.ts +2 -0
  455. package/dist/tokens/__tests__/typography.test.d.ts.map +1 -0
  456. package/dist/tokens/__tests__/typography.test.js +156 -0
  457. package/dist/tokens/__tests__/z-index.test.d.ts +2 -0
  458. package/dist/tokens/__tests__/z-index.test.d.ts.map +1 -0
  459. package/dist/tokens/__tests__/z-index.test.js +121 -0
  460. package/dist/tokens/tokens.css +87 -87
  461. package/dist/utils/apiConfig.spec.js +102 -1
  462. package/dist/utils/formatters.spec.d.ts +2 -0
  463. package/dist/utils/formatters.spec.d.ts.map +1 -0
  464. package/dist/utils/formatters.spec.js +82 -0
  465. package/dist/utils/transitions.d.ts +24 -0
  466. package/dist/utils/transitions.d.ts.map +1 -0
  467. package/dist/utils/transitions.js +62 -0
  468. package/dist/utils/transitions.spec.d.ts +2 -0
  469. package/dist/utils/transitions.spec.d.ts.map +1 -0
  470. package/dist/utils/transitions.spec.js +130 -0
  471. package/dist/utils/utils.js +354 -354
  472. package/package.json +288 -283
@@ -0,0 +1,714 @@
1
+ import { describe, it, expect, vi, afterEach, beforeEach } from 'vitest';
2
+ import { render, screen, cleanup, fireEvent, waitFor } from '@testing-library/svelte';
3
+ import ShowCard from './ShowCard.svelte';
4
+
5
+ describe('ShowCard Component', () => {
6
+ const mockEvent = {
7
+ name: 'Rock Concert',
8
+ startDateTime: '2024-03-15T20:00:00',
9
+ endDateTime: '2024-03-15T23:00:00',
10
+ doorsOpenTime: '2024-03-15T19:00:00',
11
+ displayStartTime: true,
12
+ displayEndTime: true,
13
+ venue: {
14
+ name: 'The Music Hall',
15
+ address: '123 Main St, New York, NY 10001',
16
+ googleLocationNameCache: 'The Music Hall, New York'
17
+ },
18
+ ageRequirement: 21
19
+ };
20
+
21
+ const mockShowtimes = [
22
+ { day: 'Friday', date: '2024-03-15', time: '19:30:00' },
23
+ { day: 'Saturday', date: '2024-03-16', time: '20:00:00' },
24
+ { day: 'Sunday', date: '2024-03-17', time: '18:00:00' }
25
+ ];
26
+
27
+ beforeEach(() => {
28
+ // Mock window.location
29
+ Object.defineProperty(window, 'location', {
30
+ writable: true,
31
+ value: { href: 'https://example.com/event/123' }
32
+ });
33
+
34
+ // Mock clipboard API
35
+ Object.defineProperty(navigator, 'clipboard', {
36
+ writable: true,
37
+ value: {
38
+ writeText: vi.fn().mockResolvedValue(undefined)
39
+ }
40
+ });
41
+
42
+ // Mock share API
43
+ Object.defineProperty(navigator, 'share', {
44
+ writable: true,
45
+ value: undefined
46
+ });
47
+
48
+ Object.defineProperty(navigator, 'canShare', {
49
+ writable: true,
50
+ value: undefined
51
+ });
52
+ });
53
+
54
+ afterEach(() => {
55
+ cleanup();
56
+ vi.restoreAllMocks();
57
+ vi.clearAllTimers();
58
+ });
59
+
60
+ describe('rendering', () => {
61
+ it('renders the component wrapper', () => {
62
+ const { container } = render(ShowCard, { props: { event: mockEvent } });
63
+ const wrapper = container.querySelector('.rounded-lg');
64
+ expect(wrapper).toBeInTheDocument();
65
+ });
66
+
67
+ it('renders event name when showTitle is true', () => {
68
+ render(ShowCard, { props: { event: mockEvent, showTitle: true } });
69
+ expect(screen.getByText('Rock Concert')).toBeInTheDocument();
70
+ });
71
+
72
+ it('does not render event name when showTitle is false', () => {
73
+ render(ShowCard, { props: { event: mockEvent, showTitle: false } });
74
+ expect(screen.queryByText('Rock Concert')).not.toBeInTheDocument();
75
+ });
76
+
77
+ it('renders with empty event object', () => {
78
+ const { container } = render(ShowCard, { props: { event: {} } });
79
+ expect(container.querySelector('.rounded-lg')).toBeInTheDocument();
80
+ });
81
+
82
+ it('renders without event prop', () => {
83
+ const { container } = render(ShowCard);
84
+ expect(container.querySelector('.rounded-lg')).toBeInTheDocument();
85
+ });
86
+ });
87
+
88
+ describe('date and time formatting', () => {
89
+ it('formats startDateTime correctly', () => {
90
+ const { container } = render(ShowCard, { props: { event: mockEvent } });
91
+ // Check that some part of the formatted date appears
92
+ expect(container.textContent).toMatch(/March|Mar/i);
93
+ });
94
+
95
+ it('displays doors open time when provided', () => {
96
+ render(ShowCard, {
97
+ props: {
98
+ event: {
99
+ ...mockEvent,
100
+ displayStartTime: true,
101
+ doorsOpenTime: '2024-03-15T19:00:00'
102
+ }
103
+ }
104
+ });
105
+ expect(screen.getByText(/Doors open/i)).toBeInTheDocument();
106
+ });
107
+
108
+ it('hides doors open time when displayStartTime is false', () => {
109
+ render(ShowCard, {
110
+ props: {
111
+ event: {
112
+ ...mockEvent,
113
+ displayStartTime: false,
114
+ doorsOpenTime: '2024-03-15T19:00:00'
115
+ }
116
+ }
117
+ });
118
+ expect(screen.queryByText(/Doors open/i)).not.toBeInTheDocument();
119
+ });
120
+
121
+ it('displays end time when provided', () => {
122
+ render(ShowCard, {
123
+ props: {
124
+ event: {
125
+ ...mockEvent,
126
+ displayEndTime: true,
127
+ endDateTime: '2024-03-15T23:00:00'
128
+ }
129
+ }
130
+ });
131
+ expect(screen.getByText(/Ends/i)).toBeInTheDocument();
132
+ });
133
+
134
+ it('hides end time when displayEndTime is false', () => {
135
+ render(ShowCard, {
136
+ props: {
137
+ event: {
138
+ ...mockEvent,
139
+ displayEndTime: false,
140
+ endDateTime: '2024-03-15T23:00:00'
141
+ }
142
+ }
143
+ });
144
+ expect(screen.queryByText(/Ends/i)).not.toBeInTheDocument();
145
+ });
146
+
147
+ it('handles invalid date gracefully', () => {
148
+ const { container } = render(ShowCard, {
149
+ props: { event: { startDateTime: 'invalid-date' } }
150
+ });
151
+ expect(container).toBeInTheDocument();
152
+ });
153
+
154
+ it('handles missing date', () => {
155
+ const { container } = render(ShowCard, {
156
+ props: { event: { startDateTime: null } }
157
+ });
158
+ expect(container).toBeInTheDocument();
159
+ });
160
+
161
+ it('uses custom formatDateTime function', () => {
162
+ const customFormat = vi.fn(() => 'Custom Date Format');
163
+ render(ShowCard, {
164
+ props: {
165
+ event: mockEvent,
166
+ formatDateTime: customFormat
167
+ }
168
+ });
169
+ expect(customFormat).toHaveBeenCalled();
170
+ expect(screen.getByText('Custom Date Format')).toBeInTheDocument();
171
+ });
172
+
173
+ it('uses custom formatTimeline function', () => {
174
+ const customFormat = vi.fn(() => 'Custom Time');
175
+ render(ShowCard, {
176
+ props: {
177
+ event: { ...mockEvent, displayStartTime: true },
178
+ formatTimeline: customFormat
179
+ }
180
+ });
181
+ expect(customFormat).toHaveBeenCalled();
182
+ });
183
+ });
184
+
185
+ describe('share functionality', () => {
186
+ it('renders share button when showTitle is true', () => {
187
+ render(ShowCard, { props: { event: mockEvent, showTitle: true } });
188
+ const shareButton = screen.getByLabelText('Share event');
189
+ expect(shareButton).toBeInTheDocument();
190
+ });
191
+
192
+ it('does not render share button when showTitle is false', () => {
193
+ render(ShowCard, { props: { event: mockEvent, showTitle: false } });
194
+ expect(screen.queryByLabelText('Share event')).not.toBeInTheDocument();
195
+ });
196
+
197
+ it('uses native share API when available', async () => {
198
+ const shareMock = vi.fn().mockResolvedValue(undefined);
199
+ const canShareMock = vi.fn().mockReturnValue(true);
200
+
201
+ Object.defineProperty(navigator, 'share', { value: shareMock });
202
+ Object.defineProperty(navigator, 'canShare', { value: canShareMock });
203
+
204
+ render(ShowCard, { props: { event: mockEvent, showTitle: true } });
205
+ const shareButton = screen.getByLabelText('Share event');
206
+
207
+ await fireEvent.click(shareButton);
208
+
209
+ expect(canShareMock).toHaveBeenCalledWith({
210
+ title: 'Rock Concert',
211
+ text: 'Check out Rock Concert at The Music Hall!',
212
+ url: 'https://example.com/event/123'
213
+ });
214
+ expect(shareMock).toHaveBeenCalled();
215
+ });
216
+
217
+ it('falls back to clipboard when share API not available', async () => {
218
+ render(ShowCard, { props: { event: mockEvent, showTitle: true } });
219
+ const shareButton = screen.getByLabelText('Share event');
220
+
221
+ await fireEvent.click(shareButton);
222
+
223
+ expect(navigator.clipboard.writeText).toHaveBeenCalledWith('https://example.com/event/123');
224
+ });
225
+
226
+ it('shows success indicator after clipboard copy', async () => {
227
+ vi.useFakeTimers();
228
+
229
+ render(ShowCard, { props: { event: mockEvent, showTitle: true } });
230
+ const shareButton = screen.getByLabelText('Share event');
231
+
232
+ await fireEvent.click(shareButton);
233
+
234
+ // Should show check icon
235
+ await waitFor(() => {
236
+ const checkIcon = shareButton.querySelector('.text-green-600, .text-green-500');
237
+ expect(checkIcon).toBeInTheDocument();
238
+ });
239
+
240
+ // After 2 seconds, should revert to share icon
241
+ vi.advanceTimersByTime(2000);
242
+
243
+ await waitFor(() => {
244
+ const shareIcon = shareButton.querySelector('.text-gray-500, .text-gray-400');
245
+ expect(shareIcon).toBeInTheDocument();
246
+ });
247
+
248
+ vi.useRealTimers();
249
+ });
250
+
251
+ it('handles share API abort error gracefully', async () => {
252
+ const shareMock = vi.fn().mockRejectedValue({ name: 'AbortError' });
253
+ const canShareMock = vi.fn().mockReturnValue(true);
254
+
255
+ Object.defineProperty(navigator, 'share', { value: shareMock });
256
+ Object.defineProperty(navigator, 'canShare', { value: canShareMock });
257
+
258
+ render(ShowCard, { props: { event: mockEvent, showTitle: true } });
259
+ const shareButton = screen.getByLabelText('Share event');
260
+
261
+ await fireEvent.click(shareButton);
262
+
263
+ // AbortError should NOT fall back to clipboard (user cancelled)
264
+ expect(navigator.clipboard.writeText).not.toHaveBeenCalled();
265
+ });
266
+
267
+ it('handles share API error by falling back to clipboard', async () => {
268
+ const shareMock = vi.fn().mockRejectedValue(new Error('Share failed'));
269
+ const canShareMock = vi.fn().mockReturnValue(true);
270
+
271
+ Object.defineProperty(navigator, 'share', { value: shareMock });
272
+ Object.defineProperty(navigator, 'canShare', { value: canShareMock });
273
+
274
+ render(ShowCard, { props: { event: mockEvent, showTitle: true } });
275
+ const shareButton = screen.getByLabelText('Share event');
276
+
277
+ await fireEvent.click(shareButton);
278
+
279
+ // Should fall back to clipboard
280
+ expect(navigator.clipboard.writeText).toHaveBeenCalled();
281
+ });
282
+
283
+ it('handles clipboard error gracefully', async () => {
284
+ const consoleErrorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
285
+ navigator.clipboard.writeText = vi.fn().mockRejectedValue(new Error('Clipboard failed'));
286
+
287
+ render(ShowCard, { props: { event: mockEvent, showTitle: true } });
288
+ const shareButton = screen.getByLabelText('Share event');
289
+
290
+ await fireEvent.click(shareButton);
291
+
292
+ await waitFor(() => {
293
+ expect(consoleErrorSpy).toHaveBeenCalled();
294
+ });
295
+
296
+ consoleErrorSpy.mockRestore();
297
+ });
298
+
299
+ it('handles missing venue name in share text', async () => {
300
+ const eventWithoutVenue = { ...mockEvent, venue: null };
301
+
302
+ render(ShowCard, { props: { event: eventWithoutVenue, showTitle: true } });
303
+ const shareButton = screen.getByLabelText('Share event');
304
+
305
+ await fireEvent.click(shareButton);
306
+
307
+ expect(navigator.clipboard.writeText).toHaveBeenCalledWith('https://example.com/event/123');
308
+ });
309
+ });
310
+
311
+ describe('showtimes section', () => {
312
+ it('renders showtimes when multiple are provided', () => {
313
+ render(ShowCard, { props: { event: mockEvent, showtimes: mockShowtimes } });
314
+ expect(screen.getByText('More showtimes')).toBeInTheDocument();
315
+ });
316
+
317
+ it('does not render showtimes section with single showtime', () => {
318
+ render(ShowCard, { props: { event: mockEvent, showtimes: [mockShowtimes[0]] } });
319
+ expect(screen.queryByText('More showtimes')).not.toBeInTheDocument();
320
+ });
321
+
322
+ it('does not render showtimes section with empty array', () => {
323
+ render(ShowCard, { props: { event: mockEvent, showtimes: [] } });
324
+ expect(screen.queryByText('More showtimes')).not.toBeInTheDocument();
325
+ });
326
+
327
+ it('renders all showtimes', () => {
328
+ render(ShowCard, { props: { event: mockEvent, showtimes: mockShowtimes } });
329
+ expect(screen.getByText('Friday')).toBeInTheDocument();
330
+ expect(screen.getByText('Saturday')).toBeInTheDocument();
331
+ expect(screen.getByText('Sunday')).toBeInTheDocument();
332
+ });
333
+
334
+ it('calls onShowtimeSelect when showtime is clicked', async () => {
335
+ const onShowtimeSelect = vi.fn();
336
+ render(ShowCard, {
337
+ props: {
338
+ event: mockEvent,
339
+ showtimes: mockShowtimes,
340
+ onShowtimeSelect
341
+ }
342
+ });
343
+
344
+ // Find all buttons (share button + showtime buttons)
345
+ const buttons = screen.getAllByRole('button');
346
+ // First button is share, rest are showtimes
347
+ const showtimeButton = buttons[1];
348
+
349
+ await fireEvent.click(showtimeButton);
350
+
351
+ expect(onShowtimeSelect).toHaveBeenCalled();
352
+ expect(onShowtimeSelect.mock.calls[0][0]).toHaveProperty('date');
353
+ });
354
+
355
+ it('updates selected date when showtime is clicked', async () => {
356
+ render(ShowCard, {
357
+ props: {
358
+ event: mockEvent,
359
+ showtimes: mockShowtimes
360
+ }
361
+ });
362
+
363
+ const buttons = screen.getAllByRole('button');
364
+ const firstShowtime = buttons[1];
365
+
366
+ await fireEvent.click(firstShowtime);
367
+
368
+ // Selected state should be reflected in aria-pressed
369
+ expect(firstShowtime).toHaveAttribute('aria-pressed', 'true');
370
+ });
371
+
372
+ it('does not throw when onShowtimeSelect is not provided', async () => {
373
+ render(ShowCard, {
374
+ props: {
375
+ event: mockEvent,
376
+ showtimes: mockShowtimes
377
+ }
378
+ });
379
+
380
+ const buttons = screen.getAllByRole('button');
381
+ const showtimeButton = buttons[1];
382
+
383
+ await expect(fireEvent.click(showtimeButton)).resolves.not.toThrow();
384
+ });
385
+ });
386
+
387
+ describe('venue section', () => {
388
+ it('renders venue name and address', () => {
389
+ render(ShowCard, { props: { event: mockEvent } });
390
+ expect(screen.getByText('The Music Hall')).toBeInTheDocument();
391
+ expect(screen.getByText('123 Main St, New York, NY 10001')).toBeInTheDocument();
392
+ });
393
+
394
+ it('does not render venue section when venue is missing', () => {
395
+ const eventWithoutVenue = { ...mockEvent, venue: null };
396
+ render(ShowCard, { props: { event: eventWithoutVenue } });
397
+ expect(screen.queryByText('The Music Hall')).not.toBeInTheDocument();
398
+ });
399
+
400
+ it('renders Google Maps link with correct URL', () => {
401
+ render(ShowCard, { props: { event: mockEvent } });
402
+ const link = screen.getByText('The Music Hall').closest('a');
403
+ expect(link).toHaveAttribute('href', expect.stringContaining('google.com/maps'));
404
+ expect(link).toHaveAttribute('href', expect.stringContaining('The%20Music%20Hall%2C%20New%20York'));
405
+ expect(link).toHaveAttribute('target', '_blank');
406
+ expect(link).toHaveAttribute('rel', 'noopener noreferrer');
407
+ });
408
+
409
+ it('falls back to address in Google Maps URL when googleLocationNameCache is missing', () => {
410
+ const eventWithoutCache = {
411
+ ...mockEvent,
412
+ venue: {
413
+ name: 'The Music Hall',
414
+ address: '123 Main St, New York, NY 10001'
415
+ }
416
+ };
417
+ render(ShowCard, { props: { event: eventWithoutCache } });
418
+ const link = screen.getByText('The Music Hall').closest('a');
419
+ expect(link).toHaveAttribute('href', expect.stringContaining('123%20Main%20St'));
420
+ });
421
+
422
+ it('falls back to venue name in Google Maps URL when address is missing', () => {
423
+ const eventWithoutAddress = {
424
+ ...mockEvent,
425
+ venue: {
426
+ name: 'The Music Hall'
427
+ }
428
+ };
429
+ render(ShowCard, { props: { event: eventWithoutAddress } });
430
+ const link = screen.getByText('The Music Hall').closest('a');
431
+ expect(link).toHaveAttribute('href', expect.stringContaining('The%20Music%20Hall'));
432
+ });
433
+
434
+ it('handles missing address gracefully', () => {
435
+ const eventWithoutAddress = {
436
+ ...mockEvent,
437
+ venue: {
438
+ name: 'The Music Hall',
439
+ googleLocationNameCache: 'The Music Hall, New York'
440
+ }
441
+ };
442
+ render(ShowCard, { props: { event: eventWithoutAddress } });
443
+ expect(screen.getByText('The Music Hall')).toBeInTheDocument();
444
+ });
445
+ });
446
+
447
+ describe('age restrictions', () => {
448
+ it('displays age requirement when provided', () => {
449
+ render(ShowCard, { props: { event: { ...mockEvent, ageRequirement: 21 } } });
450
+ expect(screen.getByText('21+')).toBeInTheDocument();
451
+ });
452
+
453
+ it('displays "All ages" for ageRequirement 0', () => {
454
+ const event = { ...mockEvent, hasAgeRestriction: true, ageRequirement: 0 };
455
+ render(ShowCard, { props: { event } });
456
+ expect(screen.getByText('All ages')).toBeInTheDocument();
457
+ });
458
+
459
+ it('displays "All ages" for ageRequirement 1', () => {
460
+ const event = { ...mockEvent, hasAgeRestriction: true, ageRequirement: 1 };
461
+ render(ShowCard, { props: { event } });
462
+ expect(screen.getByText('All ages')).toBeInTheDocument();
463
+ });
464
+
465
+ it('displays minimum age when ageRequirement not set', () => {
466
+ const event = { ...mockEvent, ageRequirement: null, minimumAge: 18 };
467
+ render(ShowCard, { props: { event } });
468
+ expect(screen.getByText('18+')).toBeInTheDocument();
469
+ });
470
+
471
+ it('displays "All ages" for minimumAge 1', () => {
472
+ const event = { ...mockEvent, hasAgeRestriction: true, ageRequirement: null, minimumAge: 1 };
473
+ render(ShowCard, { props: { event } });
474
+ expect(screen.getByText('All ages')).toBeInTheDocument();
475
+ });
476
+
477
+ it('falls back to ageRestriction when others not set', () => {
478
+ const event = {
479
+ ...mockEvent,
480
+ hasAgeRestriction: true,
481
+ ageRequirement: null,
482
+ minimumAge: null,
483
+ ageRestriction: 16
484
+ };
485
+ render(ShowCard, { props: { event } });
486
+ expect(screen.getByText('16+')).toBeInTheDocument();
487
+ });
488
+
489
+ it('displays "All ages" for ageRestriction 1', () => {
490
+ const event = {
491
+ ...mockEvent,
492
+ hasAgeRestriction: true,
493
+ ageRequirement: null,
494
+ minimumAge: null,
495
+ ageRestriction: 1
496
+ };
497
+ render(ShowCard, { props: { event } });
498
+ expect(screen.getByText('All ages')).toBeInTheDocument();
499
+ });
500
+
501
+ it('does not display age info when no age fields present', () => {
502
+ const eventWithoutAge = {
503
+ ...mockEvent,
504
+ hasAgeRestriction: false,
505
+ ageRequirement: null,
506
+ minimumAge: null,
507
+ ageRestriction: null
508
+ };
509
+ render(ShowCard, { props: { event: eventWithoutAge } });
510
+ expect(screen.queryByText(/\d+\+|All ages/)).not.toBeInTheDocument();
511
+ });
512
+
513
+ it('displays age info when hasAgeRestriction is true', () => {
514
+ const event = {
515
+ ...mockEvent,
516
+ hasAgeRestriction: true,
517
+ ageRequirement: 18
518
+ };
519
+ render(ShowCard, { props: { event } });
520
+ expect(screen.getByText('18+')).toBeInTheDocument();
521
+ });
522
+
523
+ it('prefers ageRequirement over minimumAge', () => {
524
+ const event = {
525
+ ...mockEvent,
526
+ ageRequirement: 21,
527
+ minimumAge: 18
528
+ };
529
+ render(ShowCard, { props: { event } });
530
+ expect(screen.getByText('21+')).toBeInTheDocument();
531
+ expect(screen.queryByText('18+')).not.toBeInTheDocument();
532
+ });
533
+ });
534
+
535
+ describe('accessibility', () => {
536
+ it('has proper heading hierarchy', () => {
537
+ render(ShowCard, { props: { event: mockEvent, showTitle: true } });
538
+ const heading = screen.getByRole('heading', { level: 2 });
539
+ expect(heading).toHaveTextContent('Rock Concert');
540
+ });
541
+
542
+ it('share button has aria-label', () => {
543
+ render(ShowCard, { props: { event: mockEvent, showTitle: true } });
544
+ const shareButton = screen.getByLabelText('Share event');
545
+ expect(shareButton).toBeInTheDocument();
546
+ });
547
+
548
+ it('venue link is keyboard accessible', () => {
549
+ render(ShowCard, { props: { event: mockEvent } });
550
+ const link = screen.getByText('The Music Hall').closest('a');
551
+ expect(link).toBeInTheDocument();
552
+ expect(link.tagName).toBe('A');
553
+ });
554
+ });
555
+
556
+ describe('styling', () => {
557
+ it('has correct base classes', () => {
558
+ const { container } = render(ShowCard, { props: { event: mockEvent } });
559
+ const wrapper = container.querySelector('.rounded-lg');
560
+ expect(wrapper).toHaveClass('h-fit', 'rounded-lg', 'py-4');
561
+ });
562
+
563
+ it('has dark mode support', () => {
564
+ const { container } = render(ShowCard, { props: { event: mockEvent } });
565
+ const wrapper = container.querySelector('.rounded-lg');
566
+ expect(wrapper.className).toContain('dark:bg-gray-800');
567
+ });
568
+
569
+ it('has border on medium screens and up', () => {
570
+ const { container } = render(ShowCard, { props: { event: mockEvent } });
571
+ const wrapper = container.querySelector('.rounded-lg');
572
+ expect(wrapper.className).toContain('md:border');
573
+ });
574
+
575
+ it('applies hover styles to share button', () => {
576
+ const { container } = render(ShowCard, { props: { event: mockEvent, showTitle: true } });
577
+ const shareButton = screen.getByLabelText('Share event');
578
+ expect(shareButton.className).toContain('hover:bg-gray-100');
579
+ expect(shareButton.className).toContain('dark:hover:bg-gray-700');
580
+ });
581
+
582
+ it('applies hover styles to venue link', () => {
583
+ const { container } = render(ShowCard, { props: { event: mockEvent } });
584
+ const venueName = screen.getByText('The Music Hall');
585
+ expect(venueName.className).toContain('group-hover:text-blue-700');
586
+ expect(venueName.className).toContain('dark:group-hover:text-blue-500');
587
+ });
588
+
589
+ it('has border between sections', () => {
590
+ const { container } = render(ShowCard, {
591
+ props: {
592
+ event: mockEvent,
593
+ showtimes: mockShowtimes
594
+ }
595
+ });
596
+ const borders = container.querySelectorAll('.border-t');
597
+ expect(borders.length).toBeGreaterThan(0);
598
+ });
599
+ });
600
+
601
+ describe('edge cases', () => {
602
+ it('handles undefined props gracefully', () => {
603
+ const { container } = render(ShowCard);
604
+ expect(container.querySelector('.rounded-lg')).toBeInTheDocument();
605
+ });
606
+
607
+ it('handles null showtimes', () => {
608
+ const { container } = render(ShowCard, {
609
+ props: { event: mockEvent, showtimes: null }
610
+ });
611
+ expect(container.querySelector('.rounded-lg')).toBeInTheDocument();
612
+ expect(screen.queryByText('More showtimes')).not.toBeInTheDocument();
613
+ });
614
+
615
+ it('handles event with only name', () => {
616
+ render(ShowCard, { props: { event: { name: 'Simple Event' }, showTitle: true } });
617
+ expect(screen.getByText('Simple Event')).toBeInTheDocument();
618
+ });
619
+
620
+ it('handles missing venue properties', () => {
621
+ const event = {
622
+ ...mockEvent,
623
+ venue: { name: 'Minimal Venue' }
624
+ };
625
+ render(ShowCard, { props: { event } });
626
+ expect(screen.getByText('Minimal Venue')).toBeInTheDocument();
627
+ });
628
+
629
+ it('handles SSR environment without window', () => {
630
+ const originalWindow = global.window;
631
+ // @ts-ignore
632
+ delete global.window;
633
+
634
+ const { container } = render(ShowCard, { props: { event: mockEvent } });
635
+ expect(container.querySelector('.rounded-lg')).toBeInTheDocument();
636
+
637
+ global.window = originalWindow;
638
+ });
639
+
640
+ it('handles SSR environment without navigator', () => {
641
+ const originalNavigator = global.navigator;
642
+ // @ts-ignore
643
+ delete global.navigator;
644
+
645
+ const { container } = render(ShowCard, { props: { event: mockEvent, showTitle: true } });
646
+ expect(container.querySelector('.rounded-lg')).toBeInTheDocument();
647
+
648
+ global.navigator = originalNavigator;
649
+ });
650
+ });
651
+
652
+ describe('integration', () => {
653
+ it('renders complete event card with all sections', () => {
654
+ render(ShowCard, {
655
+ props: {
656
+ event: mockEvent,
657
+ showtimes: mockShowtimes,
658
+ showTitle: true
659
+ }
660
+ });
661
+
662
+ // Title
663
+ expect(screen.getByText('Rock Concert')).toBeInTheDocument();
664
+
665
+ // Share button
666
+ expect(screen.getByLabelText('Share event')).toBeInTheDocument();
667
+
668
+ // Showtimes
669
+ expect(screen.getByText('More showtimes')).toBeInTheDocument();
670
+
671
+ // Venue
672
+ expect(screen.getByText('The Music Hall')).toBeInTheDocument();
673
+
674
+ // Age restriction
675
+ expect(screen.getByText('21+')).toBeInTheDocument();
676
+ });
677
+
678
+ it('handles complex user interaction flow', async () => {
679
+ vi.useFakeTimers();
680
+ const onShowtimeSelect = vi.fn();
681
+
682
+ render(ShowCard, {
683
+ props: {
684
+ event: mockEvent,
685
+ showtimes: mockShowtimes,
686
+ showTitle: true,
687
+ onShowtimeSelect
688
+ }
689
+ });
690
+
691
+ // Click share button
692
+ const shareButton = screen.getByLabelText('Share event');
693
+ await fireEvent.click(shareButton);
694
+ expect(navigator.clipboard.writeText).toHaveBeenCalled();
695
+
696
+ // Wait for success indicator
697
+ await waitFor(() => {
698
+ const checkIcon = shareButton.querySelector('.text-green-600, .text-green-500');
699
+ expect(checkIcon).toBeInTheDocument();
700
+ });
701
+
702
+ // Select a showtime
703
+ const buttons = screen.getAllByRole('button');
704
+ await fireEvent.click(buttons[1]);
705
+ expect(onShowtimeSelect).toHaveBeenCalled();
706
+
707
+ // Click venue link (verify it's interactive)
708
+ const venueLink = screen.getByText('The Music Hall').closest('a');
709
+ expect(venueLink).toHaveAttribute('href');
710
+
711
+ vi.useRealTimers();
712
+ });
713
+ });
714
+ });