@sovereignfs/ui 0.83.1 → 0.89.1

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 (556) hide show
  1. package/LICENSE +373 -661
  2. package/NOTICE +8 -0
  3. package/README.md +4 -6
  4. package/dist/AppsLauncher.module.css +6 -0
  5. package/dist/Button.module.css +5 -0
  6. package/dist/Card.module.css +6 -0
  7. package/dist/CardTile.module.css +6 -0
  8. package/dist/CheckableListRow.module.css +8 -0
  9. package/dist/Checkbox.module.css +8 -0
  10. package/dist/CodeTextarea.module.css +6 -0
  11. package/dist/ColorPicker.module.css +6 -0
  12. package/dist/Combobox.module.css +6 -0
  13. package/dist/Command.module.css +6 -0
  14. package/dist/ConfirmDialog.module.css +6 -0
  15. package/dist/DatePicker.module.css +6 -0
  16. package/dist/Dialog.module.css +1 -1
  17. package/dist/DragHandleRow.module.css +6 -0
  18. package/dist/FileDropzone.module.css +25 -1
  19. package/dist/Header.module.css +6 -0
  20. package/dist/IconPicker.module.css +14 -4
  21. package/dist/Input.module.css +6 -0
  22. package/dist/LegalLinks.module.css +9 -2
  23. package/dist/Markdown.module.css +5 -0
  24. package/dist/Message.module.css +9 -0
  25. package/dist/MobileAppsDrawer.module.css +9 -5
  26. package/dist/MobileFooter.module.css +6 -0
  27. package/dist/NavList.module.css +11 -2
  28. package/dist/NavTabs.module.css +7 -1
  29. package/dist/NotificationsPanel.module.css +10 -0
  30. package/dist/QrCode.module.css +17 -0
  31. package/dist/QuantityStepper.module.css +4 -2
  32. package/dist/RadioGroup.module.css +6 -0
  33. package/dist/SegmentedControl.module.css +6 -0
  34. package/dist/Select.module.css +6 -0
  35. package/dist/Sheet.module.css +16 -1
  36. package/dist/SplitPane.module.css +1 -1
  37. package/dist/StepStrip.module.css +5 -3
  38. package/dist/SuggestionInput.module.css +12 -1
  39. package/dist/SwipableMobileCarouselDots.module.css +6 -0
  40. package/dist/SystemBanner.module.css +6 -0
  41. package/dist/Tabs.module.css +6 -0
  42. package/dist/TagInput.module.css +6 -0
  43. package/dist/Textarea.module.css +6 -0
  44. package/dist/Toast.module.css +5 -0
  45. package/dist/Toggle.module.css +7 -0
  46. package/dist/Tooltip.module.css +6 -0
  47. package/dist/UserMenu.module.css +5 -0
  48. package/dist/fonts/OFL.txt +93 -0
  49. package/dist/fonts/hanken-grotesk-cyrillic-ext-wght-normal.woff2 +0 -0
  50. package/dist/fonts/hanken-grotesk-latin-ext-wght-normal.woff2 +0 -0
  51. package/dist/fonts/hanken-grotesk-latin-wght-normal.woff2 +0 -0
  52. package/dist/fonts/hanken-grotesk-vietnamese-wght-normal.woff2 +0 -0
  53. package/dist/index.d.ts +121 -43
  54. package/dist/index.js +1410 -1152
  55. package/dist/tokens/fonts.css +53 -0
  56. package/dist/tokens/primitives.css +12 -12
  57. package/dist/tokens.css +2 -1
  58. package/package.json +24 -13
  59. package/src/__tests__/motion.test.tsx +0 -105
  60. package/src/__tests__/package-json.test.ts +0 -8
  61. package/src/components/Accordion/Accordion.module.css +0 -3
  62. package/src/components/Accordion/Accordion.stories.tsx +0 -110
  63. package/src/components/Accordion/Accordion.tsx +0 -53
  64. package/src/components/Accordion/__tests__/Accordion.test.tsx +0 -61
  65. package/src/components/Alert/Alert.module.css +0 -62
  66. package/src/components/Alert/Alert.stories.tsx +0 -96
  67. package/src/components/Alert/Alert.tsx +0 -58
  68. package/src/components/Alert/__tests__/Alert.test.tsx +0 -75
  69. package/src/components/AppsLauncher/AppsLauncher.module.css +0 -96
  70. package/src/components/AppsLauncher/AppsLauncher.stories.tsx +0 -58
  71. package/src/components/AppsLauncher/AppsLauncher.tsx +0 -117
  72. package/src/components/AppsLauncher/__tests__/AppsLauncher.test.tsx +0 -52
  73. package/src/components/AspectRatio/AspectRatio.module.css +0 -15
  74. package/src/components/AspectRatio/AspectRatio.stories.tsx +0 -78
  75. package/src/components/AspectRatio/AspectRatio.tsx +0 -21
  76. package/src/components/AspectRatio/__tests__/AspectRatio.test.tsx +0 -27
  77. package/src/components/Avatar/Avatar.module.css +0 -38
  78. package/src/components/Avatar/Avatar.tsx +0 -42
  79. package/src/components/Badge/Badge.module.css +0 -177
  80. package/src/components/Badge/Badge.stories.tsx +0 -238
  81. package/src/components/Badge/Badge.tsx +0 -84
  82. package/src/components/Badge/__tests__/Badge.test.tsx +0 -90
  83. package/src/components/BalanceChip/BalanceChip.module.css +0 -32
  84. package/src/components/BalanceChip/BalanceChip.stories.tsx +0 -45
  85. package/src/components/BalanceChip/BalanceChip.tsx +0 -33
  86. package/src/components/Breadcrumb/Breadcrumb.module.css +0 -49
  87. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +0 -47
  88. package/src/components/Breadcrumb/Breadcrumb.tsx +0 -57
  89. package/src/components/Breadcrumb/__tests__/Breadcrumb.test.tsx +0 -52
  90. package/src/components/Button/Button.module.css +0 -169
  91. package/src/components/Button/Button.stories.tsx +0 -83
  92. package/src/components/Button/Button.tsx +0 -52
  93. package/src/components/Button/__tests__/Button.test.tsx +0 -66
  94. package/src/components/ButtonGroup/ButtonGroup.module.css +0 -29
  95. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +0 -57
  96. package/src/components/ButtonGroup/ButtonGroup.tsx +0 -27
  97. package/src/components/ButtonGroup/__tests__/ButtonGroup.test.tsx +0 -29
  98. package/src/components/Calendar/Calendar.module.css +0 -126
  99. package/src/components/Calendar/Calendar.tsx +0 -213
  100. package/src/components/Calendar/__tests__/Calendar.test.tsx +0 -98
  101. package/src/components/Calendar/dateUtils.ts +0 -97
  102. package/src/components/Card/Card.module.css +0 -42
  103. package/src/components/Card/Card.tsx +0 -34
  104. package/src/components/CardTile/CardTile.module.css +0 -181
  105. package/src/components/CardTile/CardTile.stories.tsx +0 -86
  106. package/src/components/CardTile/CardTile.tsx +0 -128
  107. package/src/components/CardTile/__tests__/CardTile.test.tsx +0 -56
  108. package/src/components/CheckableListRow/CheckableListRow.module.css +0 -95
  109. package/src/components/CheckableListRow/CheckableListRow.stories.tsx +0 -99
  110. package/src/components/CheckableListRow/CheckableListRow.tsx +0 -89
  111. package/src/components/Checkbox/Checkbox.module.css +0 -111
  112. package/src/components/Checkbox/Checkbox.tsx +0 -78
  113. package/src/components/CodeTextarea/CodeTextarea.module.css +0 -53
  114. package/src/components/CodeTextarea/CodeTextarea.stories.tsx +0 -77
  115. package/src/components/CodeTextarea/CodeTextarea.tsx +0 -36
  116. package/src/components/Collapsible/Collapsible.module.css +0 -70
  117. package/src/components/Collapsible/Collapsible.stories.tsx +0 -62
  118. package/src/components/Collapsible/Collapsible.tsx +0 -66
  119. package/src/components/Collapsible/__tests__/Collapsible.test.tsx +0 -71
  120. package/src/components/ColorPicker/ColorPicker.module.css +0 -132
  121. package/src/components/ColorPicker/ColorPicker.stories.tsx +0 -80
  122. package/src/components/ColorPicker/ColorPicker.tsx +0 -157
  123. package/src/components/ColorPicker/__tests__/ColorPicker.test.tsx +0 -117
  124. package/src/components/Combobox/Combobox.module.css +0 -122
  125. package/src/components/Combobox/Combobox.stories.tsx +0 -79
  126. package/src/components/Combobox/Combobox.tsx +0 -186
  127. package/src/components/Combobox/__tests__/Combobox.test.tsx +0 -158
  128. package/src/components/Command/Command.module.css +0 -80
  129. package/src/components/Command/Command.stories.tsx +0 -104
  130. package/src/components/Command/Command.tsx +0 -168
  131. package/src/components/Command/__tests__/Command.test.tsx +0 -162
  132. package/src/components/ConfirmDialog/ConfirmDialog.module.css +0 -113
  133. package/src/components/ConfirmDialog/ConfirmDialog.tsx +0 -150
  134. package/src/components/ConfirmDialog/__tests__/ConfirmDialog.test.tsx +0 -214
  135. package/src/components/ConsentPrompt/ConsentPrompt.module.css +0 -21
  136. package/src/components/ConsentPrompt/ConsentPrompt.stories.tsx +0 -31
  137. package/src/components/ConsentPrompt/ConsentPrompt.tsx +0 -66
  138. package/src/components/ContextMenu/ContextMenu.stories.tsx +0 -81
  139. package/src/components/ContextMenu/ContextMenu.tsx +0 -100
  140. package/src/components/ContextMenu/__tests__/ContextMenu.test.tsx +0 -87
  141. package/src/components/CurrencyInput/CurrencyInput.stories.tsx +0 -50
  142. package/src/components/CurrencyInput/CurrencyInput.tsx +0 -60
  143. package/src/components/DataTable/DataTable.module.css +0 -28
  144. package/src/components/DataTable/DataTable.stories.tsx +0 -74
  145. package/src/components/DataTable/DataTable.tsx +0 -154
  146. package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -123
  147. package/src/components/DatePicker/DatePicker.module.css +0 -61
  148. package/src/components/DatePicker/DatePicker.tsx +0 -103
  149. package/src/components/DatePicker/__tests__/DatePicker.test.tsx +0 -89
  150. package/src/components/DeviceOnlyGate/DeviceOnlyGate.tsx +0 -58
  151. package/src/components/DeviceOnlyGate/__tests__/DeviceOnlyGate.test.tsx +0 -45
  152. package/src/components/DeviceStorageKeyGate/DeviceStorageKeyGate.tsx +0 -100
  153. package/src/components/DeviceStorageKeyGate/__tests__/DeviceStorageKeyGate.test.tsx +0 -119
  154. package/src/components/Dialog/Dialog.module.css +0 -335
  155. package/src/components/Dialog/Dialog.stories.tsx +0 -324
  156. package/src/components/Dialog/Dialog.tsx +0 -254
  157. package/src/components/Dialog/__tests__/Dialog.test.tsx +0 -318
  158. package/src/components/DragHandleRow/DragHandleRow.module.css +0 -57
  159. package/src/components/DragHandleRow/DragHandleRow.tsx +0 -42
  160. package/src/components/Drawer/Drawer.module.css +0 -121
  161. package/src/components/Drawer/Drawer.stories.tsx +0 -132
  162. package/src/components/Drawer/Drawer.tsx +0 -175
  163. package/src/components/Drawer/__tests__/Drawer.test.tsx +0 -226
  164. package/src/components/EmptyState/EmptyState.module.css +0 -27
  165. package/src/components/EmptyState/EmptyState.tsx +0 -27
  166. package/src/components/FileDropzone/FileDropzone.module.css +0 -63
  167. package/src/components/FileDropzone/FileDropzone.tsx +0 -109
  168. package/src/components/FileDropzone/__tests__/FileDropzone.test.tsx +0 -67
  169. package/src/components/FormField/FormField.module.css +0 -33
  170. package/src/components/FormField/FormField.tsx +0 -78
  171. package/src/components/FormField/__tests__/FormField.test.tsx +0 -83
  172. package/src/components/GripIcon/GripIcon.tsx +0 -27
  173. package/src/components/Header/Header.module.css +0 -62
  174. package/src/components/Header/Header.stories.tsx +0 -452
  175. package/src/components/Header/Header.tsx +0 -102
  176. package/src/components/Header/__tests__/Header.test.tsx +0 -104
  177. package/src/components/HeaderFooterLayout/HeaderFooterLayout.module.css +0 -21
  178. package/src/components/HeaderFooterLayout/HeaderFooterLayout.stories.tsx +0 -111
  179. package/src/components/HeaderFooterLayout/HeaderFooterLayout.tsx +0 -54
  180. package/src/components/HeaderFooterLayout/__tests__/HeaderFooterLayout.test.tsx +0 -58
  181. package/src/components/HoverCard/HoverCard.module.css +0 -3
  182. package/src/components/HoverCard/HoverCard.stories.tsx +0 -66
  183. package/src/components/HoverCard/HoverCard.tsx +0 -111
  184. package/src/components/HoverCard/__tests__/HoverCard.test.tsx +0 -99
  185. package/src/components/Icon/Icon.module.css +0 -27
  186. package/src/components/Icon/Icon.stories.tsx +0 -95
  187. package/src/components/Icon/Icon.tsx +0 -43
  188. package/src/components/Icon/__tests__/Icon.test.tsx +0 -40
  189. package/src/components/Icon/icons/activity.tsx +0 -20
  190. package/src/components/Icon/icons/alert-triangle.tsx +0 -22
  191. package/src/components/Icon/icons/apple.tsx +0 -21
  192. package/src/components/Icon/icons/arrow-left-right.tsx +0 -23
  193. package/src/components/Icon/icons/banana.tsx +0 -21
  194. package/src/components/Icon/icons/beef.tsx +0 -22
  195. package/src/components/Icon/icons/beer.tsx +0 -24
  196. package/src/components/Icon/icons/bell.tsx +0 -21
  197. package/src/components/Icon/icons/bold.tsx +0 -20
  198. package/src/components/Icon/icons/calendar.tsx +0 -23
  199. package/src/components/Icon/icons/candy.tsx +0 -24
  200. package/src/components/Icon/icons/carrot.tsx +0 -22
  201. package/src/components/Icon/icons/check.tsx +0 -20
  202. package/src/components/Icon/icons/chevron-down.tsx +0 -20
  203. package/src/components/Icon/icons/chevron-left.tsx +0 -20
  204. package/src/components/Icon/icons/chevron-right.tsx +0 -20
  205. package/src/components/Icon/icons/chevron-up.tsx +0 -20
  206. package/src/components/Icon/icons/circle-check.tsx +0 -21
  207. package/src/components/Icon/icons/circle-chevron-left.tsx +0 -21
  208. package/src/components/Icon/icons/circle-x.tsx +0 -22
  209. package/src/components/Icon/icons/code.tsx +0 -21
  210. package/src/components/Icon/icons/coffee.tsx +0 -23
  211. package/src/components/Icon/icons/cookie.tsx +0 -25
  212. package/src/components/Icon/icons/copy.tsx +0 -21
  213. package/src/components/Icon/icons/credit-card.tsx +0 -21
  214. package/src/components/Icon/icons/croissant.tsx +0 -24
  215. package/src/components/Icon/icons/cup-soda.tsx +0 -23
  216. package/src/components/Icon/icons/database.tsx +0 -22
  217. package/src/components/Icon/icons/download.tsx +0 -22
  218. package/src/components/Icon/icons/drumstick.tsx +0 -21
  219. package/src/components/Icon/icons/egg.tsx +0 -20
  220. package/src/components/Icon/icons/ellipsis-vertical.tsx +0 -22
  221. package/src/components/Icon/icons/external-link.tsx +0 -22
  222. package/src/components/Icon/icons/eye-off.tsx +0 -23
  223. package/src/components/Icon/icons/eye.tsx +0 -21
  224. package/src/components/Icon/icons/file-text.tsx +0 -24
  225. package/src/components/Icon/icons/file.tsx +0 -21
  226. package/src/components/Icon/icons/fish.tsx +0 -25
  227. package/src/components/Icon/icons/folder-closed.tsx +0 -21
  228. package/src/components/Icon/icons/folder-open.tsx +0 -20
  229. package/src/components/Icon/icons/folder.tsx +0 -20
  230. package/src/components/Icon/icons/folders.tsx +0 -21
  231. package/src/components/Icon/icons/grid-2x2.tsx +0 -22
  232. package/src/components/Icon/icons/hat-glasses.tsx +0 -24
  233. package/src/components/Icon/icons/history.tsx +0 -22
  234. package/src/components/Icon/icons/house.tsx +0 -21
  235. package/src/components/Icon/icons/inbox.tsx +0 -21
  236. package/src/components/Icon/icons/index.ts +0 -394
  237. package/src/components/Icon/icons/info.tsx +0 -22
  238. package/src/components/Icon/icons/italic.tsx +0 -22
  239. package/src/components/Icon/icons/layers.tsx +0 -22
  240. package/src/components/Icon/icons/layout-dashboard.tsx +0 -23
  241. package/src/components/Icon/icons/layout-grid.tsx +0 -23
  242. package/src/components/Icon/icons/link.tsx +0 -21
  243. package/src/components/Icon/icons/list-ordered.tsx +0 -25
  244. package/src/components/Icon/icons/list.tsx +0 -25
  245. package/src/components/Icon/icons/lock.tsx +0 -21
  246. package/src/components/Icon/icons/log-out.tsx +0 -22
  247. package/src/components/Icon/icons/luggage.tsx +0 -24
  248. package/src/components/Icon/icons/mail.tsx +0 -21
  249. package/src/components/Icon/icons/map-pin.tsx +0 -21
  250. package/src/components/Icon/icons/menu.tsx +0 -22
  251. package/src/components/Icon/icons/milk.tsx +0 -22
  252. package/src/components/Icon/icons/minus.tsx +0 -20
  253. package/src/components/Icon/icons/package.tsx +0 -23
  254. package/src/components/Icon/icons/paint-bucket.tsx +0 -23
  255. package/src/components/Icon/icons/panel-left.tsx +0 -21
  256. package/src/components/Icon/icons/pencil.tsx +0 -21
  257. package/src/components/Icon/icons/pin.tsx +0 -21
  258. package/src/components/Icon/icons/pizza.tsx +0 -24
  259. package/src/components/Icon/icons/plus.tsx +0 -21
  260. package/src/components/Icon/icons/rectangle-ellipsis.tsx +0 -23
  261. package/src/components/Icon/icons/refresh-cw.tsx +0 -23
  262. package/src/components/Icon/icons/rotate-ccw.tsx +0 -21
  263. package/src/components/Icon/icons/rotate-cw.tsx +0 -21
  264. package/src/components/Icon/icons/route.tsx +0 -22
  265. package/src/components/Icon/icons/salad.tsx +0 -24
  266. package/src/components/Icon/icons/search.tsx +0 -21
  267. package/src/components/Icon/icons/send.tsx +0 -21
  268. package/src/components/Icon/icons/settings.tsx +0 -21
  269. package/src/components/Icon/icons/share-2.tsx +0 -24
  270. package/src/components/Icon/icons/sheet.tsx +0 -24
  271. package/src/components/Icon/icons/shield.tsx +0 -20
  272. package/src/components/Icon/icons/shopping-basket.tsx +0 -26
  273. package/src/components/Icon/icons/sliders-horizontal.tsx +0 -28
  274. package/src/components/Icon/icons/smartphone.tsx +0 -21
  275. package/src/components/Icon/icons/snowflake.tsx +0 -31
  276. package/src/components/Icon/icons/spray-can.tsx +0 -29
  277. package/src/components/Icon/icons/square-kanban.tsx +0 -23
  278. package/src/components/Icon/icons/table.tsx +0 -23
  279. package/src/components/Icon/icons/trash-2.tsx +0 -24
  280. package/src/components/Icon/icons/upload.tsx +0 -22
  281. package/src/components/Icon/icons/user-round-plus.tsx +0 -23
  282. package/src/components/Icon/icons/user.tsx +0 -21
  283. package/src/components/Icon/icons/users.tsx +0 -23
  284. package/src/components/Icon/icons/wine.tsx +0 -23
  285. package/src/components/Icon/icons/x.tsx +0 -21
  286. package/src/components/IconPicker/IconPicker.module.css +0 -63
  287. package/src/components/IconPicker/IconPicker.stories.tsx +0 -84
  288. package/src/components/IconPicker/IconPicker.tsx +0 -90
  289. package/src/components/Input/Input.module.css +0 -52
  290. package/src/components/Input/Input.stories.tsx +0 -86
  291. package/src/components/Input/Input.tsx +0 -20
  292. package/src/components/Input/__tests__/Input.test.tsx +0 -22
  293. package/src/components/Item/Item.module.css +0 -70
  294. package/src/components/Item/Item.stories.tsx +0 -62
  295. package/src/components/Item/Item.tsx +0 -54
  296. package/src/components/Item/__tests__/Item.test.tsx +0 -39
  297. package/src/components/Kbd/Kbd.module.css +0 -14
  298. package/src/components/Kbd/Kbd.stories.tsx +0 -32
  299. package/src/components/Kbd/Kbd.tsx +0 -12
  300. package/src/components/Kbd/__tests__/Kbd.test.tsx +0 -14
  301. package/src/components/Label/Label.module.css +0 -11
  302. package/src/components/Label/Label.stories.tsx +0 -40
  303. package/src/components/Label/Label.tsx +0 -24
  304. package/src/components/Label/__tests__/Label.test.tsx +0 -32
  305. package/src/components/LegalLinks/LegalLinks.module.css +0 -24
  306. package/src/components/LegalLinks/LegalLinks.stories.tsx +0 -22
  307. package/src/components/LegalLinks/LegalLinks.tsx +0 -40
  308. package/src/components/Markdown/Markdown.module.css +0 -73
  309. package/src/components/Markdown/Markdown.stories.tsx +0 -40
  310. package/src/components/Markdown/Markdown.tsx +0 -305
  311. package/src/components/Markdown/__tests__/Markdown.test.tsx +0 -144
  312. package/src/components/Marker/Marker.module.css +0 -33
  313. package/src/components/Marker/Marker.stories.tsx +0 -39
  314. package/src/components/Marker/Marker.tsx +0 -34
  315. package/src/components/Marker/__tests__/Marker.test.tsx +0 -23
  316. package/src/components/MemberMultiSelect/MemberMultiSelect.module.css +0 -27
  317. package/src/components/MemberMultiSelect/MemberMultiSelect.stories.tsx +0 -74
  318. package/src/components/MemberMultiSelect/MemberMultiSelect.tsx +0 -67
  319. package/src/components/Menu/Menu.module.css +0 -90
  320. package/src/components/Menu/Menu.tsx +0 -209
  321. package/src/components/Menu/__tests__/Menu.test.tsx +0 -227
  322. package/src/components/Menubar/Menubar.stories.tsx +0 -52
  323. package/src/components/Menubar/Menubar.tsx +0 -42
  324. package/src/components/Menubar/__tests__/Menubar.test.tsx +0 -45
  325. package/src/components/Message/Message.module.css +0 -99
  326. package/src/components/Message/Message.stories.tsx +0 -79
  327. package/src/components/Message/Message.tsx +0 -41
  328. package/src/components/Message/__tests__/Message.test.tsx +0 -46
  329. package/src/components/MessageScroller/MessageScroller.module.css +0 -65
  330. package/src/components/MessageScroller/MessageScroller.stories.tsx +0 -84
  331. package/src/components/MessageScroller/MessageScroller.tsx +0 -84
  332. package/src/components/MessageScroller/__tests__/MessageScroller.test.tsx +0 -105
  333. package/src/components/MobileAppsDrawer/MobileAppsDrawer.module.css +0 -82
  334. package/src/components/MobileAppsDrawer/MobileAppsDrawer.tsx +0 -78
  335. package/src/components/MobileAppsDrawer/__tests__/MobileAppsDrawer.test.tsx +0 -80
  336. package/src/components/MobileFooter/MobileFooter.module.css +0 -73
  337. package/src/components/MobileFooter/MobileFooter.stories.tsx +0 -47
  338. package/src/components/MobileFooter/MobileFooter.tsx +0 -122
  339. package/src/components/MobileFooter/__tests__/MobileFooter.test.tsx +0 -129
  340. package/src/components/MobileHeader/MobileHeader.module.css +0 -76
  341. package/src/components/MobileHeader/MobileHeader.stories.tsx +0 -57
  342. package/src/components/MobileHeader/MobileHeader.tsx +0 -90
  343. package/src/components/MobileHeader/__tests__/MobileHeader.test.tsx +0 -113
  344. package/src/components/NavList/NavList.module.css +0 -130
  345. package/src/components/NavList/NavList.tsx +0 -136
  346. package/src/components/NavList/__tests__/NavList.test.tsx +0 -109
  347. package/src/components/NavTabs/NavTabs.module.css +0 -50
  348. package/src/components/NavTabs/NavTabs.tsx +0 -61
  349. package/src/components/NavigationMenu/NavigationMenu.module.css +0 -53
  350. package/src/components/NavigationMenu/NavigationMenu.stories.tsx +0 -58
  351. package/src/components/NavigationMenu/NavigationMenu.tsx +0 -125
  352. package/src/components/NavigationMenu/__tests__/NavigationMenu.test.tsx +0 -93
  353. package/src/components/NotificationsPanel/NotificationsPanel.module.css +0 -258
  354. package/src/components/NotificationsPanel/NotificationsPanel.stories.tsx +0 -61
  355. package/src/components/NotificationsPanel/NotificationsPanel.tsx +0 -187
  356. package/src/components/NotificationsPanel/__tests__/NotificationsPanel.test.tsx +0 -78
  357. package/src/components/OfflineGate/OfflineGate.tsx +0 -44
  358. package/src/components/OfflineGate/__tests__/OfflineGate.test.tsx +0 -66
  359. package/src/components/OverlayHeader/OverlayHeader.module.css +0 -98
  360. package/src/components/OverlayHeader/OverlayHeader.tsx +0 -77
  361. package/src/components/OverlayHeader/__tests__/OverlayHeader.test.tsx +0 -69
  362. package/src/components/PageContainer/PageContainer.module.css +0 -82
  363. package/src/components/PageContainer/PageContainer.tsx +0 -64
  364. package/src/components/PageContainer/__tests__/PageContainer.test.tsx +0 -70
  365. package/src/components/PageHeader/PageHeader.module.css +0 -86
  366. package/src/components/PageHeader/PageHeader.tsx +0 -176
  367. package/src/components/PageHeader/__tests__/PageHeader.test.tsx +0 -103
  368. package/src/components/PageLayout/PageLayout.module.css +0 -51
  369. package/src/components/PageLayout/PageLayout.stories.tsx +0 -73
  370. package/src/components/PageLayout/PageLayout.tsx +0 -51
  371. package/src/components/PageLayout/__tests__/PageLayout.test.tsx +0 -34
  372. package/src/components/Pagination/Pagination.module.css +0 -98
  373. package/src/components/Pagination/Pagination.stories.tsx +0 -49
  374. package/src/components/Pagination/Pagination.tsx +0 -87
  375. package/src/components/Pagination/__tests__/Pagination.test.tsx +0 -56
  376. package/src/components/Popover/Popover.module.css +0 -74
  377. package/src/components/Popover/Popover.stories.tsx +0 -357
  378. package/src/components/Popover/Popover.tsx +0 -290
  379. package/src/components/Popover/__tests__/Popover.test.tsx +0 -263
  380. package/src/components/Progress/Progress.module.css +0 -20
  381. package/src/components/Progress/Progress.stories.tsx +0 -40
  382. package/src/components/Progress/Progress.tsx +0 -35
  383. package/src/components/Progress/__tests__/Progress.test.tsx +0 -31
  384. package/src/components/QuantityStepper/QuantityStepper.module.css +0 -67
  385. package/src/components/QuantityStepper/QuantityStepper.stories.tsx +0 -79
  386. package/src/components/QuantityStepper/QuantityStepper.tsx +0 -107
  387. package/src/components/RadioGroup/RadioGroup.module.css +0 -88
  388. package/src/components/RadioGroup/RadioGroup.stories.tsx +0 -69
  389. package/src/components/RadioGroup/RadioGroup.tsx +0 -99
  390. package/src/components/RadioGroup/__tests__/RadioGroup.test.tsx +0 -59
  391. package/src/components/Resizable/Resizable.module.css +0 -70
  392. package/src/components/Resizable/Resizable.stories.tsx +0 -82
  393. package/src/components/Resizable/Resizable.tsx +0 -313
  394. package/src/components/Resizable/__tests__/Resizable.test.tsx +0 -128
  395. package/src/components/ResponsiveSurface/ResponsiveSurface.tsx +0 -24
  396. package/src/components/ResponsiveSurface/__tests__/ResponsiveSurface.test.tsx +0 -73
  397. package/src/components/RootLayout/RootLayout.module.css +0 -12
  398. package/src/components/RootLayout/RootLayout.stories.tsx +0 -125
  399. package/src/components/RootLayout/RootLayout.tsx +0 -185
  400. package/src/components/RootLayout/__tests__/RootLayout.test.tsx +0 -161
  401. package/src/components/ScrollArea/ScrollArea.module.css +0 -20
  402. package/src/components/ScrollArea/ScrollArea.stories.tsx +0 -57
  403. package/src/components/ScrollArea/ScrollArea.tsx +0 -27
  404. package/src/components/ScrollArea/__tests__/ScrollArea.test.tsx +0 -39
  405. package/src/components/SegmentedControl/SegmentedControl.module.css +0 -55
  406. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +0 -118
  407. package/src/components/SegmentedControl/SegmentedControl.tsx +0 -56
  408. package/src/components/SegmentedControl/__tests__/SegmentedControl.test.tsx +0 -63
  409. package/src/components/Select/Select.module.css +0 -82
  410. package/src/components/Select/Select.stories.tsx +0 -115
  411. package/src/components/Select/Select.tsx +0 -48
  412. package/src/components/Select/__tests__/Select.test.tsx +0 -59
  413. package/src/components/Sheet/Sheet.module.css +0 -58
  414. package/src/components/Sheet/Sheet.tsx +0 -109
  415. package/src/components/Sheet/__tests__/Sheet.test.tsx +0 -99
  416. package/src/components/Slider/Slider.module.css +0 -95
  417. package/src/components/Slider/Slider.stories.tsx +0 -64
  418. package/src/components/Slider/Slider.tsx +0 -77
  419. package/src/components/Slider/__tests__/Slider.test.tsx +0 -45
  420. package/src/components/Spinner/Spinner.module.css +0 -39
  421. package/src/components/Spinner/Spinner.tsx +0 -23
  422. package/src/components/SplitMethodSelector/SplitMethodSelector.stories.tsx +0 -33
  423. package/src/components/SplitMethodSelector/SplitMethodSelector.tsx +0 -43
  424. package/src/components/SplitPane/SplitPane.module.css +0 -85
  425. package/src/components/SplitPane/SplitPane.stories.tsx +0 -160
  426. package/src/components/SplitPane/SplitPane.tsx +0 -149
  427. package/src/components/SplitPane/__tests__/SplitPane.test.tsx +0 -51
  428. package/src/components/StatusBadge/StatusBadge.module.css +0 -59
  429. package/src/components/StatusBadge/StatusBadge.stories.tsx +0 -74
  430. package/src/components/StatusBadge/StatusBadge.tsx +0 -65
  431. package/src/components/StepStrip/StepStrip.module.css +0 -53
  432. package/src/components/StepStrip/StepStrip.tsx +0 -74
  433. package/src/components/SuggestionInput/SuggestionInput.module.css +0 -103
  434. package/src/components/SuggestionInput/SuggestionInput.stories.tsx +0 -144
  435. package/src/components/SuggestionInput/SuggestionInput.tsx +0 -207
  436. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.module.css +0 -64
  437. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.tsx +0 -243
  438. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlide.tsx +0 -35
  439. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideBody.tsx +0 -42
  440. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideFooter.tsx +0 -18
  441. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideHeader.tsx +0 -21
  442. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideParts.module.css +0 -29
  443. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarousel.test.tsx +0 -214
  444. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarouselDevGuard.test.tsx +0 -61
  445. package/src/components/SwipableMobileCarousel/context.ts +0 -13
  446. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.module.css +0 -64
  447. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.tsx +0 -73
  448. package/src/components/SwipableMobileCarouselDots/__tests__/SwipableMobileCarouselDots.test.tsx +0 -63
  449. package/src/components/SwipeStack/SwipeStack.module.css +0 -101
  450. package/src/components/SwipeStack/SwipeStack.tsx +0 -199
  451. package/src/components/SwipeStack/SwipeStackCard.tsx +0 -22
  452. package/src/components/SwipeStack/__tests__/SwipeStack.test.tsx +0 -169
  453. package/src/components/SystemBanner/SystemBanner.module.css +0 -79
  454. package/src/components/SystemBanner/SystemBanner.stories.tsx +0 -86
  455. package/src/components/SystemBanner/SystemBanner.tsx +0 -50
  456. package/src/components/SystemBanner/__tests__/SystemBanner.test.tsx +0 -50
  457. package/src/components/Table/Table.module.css +0 -45
  458. package/src/components/Table/Table.stories.tsx +0 -125
  459. package/src/components/Table/Table.tsx +0 -51
  460. package/src/components/Table/__tests__/Table.test.tsx +0 -50
  461. package/src/components/Tabs/Tabs.module.css +0 -56
  462. package/src/components/Tabs/Tabs.stories.tsx +0 -100
  463. package/src/components/Tabs/Tabs.tsx +0 -46
  464. package/src/components/Tabs/__tests__/Tabs.test.tsx +0 -45
  465. package/src/components/TagInput/TagInput.module.css +0 -141
  466. package/src/components/TagInput/TagInput.stories.tsx +0 -109
  467. package/src/components/TagInput/TagInput.tsx +0 -174
  468. package/src/components/TagInput/__tests__/TagInput.test.tsx +0 -69
  469. package/src/components/Textarea/Textarea.module.css +0 -47
  470. package/src/components/Textarea/Textarea.tsx +0 -38
  471. package/src/components/Textarea/__tests__/Textarea.test.tsx +0 -51
  472. package/src/components/ThreeColumnLayout/ThreeColumnLayout.module.css +0 -35
  473. package/src/components/ThreeColumnLayout/ThreeColumnLayout.stories.tsx +0 -152
  474. package/src/components/ThreeColumnLayout/ThreeColumnLayout.tsx +0 -87
  475. package/src/components/ThreeColumnLayout/__tests__/ThreeColumnLayout.test.tsx +0 -78
  476. package/src/components/Toast/Toast.module.css +0 -191
  477. package/src/components/Toast/Toast.stories.tsx +0 -191
  478. package/src/components/Toast/Toast.tsx +0 -139
  479. package/src/components/Toggle/Toggle.module.css +0 -57
  480. package/src/components/Toggle/Toggle.stories.tsx +0 -95
  481. package/src/components/Toggle/Toggle.tsx +0 -39
  482. package/src/components/Toggle/__tests__/Toggle.test.tsx +0 -47
  483. package/src/components/Tooltip/Tooltip.module.css +0 -56
  484. package/src/components/Tooltip/Tooltip.tsx +0 -30
  485. package/src/components/Typography/Typography.module.css +0 -47
  486. package/src/components/Typography/Typography.stories.tsx +0 -62
  487. package/src/components/Typography/Typography.tsx +0 -30
  488. package/src/components/Typography/__tests__/Typography.test.tsx +0 -34
  489. package/src/components/UserMenu/UserMenu.module.css +0 -90
  490. package/src/components/UserMenu/UserMenu.stories.tsx +0 -49
  491. package/src/components/UserMenu/UserMenu.tsx +0 -132
  492. package/src/components/UserMenu/__tests__/UserMenu.test.tsx +0 -77
  493. package/src/css-modules.d.ts +0 -4
  494. package/src/hooks/__tests__/useCarouselRouteSync.test.tsx +0 -126
  495. package/src/hooks/__tests__/useDoubleTap.test.tsx +0 -117
  496. package/src/hooks/__tests__/useIsMobile.test.tsx +0 -80
  497. package/src/hooks/__tests__/useIsOffline.test.tsx +0 -53
  498. package/src/hooks/__tests__/useLongPress.test.tsx +0 -158
  499. package/src/hooks/__tests__/useOfflineTileState.test.tsx +0 -69
  500. package/src/hooks/__tests__/usePublishShellChromeHeight.test.tsx +0 -118
  501. package/src/hooks/__tests__/useReorderSensors.test.ts +0 -26
  502. package/src/hooks/__tests__/useResponsiveLayout.test.tsx +0 -87
  503. package/src/hooks/__tests__/useSnapCarousel.test.tsx +0 -175
  504. package/src/hooks/__tests__/useSwipeReveal.test.tsx +0 -110
  505. package/src/hooks/__tests__/useSwipeStack.test.tsx +0 -155
  506. package/src/hooks/index.ts +0 -33
  507. package/src/hooks/useCarouselRouteSync.ts +0 -92
  508. package/src/hooks/useCommitOnEnterOrBlur.ts +0 -39
  509. package/src/hooks/useDoubleTap.ts +0 -91
  510. package/src/hooks/useIsMobile.ts +0 -33
  511. package/src/hooks/useIsOffline.ts +0 -41
  512. package/src/hooks/useLongPress.ts +0 -185
  513. package/src/hooks/useOfflineTileState.ts +0 -45
  514. package/src/hooks/usePublishShellChromeHeight.ts +0 -96
  515. package/src/hooks/useReorderSensors.ts +0 -88
  516. package/src/hooks/useResponsiveLayout.ts +0 -36
  517. package/src/hooks/useSnapCarousel.ts +0 -284
  518. package/src/hooks/useSwipeReveal.ts +0 -107
  519. package/src/hooks/useSwipeStack.ts +0 -235
  520. package/src/index.ts +0 -311
  521. package/src/motion.ts +0 -78
  522. package/src/overlay-shell.ts +0 -159
  523. package/src/scroll-lock.ts +0 -22
  524. package/src/stories/Avatar.stories.tsx +0 -44
  525. package/src/stories/Card.stories.tsx +0 -35
  526. package/src/stories/Checkbox.stories.tsx +0 -45
  527. package/src/stories/DesignSystemOverview.stories.tsx +0 -3793
  528. package/src/stories/DeviceOnlyGate.stories.tsx +0 -35
  529. package/src/stories/DeviceStorageKeyGate.stories.tsx +0 -57
  530. package/src/stories/DragHandleRow.stories.tsx +0 -41
  531. package/src/stories/EmptyState.stories.tsx +0 -33
  532. package/src/stories/FileDropzone.stories.tsx +0 -69
  533. package/src/stories/FormField.stories.tsx +0 -47
  534. package/src/stories/GripIcon.stories.tsx +0 -29
  535. package/src/stories/InteractionHooks.stories.tsx +0 -925
  536. package/src/stories/LayoutSystem.stories.tsx +0 -639
  537. package/src/stories/MenuEntries.stories.tsx +0 -86
  538. package/src/stories/MobilePatterns.stories.tsx +0 -1536
  539. package/src/stories/NavList.stories.tsx +0 -147
  540. package/src/stories/NavTabs.stories.tsx +0 -53
  541. package/src/stories/OfflineGate.stories.tsx +0 -42
  542. package/src/stories/PageContainer.stories.tsx +0 -82
  543. package/src/stories/PageHeader.stories.tsx +0 -95
  544. package/src/stories/ResponsiveSurface.stories.tsx +0 -47
  545. package/src/stories/Spinner.stories.tsx +0 -25
  546. package/src/stories/StepStrip.stories.tsx +0 -76
  547. package/src/stories/SwipableMobileCarousel.stories.tsx +0 -362
  548. package/src/stories/SwipeStack.stories.tsx +0 -200
  549. package/src/stories/Textarea.stories.tsx +0 -63
  550. package/src/stories/TokenGallery.stories.tsx +0 -652
  551. package/src/stories/Tooltip.stories.tsx +0 -59
  552. package/src/tokens/primitives.css +0 -168
  553. package/src/tokens/semantic.css +0 -162
  554. package/src/tokens/theme-presets.css +0 -33
  555. package/src/tokens/theme-presets.ts +0 -72
  556. package/src/tokens.css +0 -5
