@getmicdrop/svelte-components 5.17.1 → 5.17.3

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 (382) hide show
  1. package/dist/calendar/AboutShow/AboutShow.svelte +187 -187
  2. package/dist/calendar/Calendar/MiniMonthCalendar.svelte +782 -782
  3. package/dist/calendar/FAQs/FAQs.svelte +77 -77
  4. package/dist/calendar/MonthSwitcher/MonthSwitcher.svelte +126 -126
  5. package/dist/calendar/OrderSummary/OrderSummary.svelte +457 -457
  6. package/dist/calendar/PublicCard/PublicCard.svelte +146 -146
  7. package/dist/calendar/ShowCard/ShowCard.svelte +157 -157
  8. package/dist/calendar/ShowTimeCard/ShowTimeCard.svelte +61 -61
  9. package/dist/components/Heading.spec.d.ts +2 -0
  10. package/dist/components/Heading.spec.d.ts.map +1 -0
  11. package/dist/components/Heading.spec.js +89 -0
  12. package/dist/components/Heading.svelte +60 -60
  13. package/dist/components/Layout/AppShell.svelte +104 -104
  14. package/dist/components/Layout/ContentSection.svelte +80 -80
  15. package/dist/components/Layout/Grid.svelte +4 -4
  16. package/dist/components/Layout/Heading.svelte +81 -81
  17. package/dist/components/Layout/PageContainer.svelte +69 -69
  18. package/dist/components/Layout/Responsive.svelte +75 -75
  19. package/dist/components/Layout/Section.svelte +80 -80
  20. package/dist/components/Layout/ShowOnDesktop.svelte +37 -37
  21. package/dist/components/Layout/ShowOnMobile.svelte +37 -37
  22. package/dist/components/Layout/Sidebar.svelte +108 -108
  23. package/dist/components/Layout/Stack.spec.js +1 -1
  24. package/dist/components/Layout/Stack.svelte +6 -6
  25. package/dist/components/Layout/Text.svelte +87 -87
  26. package/dist/components/Layout/TwoColumn.svelte +108 -108
  27. package/dist/components/Layout/__tests__/AppShell.test.js +140 -0
  28. package/dist/components/Text.spec.d.ts +2 -0
  29. package/dist/components/Text.spec.d.ts.map +1 -0
  30. package/dist/components/Text.spec.js +89 -0
  31. package/dist/components/Text.svelte +53 -53
  32. package/dist/constants/validation.js +91 -91
  33. package/dist/constants/validation.spec.js +64 -64
  34. package/dist/datetime/__tests__/format.test.js +1 -1
  35. package/dist/datetime/__tests__/parse.test.js +1 -1
  36. package/dist/datetime/__tests__/timezone.test.js +1 -1
  37. package/dist/datetime/parse.js +1 -1
  38. package/dist/forms/createFormStore.svelte.js +1 -0
  39. package/dist/forms/createFormStore.svelte.spec.d.ts +2 -0
  40. package/dist/forms/createFormStore.svelte.spec.d.ts.map +1 -0
  41. package/dist/forms/createFormStore.svelte.spec.js +388 -0
  42. package/dist/index.js +57 -57
  43. package/dist/index.spec.js +369 -369
  44. package/dist/patterns/chat/ChatActivityNotice.spec.d.ts +2 -0
  45. package/dist/patterns/chat/ChatActivityNotice.spec.d.ts.map +1 -0
  46. package/dist/patterns/chat/ChatActivityNotice.spec.js +59 -0
  47. package/dist/patterns/chat/ChatActivityNotice.svelte +41 -41
  48. package/dist/patterns/chat/ChatBubble.spec.d.ts +2 -0
  49. package/dist/patterns/chat/ChatBubble.spec.d.ts.map +1 -0
  50. package/dist/patterns/chat/ChatBubble.spec.js +91 -0
  51. package/dist/patterns/chat/ChatBubble.svelte +95 -95
  52. package/dist/patterns/chat/ChatContainer.spec.d.ts +2 -0
  53. package/dist/patterns/chat/ChatContainer.spec.d.ts.map +1 -0
  54. package/dist/patterns/chat/ChatContainer.spec.js +30 -0
  55. package/dist/patterns/chat/ChatContainer.svelte +46 -46
  56. package/dist/patterns/chat/ChatDateDivider.spec.d.ts +2 -0
  57. package/dist/patterns/chat/ChatDateDivider.spec.d.ts.map +1 -0
  58. package/dist/patterns/chat/ChatDateDivider.spec.js +30 -0
  59. package/dist/patterns/chat/ChatDateDivider.svelte +27 -27
  60. package/dist/patterns/chat/ChatInvitationBubble.spec.d.ts +2 -0
  61. package/dist/patterns/chat/ChatInvitationBubble.spec.d.ts.map +1 -0
  62. package/dist/patterns/chat/ChatInvitationBubble.spec.js +46 -0
  63. package/dist/patterns/chat/ChatInvitationBubble.svelte +37 -37
  64. package/dist/patterns/chat/ChatInvitationNotice.spec.d.ts +2 -0
  65. package/dist/patterns/chat/ChatInvitationNotice.spec.d.ts.map +1 -0
  66. package/dist/patterns/chat/ChatInvitationNotice.spec.js +32 -0
  67. package/dist/patterns/chat/ChatInvitationNotice.svelte +27 -27
  68. package/dist/patterns/chat/ChatMessageGroup.spec.d.ts +2 -0
  69. package/dist/patterns/chat/ChatMessageGroup.spec.d.ts.map +1 -0
  70. package/dist/patterns/chat/ChatMessageGroup.spec.js +58 -0
  71. package/dist/patterns/chat/ChatMessageGroup.svelte +57 -57
  72. package/dist/patterns/chat/ChatSlotUpdate.spec.d.ts +2 -0
  73. package/dist/patterns/chat/ChatSlotUpdate.spec.d.ts.map +1 -0
  74. package/dist/patterns/chat/ChatSlotUpdate.spec.js +65 -0
  75. package/dist/patterns/chat/ChatSlotUpdate.svelte +46 -46
  76. package/dist/patterns/chat/ChatStatusBadge.spec.d.ts +2 -0
  77. package/dist/patterns/chat/ChatStatusBadge.spec.d.ts.map +1 -0
  78. package/dist/patterns/chat/ChatStatusBadge.spec.js +79 -0
  79. package/dist/patterns/chat/ChatStatusBadge.svelte +91 -91
  80. package/dist/patterns/chat/ChatStatusTransition.spec.d.ts +2 -0
  81. package/dist/patterns/chat/ChatStatusTransition.spec.d.ts.map +1 -0
  82. package/dist/patterns/chat/ChatStatusTransition.spec.js +81 -0
  83. package/dist/patterns/chat/ChatStatusTransition.svelte +64 -64
  84. package/dist/patterns/chat/ChatTextBubble.spec.d.ts +2 -0
  85. package/dist/patterns/chat/ChatTextBubble.spec.d.ts.map +1 -0
  86. package/dist/patterns/chat/ChatTextBubble.spec.js +35 -0
  87. package/dist/patterns/chat/ChatTextBubble.svelte +41 -41
  88. package/dist/patterns/chat/index.js +22 -22
  89. package/dist/patterns/data/DataGrid.svelte +45 -45
  90. package/dist/patterns/data/DataList.svelte +24 -24
  91. package/dist/patterns/data/DataTable.spec.js +61 -0
  92. package/dist/patterns/data/DataTable.svelte +36 -36
  93. package/dist/patterns/forms/FormActions.spec.js +95 -95
  94. package/dist/patterns/forms/FormActions.stories.svelte +97 -97
  95. package/dist/patterns/forms/FormActions.svelte +46 -46
  96. package/dist/patterns/forms/FormGrid.spec.js +34 -0
  97. package/dist/patterns/forms/FormGrid.svelte +33 -33
  98. package/dist/patterns/forms/FormSection.svelte +32 -32
  99. package/dist/patterns/forms/FormValidationSummary.stories.svelte +83 -83
  100. package/dist/patterns/forms/FormValidationSummary.svelte +74 -74
  101. package/dist/patterns/index.js +21 -21
  102. package/dist/patterns/layout/Sidebar.spec.js +240 -1
  103. package/dist/patterns/layout/Sidebar.svelte +39 -39
  104. package/dist/patterns/layout/SidebarTestWrapper.svelte +34 -0
  105. package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts +23 -0
  106. package/dist/patterns/layout/SidebarTestWrapper.svelte.d.ts.map +1 -0
  107. package/dist/patterns/layout/index.js +29 -29
  108. package/dist/patterns/navigation/BottomNav.stories.svelte +117 -117
  109. package/dist/patterns/navigation/BottomNav.svelte +74 -74
  110. package/dist/patterns/navigation/Header.spec.js +123 -0
  111. package/dist/patterns/navigation/Header.stories.svelte +77 -77
  112. package/dist/patterns/navigation/Header.svelte +251 -251
  113. package/dist/patterns/page/PageHeader.svelte +18 -18
  114. package/dist/patterns/page/PageLayout.svelte +40 -40
  115. package/dist/patterns/page/PageLoader.spec.js +57 -57
  116. package/dist/patterns/page/PageLoader.stories.svelte +137 -137
  117. package/dist/patterns/page/PageLoader.svelte +24 -24
  118. package/dist/patterns/page/SectionHeader.svelte +29 -29
  119. package/dist/presets/badges.js +112 -112
  120. package/dist/presets/buttons.js +76 -76
  121. package/dist/presets/index.js +9 -9
  122. package/dist/primitives/Accordion/Accordion.spec.js +112 -2
  123. package/dist/primitives/Accordion/Accordion.stories.svelte +75 -75
  124. package/dist/primitives/Accordion/Accordion.svelte +42 -42
  125. package/dist/primitives/Accordion/AccordionItem.svelte +95 -95
  126. package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte +28 -0
  127. package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte.d.ts +7 -0
  128. package/dist/primitives/Accordion/AccordionToggleWrapper.test.svelte.d.ts.map +1 -0
  129. package/dist/primitives/Alert/Alert.spec.js +173 -173
  130. package/dist/primitives/Alert/Alert.stories.svelte +88 -88
  131. package/dist/primitives/Alert/Alert.svelte +27 -27
  132. package/dist/primitives/Avatar/Avatar.spec.js +23 -0
  133. package/dist/primitives/Avatar/Avatar.stories.svelte +94 -94
  134. package/dist/primitives/Avatar/Avatar.svelte +66 -66
  135. package/dist/primitives/AvatarButton/AvatarButton.svelte +57 -57
  136. package/dist/primitives/Badges/Badge.spec.js +144 -144
  137. package/dist/primitives/Badges/Badge.stories.svelte +86 -86
  138. package/dist/primitives/Badges/Badge.svelte +99 -99
  139. package/dist/primitives/BottomSheet/BottomSheet.spec.js +238 -136
  140. package/dist/primitives/BottomSheet/BottomSheet.stories.svelte +83 -83
  141. package/dist/primitives/BottomSheet/BottomSheet.svelte +115 -115
  142. package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte +20 -0
  143. package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte.d.ts +10 -0
  144. package/dist/primitives/BottomSheet/BottomSheetWithActions.test.svelte.d.ts.map +1 -0
  145. package/dist/primitives/Breadcrumb/Breadcrumb.spec.js +123 -123
  146. package/dist/primitives/Breadcrumb/Breadcrumb.stories.svelte +23 -23
  147. package/dist/primitives/Breadcrumb/Breadcrumb.svelte +99 -99
  148. package/dist/primitives/Button/Button.spec.js +225 -225
  149. package/dist/primitives/Button/Button.stories.svelte +76 -76
  150. package/dist/primitives/Button/Button.svelte +278 -278
  151. package/dist/primitives/Button/ButtonGroup.spec.d.ts +2 -0
  152. package/dist/primitives/Button/ButtonGroup.spec.d.ts.map +1 -0
  153. package/dist/primitives/Button/ButtonGroup.spec.js +44 -0
  154. package/dist/primitives/Button/ButtonGroup.svelte +50 -50
  155. package/dist/primitives/Button/ButtonSaveDemo.spec.js +146 -146
  156. package/dist/primitives/Button/ButtonSaveDemo.svelte +25 -25
  157. package/dist/primitives/Button/ButtonVariantShowcase.svelte +129 -129
  158. package/dist/primitives/Card.spec.js +49 -49
  159. package/dist/primitives/Card.stories.svelte +22 -22
  160. package/dist/primitives/Card.svelte +28 -28
  161. package/dist/primitives/CardAction/CardAction.svelte +68 -68
  162. package/dist/primitives/Checkbox/Checkbox.spec.js +32 -0
  163. package/dist/primitives/Checkbox/Checkbox.stories.svelte +84 -84
  164. package/dist/primitives/Checkbox/Checkbox.svelte +88 -88
  165. package/dist/primitives/DarkModeToggle.spec.js +390 -390
  166. package/dist/primitives/DarkModeToggle.stories.svelte +57 -57
  167. package/dist/primitives/DarkModeToggle.svelte +136 -136
  168. package/dist/primitives/Drawer/Drawer.spec.js +437 -0
  169. package/dist/primitives/Drawer/Drawer.stories.svelte +80 -80
  170. package/dist/primitives/Drawer/Drawer.svelte +224 -224
  171. package/dist/primitives/Drawer/DrawerTestWrapper.svelte +86 -0
  172. package/dist/primitives/Drawer/DrawerTestWrapper.svelte.d.ts +26 -0
  173. package/dist/primitives/Drawer/DrawerTestWrapper.svelte.d.ts.map +1 -0
  174. package/dist/primitives/Dropdown/Dropdown.spec.js +116 -0
  175. package/dist/primitives/Dropdown/Dropdown.stories.svelte +137 -137
  176. package/dist/primitives/Dropdown/Dropdown.svelte +170 -170
  177. package/dist/primitives/Dropdown/DropdownDivider.spec.d.ts +2 -0
  178. package/dist/primitives/Dropdown/DropdownDivider.spec.d.ts.map +1 -0
  179. package/dist/primitives/Dropdown/DropdownDivider.spec.js +30 -0
  180. package/dist/primitives/Dropdown/DropdownDivider.svelte +9 -9
  181. package/dist/primitives/Dropdown/DropdownItem.spec.js +155 -1
  182. package/dist/primitives/Dropdown/DropdownItem.svelte +80 -80
  183. package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte +43 -0
  184. package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte.d.ts +17 -0
  185. package/dist/primitives/Dropdown/DropdownItemTestWrapper.svelte.d.ts.map +1 -0
  186. package/dist/primitives/Helper/Helper.spec.d.ts +2 -0
  187. package/dist/primitives/Helper/Helper.spec.d.ts.map +1 -0
  188. package/dist/primitives/Helper/Helper.spec.js +57 -0
  189. package/dist/primitives/Helper/Helper.svelte +33 -33
  190. package/dist/primitives/Icons/ArrowLeft.svelte +8 -8
  191. package/dist/primitives/Icons/ArrowRight.svelte +8 -8
  192. package/dist/primitives/Icons/Availability.svelte +14 -14
  193. package/dist/primitives/Icons/Back.svelte +14 -14
  194. package/dist/primitives/Icons/CheckCircle.svelte +6 -6
  195. package/dist/primitives/Icons/CheckCircleOutline.svelte +15 -15
  196. package/dist/primitives/Icons/ChevronLeft.svelte +4 -4
  197. package/dist/primitives/Icons/ChevronRight.svelte +4 -4
  198. package/dist/primitives/Icons/Copy.svelte +15 -15
  199. package/dist/primitives/Icons/Cross.svelte +5 -5
  200. package/dist/primitives/Icons/DownArrow.svelte +8 -8
  201. package/dist/primitives/Icons/ErrorCircle.svelte +6 -6
  202. package/dist/primitives/Icons/FacebookIcon.svelte +2 -2
  203. package/dist/primitives/Icons/Home.svelte +15 -15
  204. package/dist/primitives/Icons/Icon.spec.js +169 -169
  205. package/dist/primitives/Icons/Icon.stories.svelte +100 -100
  206. package/dist/primitives/Icons/Icon.svelte +52 -52
  207. package/dist/primitives/Icons/IconGallery.stories.svelte +235 -235
  208. package/dist/primitives/Icons/Info.svelte +7 -7
  209. package/dist/primitives/Icons/InstagramIcon.svelte +4 -4
  210. package/dist/primitives/Icons/LogoInstagram.svelte +2 -2
  211. package/dist/primitives/Icons/Message.svelte +15 -15
  212. package/dist/primitives/Icons/MoonIcon.svelte +5 -5
  213. package/dist/primitives/Icons/More.svelte +21 -21
  214. package/dist/primitives/Icons/MoreHori.spec.js +61 -61
  215. package/dist/primitives/Icons/MoreHori.svelte +22 -22
  216. package/dist/primitives/Icons/Notification.svelte +14 -14
  217. package/dist/primitives/Icons/Payment.svelte +14 -14
  218. package/dist/primitives/Icons/Profile.svelte +21 -21
  219. package/dist/primitives/Icons/Reload.svelte +29 -29
  220. package/dist/primitives/Icons/Shows.svelte +21 -21
  221. package/dist/primitives/Icons/Signout.svelte +21 -21
  222. package/dist/primitives/Icons/SunIcon.svelte +8 -8
  223. package/dist/primitives/Icons/TiktokIcon.svelte +2 -2
  224. package/dist/primitives/Icons/TwitterIcon.svelte +2 -2
  225. package/dist/primitives/Icons/WarningIcon.spec.js +18 -18
  226. package/dist/primitives/Icons/WarningIcon.svelte +5 -5
  227. package/dist/primitives/Input/Input.spec.js +1235 -573
  228. package/dist/primitives/Input/Input.stories.svelte +139 -139
  229. package/dist/primitives/Input/Input.svelte +423 -423
  230. package/dist/primitives/Input/Select.spec.js +632 -218
  231. package/dist/primitives/Input/Select.stories.svelte +112 -112
  232. package/dist/primitives/Input/Select.svelte +252 -252
  233. package/dist/primitives/Input/Textarea.stories.svelte +137 -137
  234. package/dist/primitives/Input/Textarea.svelte +105 -105
  235. package/dist/primitives/Label/Label.spec.js +9 -0
  236. package/dist/primitives/Label/Label.svelte +37 -37
  237. package/dist/primitives/LandingButton/LandingButton.spec.d.ts +2 -0
  238. package/dist/primitives/LandingButton/LandingButton.spec.d.ts.map +1 -0
  239. package/dist/primitives/LandingButton/LandingButton.spec.js +61 -0
  240. package/dist/primitives/LandingButton/LandingButton.svelte +92 -92
  241. package/dist/primitives/MenuItem/MenuItem.spec.d.ts +2 -0
  242. package/dist/primitives/MenuItem/MenuItem.spec.d.ts.map +1 -0
  243. package/dist/primitives/MenuItem/MenuItem.spec.js +130 -0
  244. package/dist/primitives/MenuItem/MenuItem.svelte +85 -85
  245. package/dist/primitives/Modal/Modal.spec.js +314 -99
  246. package/dist/primitives/Modal/Modal.stories.svelte +86 -86
  247. package/dist/primitives/Modal/Modal.svelte +181 -181
  248. package/dist/primitives/NavItem/NavItem.spec.d.ts +2 -0
  249. package/dist/primitives/NavItem/NavItem.spec.d.ts.map +1 -0
  250. package/dist/primitives/NavItem/NavItem.spec.js +97 -0
  251. package/dist/primitives/NavItem/NavItem.svelte +75 -75
  252. package/dist/primitives/Pagination/Pagination.stories.svelte +76 -76
  253. package/dist/primitives/Pagination/Pagination.svelte +261 -261
  254. package/dist/primitives/Radio/Radio.stories.svelte +80 -80
  255. package/dist/primitives/Radio/Radio.svelte +67 -67
  256. package/dist/primitives/SearchResultItem/SearchResultItem.spec.d.ts +2 -0
  257. package/dist/primitives/SearchResultItem/SearchResultItem.spec.d.ts.map +1 -0
  258. package/dist/primitives/SearchResultItem/SearchResultItem.spec.js +78 -0
  259. package/dist/primitives/SearchResultItem/SearchResultItem.svelte +109 -109
  260. package/dist/primitives/SidebarToggle/SidebarToggle.spec.d.ts +2 -0
  261. package/dist/primitives/SidebarToggle/SidebarToggle.spec.d.ts.map +1 -0
  262. package/dist/primitives/SidebarToggle/SidebarToggle.spec.js +61 -0
  263. package/dist/primitives/SidebarToggle/SidebarToggle.svelte +55 -55
  264. package/dist/primitives/Skeleton/CardPlaceholder.svelte +87 -87
  265. package/dist/primitives/Skeleton/ImagePlaceholder.svelte +59 -59
  266. package/dist/primitives/Skeleton/ListPlaceholder.svelte +76 -76
  267. package/dist/primitives/Skeleton/Skeleton.stories.svelte +151 -151
  268. package/dist/primitives/Skeleton/Skeleton.svelte +26 -26
  269. package/dist/primitives/Spinner/Spinner.spec.js +84 -71
  270. package/dist/primitives/Spinner/Spinner.stories.svelte +29 -29
  271. package/dist/primitives/Spinner/Spinner.svelte +20 -20
  272. package/dist/primitives/Tabs/TabItem.svelte +49 -49
  273. package/dist/primitives/Tabs/Tabs.stories.svelte +112 -112
  274. package/dist/primitives/Tabs/Tabs.svelte +137 -137
  275. package/dist/primitives/Toggle.spec.js +221 -146
  276. package/dist/primitives/Toggle.stories.svelte +92 -92
  277. package/dist/primitives/Toggle.svelte +141 -141
  278. package/dist/primitives/ToggleTestWrapper.svelte +30 -0
  279. package/dist/primitives/ToggleTestWrapper.svelte.d.ts +29 -0
  280. package/dist/primitives/ToggleTestWrapper.svelte.d.ts.map +1 -0
  281. package/dist/primitives/Tooltip/Tooltip.spec.d.ts +2 -0
  282. package/dist/primitives/Tooltip/Tooltip.spec.d.ts.map +1 -0
  283. package/dist/primitives/Tooltip/Tooltip.spec.js +126 -0
  284. package/dist/primitives/Tooltip/Tooltip.svelte +83 -83
  285. package/dist/primitives/Typography/Typography.svelte +53 -53
  286. package/dist/primitives/ValidationError.spec.js +103 -103
  287. package/dist/primitives/ValidationError.stories.svelte +69 -69
  288. package/dist/primitives/ValidationError.svelte +29 -29
  289. package/dist/primitives/index.js +113 -113
  290. package/dist/recipes/CropImage/CropImage.spec.js +208 -208
  291. package/dist/recipes/CropImage/CropImage.stories.svelte +104 -104
  292. package/dist/recipes/CropImage/CropImage.svelte +241 -241
  293. package/dist/recipes/ImageUploader/ImageUploader.stories.svelte +125 -125
  294. package/dist/recipes/ImageUploader/ImageUploader.svelte +992 -992
  295. package/dist/recipes/SuperLogin/SuperLogin.spec.js +2 -2
  296. package/dist/recipes/SuperLogin/SuperLogin.svelte +1 -1
  297. package/dist/recipes/Toaster/Toaster.stories.svelte +62 -62
  298. package/dist/recipes/feedback/EmptyState/EmptyState.svelte +1 -1
  299. package/dist/recipes/feedback/ErrorDisplay.spec.js +69 -69
  300. package/dist/recipes/feedback/ErrorDisplay.stories.svelte +101 -101
  301. package/dist/recipes/feedback/ErrorDisplay.svelte +1 -1
  302. package/dist/recipes/feedback/StatusIndicator/StatusIndicator.spec.js +133 -133
  303. package/dist/recipes/feedback/StatusIndicator/StatusIndicator.svelte +157 -157
  304. package/dist/recipes/fields/CheckboxField.svelte +85 -85
  305. package/dist/recipes/fields/FormField.svelte +58 -58
  306. package/dist/recipes/fields/RadioGroup.svelte +95 -95
  307. package/dist/recipes/fields/SelectField.svelte +82 -82
  308. package/dist/recipes/fields/TextareaField.svelte +97 -97
  309. package/dist/recipes/fields/ToggleField.svelte +60 -60
  310. package/dist/recipes/fields/index.js +7 -7
  311. package/dist/recipes/inputs/MultiSelect.spec.js +263 -263
  312. package/dist/recipes/inputs/MultiSelect.stories.svelte +133 -133
  313. package/dist/recipes/inputs/MultiSelect.svelte +283 -283
  314. package/dist/recipes/inputs/OTPInput.spec.js +251 -251
  315. package/dist/recipes/inputs/OTPInput.stories.svelte +162 -162
  316. package/dist/recipes/inputs/OTPInput.svelte +117 -117
  317. package/dist/recipes/inputs/PasswordInput.svelte +22 -22
  318. package/dist/recipes/inputs/PasswordStrengthIndicator/PasswordStrengthIndicator.svelte +131 -131
  319. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.stories.svelte +123 -123
  320. package/dist/recipes/inputs/PlaceAutocomplete/PlaceAutocomplete.svelte +336 -336
  321. package/dist/recipes/inputs/Search.spec.js +66 -2
  322. package/dist/recipes/inputs/Search.svelte +102 -102
  323. package/dist/recipes/inputs/index.js +7 -7
  324. package/dist/recipes/modals/AlertModal.svelte +130 -130
  325. package/dist/recipes/modals/ConfirmationModal.spec.js +396 -206
  326. package/dist/recipes/modals/ConfirmationModal.stories.svelte +119 -119
  327. package/dist/recipes/modals/ConfirmationModal.svelte +162 -162
  328. package/dist/recipes/modals/InputModal.svelte +182 -182
  329. package/dist/recipes/modals/ModalStateManager.spec.js +100 -100
  330. package/dist/recipes/modals/ModalStateManager.svelte +77 -77
  331. package/dist/recipes/modals/ModalTestWrapper.svelte +65 -65
  332. package/dist/recipes/modals/StatusModal.svelte +206 -206
  333. package/dist/services/EventService.js +79 -79
  334. package/dist/services/EventService.spec.js +217 -217
  335. package/dist/services/ShowService.js +144 -144
  336. package/dist/services/ShowService.spec.js +345 -345
  337. package/dist/stores/auth.svelte.spec.d.ts +2 -0
  338. package/dist/stores/auth.svelte.spec.d.ts.map +1 -0
  339. package/dist/stores/auth.svelte.spec.js +112 -0
  340. package/dist/stores/formDataStore.svelte.spec.d.ts +2 -0
  341. package/dist/stores/formDataStore.svelte.spec.d.ts.map +1 -0
  342. package/dist/stores/formDataStore.svelte.spec.js +150 -0
  343. package/dist/stores/formSave.svelte.spec.d.ts +2 -0
  344. package/dist/stores/formSave.svelte.spec.d.ts.map +1 -0
  345. package/dist/stores/formSave.svelte.spec.js +196 -0
  346. package/dist/stores/navigation.spec.d.ts +2 -0
  347. package/dist/stores/navigation.spec.d.ts.map +1 -0
  348. package/dist/stores/navigation.spec.js +53 -0
  349. package/dist/stores/toaster.js +13 -13
  350. package/dist/stories/ButtonAuditReview.stories.svelte +14 -14
  351. package/dist/stories/ButtonAuditReview.svelte +427 -427
  352. package/dist/stories/PatternsGallery.stories.svelte +19 -19
  353. package/dist/stories/PatternsGallery.svelte +206 -206
  354. package/dist/stories/PrimitivesGallery.stories.svelte +19 -19
  355. package/dist/stories/PrimitivesGallery.svelte +756 -756
  356. package/dist/stories/RecipesGallery.stories.svelte +19 -19
  357. package/dist/stories/RecipesGallery.svelte +454 -454
  358. package/dist/stories/button-audit-manifest.json +11186 -11186
  359. package/dist/tailwind/preset.cjs +82 -82
  360. package/dist/telemetry.js +402 -402
  361. package/dist/telemetry.server.js +212 -212
  362. package/dist/telemetry.server.spec.js +437 -437
  363. package/dist/telemetry.spec.js +1168 -1168
  364. package/dist/tokens/tokens.css +87 -87
  365. package/dist/tokens/typography-base.css +163 -163
  366. package/dist/tokens/utilities.css +353 -353
  367. package/dist/utils/apiConfig.js +117 -117
  368. package/dist/utils/apiConfig.spec.js +219 -219
  369. package/dist/utils/greetings.js +187 -187
  370. package/dist/utils/haptic.spec.d.ts +2 -0
  371. package/dist/utils/haptic.spec.d.ts.map +1 -0
  372. package/dist/utils/haptic.spec.js +153 -0
  373. package/dist/utils/imageOptimizer.spec.d.ts +2 -0
  374. package/dist/utils/imageOptimizer.spec.d.ts.map +1 -0
  375. package/dist/utils/imageOptimizer.spec.js +201 -0
  376. package/dist/utils/imageValidation.js +121 -121
  377. package/dist/utils/logger.spec.d.ts +2 -0
  378. package/dist/utils/logger.spec.d.ts.map +1 -0
  379. package/dist/utils/logger.spec.js +95 -0
  380. package/dist/utils/transitions.js +4 -4
  381. package/dist/utils/utils.js +693 -693
  382. package/package.json +292 -293
