@sovereignfs/ui 0.54.0 → 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 (473) hide show
  1. package/LICENSE +373 -661
  2. package/NOTICE +8 -0
  3. package/README.md +4 -6
  4. package/dist/Accordion.module.css +1 -1
  5. package/dist/Alert.module.css +1 -1
  6. package/dist/AppsLauncher.module.css +102 -0
  7. package/dist/Avatar.module.css +1 -1
  8. package/dist/Badge.module.css +30 -7
  9. package/dist/BalanceChip.module.css +1 -1
  10. package/dist/Button.module.css +23 -2
  11. package/dist/Card.module.css +7 -1
  12. package/dist/CardTile.module.css +187 -0
  13. package/dist/CheckableListRow.module.css +8 -0
  14. package/dist/Checkbox.module.css +8 -0
  15. package/dist/CodeTextarea.module.css +7 -1
  16. package/dist/Collapsible.module.css +1 -1
  17. package/dist/ColorPicker.module.css +138 -0
  18. package/dist/Combobox.module.css +8 -2
  19. package/dist/Command.module.css +7 -1
  20. package/dist/ConfirmDialog.module.css +8 -2
  21. package/dist/ConsentPrompt.module.css +21 -0
  22. package/dist/DatePicker.module.css +7 -1
  23. package/dist/Dialog.module.css +130 -21
  24. package/dist/DragHandleRow.module.css +6 -0
  25. package/dist/Drawer.module.css +36 -7
  26. package/dist/FileDropzone.module.css +25 -1
  27. package/dist/Header.module.css +68 -0
  28. package/dist/HeaderFooterLayout.module.css +21 -0
  29. package/dist/IconPicker.module.css +15 -5
  30. package/dist/Input.module.css +7 -1
  31. package/dist/Kbd.module.css +1 -1
  32. package/dist/LegalLinks.module.css +9 -2
  33. package/dist/Markdown.module.css +29 -0
  34. package/dist/Menu.module.css +1 -0
  35. package/dist/Message.module.css +10 -1
  36. package/dist/MessageScroller.module.css +12 -1
  37. package/dist/MobileAppsDrawer.module.css +19 -14
  38. package/dist/MobileFooter.module.css +7 -1
  39. package/dist/MobileHeader.module.css +14 -1
  40. package/dist/NavList.module.css +139 -0
  41. package/dist/NavTabs.module.css +8 -2
  42. package/dist/NotificationsPanel.module.css +268 -0
  43. package/dist/OverlayHeader.module.css +1 -1
  44. package/dist/PageContainer.module.css +62 -0
  45. package/dist/PageHeader.module.css +54 -0
  46. package/dist/PageLayout.module.css +51 -0
  47. package/dist/Popover.module.css +1 -1
  48. package/dist/QrCode.module.css +17 -0
  49. package/dist/QuantityStepper.module.css +5 -3
  50. package/dist/RadioGroup.module.css +6 -0
  51. package/dist/Resizable.module.css +3 -3
  52. package/dist/RootLayout.module.css +12 -0
  53. package/dist/SegmentedControl.module.css +7 -1
  54. package/dist/Select.module.css +7 -1
  55. package/dist/Sheet.module.css +20 -2
  56. package/dist/SplitPane.module.css +5 -5
  57. package/dist/StatusBadge.module.css +1 -1
  58. package/dist/StepStrip.module.css +55 -0
  59. package/dist/SuggestionInput.module.css +14 -3
  60. package/dist/SwipableMobileCarousel.module.css +12 -3
  61. package/dist/SwipableMobileCarouselDots.module.css +21 -0
  62. package/dist/SwipeStack.module.css +101 -0
  63. package/dist/SystemBanner.module.css +16 -0
  64. package/dist/Table.module.css +2 -2
  65. package/dist/Tabs.module.css +7 -1
  66. package/dist/TagInput.module.css +8 -2
  67. package/dist/Textarea.module.css +15 -1
  68. package/dist/ThreeColumnLayout.module.css +35 -0
  69. package/dist/Toast.module.css +67 -3
  70. package/dist/Toggle.module.css +7 -0
  71. package/dist/Tooltip.module.css +7 -1
  72. package/dist/UserMenu.module.css +95 -0
  73. package/dist/fonts/OFL.txt +93 -0
  74. package/dist/fonts/hanken-grotesk-cyrillic-ext-wght-normal.woff2 +0 -0
  75. package/dist/fonts/hanken-grotesk-latin-ext-wght-normal.woff2 +0 -0
  76. package/dist/fonts/hanken-grotesk-latin-wght-normal.woff2 +0 -0
  77. package/dist/fonts/hanken-grotesk-vietnamese-wght-normal.woff2 +0 -0
  78. package/dist/index.d.ts +1156 -76
  79. package/dist/index.js +4223 -1513
  80. package/dist/tokens/fonts.css +53 -0
  81. package/dist/tokens/primitives.css +23 -12
  82. package/dist/tokens/semantic.css +32 -0
  83. package/dist/tokens/theme-presets.css +33 -0
  84. package/dist/tokens.css +2 -1
  85. package/package.json +46 -19
  86. package/src/__tests__/motion.test.tsx +0 -105
  87. package/src/components/Accordion/Accordion.module.css +0 -3
  88. package/src/components/Accordion/Accordion.stories.tsx +0 -110
  89. package/src/components/Accordion/Accordion.tsx +0 -53
  90. package/src/components/Accordion/__tests__/Accordion.test.tsx +0 -61
  91. package/src/components/Alert/Alert.module.css +0 -62
  92. package/src/components/Alert/Alert.stories.tsx +0 -96
  93. package/src/components/Alert/Alert.tsx +0 -58
  94. package/src/components/Alert/__tests__/Alert.test.tsx +0 -75
  95. package/src/components/AspectRatio/AspectRatio.module.css +0 -15
  96. package/src/components/AspectRatio/AspectRatio.stories.tsx +0 -78
  97. package/src/components/AspectRatio/AspectRatio.tsx +0 -21
  98. package/src/components/AspectRatio/__tests__/AspectRatio.test.tsx +0 -27
  99. package/src/components/Avatar/Avatar.module.css +0 -38
  100. package/src/components/Avatar/Avatar.tsx +0 -42
  101. package/src/components/Badge/Badge.module.css +0 -154
  102. package/src/components/Badge/Badge.stories.tsx +0 -226
  103. package/src/components/Badge/Badge.tsx +0 -81
  104. package/src/components/Badge/__tests__/Badge.test.tsx +0 -88
  105. package/src/components/BalanceChip/BalanceChip.module.css +0 -32
  106. package/src/components/BalanceChip/BalanceChip.stories.tsx +0 -45
  107. package/src/components/BalanceChip/BalanceChip.tsx +0 -33
  108. package/src/components/Breadcrumb/Breadcrumb.module.css +0 -49
  109. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +0 -47
  110. package/src/components/Breadcrumb/Breadcrumb.tsx +0 -57
  111. package/src/components/Breadcrumb/__tests__/Breadcrumb.test.tsx +0 -52
  112. package/src/components/Button/Button.module.css +0 -153
  113. package/src/components/Button/Button.stories.tsx +0 -83
  114. package/src/components/Button/Button.tsx +0 -52
  115. package/src/components/Button/__tests__/Button.test.tsx +0 -66
  116. package/src/components/ButtonGroup/ButtonGroup.module.css +0 -29
  117. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +0 -57
  118. package/src/components/ButtonGroup/ButtonGroup.tsx +0 -27
  119. package/src/components/ButtonGroup/__tests__/ButtonGroup.test.tsx +0 -29
  120. package/src/components/Calendar/Calendar.module.css +0 -126
  121. package/src/components/Calendar/Calendar.tsx +0 -213
  122. package/src/components/Calendar/__tests__/Calendar.test.tsx +0 -98
  123. package/src/components/Calendar/dateUtils.ts +0 -97
  124. package/src/components/Card/Card.module.css +0 -42
  125. package/src/components/Card/Card.tsx +0 -34
  126. package/src/components/CheckableListRow/CheckableListRow.module.css +0 -95
  127. package/src/components/CheckableListRow/CheckableListRow.stories.tsx +0 -99
  128. package/src/components/CheckableListRow/CheckableListRow.tsx +0 -89
  129. package/src/components/Checkbox/Checkbox.module.css +0 -111
  130. package/src/components/Checkbox/Checkbox.tsx +0 -78
  131. package/src/components/CodeTextarea/CodeTextarea.module.css +0 -53
  132. package/src/components/CodeTextarea/CodeTextarea.stories.tsx +0 -77
  133. package/src/components/CodeTextarea/CodeTextarea.tsx +0 -36
  134. package/src/components/Collapsible/Collapsible.module.css +0 -70
  135. package/src/components/Collapsible/Collapsible.stories.tsx +0 -62
  136. package/src/components/Collapsible/Collapsible.tsx +0 -66
  137. package/src/components/Collapsible/__tests__/Collapsible.test.tsx +0 -71
  138. package/src/components/Combobox/Combobox.module.css +0 -122
  139. package/src/components/Combobox/Combobox.stories.tsx +0 -79
  140. package/src/components/Combobox/Combobox.tsx +0 -186
  141. package/src/components/Combobox/__tests__/Combobox.test.tsx +0 -158
  142. package/src/components/Command/Command.module.css +0 -80
  143. package/src/components/Command/Command.stories.tsx +0 -104
  144. package/src/components/Command/Command.tsx +0 -168
  145. package/src/components/Command/__tests__/Command.test.tsx +0 -162
  146. package/src/components/ConfirmDialog/ConfirmDialog.module.css +0 -113
  147. package/src/components/ConfirmDialog/ConfirmDialog.tsx +0 -124
  148. package/src/components/ConfirmDialog/__tests__/ConfirmDialog.test.tsx +0 -146
  149. package/src/components/ContextMenu/ContextMenu.stories.tsx +0 -81
  150. package/src/components/ContextMenu/ContextMenu.tsx +0 -100
  151. package/src/components/ContextMenu/__tests__/ContextMenu.test.tsx +0 -87
  152. package/src/components/CurrencyInput/CurrencyInput.stories.tsx +0 -50
  153. package/src/components/CurrencyInput/CurrencyInput.tsx +0 -60
  154. package/src/components/DataTable/DataTable.module.css +0 -28
  155. package/src/components/DataTable/DataTable.stories.tsx +0 -74
  156. package/src/components/DataTable/DataTable.tsx +0 -154
  157. package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -123
  158. package/src/components/DatePicker/DatePicker.module.css +0 -61
  159. package/src/components/DatePicker/DatePicker.tsx +0 -103
  160. package/src/components/DatePicker/__tests__/DatePicker.test.tsx +0 -89
  161. package/src/components/DeviceOnlyGate/DeviceOnlyGate.tsx +0 -58
  162. package/src/components/DeviceOnlyGate/__tests__/DeviceOnlyGate.test.tsx +0 -45
  163. package/src/components/DeviceStorageKeyGate/DeviceStorageKeyGate.tsx +0 -100
  164. package/src/components/DeviceStorageKeyGate/__tests__/DeviceStorageKeyGate.test.tsx +0 -119
  165. package/src/components/Dialog/Dialog.module.css +0 -226
  166. package/src/components/Dialog/Dialog.stories.tsx +0 -147
  167. package/src/components/Dialog/Dialog.tsx +0 -160
  168. package/src/components/Dialog/__tests__/Dialog.test.tsx +0 -137
  169. package/src/components/DragHandleRow/DragHandleRow.module.css +0 -57
  170. package/src/components/DragHandleRow/DragHandleRow.tsx +0 -61
  171. package/src/components/Drawer/Drawer.module.css +0 -92
  172. package/src/components/Drawer/Drawer.stories.tsx +0 -132
  173. package/src/components/Drawer/Drawer.tsx +0 -176
  174. package/src/components/Drawer/__tests__/Drawer.test.tsx +0 -199
  175. package/src/components/EmptyState/EmptyState.module.css +0 -27
  176. package/src/components/EmptyState/EmptyState.tsx +0 -27
  177. package/src/components/FileDropzone/FileDropzone.module.css +0 -63
  178. package/src/components/FileDropzone/FileDropzone.tsx +0 -109
  179. package/src/components/FileDropzone/__tests__/FileDropzone.test.tsx +0 -67
  180. package/src/components/FormField/FormField.module.css +0 -33
  181. package/src/components/FormField/FormField.tsx +0 -78
  182. package/src/components/FormField/__tests__/FormField.test.tsx +0 -83
  183. package/src/components/HoverCard/HoverCard.module.css +0 -3
  184. package/src/components/HoverCard/HoverCard.stories.tsx +0 -66
  185. package/src/components/HoverCard/HoverCard.tsx +0 -111
  186. package/src/components/HoverCard/__tests__/HoverCard.test.tsx +0 -99
  187. package/src/components/Icon/Icon.module.css +0 -27
  188. package/src/components/Icon/Icon.stories.tsx +0 -95
  189. package/src/components/Icon/Icon.tsx +0 -43
  190. package/src/components/Icon/__tests__/Icon.test.tsx +0 -40
  191. package/src/components/Icon/icons/activity.tsx +0 -20
  192. package/src/components/Icon/icons/alert-triangle.tsx +0 -22
  193. package/src/components/Icon/icons/apple.tsx +0 -21
  194. package/src/components/Icon/icons/banana.tsx +0 -21
  195. package/src/components/Icon/icons/beef.tsx +0 -22
  196. package/src/components/Icon/icons/beer.tsx +0 -24
  197. package/src/components/Icon/icons/bell.tsx +0 -21
  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-x.tsx +0 -22
  208. package/src/components/Icon/icons/coffee.tsx +0 -23
  209. package/src/components/Icon/icons/cookie.tsx +0 -25
  210. package/src/components/Icon/icons/croissant.tsx +0 -24
  211. package/src/components/Icon/icons/cup-soda.tsx +0 -23
  212. package/src/components/Icon/icons/drumstick.tsx +0 -21
  213. package/src/components/Icon/icons/egg.tsx +0 -20
  214. package/src/components/Icon/icons/ellipsis-vertical.tsx +0 -22
  215. package/src/components/Icon/icons/external-link.tsx +0 -22
  216. package/src/components/Icon/icons/eye-off.tsx +0 -23
  217. package/src/components/Icon/icons/eye.tsx +0 -21
  218. package/src/components/Icon/icons/file.tsx +0 -21
  219. package/src/components/Icon/icons/fish.tsx +0 -25
  220. package/src/components/Icon/icons/grid-2x2.tsx +0 -22
  221. package/src/components/Icon/icons/house.tsx +0 -21
  222. package/src/components/Icon/icons/index.ts +0 -234
  223. package/src/components/Icon/icons/info.tsx +0 -22
  224. package/src/components/Icon/icons/lock.tsx +0 -21
  225. package/src/components/Icon/icons/log-out.tsx +0 -22
  226. package/src/components/Icon/icons/mail.tsx +0 -21
  227. package/src/components/Icon/icons/menu.tsx +0 -22
  228. package/src/components/Icon/icons/milk.tsx +0 -22
  229. package/src/components/Icon/icons/package.tsx +0 -23
  230. package/src/components/Icon/icons/pencil.tsx +0 -21
  231. package/src/components/Icon/icons/pizza.tsx +0 -24
  232. package/src/components/Icon/icons/plus.tsx +0 -21
  233. package/src/components/Icon/icons/rotate-ccw.tsx +0 -21
  234. package/src/components/Icon/icons/salad.tsx +0 -24
  235. package/src/components/Icon/icons/search.tsx +0 -21
  236. package/src/components/Icon/icons/settings.tsx +0 -21
  237. package/src/components/Icon/icons/shield.tsx +0 -20
  238. package/src/components/Icon/icons/shopping-basket.tsx +0 -26
  239. package/src/components/Icon/icons/sliders-horizontal.tsx +0 -28
  240. package/src/components/Icon/icons/smartphone.tsx +0 -21
  241. package/src/components/Icon/icons/snowflake.tsx +0 -31
  242. package/src/components/Icon/icons/spray-can.tsx +0 -29
  243. package/src/components/Icon/icons/trash-2.tsx +0 -24
  244. package/src/components/Icon/icons/upload.tsx +0 -22
  245. package/src/components/Icon/icons/user.tsx +0 -21
  246. package/src/components/Icon/icons/wine.tsx +0 -23
  247. package/src/components/Icon/icons/x.tsx +0 -21
  248. package/src/components/IconPicker/IconPicker.module.css +0 -63
  249. package/src/components/IconPicker/IconPicker.stories.tsx +0 -84
  250. package/src/components/IconPicker/IconPicker.tsx +0 -90
  251. package/src/components/Input/Input.module.css +0 -52
  252. package/src/components/Input/Input.stories.tsx +0 -86
  253. package/src/components/Input/Input.tsx +0 -14
  254. package/src/components/Input/__tests__/Input.test.tsx +0 -22
  255. package/src/components/Item/Item.module.css +0 -70
  256. package/src/components/Item/Item.stories.tsx +0 -62
  257. package/src/components/Item/Item.tsx +0 -54
  258. package/src/components/Item/__tests__/Item.test.tsx +0 -39
  259. package/src/components/Kbd/Kbd.module.css +0 -14
  260. package/src/components/Kbd/Kbd.stories.tsx +0 -32
  261. package/src/components/Kbd/Kbd.tsx +0 -12
  262. package/src/components/Kbd/__tests__/Kbd.test.tsx +0 -14
  263. package/src/components/Label/Label.module.css +0 -11
  264. package/src/components/Label/Label.stories.tsx +0 -40
  265. package/src/components/Label/Label.tsx +0 -24
  266. package/src/components/Label/__tests__/Label.test.tsx +0 -32
  267. package/src/components/LegalLinks/LegalLinks.module.css +0 -24
  268. package/src/components/LegalLinks/LegalLinks.stories.tsx +0 -22
  269. package/src/components/LegalLinks/LegalLinks.tsx +0 -40
  270. package/src/components/Markdown/Markdown.module.css +0 -49
  271. package/src/components/Markdown/Markdown.stories.tsx +0 -30
  272. package/src/components/Markdown/Markdown.tsx +0 -168
  273. package/src/components/Marker/Marker.module.css +0 -33
  274. package/src/components/Marker/Marker.stories.tsx +0 -39
  275. package/src/components/Marker/Marker.tsx +0 -34
  276. package/src/components/Marker/__tests__/Marker.test.tsx +0 -23
  277. package/src/components/MemberMultiSelect/MemberMultiSelect.module.css +0 -27
  278. package/src/components/MemberMultiSelect/MemberMultiSelect.stories.tsx +0 -74
  279. package/src/components/MemberMultiSelect/MemberMultiSelect.tsx +0 -67
  280. package/src/components/Menu/Menu.module.css +0 -89
  281. package/src/components/Menu/Menu.tsx +0 -159
  282. package/src/components/Menu/__tests__/Menu.test.tsx +0 -197
  283. package/src/components/Menubar/Menubar.stories.tsx +0 -52
  284. package/src/components/Menubar/Menubar.tsx +0 -42
  285. package/src/components/Menubar/__tests__/Menubar.test.tsx +0 -45
  286. package/src/components/Message/Message.module.css +0 -99
  287. package/src/components/Message/Message.stories.tsx +0 -79
  288. package/src/components/Message/Message.tsx +0 -41
  289. package/src/components/Message/__tests__/Message.test.tsx +0 -46
  290. package/src/components/MessageScroller/MessageScroller.module.css +0 -54
  291. package/src/components/MessageScroller/MessageScroller.stories.tsx +0 -84
  292. package/src/components/MessageScroller/MessageScroller.tsx +0 -72
  293. package/src/components/MessageScroller/__tests__/MessageScroller.test.tsx +0 -105
  294. package/src/components/MobileAppsDrawer/MobileAppsDrawer.module.css +0 -81
  295. package/src/components/MobileAppsDrawer/MobileAppsDrawer.tsx +0 -78
  296. package/src/components/MobileAppsDrawer/__tests__/MobileAppsDrawer.test.tsx +0 -80
  297. package/src/components/MobileFooter/MobileFooter.module.css +0 -73
  298. package/src/components/MobileFooter/MobileFooter.stories.tsx +0 -47
  299. package/src/components/MobileFooter/MobileFooter.tsx +0 -109
  300. package/src/components/MobileFooter/__tests__/MobileFooter.test.tsx +0 -71
  301. package/src/components/MobileHeader/MobileHeader.module.css +0 -63
  302. package/src/components/MobileHeader/MobileHeader.stories.tsx +0 -57
  303. package/src/components/MobileHeader/MobileHeader.tsx +0 -77
  304. package/src/components/MobileHeader/__tests__/MobileHeader.test.tsx +0 -58
  305. package/src/components/NavTabs/NavTabs.module.css +0 -50
  306. package/src/components/NavTabs/NavTabs.tsx +0 -61
  307. package/src/components/NavigationMenu/NavigationMenu.module.css +0 -53
  308. package/src/components/NavigationMenu/NavigationMenu.stories.tsx +0 -58
  309. package/src/components/NavigationMenu/NavigationMenu.tsx +0 -125
  310. package/src/components/NavigationMenu/__tests__/NavigationMenu.test.tsx +0 -93
  311. package/src/components/OfflineGate/OfflineGate.tsx +0 -44
  312. package/src/components/OfflineGate/__tests__/OfflineGate.test.tsx +0 -66
  313. package/src/components/OverlayHeader/OverlayHeader.module.css +0 -98
  314. package/src/components/OverlayHeader/OverlayHeader.tsx +0 -62
  315. package/src/components/OverlayHeader/__tests__/OverlayHeader.test.tsx +0 -51
  316. package/src/components/PageContainer/PageContainer.module.css +0 -20
  317. package/src/components/PageContainer/PageContainer.tsx +0 -31
  318. package/src/components/PageContainer/__tests__/PageContainer.test.tsx +0 -37
  319. package/src/components/PageHeader/PageHeader.module.css +0 -32
  320. package/src/components/PageHeader/PageHeader.tsx +0 -35
  321. package/src/components/Pagination/Pagination.module.css +0 -98
  322. package/src/components/Pagination/Pagination.stories.tsx +0 -49
  323. package/src/components/Pagination/Pagination.tsx +0 -87
  324. package/src/components/Pagination/__tests__/Pagination.test.tsx +0 -56
  325. package/src/components/Popover/Popover.module.css +0 -74
  326. package/src/components/Popover/Popover.stories.tsx +0 -357
  327. package/src/components/Popover/Popover.tsx +0 -208
  328. package/src/components/Popover/__tests__/Popover.test.tsx +0 -98
  329. package/src/components/Progress/Progress.module.css +0 -20
  330. package/src/components/Progress/Progress.stories.tsx +0 -40
  331. package/src/components/Progress/Progress.tsx +0 -35
  332. package/src/components/Progress/__tests__/Progress.test.tsx +0 -31
  333. package/src/components/QuantityStepper/QuantityStepper.module.css +0 -67
  334. package/src/components/QuantityStepper/QuantityStepper.stories.tsx +0 -79
  335. package/src/components/QuantityStepper/QuantityStepper.tsx +0 -107
  336. package/src/components/RadioGroup/RadioGroup.module.css +0 -88
  337. package/src/components/RadioGroup/RadioGroup.stories.tsx +0 -69
  338. package/src/components/RadioGroup/RadioGroup.tsx +0 -99
  339. package/src/components/RadioGroup/__tests__/RadioGroup.test.tsx +0 -59
  340. package/src/components/Resizable/Resizable.module.css +0 -70
  341. package/src/components/Resizable/Resizable.stories.tsx +0 -82
  342. package/src/components/Resizable/Resizable.tsx +0 -313
  343. package/src/components/Resizable/__tests__/Resizable.test.tsx +0 -128
  344. package/src/components/ResponsiveSurface/ResponsiveSurface.tsx +0 -24
  345. package/src/components/ResponsiveSurface/__tests__/ResponsiveSurface.test.tsx +0 -73
  346. package/src/components/ScrollArea/ScrollArea.module.css +0 -20
  347. package/src/components/ScrollArea/ScrollArea.stories.tsx +0 -57
  348. package/src/components/ScrollArea/ScrollArea.tsx +0 -27
  349. package/src/components/ScrollArea/__tests__/ScrollArea.test.tsx +0 -39
  350. package/src/components/SegmentedControl/SegmentedControl.module.css +0 -55
  351. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +0 -118
  352. package/src/components/SegmentedControl/SegmentedControl.tsx +0 -56
  353. package/src/components/SegmentedControl/__tests__/SegmentedControl.test.tsx +0 -63
  354. package/src/components/Select/Select.module.css +0 -82
  355. package/src/components/Select/Select.stories.tsx +0 -115
  356. package/src/components/Select/Select.tsx +0 -48
  357. package/src/components/Select/__tests__/Select.test.tsx +0 -59
  358. package/src/components/Sheet/Sheet.module.css +0 -55
  359. package/src/components/Sheet/Sheet.tsx +0 -109
  360. package/src/components/Sheet/__tests__/Sheet.test.tsx +0 -99
  361. package/src/components/Slider/Slider.module.css +0 -95
  362. package/src/components/Slider/Slider.stories.tsx +0 -64
  363. package/src/components/Slider/Slider.tsx +0 -77
  364. package/src/components/Slider/__tests__/Slider.test.tsx +0 -45
  365. package/src/components/Spinner/Spinner.module.css +0 -39
  366. package/src/components/Spinner/Spinner.tsx +0 -23
  367. package/src/components/SplitMethodSelector/SplitMethodSelector.stories.tsx +0 -33
  368. package/src/components/SplitMethodSelector/SplitMethodSelector.tsx +0 -43
  369. package/src/components/SplitPane/SplitPane.module.css +0 -85
  370. package/src/components/SplitPane/SplitPane.stories.tsx +0 -160
  371. package/src/components/SplitPane/SplitPane.tsx +0 -149
  372. package/src/components/SplitPane/__tests__/SplitPane.test.tsx +0 -51
  373. package/src/components/StatusBadge/StatusBadge.module.css +0 -59
  374. package/src/components/StatusBadge/StatusBadge.stories.tsx +0 -74
  375. package/src/components/StatusBadge/StatusBadge.tsx +0 -65
  376. package/src/components/SuggestionInput/SuggestionInput.module.css +0 -103
  377. package/src/components/SuggestionInput/SuggestionInput.stories.tsx +0 -144
  378. package/src/components/SuggestionInput/SuggestionInput.tsx +0 -207
  379. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.module.css +0 -55
  380. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.tsx +0 -227
  381. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlide.tsx +0 -35
  382. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideBody.tsx +0 -42
  383. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideFooter.tsx +0 -18
  384. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideHeader.tsx +0 -21
  385. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideParts.module.css +0 -29
  386. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarousel.test.tsx +0 -133
  387. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarouselDevGuard.test.tsx +0 -61
  388. package/src/components/SwipableMobileCarousel/context.ts +0 -13
  389. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.module.css +0 -49
  390. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.tsx +0 -62
  391. package/src/components/SwipableMobileCarouselDots/__tests__/SwipableMobileCarouselDots.test.tsx +0 -63
  392. package/src/components/SystemBanner/SystemBanner.module.css +0 -69
  393. package/src/components/SystemBanner/SystemBanner.stories.tsx +0 -86
  394. package/src/components/SystemBanner/SystemBanner.tsx +0 -50
  395. package/src/components/SystemBanner/__tests__/SystemBanner.test.tsx +0 -50
  396. package/src/components/Table/Table.module.css +0 -45
  397. package/src/components/Table/Table.stories.tsx +0 -125
  398. package/src/components/Table/Table.tsx +0 -51
  399. package/src/components/Table/__tests__/Table.test.tsx +0 -50
  400. package/src/components/Tabs/Tabs.module.css +0 -56
  401. package/src/components/Tabs/Tabs.stories.tsx +0 -100
  402. package/src/components/Tabs/Tabs.tsx +0 -46
  403. package/src/components/Tabs/__tests__/Tabs.test.tsx +0 -45
  404. package/src/components/TagInput/TagInput.module.css +0 -141
  405. package/src/components/TagInput/TagInput.stories.tsx +0 -109
  406. package/src/components/TagInput/TagInput.tsx +0 -174
  407. package/src/components/TagInput/__tests__/TagInput.test.tsx +0 -69
  408. package/src/components/Textarea/Textarea.module.css +0 -39
  409. package/src/components/Textarea/Textarea.tsx +0 -15
  410. package/src/components/Textarea/__tests__/Textarea.test.tsx +0 -29
  411. package/src/components/Toast/Toast.module.css +0 -132
  412. package/src/components/Toast/Toast.stories.tsx +0 -191
  413. package/src/components/Toast/Toast.tsx +0 -139
  414. package/src/components/Toggle/Toggle.module.css +0 -57
  415. package/src/components/Toggle/Toggle.stories.tsx +0 -95
  416. package/src/components/Toggle/Toggle.tsx +0 -39
  417. package/src/components/Toggle/__tests__/Toggle.test.tsx +0 -47
  418. package/src/components/Tooltip/Tooltip.module.css +0 -56
  419. package/src/components/Tooltip/Tooltip.tsx +0 -30
  420. package/src/components/Typography/Typography.module.css +0 -47
  421. package/src/components/Typography/Typography.stories.tsx +0 -62
  422. package/src/components/Typography/Typography.tsx +0 -30
  423. package/src/components/Typography/__tests__/Typography.test.tsx +0 -34
  424. package/src/css-modules.d.ts +0 -4
  425. package/src/hooks/__tests__/useCarouselRouteSync.test.tsx +0 -126
  426. package/src/hooks/__tests__/useDoubleTap.test.tsx +0 -117
  427. package/src/hooks/__tests__/useIsMobile.test.tsx +0 -80
  428. package/src/hooks/__tests__/useIsOffline.test.tsx +0 -53
  429. package/src/hooks/__tests__/useLongPress.test.tsx +0 -158
  430. package/src/hooks/__tests__/useOfflineTileState.test.tsx +0 -69
  431. package/src/hooks/__tests__/useResponsiveLayout.test.tsx +0 -87
  432. package/src/hooks/__tests__/useSnapCarousel.test.tsx +0 -93
  433. package/src/hooks/__tests__/useSwipeReveal.test.tsx +0 -110
  434. package/src/hooks/index.ts +0 -24
  435. package/src/hooks/useCarouselRouteSync.ts +0 -92
  436. package/src/hooks/useCommitOnEnterOrBlur.ts +0 -39
  437. package/src/hooks/useDoubleTap.ts +0 -91
  438. package/src/hooks/useIsMobile.ts +0 -33
  439. package/src/hooks/useIsOffline.ts +0 -41
  440. package/src/hooks/useLongPress.ts +0 -185
  441. package/src/hooks/useOfflineTileState.ts +0 -45
  442. package/src/hooks/useResponsiveLayout.ts +0 -36
  443. package/src/hooks/useSnapCarousel.ts +0 -79
  444. package/src/hooks/useSwipeReveal.ts +0 -107
  445. package/src/index.ts +0 -251
  446. package/src/motion.ts +0 -78
  447. package/src/overlay-shell.ts +0 -94
  448. package/src/scroll-lock.ts +0 -22
  449. package/src/stories/Avatar.stories.tsx +0 -44
  450. package/src/stories/Card.stories.tsx +0 -35
  451. package/src/stories/Checkbox.stories.tsx +0 -45
  452. package/src/stories/DesignSystemOverview.stories.tsx +0 -3187
  453. package/src/stories/DeviceOnlyGate.stories.tsx +0 -35
  454. package/src/stories/DeviceStorageKeyGate.stories.tsx +0 -57
  455. package/src/stories/DragHandleRow.stories.tsx +0 -41
  456. package/src/stories/EmptyState.stories.tsx +0 -33
  457. package/src/stories/FileDropzone.stories.tsx +0 -69
  458. package/src/stories/FormField.stories.tsx +0 -47
  459. package/src/stories/InteractionHooks.stories.tsx +0 -925
  460. package/src/stories/MobilePatterns.stories.tsx +0 -1536
  461. package/src/stories/NavTabs.stories.tsx +0 -53
  462. package/src/stories/OfflineGate.stories.tsx +0 -42
  463. package/src/stories/PageContainer.stories.tsx +0 -37
  464. package/src/stories/PageHeader.stories.tsx +0 -42
  465. package/src/stories/ResponsiveSurface.stories.tsx +0 -47
  466. package/src/stories/Spinner.stories.tsx +0 -25
  467. package/src/stories/SwipableMobileCarousel.stories.tsx +0 -304
  468. package/src/stories/Textarea.stories.tsx +0 -51
  469. package/src/stories/TokenGallery.stories.tsx +0 -602
  470. package/src/stories/Tooltip.stories.tsx +0 -59
  471. package/src/tokens/primitives.css +0 -157
  472. package/src/tokens/semantic.css +0 -130
  473. package/src/tokens.css +0 -5