@@ -1,42 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import styles from './SwipableMobileCarouselSlideParts.module.css';
3
-
4
- export interface SwipableMobileCarouselSlideBodyProps {
5
- children: ReactNode;
6
- /** While true, renders `loadingFallback` INSTEAD OF children — scoped to
7
- * just this region, not the whole slide. This is what fixes the
8
- * "whole slide blanks out, title included, until its own fetch resolves"
9
- * bug: a caller renders `<SwipableMobileCarouselSlideHeader>` from
10
- * already-known metadata unconditionally, and gates only this component's
11
- * `loading` on the slower fetch — the natural way to compose
12
- * Header/Body/Footer as siblings already produces that behavior, instead
13
- * of gating the entire slide behind one boolean. */
14
- loading?: boolean;
15
- loadingFallback?: ReactNode;
16
- className?: string;
17
- }
18
-
19
- const defaultLoadingFallback = <div className={styles.loading}>Loading…</div>;
20
-
21
- /**
22
- * SwipableMobileCarouselSlideBody — the scrollable region of a slide.
23
- *
24
- * Deliberately does not set `touch-action: pan-y` on its scroll container
25
- * (see SwipableMobileCarouselSlideParts.module.css's `.body` rule) — that
26
- * would intersect-to-empty against the carousel's own horizontal
27
- * touch-action handling (docs/architecture-rules.md's touch-action
28
- * intersection rule), breaking both the vertical scroll here and the
29
- * horizontal swipe between slides.
30
- */
31
- export function SwipableMobileCarouselSlideBody({
32
- children,
33
- loading = false,
34
- loadingFallback,
35
- className,
36
- }: SwipableMobileCarouselSlideBodyProps) {
37
- return (
38
- <div className={[styles.body, className].filter(Boolean).join(' ')}>
39
- {loading ? (loadingFallback ?? defaultLoadingFallback) : children}
40
- </div>
41
- );
42
- }
@@ -1,18 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import styles from './SwipableMobileCarouselSlideParts.module.css';
3
-
4
- export interface SwipableMobileCarouselSlideFooterProps {
5
- children: ReactNode;
6
- className?: string;
7
- }
8
-
9
- /**
10
- * SwipableMobileCarouselSlideFooter — always renders its children, no
11
- * loading concept. See SwipableMobileCarouselSlideHeader's doc comment.
12
- */
13
- export function SwipableMobileCarouselSlideFooter({
14
- children,
15
- className,
16
- }: SwipableMobileCarouselSlideFooterProps) {
17
- return <div className={[styles.footer, className].filter(Boolean).join(' ')}>{children}</div>;
18
- }
@@ -1,21 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import styles from './SwipableMobileCarouselSlideParts.module.css';
3
-
4
- export interface SwipableMobileCarouselSlideHeaderProps {
5
- children: ReactNode;
6
- className?: string;
7
- }
8
-
9
- /**
10
- * SwipableMobileCarouselSlideHeader — always renders its children, no
11
- * loading concept. Meant for content already known synchronously (a list's
12
- * title, color, item count from data the caller already has) so it can
13
- * render immediately even while SwipableMobileCarouselSlideBody's own
14
- * content is still loading — see that component's doc comment.
15
- */
16
- export function SwipableMobileCarouselSlideHeader({
17
- children,
18
- className,
19
- }: SwipableMobileCarouselSlideHeaderProps) {
20
- return <div className={[styles.header, className].filter(Boolean).join(' ')}>{children}</div>;
21
- }
@@ -1,29 +0,0 @@
1
- .header,
2
- .footer {
3
- flex: 0 0 auto;
4
- }
5
-
6
- .body {
7
- flex: 1 1 auto;
8
- min-height: 0; /* allow shrinking inside the slide's flex column, so it can scroll instead of overflowing */
9
- overflow-y: auto;
10
- overflow-x: hidden;
11
- /* Deliberately does NOT set touch-action: pan-y here. touch-action's
12
- effective value is the INTERSECTION of this element's and every
13
- ancestor's value (docs/architecture-rules.md) — the ancestor .scroller
14
- (SwipableMobileCarousel.module.css) needs the horizontal swipe gesture,
15
- so pan-y here ∩ that horizontal handling would resolve to neither axis
16
- working natively. Relying on the browser's default touch-action (auto)
17
- here lets native gesture arbitration between the two nested scrollers
18
- sort out which axis wins per-gesture — don't "fix" perceived nested-
19
- scroll jank by adding pan-y; it silently breaks horizontal swipe instead. */
20
- }
21
-
22
- .loading {
23
- display: flex;
24
- align-items: center;
25
- justify-content: center;
26
- height: 100%;
27
- color: var(--sv-color-text-subtle);
28
- font-size: var(--sv-font-size-sm);
29
- }
@@ -1,214 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
- import { act, cleanup, fireEvent, render, screen } from '@testing-library/react';
4
- import { SwipableMobileCarousel } from '../SwipableMobileCarousel';
5
- import { SwipableMobileCarouselSlide } from '../SwipableMobileCarouselSlide';
6
- import { SwipableMobileCarouselSlideHeader } from '../SwipableMobileCarouselSlideHeader';
7
- import { SwipableMobileCarouselSlideBody } from '../SwipableMobileCarouselSlideBody';
8
-
9
- // Same jsdom scroll polyfill/fake-timer setup as useSnapCarousel.test.tsx,
10
- // since this component wraps that hook directly.
11
- beforeEach(() => {
12
- vi.useFakeTimers();
13
- if (!Element.prototype.scrollTo) {
14
- Element.prototype.scrollTo = vi.fn();
15
- }
16
- });
17
-
18
- afterEach(() => {
19
- vi.runOnlyPendingTimers();
20
- vi.useRealTimers();
21
- cleanup();
22
- });
23
-
24
- function setLayout(el: HTMLElement, clientWidth: number, scrollLeft: number) {
25
- Object.defineProperty(el, 'clientWidth', { value: clientWidth, configurable: true });
26
- Object.defineProperty(el, 'scrollLeft', { value: scrollLeft, configurable: true });
27
- }
28
-
29
- const KEYS = ['a', 'b', 'c', 'd', 'e'];
30
-
31
- function FiveSlides({
32
- activeIndex,
33
- onSettle,
34
- }: {
35
- activeIndex: number;
36
- onSettle: (i: number) => void;
37
- }) {
38
- return (
39
- <SwipableMobileCarousel activeIndex={activeIndex} onSettle={onSettle} aria-label="Test slides">
40
- {KEYS.map((key) => (
41
- <SwipableMobileCarouselSlide key={key} slideKey={key} label={key}>
42
- <SwipableMobileCarouselSlideHeader>{`header-${key}`}</SwipableMobileCarouselSlideHeader>
43
- <SwipableMobileCarouselSlideBody>{`body-${key}`}</SwipableMobileCarouselSlideBody>
44
- </SwipableMobileCarouselSlide>
45
- ))}
46
- </SwipableMobileCarousel>
47
- );
48
- }
49
-
50
- describe('SwipableMobileCarousel', () => {
51
- it('only mounts the active slide and its immediate neighbors (default prefetchDistance=1)', () => {
52
- render(<FiveSlides activeIndex={2} onSettle={() => {}} />);
53
- // active (c) and neighbors (b, d) are mounted
54
- expect(screen.getByText('header-b')).toBeDefined();
55
- expect(screen.getByText('header-c')).toBeDefined();
56
- expect(screen.getByText('header-d')).toBeDefined();
57
- // out-of-window slides (a, e) render nothing at all
58
- expect(screen.queryByText('header-a')).toBeNull();
59
- expect(screen.queryByText('body-a')).toBeNull();
60
- expect(screen.queryByText('header-e')).toBeNull();
61
- expect(screen.queryByText('body-e')).toBeNull();
62
- });
63
-
64
- it("SlideBody's loading prop only hides that region, not the Header", () => {
65
- render(
66
- <SwipableMobileCarousel activeIndex={0} onSettle={() => {}} aria-label="Test slides">
67
- <SwipableMobileCarouselSlide slideKey="only" label="Only">
68
- <SwipableMobileCarouselSlideHeader>the-title</SwipableMobileCarouselSlideHeader>
69
- <SwipableMobileCarouselSlideBody loading>tasks-content</SwipableMobileCarouselSlideBody>
70
- </SwipableMobileCarouselSlide>
71
- </SwipableMobileCarousel>,
72
- );
73
- expect(screen.getByText('the-title')).toBeDefined();
74
- expect(screen.queryByText('tasks-content')).toBeNull();
75
- expect(screen.getByText('Loading…')).toBeDefined();
76
- });
77
-
78
- it('calls onSettle with the new index after a swipe settles', () => {
79
- const onSettle = vi.fn();
80
- render(<FiveSlides activeIndex={0} onSettle={onSettle} />);
81
- const scroller = screen.getByRole('region', { name: 'Test slides' });
82
- fireEvent.touchStart(scroller);
83
- setLayout(scroller, 300, 300); // scrollLeft 300 / width 300 -> index 1
84
- fireEvent.scroll(scroller);
85
- act(() => void vi.advanceTimersByTime(120));
86
- expect(onSettle).toHaveBeenCalledWith(1);
87
- });
88
-
89
- it('clicking a dot calls onSettle directly with that index', () => {
90
- const onSettle = vi.fn();
91
- render(<FiveSlides activeIndex={0} onSettle={onSettle} />);
92
- const dots = screen.getAllByRole('tab');
93
- const fourthDot = dots[3];
94
- if (!fourthDot) throw new Error('expected a 4th dot');
95
- setLayout(screen.getByRole('region', { name: 'Test slides' }), 300, 0);
96
- fireEvent.click(fourthDot);
97
- expect(onSettle).toHaveBeenCalledWith(3);
98
- });
99
-
100
- it('positions both the default and a custom renderIndicator inside the same overlay slot', () => {
101
- // Regression test: the overlay-positioning class used to be applied
102
- // directly to the default SwipableMobileCarouselDots instance, so any
103
- // caller-supplied renderIndicator rendered as a plain static element
104
- // instead — pushed out of view below the full-height scroller. The
105
- // carousel must own positioning for whatever renderIndicator returns.
106
- const { unmount } = render(<FiveSlides activeIndex={0} onSettle={() => {}} />);
107
- const defaultTablist = screen.getByRole('tablist');
108
- expect(defaultTablist.parentElement?.className).toMatch(/indicatorSlot/);
109
- unmount();
110
-
111
- render(
112
- <SwipableMobileCarousel
113
- activeIndex={0}
114
- onSettle={() => {}}
115
- aria-label="Test slides"
116
- renderIndicator={({ count, activeIndex, onJump }) => (
117
- <div role="tablist" aria-label="Custom">
118
- {Array.from({ length: count }, (_, i) => (
119
- <button key={i} type="button" role="tab" onClick={() => onJump(i)}>
120
- {i === activeIndex ? 'active' : 'inactive'}
121
- </button>
122
- ))}
123
- </div>
124
- )}
125
- >
126
- {KEYS.map((key) => (
127
- <SwipableMobileCarouselSlide key={key} slideKey={key} label={key}>
128
- {`slide-${key}`}
129
- </SwipableMobileCarouselSlide>
130
- ))}
131
- </SwipableMobileCarousel>,
132
- );
133
- const customTablist = screen.getByRole('tablist', { name: 'Custom' });
134
- expect(customTablist.parentElement?.className).toMatch(/indicatorSlot/);
135
- });
136
-
137
- it('re-snaps and reports the new index when the active slide moves position (reorder-jump fix)', () => {
138
- function Reorderable({ order, onSettle }: { order: string[]; onSettle: (i: number) => void }) {
139
- return (
140
- <SwipableMobileCarousel activeIndex={1} onSettle={onSettle} aria-label="Test slides">
141
- {order.map((key) => (
142
- <SwipableMobileCarouselSlide key={key} slideKey={key} label={key}>
143
- <SwipableMobileCarouselSlideHeader>{`header-${key}`}</SwipableMobileCarouselSlideHeader>
144
- </SwipableMobileCarouselSlide>
145
- ))}
146
- </SwipableMobileCarousel>
147
- );
148
- }
149
- const onSettle = vi.fn();
150
- const { rerender } = render(<Reorderable order={['a', 'b', 'c']} onSettle={onSettle} />);
151
- const scroller = screen.getByRole('region', { name: 'Test slides' });
152
- setLayout(scroller, 300, 0);
153
- const spy = vi.spyOn(scroller, 'scrollTo');
154
-
155
- // 'b' (index 1, active) moves to index 0.
156
- rerender(<Reorderable order={['b', 'a', 'c']} onSettle={onSettle} />);
157
-
158
- expect(onSettle).toHaveBeenCalledWith(0);
159
- expect(spy).toHaveBeenCalledWith({ left: 0, behavior: 'instant' });
160
- });
161
-
162
- it('mounts a slide reached by a fast multi-slide flick before settle-detection reports it', () => {
163
- // Regression test, found via a user screen recording: a fast flick can
164
- // carry native scroll-snap momentum straight past an intermediate slide
165
- // to one two-or-more away in a single continuous gesture. Settle-
166
- // detection deliberately still waits out the full debounce window before
167
- // calling onSettle (to distinguish a real settle from drift — see
168
- // useSnapCarousel's chainTrustedRef comment), but the mount window used
169
- // to be keyed *only* off that settled index — so the slide the container
170
- // had already scrolled to, visually, sat completely unmounted (not even
171
- // a loading skeleton, per SwipableMobileCarouselSlide's `return null`)
172
- // for the entire debounce window. liveIndex closes that gap.
173
- const onSettle = vi.fn();
174
- const KEYS8 = ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h'];
175
- function EightSlides({ onSettle }: { onSettle: (i: number) => void }) {
176
- return (
177
- <SwipableMobileCarousel activeIndex={0} onSettle={onSettle} aria-label="Test slides">
178
- {KEYS8.map((key) => (
179
- <SwipableMobileCarouselSlide key={key} slideKey={key} label={key}>
180
- <SwipableMobileCarouselSlideHeader>{`header-${key}`}</SwipableMobileCarouselSlideHeader>
181
- </SwipableMobileCarouselSlide>
182
- ))}
183
- </SwipableMobileCarousel>
184
- );
185
- }
186
- render(<EightSlides onSettle={onSettle} />);
187
- const scroller = screen.getByRole('region', { name: 'Test slides' });
188
- // Slide 'e' (index 4) is well outside the default prefetchDistance=1
189
- // window around the settled index 0.
190
- expect(screen.queryByText('header-e')).toBeNull();
191
-
192
- fireEvent.touchStart(scroller);
193
- setLayout(scroller, 300, 1200); // scrollLeft 1200 / width 300 -> index 4
194
- fireEvent.scroll(scroller);
195
- // Well short of the 120ms settle debounce — onSettle must not have fired
196
- // yet, but the rAF-throttled liveIndex update has had time to run.
197
- act(() => void vi.advanceTimersByTime(20));
198
- expect(onSettle).not.toHaveBeenCalled();
199
- expect(screen.getByText('header-e')).toBeDefined();
200
-
201
- act(() => void vi.advanceTimersByTime(120));
202
- expect(onSettle).toHaveBeenCalledWith(4);
203
- });
204
-
205
- it('does not re-snap when slide order is unchanged', () => {
206
- function Reorderable({ onSettle }: { onSettle: (i: number) => void }) {
207
- return <FiveSlides activeIndex={2} onSettle={onSettle} />;
208
- }
209
- const onSettle = vi.fn();
210
- const { rerender } = render(<Reorderable onSettle={onSettle} />);
211
- rerender(<Reorderable onSettle={onSettle} />);
212
- expect(onSettle).not.toHaveBeenCalled();
213
- });
214
- });
@@ -1,61 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, render } from '@testing-library/react';
4
- import { SwipableMobileCarousel } from '../SwipableMobileCarousel';
5
- import { SwipableMobileCarouselSlide } from '../SwipableMobileCarouselSlide';
6
-
7
- beforeEach(() => {
8
- if (!Element.prototype.scrollTo) {
9
- Element.prototype.scrollTo = vi.fn();
10
- }
11
- });
12
-
13
- afterEach(() => {
14
- cleanup();
15
- vi.restoreAllMocks();
16
- });
17
-
18
- function renderWithStrayChild() {
19
- return render(
20
- <SwipableMobileCarousel activeIndex={0} onSettle={() => {}} aria-label="Test slides">
21
- <SwipableMobileCarouselSlide slideKey="a" label="A">
22
- content
23
- </SwipableMobileCarouselSlide>
24
- {/* stray non-Slide child — shifts index math for anything after it */}
25
- <div>oops</div>
26
- <SwipableMobileCarouselSlide slideKey="b" label="B">
27
- content
28
- </SwipableMobileCarouselSlide>
29
- </SwipableMobileCarousel>,
30
- );
31
- }
32
-
33
- describe('SwipableMobileCarousel dev-mode child-type guard', () => {
34
- it('warns via console.error in development, mentioning the offending child', () => {
35
- const originalEnv = process.env.NODE_ENV;
36
- vi.stubEnv('NODE_ENV', 'development');
37
- const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
38
-
39
- expect(() => renderWithStrayChild()).not.toThrow();
40
-
41
- expect(errorSpy).toHaveBeenCalledWith(expect.stringContaining('<div>'));
42
- vi.stubEnv('NODE_ENV', originalEnv ?? 'test');
43
- });
44
-
45
- it('does not call console.error in production', () => {
46
- const originalEnv = process.env.NODE_ENV;
47
- vi.stubEnv('NODE_ENV', 'production');
48
- const errorSpy = vi.spyOn(console, 'error').mockImplementation(() => {});
49
-
50
- expect(() => renderWithStrayChild()).not.toThrow();
51
-
52
- expect(errorSpy).not.toHaveBeenCalled();
53
- vi.stubEnv('NODE_ENV', originalEnv ?? 'test');
54
- });
55
-
56
- it('never throws, even with a stray child (a miscounted slide degrades, it does not crash)', () => {
57
- vi.stubEnv('NODE_ENV', 'development');
58
- vi.spyOn(console, 'error').mockImplementation(() => {});
59
- expect(() => renderWithStrayChild()).not.toThrow();
60
- });
61
- });
@@ -1,13 +0,0 @@
1
- 'use client';
2
-
3
- import { createContext } from 'react';
4
-
5
- export interface CarouselSlideMountContextValue {
6
- /** Whether this slide is within the carousel's mount window (the active
7
- * slide ± its configured prefetchDistance). Kept out of the main .tsx
8
- * file for React Fast Refresh hygiene (a file exporting only components
9
- * refreshes more reliably than one mixing components and plain values). */
10
- isMounted: boolean;
11
- }
12
-
13
- export const CarouselSlideMountContext = createContext<CarouselSlideMountContextValue | null>(null);
@@ -1,64 +0,0 @@
1
- .dots {
2
- display: flex;
3
- align-items: center;
4
- justify-content: center;
5
- gap: var(--sv-space-2);
6
- }
7
-
8
- /* Opt-in — see the `density` prop doc comment. Shrinks both the gap and each
9
- dot's own hit target (20px -> 16px) — for a carousel with enough slides
10
- that even the space-1 gap alone still read as too wide. The visible 6px
11
- dot is unchanged; only the surrounding tap-target box shrinks, via the
12
- descendant override below rather than a second dot variant, so this stays
13
- a pure CSS opt-in with no JS/prop plumbing beyond `density` itself. */
14
- .dotsCompact {
15
- gap: var(--sv-space-1);
16
- }
17
-
18
- .dotsCompact .dot {
19
- width: 16px;
20
- height: 16px;
21
- }
22
-
23
- .dot {
24
- /* A 6px visible dot is too small a hit target on its own — the button's
25
- real box is larger (20px) with the dot itself painted by ::before and
26
- centered inside, so tap area grows without changing the visible dot
27
- size or the row's gap-based spacing math. */
28
- position: relative;
29
- width: 20px;
30
- height: 20px;
31
- padding: 0;
32
- border: none;
33
- background: transparent;
34
- cursor: pointer;
35
- }
36
-
37
- .dot::before {
38
- content: '';
39
- position: absolute;
40
- top: 50%;
41
- left: 50%;
42
- width: 6px;
43
- height: 6px;
44
- border-radius: 50%;
45
- background: var(--sv-color-border-strong);
46
- transform: translate(-50%, -50%);
47
- transition: background 0.15s ease;
48
- }
49
-
50
- .dot:focus-visible {
51
- outline: 2px solid var(--sv-color-focus-ring);
52
- outline-offset: 2px;
53
- border-radius: 50%;
54
- }
55
-
56
- .dotActive::before {
57
- background: var(--sv-color-text-primary);
58
- }
59
-
60
- @media (hover: hover) {
61
- .dot:not(.dotActive):hover::before {
62
- background: var(--sv-color-text-muted);
63
- }
64
- }
@@ -1,73 +0,0 @@
1
- 'use client';
2
-
3
- import styles from './SwipableMobileCarouselDots.module.css';
4
-
5
- export interface SwipableMobileCarouselDotsProps {
6
- count: number;
7
- activeIndex: number;
8
- onJump: (index: number) => void;
9
- /** Per-dot accessible names, e.g. ["Lists", "Starred", "Groceries"]. Falls
10
- * back to "Slide N of count" for any index without one. */
11
- labels?: (string | undefined)[];
12
- /** Labels the whole group — required, no generic fallback (mirrors
13
- * SwipableMobileCarousel's own required aria-label). */
14
- 'aria-label': string;
15
- /** `'compact'` halves the gap between dots (`--sv-space-2` → `--sv-space-1`)
16
- * and shrinks each dot's own hit target (20px → 16px) — for a carousel
17
- * with enough slides that even the reduced gap alone still reads as too
18
- * wide on a narrow viewport (e.g. a many-list mobile app). The visible
19
- * 6px dot itself is unchanged; only its surrounding tap-target box
20
- * shrinks. Defaults to `'default'` — every existing consumer's spacing is
21
- * unaffected unless it opts in. */
22
- density?: 'default' | 'compact';
23
- className?: string;
24
- }
25
-
26
- /**
27
- * SwipableMobileCarouselDots — a real, tappable, labeled slide indicator.
28
- * Standalone (not carousel-only): reusable anywhere a set of positions needs
29
- * a dot indicator (e.g. an image gallery, an onboarding stepper), and is also
30
- * SwipableMobileCarousel's default `renderIndicator`.
31
- *
32
- * Replaces the `aria-hidden`, non-interactive dots pattern both
33
- * sovereign-tasks and sovereign-shopper currently hand-roll — every dot here
34
- * is a real `role="tab"` button with its own accessible name, reachable by
35
- * keyboard. No roving tabIndex/arrow-key handling: `Tabs` (this library's
36
- * other `role="tablist"` component) has none either, so this stays
37
- * consistent with it rather than gold-plating past its sibling.
38
- */
39
- export function SwipableMobileCarouselDots({
40
- count,
41
- activeIndex,
42
- onJump,
43
- labels,
44
- 'aria-label': ariaLabel,
45
- density = 'default',
46
- className,
47
- }: SwipableMobileCarouselDotsProps) {
48
- return (
49
- <div
50
- role="tablist"
51
- aria-label={ariaLabel}
52
- className={[styles.dots, density === 'compact' ? styles.dotsCompact : '', className]
53
- .filter(Boolean)
54
- .join(' ')}
55
- >
56
- {Array.from({ length: count }, (_, i) => {
57
- const active = i === activeIndex;
58
- const label = labels?.[i] ?? `Slide ${i + 1} of ${count}`;
59
- return (
60
- <button
61
- key={i}
62
- type="button"
63
- role="tab"
64
- aria-selected={active}
65
- aria-label={label}
66
- className={[styles.dot, active ? styles.dotActive : ''].filter(Boolean).join(' ')}
67
- onClick={() => onJump(i)}
68
- />
69
- );
70
- })}
71
- </div>
72
- );
73
- }
@@ -1,63 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, fireEvent, render, screen } from '@testing-library/react';
4
- import { SwipableMobileCarouselDots } from '../SwipableMobileCarouselDots';
5
-
6
- afterEach(cleanup);
7
-
8
- describe('SwipableMobileCarouselDots', () => {
9
- it('renders a tablist with one tab per count, none aria-hidden', () => {
10
- render(
11
- <SwipableMobileCarouselDots count={3} activeIndex={0} onJump={() => {}} aria-label="Lists" />,
12
- );
13
- const list = screen.getByRole('tablist', { name: 'Lists' });
14
- expect(list.getAttribute('aria-hidden')).toBeNull();
15
- const tabs = screen.getAllByRole('tab');
16
- expect(tabs).toHaveLength(3);
17
- tabs.forEach((tab) => expect(tab.getAttribute('aria-hidden')).toBeNull());
18
- });
19
-
20
- it('marks only the active dot as aria-selected', () => {
21
- render(
22
- <SwipableMobileCarouselDots count={3} activeIndex={1} onJump={() => {}} aria-label="Lists" />,
23
- );
24
- const tabs = screen.getAllByRole('tab');
25
- expect(tabs[0]?.getAttribute('aria-selected')).toBe('false');
26
- expect(tabs[1]?.getAttribute('aria-selected')).toBe('true');
27
- expect(tabs[2]?.getAttribute('aria-selected')).toBe('false');
28
- });
29
-
30
- it('uses the provided per-dot labels, falling back to "Slide N of count"', () => {
31
- render(
32
- <SwipableMobileCarouselDots
33
- count={3}
34
- activeIndex={0}
35
- onJump={() => {}}
36
- labels={['Lists', undefined, 'Groceries']}
37
- aria-label="Lists"
38
- />,
39
- );
40
- expect(screen.getByRole('tab', { name: 'Lists' })).toBeDefined();
41
- expect(screen.getByRole('tab', { name: 'Slide 2 of 3' })).toBeDefined();
42
- expect(screen.getByRole('tab', { name: 'Groceries' })).toBeDefined();
43
- });
44
-
45
- it('clicking a dot calls onJump with its index', () => {
46
- const onJump = vi.fn();
47
- render(
48
- <SwipableMobileCarouselDots count={3} activeIndex={0} onJump={onJump} aria-label="Lists" />,
49
- );
50
- const thirdTab = screen.getAllByRole('tab')[2];
51
- if (!thirdTab) throw new Error('expected a 3rd tab');
52
- fireEvent.click(thirdTab);
53
- expect(onJump).toHaveBeenCalledWith(2);
54
- });
55
-
56
- it('every dot is a real, focusable button (not a decorative element)', () => {
57
- render(
58
- <SwipableMobileCarouselDots count={2} activeIndex={0} onJump={() => {}} aria-label="Lists" />,
59
- );
60
- const tabs = screen.getAllByRole('tab');
61
- tabs.forEach((tab) => expect(tab.tagName).toBe('BUTTON'));
62
- });
63
- });