@@ -1,117 +1,117 @@
1
- <script module>
2
- import { defineMeta } from "@storybook/addon-svelte-csf";
3
-
4
- import BottomNav from './BottomNav.svelte';
5
-
6
- const { Story } = defineMeta({
7
- title: 'Components/Layout/BottomNav',
8
- component: BottomNav,
9
- tags: ['autodocs'],
10
- });
11
-
12
- </script>
13
-
14
- <script>
15
-
16
- const defaultLinks = [
17
- { label: 'Home', href: '/', icon: 'Home' },
18
- { label: 'Shows', href: '/shows', icon: 'Shows' },
19
- { label: 'Availability', href: '/availability', icon: 'Availability' },
20
- { label: 'Profile', href: '/profile', icon: 'Profile' },
21
- ];
22
-
23
- const extendedLinks = [
24
- { label: 'Home', href: '/', icon: 'Home' },
25
- { label: 'Shows', href: '/shows', icon: 'Shows' },
26
- { label: 'Availability', href: '/availability', icon: 'Availability' },
27
- { label: 'Messages', href: '/messages', icon: 'Message' },
28
- { label: 'Profile', href: '/profile', icon: 'Profile' },
29
- ];
30
- </script>
31
-
32
- <Story name="Default (4 Tabs)">
33
- <div class="bg-gray-100 dark:bg-gray-700 p-4">
34
- <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Mobile Bottom Navigation (4 tabs)</p>
35
- <div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
36
- <div class="h-64 bg-gradient-to-br from-blue-50 to-blue-100 flex items-center justify-center">
37
- <p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
38
- </div>
39
- <div class="flex border-t bg-white dark:bg-gray-900">
40
- <BottomNav links={defaultLinks} />
41
- </div>
42
- </div>
43
- </div>
44
- </Story>
45
-
46
- <Story name="With 5 Tabs">
47
- <div class="bg-gray-100 dark:bg-gray-700 p-4">
48
- <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Extended Navigation (5 tabs)</p>
49
- <div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
50
- <div class="h-64 bg-gradient-to-br from-purple-50 to-purple-100 flex items-center justify-center">
51
- <p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
52
- </div>
53
- <div class="flex border-t bg-white dark:bg-gray-900">
54
- <BottomNav links={extendedLinks} />
55
- </div>
56
- </div>
57
- </div>
58
- </Story>
59
-
60
- <Story name="Different Icon Set">
61
- <div class="bg-gray-100 dark:bg-gray-700 p-4">
62
- <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Custom Icons</p>
63
- <div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
64
- <div class="h-64 bg-gradient-to-br from-green-50 to-green-100 flex items-center justify-center">
65
- <p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
66
- </div>
67
- <div class="flex border-t bg-white dark:bg-gray-900">
68
- <BottomNav
69
- links={[
70
- { label: 'Dashboard', href: '/', icon: 'Home' },
71
- { label: 'Events', href: '/events', icon: 'Shows' },
72
- { label: 'Notifications', href: '/notifications', icon: 'Notification' },
73
- { label: 'Settings', href: '/settings', icon: 'Profile' },
74
- ]}
75
- />
76
- </div>
77
- </div>
78
- </div>
79
- </Story>
80
-
81
- <Story name="Mobile Viewport">
82
- <div class="max-w-[375px] mx-auto bg-white dark:bg-gray-900 shadow-2xl rounded-3xl overflow-hidden">
83
- <!-- Mock iPhone screen -->
84
- <div class="h-[667px] flex flex-col">
85
- <!-- Status bar -->
86
- <div class="h-6 bg-black flex items-center justify-between px-4">
87
- <span class="text-white text-xs">9:41</span>
88
- <span class="text-white text-xs">100%</span>
89
- </div>
90
-
91
- <!-- Content area -->
92
- <div class="flex-1 bg-gradient-to-br from-blue-50 to-purple-50 p-4">
93
- <h1 class="text-2xl font-bold mb-2">Home</h1>
94
- <p class="text-gray-500 dark:text-gray-400">This is a mobile viewport simulation</p>
95
- </div>
96
-
97
- <!-- Bottom navigation -->
98
- <div class="flex border-t bg-white dark:bg-gray-900 safe-bottom">
99
- <BottomNav links={defaultLinks} />
100
- </div>
101
- </div>
102
- </div>
103
- </Story>
104
-
105
- <Story name="Dark Mode">
106
- <div class="dark bg-gray-900 p-4 min-h-screen">
107
- <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Dark Mode Bottom Navigation</p>
108
- <div class="max-w-md mx-auto bg-gray-800 rounded-lg shadow-2xl overflow-hidden">
109
- <div class="h-64 bg-gradient-to-br from-gray-900 to-gray-800 flex items-center justify-center">
110
- <p class="text-gray-500 dark:text-gray-400">Dark Mode Content</p>
111
- </div>
112
- <div class="flex border-t border-gray-700 bg-gray-800">
113
- <BottomNav links={defaultLinks} />
114
- </div>
115
- </div>
116
- </div>
117
- </Story>
1
+ <script module>
2
+ import { defineMeta } from "@storybook/addon-svelte-csf";
3
+
4
+ import BottomNav from './BottomNav.svelte';
5
+
6
+ const { Story } = defineMeta({
7
+ title: 'Components/Layout/BottomNav',
8
+ component: BottomNav,
9
+ tags: ['autodocs'],
10
+ });
11
+
12
+ </script>
13
+
14
+ <script>
15
+
16
+ const defaultLinks = [
17
+ { label: 'Home', href: '/', icon: 'Home' },
18
+ { label: 'Shows', href: '/shows', icon: 'Shows' },
19
+ { label: 'Availability', href: '/availability', icon: 'Availability' },
20
+ { label: 'Profile', href: '/profile', icon: 'Profile' },
21
+ ];
22
+
23
+ const extendedLinks = [
24
+ { label: 'Home', href: '/', icon: 'Home' },
25
+ { label: 'Shows', href: '/shows', icon: 'Shows' },
26
+ { label: 'Availability', href: '/availability', icon: 'Availability' },
27
+ { label: 'Messages', href: '/messages', icon: 'Message' },
28
+ { label: 'Profile', href: '/profile', icon: 'Profile' },
29
+ ];
30
+ </script>
31
+
32
+ <Story name="Default (4 Tabs)">
33
+ <div class="bg-gray-100 dark:bg-gray-700 p-4">
34
+ <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Mobile Bottom Navigation (4 tabs)</p>
35
+ <div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
36
+ <div class="h-64 bg-gradient-to-br from-blue-50 to-blue-100 flex items-center justify-center">
37
+ <p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
38
+ </div>
39
+ <div class="flex border-t bg-white dark:bg-gray-900">
40
+ <BottomNav links={defaultLinks} />
41
+ </div>
42
+ </div>
43
+ </div>
44
+ </Story>
45
+
46
+ <Story name="With 5 Tabs">
47
+ <div class="bg-gray-100 dark:bg-gray-700 p-4">
48
+ <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Extended Navigation (5 tabs)</p>
49
+ <div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
50
+ <div class="h-64 bg-gradient-to-br from-purple-50 to-purple-100 flex items-center justify-center">
51
+ <p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
52
+ </div>
53
+ <div class="flex border-t bg-white dark:bg-gray-900">
54
+ <BottomNav links={extendedLinks} />
55
+ </div>
56
+ </div>
57
+ </div>
58
+ </Story>
59
+
60
+ <Story name="Different Icon Set">
61
+ <div class="bg-gray-100 dark:bg-gray-700 p-4">
62
+ <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Custom Icons</p>
63
+ <div class="max-w-md mx-auto bg-white dark:bg-gray-900 rounded-lg shadow-lg overflow-hidden">
64
+ <div class="h-64 bg-gradient-to-br from-green-50 to-green-100 flex items-center justify-center">
65
+ <p class="text-gray-500 dark:text-gray-400">Page Content Area</p>
66
+ </div>
67
+ <div class="flex border-t bg-white dark:bg-gray-900">
68
+ <BottomNav
69
+ links={[
70
+ { label: 'Dashboard', href: '/', icon: 'Home' },
71
+ { label: 'Events', href: '/events', icon: 'Shows' },
72
+ { label: 'Notifications', href: '/notifications', icon: 'Notification' },
73
+ { label: 'Settings', href: '/settings', icon: 'Profile' },
74
+ ]}
75
+ />
76
+ </div>
77
+ </div>
78
+ </div>
79
+ </Story>
80
+
81
+ <Story name="Mobile Viewport">
82
+ <div class="max-w-[375px] mx-auto bg-white dark:bg-gray-900 shadow-2xl rounded-3xl overflow-hidden">
83
+ <!-- Mock iPhone screen -->
84
+ <div class="h-[667px] flex flex-col">
85
+ <!-- Status bar -->
86
+ <div class="h-6 bg-black flex items-center justify-between px-4">
87
+ <span class="text-white text-xs">9:41</span>
88
+ <span class="text-white text-xs">100%</span>
89
+ </div>
90
+
91
+ <!-- Content area -->
92
+ <div class="flex-1 bg-gradient-to-br from-blue-50 to-purple-50 p-4">
93
+ <h1 class="text-2xl font-bold mb-2">Home</h1>
94
+ <p class="text-gray-500 dark:text-gray-400">This is a mobile viewport simulation</p>
95
+ </div>
96
+
97
+ <!-- Bottom navigation -->
98
+ <div class="flex border-t bg-white dark:bg-gray-900 safe-bottom">
99
+ <BottomNav links={defaultLinks} />
100
+ </div>
101
+ </div>
102
+ </div>
103
+ </Story>
104
+
105
+ <Story name="Dark Mode">
106
+ <div class="dark bg-gray-900 p-4 min-h-screen">
107
+ <p class="text-sm text-gray-500 dark:text-gray-400 mb-4">Dark Mode Bottom Navigation</p>
108
+ <div class="max-w-md mx-auto bg-gray-800 rounded-lg shadow-2xl overflow-hidden">
109
+ <div class="h-64 bg-gradient-to-br from-gray-900 to-gray-800 flex items-center justify-center">
110
+ <p class="text-gray-500 dark:text-gray-400">Dark Mode Content</p>
111
+ </div>
112
+ <div class="flex border-t border-gray-700 bg-gray-800">
113
+ <BottomNav links={defaultLinks} />
114
+ </div>
115
+ </div>
116
+ </div>
117
+ </Story>
@@ -1,74 +1,74 @@
1
- <script lang="ts">
2
- import { page } from '../../__LIB_STORES__.js';
3
- import { base } from '../../__LIB_PATHS__.js';
4
- import { browser } from '../../__LIB_ENVIRONMENT__.js';
5
- import { onMount } from "svelte";
6
- import Icon from "../../primitives/Icons/Icon.svelte";
7
- import { typography } from '../../tokens/typography';
8
-
9
- interface NavLink {
10
- label: string;
11
- href: string;
12
- icon: string;
13
- }
14
-
15
- interface Props {
16
- links?: NavLink[];
17
- }
18
-
19
- let {
20
- links = [],
21
- }: Props = $props();
22
-
23
- let invitationCount = $state(0);
24
-
25
- let currentPath = $derived($page.url.pathname);
26
-
27
- function isActive(href: string, path: string): boolean {
28
- if (href === `${base}/` || href === '/') {
29
- return path === href || path === `${base}/`;
30
- }
31
- return path.startsWith(href);
32
- }
33
-
34
- onMount(() => {
35
- async function fetchShows() {
36
- try {
37
- const res = await fetch(`/api/getEventsForVenue`);
38
- if (!res.ok) {
39
- // Silently ignore auth errors - user may not be logged in yet
40
- if (res.status === 401) return;
41
- return;
42
- }
43
- const events = await res.json();
44
- invitationCount = events.filter((event: { acceptedState: number }) => event.acceptedState === 0).length;
45
- } catch (_err) {
46
- // Silently fail - this is non-critical UI enhancement
47
- }
48
- }
49
-
50
- if (browser) {
51
- fetchShows();
52
- }
53
- });
54
- </script>
55
-
56
- {#each links as { label, href, icon }}
57
- <a
58
- {href}
59
- class={`bottom-nav-item flex-1 flex items-center justify-center py-3 px-2 no-underline bg-transparent border-none cursor-pointer min-w-0
60
- ${typography.textMuted} transition-colors duration-150
61
- hover:text-gray-900 hover:no-underline dark:hover:text-white
62
- select-none touch-manipulation
63
- ${isActive(href, currentPath) ? 'active text-blue-700 dark:text-blue-500' : ''}`}
64
- aria-label={label}
65
- style="-webkit-tap-highlight-color: transparent; -webkit-touch-callout: none;"
66
- >
67
- <span class="bottom-nav-icon relative flex items-center justify-center transition-transform duration-150 active:scale-[0.8]">
68
- <Icon name={icon} size="24" />
69
- {#if label === "Shows" && invitationCount > 0}
70
- <span class="notification-dot absolute -top-1 -right-1 w-2 h-2 bg-red-500 rounded-full"></span>
71
- {/if}
72
- </span>
73
- </a>
74
- {/each}
1
+ <script lang="ts">
2
+ import { page } from '../../__LIB_STORES__.js';
3
+ import { base } from '../../__LIB_PATHS__.js';
4
+ import { browser } from '../../__LIB_ENVIRONMENT__.js';
5
+ import { onMount } from "svelte";
6
+ import Icon from "../../primitives/Icons/Icon.svelte";
7
+ import { typography } from '../../tokens/typography';
8
+
9
+ interface NavLink {
10
+ label: string;
11
+ href: string;
12
+ icon: string;
13
+ }
14
+
15
+ interface Props {
16
+ links?: NavLink[];
17
+ }
18
+
19
+ let {
20
+ links = [],
21
+ }: Props = $props();
22
+
23
+ let invitationCount = $state(0);
24
+
25
+ let currentPath = $derived($page.url.pathname);
26
+
27
+ function isActive(href: string, path: string): boolean {
28
+ if (href === `${base}/` || href === '/') {
29
+ return path === href || path === `${base}/`;
30
+ }
31
+ return path.startsWith(href);
32
+ }
33
+
34
+ onMount(() => {
35
+ async function fetchShows() {
36
+ try {
37
+ const res = await fetch(`/api/getEventsForVenue`);
38
+ if (!res.ok) {
39
+ // Silently ignore auth errors - user may not be logged in yet
40
+ if (res.status === 401) return;
41
+ return;
42
+ }
43
+ const events = await res.json();
44
+ invitationCount = events.filter((event: { acceptedState: number }) => event.acceptedState === 0).length;
45
+ } catch (_err) {
46
+ // Silently fail - this is non-critical UI enhancement
47
+ }
48
+ }
49
+
50
+ if (browser) {
51
+ fetchShows();
52
+ }
53
+ });
54
+ </script>
55
+
56
+ {#each links as { label, href, icon }}
57
+ <a
58
+ {href}
59
+ class={`bottom-nav-item flex-1 flex items-center justify-center py-3 px-2 no-underline bg-transparent border-none cursor-pointer min-w-0
60
+ ${typography.textMuted} transition-colors duration-150
61
+ hover:text-gray-900 hover:no-underline dark:hover:text-white
62
+ select-none touch-manipulation
63
+ ${isActive(href, currentPath) ? 'active text-blue-700 dark:text-blue-500' : ''}`}
64
+ aria-label={label}
65
+ style="-webkit-tap-highlight-color: transparent; -webkit-touch-callout: none;"
66
+ >
67
+ <span class="bottom-nav-icon relative flex items-center justify-center transition-transform duration-150 active:scale-[0.8]">
68
+ <Icon name={icon} size="24" />
69
+ {#if label === "Shows" && invitationCount > 0}
70
+ <span class="notification-dot absolute -top-1 -right-1 w-2 h-2 bg-red-500 rounded-full"></span>
71
+ {/if}
72
+ </span>
73
+ </a>
74
+ {/each}
@@ -136,6 +136,18 @@ describe('Header', () => {
136
136
  await fireEvent.click(desktopButton);
137
137
  expect(container.querySelector('div.absolute.top-\\[calc\\(100\\%\\+0\\.5rem\\)\\]')).toBeFalsy();
138
138
  });
139
+ it('navigates and closes dropdown when a dropdown link is clicked', async () => {
140
+ const { goto } = await import('$app/navigation');
141
+ const { container } = render(Header, defaultProps);
142
+ const desktopButton = container.querySelector('button.hidden.md\\:block');
143
+ await fireEvent.click(desktopButton);
144
+ // Click the "Account Settings" menu item in the dropdown
145
+ const accountSettings = screen.getByText('Account Settings');
146
+ await fireEvent.click(accountSettings);
147
+ expect(goto).toHaveBeenCalledWith('/account-settings');
148
+ // Dropdown should be closed after clicking
149
+ expect(container.querySelector('div.absolute.top-\\[calc\\(100\\%\\+0\\.5rem\\)\\]')).toBeFalsy();
150
+ });
139
151
  });
140
152
  describe('mobile sheet', () => {
141
153
  it('triggers mobile sheet state when mobile avatar is clicked', async () => {
@@ -150,6 +162,69 @@ describe('Header', () => {
150
162
  const mobileSheet = document.body.querySelector('div.fixed.inset-0.bg-black\\/50');
151
163
  expect(mobileSheet).toBeTruthy();
152
164
  });
165
+ it('navigates when a mobile sheet dropdown link is clicked', async () => {
166
+ const { goto } = await import('$app/navigation');
167
+ const { container } = render(Header, defaultProps);
168
+ const mobileButton = container.querySelector('button.block.md\\:hidden');
169
+ await fireEvent.click(mobileButton);
170
+ // Mobile sheet renders via portal in document.body
171
+ const mobileSheet = document.body.querySelector('div.fixed.inset-0.bg-black\\/50');
172
+ expect(mobileSheet).toBeTruthy();
173
+ // Click the first dropdown link in the mobile sheet
174
+ const menuItems = mobileSheet.querySelectorAll('button');
175
+ // Find the menu item with "Account Settings" text
176
+ const accountBtn = Array.from(menuItems).find(btn => btn.textContent?.includes('Account Settings'));
177
+ expect(accountBtn).toBeTruthy();
178
+ await fireEvent.click(accountBtn);
179
+ expect(goto).toHaveBeenCalledWith('/account-settings');
180
+ });
181
+ it('calls signoutHandler and closes sheet when mobile sign out is clicked', async () => {
182
+ const signoutHandler = vi.fn();
183
+ const { container } = render(Header, { ...defaultProps, signoutHandler });
184
+ const mobileButton = container.querySelector('button.block.md\\:hidden');
185
+ await fireEvent.click(mobileButton);
186
+ const mobileSheet = document.body.querySelector('div.fixed.inset-0.bg-black\\/50');
187
+ expect(mobileSheet).toBeTruthy();
188
+ // Find the Sign Out button in the mobile sheet
189
+ const menuItems = mobileSheet.querySelectorAll('button');
190
+ const signOutBtn = Array.from(menuItems).find(btn => btn.textContent?.includes('Sign Out'));
191
+ expect(signOutBtn).toBeTruthy();
192
+ await fireEvent.click(signOutBtn);
193
+ expect(signoutHandler).toHaveBeenCalled();
194
+ });
195
+ });
196
+ describe('back button mode desktop dropdown', () => {
197
+ it('shows dropdown with dropdown links and sign out when avatar clicked in back-button mode', async () => {
198
+ const { goto } = await import('$app/navigation');
199
+ const signoutHandler = vi.fn();
200
+ const { container } = render(Header, { ...defaultProps, showBackButton: true, signoutHandler });
201
+ // In back-button mode, the desktop section is within "hidden md:flex"
202
+ // The avatar button is the only AvatarButton in that section
203
+ const avatarButtons = container.querySelectorAll('button');
204
+ // Find the avatar button that opens the dropdown (not the Back button)
205
+ const desktopAvatarBtn = Array.from(avatarButtons).find(btn => !btn.textContent?.includes('Back') && btn.querySelector('img'));
206
+ expect(desktopAvatarBtn).toBeTruthy();
207
+ await fireEvent.click(desktopAvatarBtn);
208
+ // Dropdown should be visible
209
+ const dropdown = container.querySelector('div.absolute.top-\\[calc\\(100\\%\\+0\\.5rem\\)\\]');
210
+ expect(dropdown).toBeTruthy();
211
+ // Click a dropdown link
212
+ const accountSettings = screen.getByText('Account Settings');
213
+ await fireEvent.click(accountSettings);
214
+ expect(goto).toHaveBeenCalledWith('/account-settings');
215
+ });
216
+ it('calls signoutHandler when sign out clicked in back-button mode dropdown', async () => {
217
+ const signoutHandler = vi.fn();
218
+ const { container } = render(Header, { ...defaultProps, showBackButton: true, signoutHandler });
219
+ // Find the avatar button (not the Back button)
220
+ const avatarButtons = container.querySelectorAll('button');
221
+ const desktopAvatarBtn = Array.from(avatarButtons).find(btn => !btn.textContent?.includes('Back') && btn.querySelector('img'));
222
+ await fireEvent.click(desktopAvatarBtn);
223
+ // Click sign out
224
+ const signOutBtn = screen.getByText('Sign out');
225
+ await fireEvent.click(signOutBtn);
226
+ expect(signoutHandler).toHaveBeenCalled();
227
+ });
153
228
  });
154
229
  describe('navigation active state', () => {
155
230
  it('marks current path as active', () => {
@@ -166,5 +241,53 @@ describe('Header', () => {
166
241
  await fireEvent.click(desktopButton);
167
242
  expect(screen.getByText('Performer')).toBeTruthy();
168
243
  });
244
+ it('shows name in mobile sheet when provided', async () => {
245
+ const { container } = render(Header, { ...defaultProps, name: 'Jane Doe' });
246
+ const mobileButton = container.querySelector('button.block.md\\:hidden');
247
+ await fireEvent.click(mobileButton);
248
+ const mobileSheet = document.body.querySelector('div.fixed.inset-0.bg-black\\/50');
249
+ expect(mobileSheet).toBeTruthy();
250
+ expect(mobileSheet.textContent).toContain('Jane Doe');
251
+ });
252
+ it('shows "Performer" in mobile sheet when name is empty', async () => {
253
+ const { container } = render(Header, { ...defaultProps, name: '' });
254
+ const mobileButton = container.querySelector('button.block.md\\:hidden');
255
+ await fireEvent.click(mobileButton);
256
+ const mobileSheet = document.body.querySelector('div.fixed.inset-0.bg-black\\/50');
257
+ expect(mobileSheet).toBeTruthy();
258
+ expect(mobileSheet.textContent).toContain('Performer');
259
+ });
260
+ it('shows "Performer" in back-button mode dropdown when name is empty', async () => {
261
+ const { container } = render(Header, { ...defaultProps, name: '', showBackButton: true });
262
+ const avatarButtons = container.querySelectorAll('button');
263
+ const desktopAvatarBtn = Array.from(avatarButtons).find(btn => !btn.textContent?.includes('Back') && btn.querySelector('img'));
264
+ await fireEvent.click(desktopAvatarBtn);
265
+ const dropdown = container.querySelector('div.absolute.top-\\[calc\\(100\\%\\+0\\.5rem\\)\\]');
266
+ expect(dropdown).toBeTruthy();
267
+ expect(dropdown.textContent).toContain('Performer');
268
+ });
269
+ });
270
+ describe('isActive edge cases', () => {
271
+ it('marks root nav link as active when path matches base', () => {
272
+ // The mock sets page pathname to '/shows' and base to '/performers'
273
+ // Add a root link and verify it is NOT active (since path is /shows)
274
+ const propsWithRoot = {
275
+ ...defaultProps,
276
+ navLinks: [
277
+ { label: 'Home', href: '/performers/' },
278
+ ...defaultProps.navLinks
279
+ ]
280
+ };
281
+ const { container } = render(Header, propsWithRoot);
282
+ const homeLink = container.querySelector('a[href="/performers/"]');
283
+ // /shows does not match /performers/, so it should NOT be active
284
+ expect(homeLink.classList.contains('text-blue-700')).toBe(false);
285
+ });
286
+ it('marks link as active using startsWith for non-root paths', () => {
287
+ const { container } = render(Header, defaultProps);
288
+ // '/shows' starts with '/shows' so it should be active
289
+ const showsLink = container.querySelector('a[href="/shows"]');
290
+ expect(showsLink.classList.contains('text-blue-700')).toBe(true);
291
+ });
169
292
  });
170
293
  });