@@ -1,95 +0,0 @@
1
- import { useState } from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react-vite';
3
- import { Toggle } from './Toggle';
4
-
5
- const meta = {
6
- title: 'Components/Toggle',
7
- component: Toggle,
8
- parameters: {
9
- layout: 'centered',
10
- docs: {
11
- description: {
12
- component:
13
- '38×22px binary switch for settings rows. Renders as `<button role="switch">` for reliable VoiceOver support. `aria-label` is required.',
14
- },
15
- },
16
- },
17
- argTypes: {
18
- checked: { control: 'boolean' },
19
- disabled: { control: 'boolean' },
20
- },
21
- args: {
22
- checked: false,
23
- onChange: () => {},
24
- 'aria-label': 'Toggle setting',
25
- },
26
- } satisfies Meta<typeof Toggle>;
27
-
28
- export default meta;
29
- type Story = StoryObj<typeof meta>;
30
-
31
- // ---------------------------------------------------------------------------
32
-
33
- export const Off: Story = { args: { checked: false } };
34
- export const On: Story = { args: { checked: true } };
35
- export const Disabled: Story = { args: { checked: false, disabled: true } };
36
- export const DisabledOn: Story = { args: { checked: true, disabled: true } };
37
-
38
- /** Interactive — click to toggle. */
39
- export const Interactive: Story = {
40
- render: (args) => {
41
- const [checked, setChecked] = useState(args.checked);
42
- return <Toggle {...args} checked={checked} onChange={setChecked} />;
43
- },
44
- };
45
-
46
- /** Settings rows — typical usage with adjacent label text. */
47
- export const SettingsRows: Story = {
48
- render: (_args) => {
49
- const [twoFA, setTwoFA] = useState(true);
50
- const [email, setEmail] = useState(false);
51
-
52
- const rowStyle: React.CSSProperties = {
53
- display: 'flex',
54
- alignItems: 'center',
55
- justifyContent: 'space-between',
56
- gap: 32,
57
- padding: '12px 0',
58
- borderBottom: '1px solid var(--sv-color-border)',
59
- fontFamily: 'var(--sv-font-family)',
60
- };
61
- const labelStyle: React.CSSProperties = {
62
- display: 'flex',
63
- flexDirection: 'column',
64
- gap: 2,
65
- };
66
- const titleStyle: React.CSSProperties = {
67
- fontSize: 'var(--sv-font-size-sm)',
68
- fontWeight: 'var(--sv-font-weight-medium)',
69
- color: 'var(--sv-color-text-primary)',
70
- };
71
- const descStyle: React.CSSProperties = {
72
- fontSize: 'var(--sv-font-size-caption)',
73
- color: 'var(--sv-color-text-muted)',
74
- };
75
-
76
- return (
77
- <div style={{ width: 320 }}>
78
- <div style={rowStyle}>
79
- <div style={labelStyle}>
80
- <span style={titleStyle}>Two-factor authentication</span>
81
- <span style={descStyle}>Require a code when signing in.</span>
82
- </div>
83
- <Toggle checked={twoFA} onChange={setTwoFA} aria-label="Two-factor authentication" />
84
- </div>
85
- <div style={rowStyle}>
86
- <div style={labelStyle}>
87
- <span style={titleStyle}>Email notifications</span>
88
- <span style={descStyle}>Receive digests and alerts.</span>
89
- </div>
90
- <Toggle checked={email} onChange={setEmail} aria-label="Email notifications" />
91
- </div>
92
- </div>
93
- );
94
- },
95
- };
@@ -1,39 +0,0 @@
1
- 'use client';
2
-
3
- import type { ButtonHTMLAttributes } from 'react';
4
- import styles from './Toggle.module.css';
5
-
6
- export interface ToggleProps extends Omit<
7
- ButtonHTMLAttributes<HTMLButtonElement>,
8
- 'onChange' | 'aria-label'
9
- > {
10
- checked: boolean;
11
- onChange: (checked: boolean) => void;
12
- disabled?: boolean;
13
- 'aria-label': string;
14
- }
15
-
16
- /**
17
- * Toggle — 38×22px binary switch for settings rows.
18
- *
19
- * Renders as `<button role="switch">` rather than a hidden `<input type="checkbox">`
20
- * to avoid iOS VoiceOver focus quirks on visually styled checkboxes. The `aria-label`
21
- * prop is required because the control has no visible text label of its own.
22
- */
23
- export function Toggle({ checked, onChange, disabled, className, ...rest }: ToggleProps) {
24
- return (
25
- <button
26
- type="button"
27
- role="switch"
28
- aria-checked={checked}
29
- disabled={disabled}
30
- className={[styles.track, checked ? styles.on : styles.off, className]
31
- .filter(Boolean)
32
- .join(' ')}
33
- onClick={() => onChange(!checked)}
34
- {...rest}
35
- >
36
- <span className={styles.thumb} />
37
- </button>
38
- );
39
- }
@@ -1,47 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, render, screen, fireEvent } from '@testing-library/react';
4
-
5
- afterEach(cleanup);
6
- import { Toggle } from '../Toggle';
7
-
8
- describe('Toggle', () => {
9
- it('renders as a switch button', () => {
10
- render(<Toggle checked={false} onChange={() => {}} aria-label="Notifications" />);
11
- expect(screen.getByRole('switch', { name: 'Notifications' })).toBeDefined();
12
- });
13
-
14
- it('reflects checked state via aria-checked', () => {
15
- const { rerender } = render(
16
- <Toggle checked={false} onChange={() => {}} aria-label="Setting" />,
17
- );
18
- expect(screen.getByRole('switch').getAttribute('aria-checked')).toBe('false');
19
-
20
- rerender(<Toggle checked={true} onChange={() => {}} aria-label="Setting" />);
21
- expect(screen.getByRole('switch').getAttribute('aria-checked')).toBe('true');
22
- });
23
-
24
- it('calls onChange with toggled value on click', () => {
25
- const onChange = vi.fn();
26
- render(<Toggle checked={false} onChange={onChange} aria-label="Setting" />);
27
- fireEvent.click(screen.getByRole('switch'));
28
- expect(onChange).toHaveBeenCalledWith(true);
29
- });
30
-
31
- it('does not call onChange when disabled', () => {
32
- const onChange = vi.fn();
33
- render(<Toggle checked={false} onChange={onChange} disabled aria-label="Setting" />);
34
- fireEvent.click(screen.getByRole('switch'));
35
- expect(onChange).not.toHaveBeenCalled();
36
- });
37
-
38
- it('applies on class when checked', () => {
39
- render(<Toggle checked={true} onChange={() => {}} aria-label="Setting" />);
40
- expect(screen.getByRole('switch').className).toContain('on');
41
- });
42
-
43
- it('applies off class when unchecked', () => {
44
- render(<Toggle checked={false} onChange={() => {}} aria-label="Setting" />);
45
- expect(screen.getByRole('switch').className).toContain('off');
46
- });
47
- });
@@ -1,56 +0,0 @@
1
- .wrapper {
2
- position: relative;
3
- display: inline-flex;
4
- }
5
-
6
- .tip {
7
- position: absolute;
8
- z-index: 50;
9
- white-space: nowrap;
10
- padding: var(--sv-space-1) var(--sv-space-2);
11
- background: var(--sv-color-surface-raised);
12
- border: 1px solid var(--sv-color-border);
13
- border-radius: var(--sv-radius-md);
14
- box-shadow: var(--sv-shadow-popover);
15
- font-size: var(--sv-font-size-xs);
16
- color: var(--sv-color-text-primary);
17
- font-family: var(--sv-font-family);
18
- pointer-events: none;
19
- opacity: 0;
20
- transition: opacity 0.1s ease;
21
- }
22
-
23
- @media (hover: hover) {
24
- .wrapper:hover .tip {
25
- opacity: 1;
26
- }
27
- }
28
-
29
- .wrapper:focus-within .tip {
30
- opacity: 1;
31
- }
32
-
33
- /* Placement */
34
- .top {
35
- bottom: calc(100% + var(--sv-space-2));
36
- left: 50%;
37
- transform: translateX(-50%);
38
- }
39
-
40
- .bottom {
41
- top: calc(100% + var(--sv-space-2));
42
- left: 50%;
43
- transform: translateX(-50%);
44
- }
45
-
46
- .left {
47
- right: calc(100% + var(--sv-space-2));
48
- top: 50%;
49
- transform: translateY(-50%);
50
- }
51
-
52
- .right {
53
- left: calc(100% + var(--sv-space-2));
54
- top: 50%;
55
- transform: translateY(-50%);
56
- }
@@ -1,30 +0,0 @@
1
- import type { ReactElement } from 'react';
2
- import { useId } from 'react';
3
- import styles from './Tooltip.module.css';
4
-
5
- export interface TooltipProps {
6
- content: string;
7
- children: ReactElement;
8
- side?: 'top' | 'bottom' | 'left' | 'right';
9
- }
10
-
11
- const sideClass: Record<NonNullable<TooltipProps['side']>, string> = {
12
- top: styles.top as string,
13
- bottom: styles.bottom as string,
14
- left: styles.left as string,
15
- right: styles.right as string,
16
- };
17
-
18
- export function Tooltip({ content, children, side = 'top' }: TooltipProps) {
19
- const tipId = useId();
20
-
21
- return (
22
- <span className={styles.wrapper}>
23
- {/* aria-describedby wires the tooltip text to the trigger for screen readers */}
24
- <span aria-describedby={tipId}>{children}</span>
25
- <span id={tipId} role="tooltip" className={[styles.tip, sideClass[side]].join(' ')}>
26
- {content}
27
- </span>
28
- </span>
29
- );
30
- }
@@ -1,47 +0,0 @@
1
- .h1 {
2
- margin: 0;
3
- font-size: var(--sv-font-size-2xl);
4
- font-weight: var(--sv-font-weight-semibold);
5
- color: var(--sv-color-text-primary);
6
- }
7
-
8
- .h2 {
9
- margin: 0;
10
- font-size: var(--sv-font-size-xl);
11
- font-weight: var(--sv-font-weight-semibold);
12
- color: var(--sv-color-text-primary);
13
- }
14
-
15
- .h3 {
16
- margin: 0;
17
- font-size: var(--sv-font-size-lg);
18
- font-weight: var(--sv-font-weight-semibold);
19
- color: var(--sv-color-text-primary);
20
- }
21
-
22
- .h4 {
23
- margin: 0;
24
- font-size: var(--sv-font-size-md);
25
- font-weight: var(--sv-font-weight-semibold);
26
- color: var(--sv-color-text-primary);
27
- }
28
-
29
- .body {
30
- margin: 0;
31
- font-size: var(--sv-font-size-sm);
32
- color: var(--sv-color-text-primary);
33
- }
34
-
35
- .caption {
36
- margin: 0;
37
- font-size: var(--sv-font-size-caption);
38
- color: var(--sv-color-text-muted);
39
- }
40
-
41
- .label {
42
- font-size: var(--sv-font-size-label);
43
- font-weight: var(--sv-font-weight-semibold);
44
- color: var(--sv-color-text-muted);
45
- text-transform: uppercase;
46
- letter-spacing: 0.04em;
47
- }
@@ -1,62 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { Typography } from './Typography';
3
-
4
- const meta = {
5
- title: 'Components/Typography',
6
- component: Typography,
7
- parameters: { layout: 'padded' },
8
- args: {
9
- variant: 'body',
10
- children: 'The quick brown fox',
11
- },
12
- } satisfies Meta<typeof Typography>;
13
-
14
- export default meta;
15
- type Story = StoryObj<typeof meta>;
16
-
17
- // ---------------------------------------------------------------------------
18
-
19
- export const H1: Story = {
20
- args: { variant: 'h1' },
21
- };
22
-
23
- export const H2: Story = {
24
- args: { variant: 'h2' },
25
- };
26
-
27
- export const H3: Story = {
28
- args: { variant: 'h3' },
29
- };
30
-
31
- export const H4: Story = {
32
- args: { variant: 'h4' },
33
- };
34
-
35
- export const Body: Story = {
36
- args: { variant: 'body' },
37
- };
38
-
39
- export const Caption: Story = {
40
- args: { variant: 'caption' },
41
- };
42
-
43
- export const LabelVariant: Story = {
44
- name: 'Label',
45
- args: { variant: 'label', children: 'Section label' },
46
- };
47
-
48
- export const AllVariants: Story = {
49
- render: () => (
50
- <div style={{ display: 'flex', flexDirection: 'column', gap: 12 }}>
51
- <Typography variant="h1">Heading 1</Typography>
52
- <Typography variant="h2">Heading 2</Typography>
53
- <Typography variant="h3">Heading 3</Typography>
54
- <Typography variant="h4">Heading 4</Typography>
55
- <Typography variant="body">
56
- Body copy — the default reading size for paragraphs and descriptions.
57
- </Typography>
58
- <Typography variant="caption">Caption — secondary, supporting copy.</Typography>
59
- <Typography variant="label">Section label</Typography>
60
- </div>
61
- ),
62
- };
@@ -1,30 +0,0 @@
1
- import type { ElementType, ReactNode } from 'react';
2
- import styles from './Typography.module.css';
3
-
4
- export type TypographyVariant = 'h1' | 'h2' | 'h3' | 'h4' | 'body' | 'caption' | 'label';
5
-
6
- const DEFAULT_TAG: Record<TypographyVariant, ElementType> = {
7
- h1: 'h1',
8
- h2: 'h2',
9
- h3: 'h3',
10
- h4: 'h4',
11
- body: 'p',
12
- caption: 'p',
13
- label: 'span',
14
- };
15
-
16
- export interface TypographyProps {
17
- variant: TypographyVariant;
18
- children: ReactNode;
19
- /** Override the rendered tag while keeping the variant's visual style —
20
- * e.g. `variant="h1" as="div"` to avoid a second `<h1>` on a page that
21
- * already has one. */
22
- as?: ElementType;
23
- className?: string;
24
- }
25
-
26
- /** Typography — text bound to the design system's font-size/weight scale. */
27
- export function Typography({ variant, children, as, className }: TypographyProps) {
28
- const Tag = as ?? DEFAULT_TAG[variant];
29
- return <Tag className={[styles[variant], className].filter(Boolean).join(' ')}>{children}</Tag>;
30
- }
@@ -1,34 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it } from 'vitest';
3
- import { cleanup, render, screen } from '@testing-library/react';
4
- import { Typography } from '../Typography';
5
-
6
- afterEach(cleanup);
7
-
8
- describe('Typography', () => {
9
- it('renders the default tag for each variant', () => {
10
- render(<Typography variant="h1">Title</Typography>);
11
- expect(screen.getByText('Title').tagName).toBe('H1');
12
- });
13
-
14
- it('renders body as a <p> by default', () => {
15
- render(<Typography variant="body">Body copy</Typography>);
16
- expect(screen.getByText('Body copy').tagName).toBe('P');
17
- });
18
-
19
- it('renders label as a <span> by default', () => {
20
- render(<Typography variant="label">Section</Typography>);
21
- expect(screen.getByText('Section').tagName).toBe('SPAN');
22
- });
23
-
24
- it('overrides the rendered tag via `as` while keeping the variant class', () => {
25
- render(
26
- <Typography variant="h1" as="div">
27
- Title
28
- </Typography>,
29
- );
30
- const el = screen.getByText('Title');
31
- expect(el.tagName).toBe('DIV');
32
- expect(el.className).toContain('h1');
33
- });
34
- });
@@ -1,4 +0,0 @@
1
- declare module '*.module.css' {
2
- const classes: Readonly<Record<string, string>>;
3
- export default classes;
4
- }
@@ -1,126 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it, vi } from 'vitest';
3
- import { act, cleanup, render } from '@testing-library/react';
4
- import { useCarouselRouteSync } from '../useCarouselRouteSync';
5
-
6
- const SLIDES = ['/a', '/b', '/c'];
7
- function indexForPathname(pathname: string) {
8
- const i = SLIDES.indexOf(pathname);
9
- return i === -1 ? 0 : i;
10
- }
11
- function pathForIndex(index: number) {
12
- return SLIDES[index] ?? '/a';
13
- }
14
-
15
- function Harness({
16
- pathname,
17
- onNavigate,
18
- onResult,
19
- }: {
20
- pathname: string;
21
- onNavigate: (path: string) => void;
22
- onResult: (result: { activeIndex: number; onSettle: (i: number) => void }) => void;
23
- }) {
24
- const result = useCarouselRouteSync({ indexForPathname, pathForIndex, pathname, onNavigate });
25
- onResult(result);
26
- return <span data-testid="active">{result.activeIndex}</span>;
27
- }
28
-
29
- afterEach(cleanup);
30
-
31
- describe('useCarouselRouteSync', () => {
32
- it('initializes activeIndex from the current pathname', () => {
33
- const onNavigate = vi.fn();
34
- const { getByTestId } = render(
35
- <Harness pathname="/b" onNavigate={onNavigate} onResult={() => {}} />,
36
- );
37
- expect(getByTestId('active').textContent).toBe('1');
38
- expect(onNavigate).not.toHaveBeenCalled();
39
- });
40
-
41
- it('an external pathname change (tapped Link, browser back/forward) updates activeIndex without calling onNavigate', () => {
42
- const onNavigate = vi.fn();
43
- const { getByTestId, rerender } = render(
44
- <Harness pathname="/a" onNavigate={onNavigate} onResult={() => {}} />,
45
- );
46
- expect(getByTestId('active').textContent).toBe('0');
47
-
48
- rerender(<Harness pathname="/c" onNavigate={onNavigate} onResult={() => {}} />);
49
- expect(getByTestId('active').textContent).toBe('2');
50
- expect(onNavigate).not.toHaveBeenCalled();
51
- });
52
-
53
- it("onSettle calls onNavigate with pathForIndex's output and updates activeIndex synchronously", () => {
54
- const onNavigate = vi.fn();
55
- let latest: { activeIndex: number; onSettle: (i: number) => void } = {
56
- activeIndex: -1,
57
- onSettle: () => {},
58
- };
59
- const { getByTestId } = render(
60
- <Harness
61
- pathname="/a"
62
- onNavigate={onNavigate}
63
- onResult={(r) => {
64
- latest = r;
65
- }}
66
- />,
67
- );
68
-
69
- act(() => void latest.onSettle(2));
70
-
71
- expect(getByTestId('active').textContent).toBe('2');
72
- expect(onNavigate).toHaveBeenCalledWith('/c');
73
- expect(onNavigate).toHaveBeenCalledTimes(1);
74
- });
75
-
76
- it('does NOT re-trigger the external-nav branch on the pathname-effect run that follows its own onSettle-driven navigation', () => {
77
- // This is the isInternalNav dance: onSettle navigates via onNavigate; the
78
- // caller's router then re-renders this hook with the new pathname — that
79
- // pathname change must be recognized as "our own settle, already
80
- // applied" and NOT reprocessed as an external nav. Both existing plugins'
81
- // code comments describe a real double-flicker bug from getting this
82
- // wrong, so this is the highest-value assertion in this file.
83
- const onNavigate = vi.fn();
84
- let latest: { activeIndex: number; onSettle: (i: number) => void } = {
85
- activeIndex: -1,
86
- onSettle: () => {},
87
- };
88
- const { getByTestId, rerender } = render(
89
- <Harness
90
- pathname="/a"
91
- onNavigate={onNavigate}
92
- onResult={(r) => {
93
- latest = r;
94
- }}
95
- />,
96
- );
97
-
98
- // Settle on /b (index 1) — this is the carousel's own gesture-driven navigation.
99
- act(() => void latest.onSettle(1));
100
- expect(getByTestId('active').textContent).toBe('1');
101
- expect(onNavigate).toHaveBeenCalledWith('/b');
102
-
103
- // The caller's router "commits" the navigation by re-rendering with the
104
- // new pathname (exactly what onNavigate's real router.replace would
105
- // eventually cause). If this were misidentified as an external nav, the
106
- // effect would recompute indexForPathname('/b') anyway — same value, so
107
- // a bug here wouldn't show up as a *wrong* index, only as an extra,
108
- // redundant setState (the actual symptom in the original bug was a
109
- // visible re-snap/flicker, not a wrong end state) — so this test also
110
- // asserts onNavigate is never called a second time as a side effect of
111
- // that re-render, which would happen if the effect treated it as new
112
- // settle-worthy input rather than a no-op resync.
113
- rerender(<Harness pathname="/b" onNavigate={onNavigate} onResult={(r) => (latest = r)} />);
114
-
115
- expect(getByTestId('active').textContent).toBe('1');
116
- expect(onNavigate).toHaveBeenCalledTimes(1);
117
- });
118
-
119
- it('an unrecognized pathname falls back to index 0', () => {
120
- const onNavigate = vi.fn();
121
- const { getByTestId } = render(
122
- <Harness pathname="/unknown" onNavigate={onNavigate} onResult={() => {}} />,
123
- );
124
- expect(getByTestId('active').textContent).toBe('0');
125
- });
126
- });