@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,111 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { HeaderFooterLayout } from './HeaderFooterLayout';
3
-
4
- function Bar({ label }: { label: string }) {
5
- return (
6
- <div
7
- style={{
8
- display: 'flex',
9
- alignItems: 'center',
10
- justifyContent: 'center',
11
- height: '100%',
12
- fontFamily: 'var(--sv-font-family)',
13
- fontSize: 'var(--sv-font-size-sm)',
14
- fontWeight: 600,
15
- color: 'var(--sv-color-text-primary)',
16
- background: 'var(--sv-color-surface-raised)',
17
- borderBlock: '1px solid var(--sv-color-border)',
18
- }}
19
- >
20
- {label}
21
- </div>
22
- );
23
- }
24
-
25
- function ScrollableMain() {
26
- return (
27
- <div style={{ padding: 'var(--sv-space-4)', fontFamily: 'var(--sv-font-family)' }}>
28
- {Array.from({ length: 30 }, (_, index) => (
29
- <p key={index} style={{ color: 'var(--sv-color-text-primary)' }}>
30
- Row {index + 1} — the main region scrolls independently; header and footer stay put.
31
- </p>
32
- ))}
33
- </div>
34
- );
35
- }
36
-
37
- const meta = {
38
- title: 'Components/HeaderFooterLayout',
39
- component: HeaderFooterLayout,
40
- parameters: {
41
- layout: 'fullscreen',
42
- docs: {
43
- description: {
44
- component:
45
- 'Header + main + optional footer, both fixed-height and independently optional, with main always claiming the remaining height. The vertical counterpart to ThreeColumnLayout — a plain flex column, no color opinions, no responsive behavior of its own.',
46
- },
47
- },
48
- },
49
- args: {
50
- children: <ScrollableMain />,
51
- },
52
- } satisfies Meta<typeof HeaderFooterLayout>;
53
-
54
- export default meta;
55
- type Story = StoryObj<typeof meta>;
56
-
57
- /** The canonical usage — header + main + footer, all three present. */
58
- export const Default: Story = {
59
- render: () => (
60
- <div style={{ height: '480px' }}>
61
- <HeaderFooterLayout header={<Bar label="Header" />} footer={<Bar label="Footer" />}>
62
- <ScrollableMain />
63
- </HeaderFooterLayout>
64
- </div>
65
- ),
66
- };
67
-
68
- export const HeaderOnly: Story = {
69
- render: () => (
70
- <div style={{ height: '480px' }}>
71
- <HeaderFooterLayout header={<Bar label="Header" />}>
72
- <ScrollableMain />
73
- </HeaderFooterLayout>
74
- </div>
75
- ),
76
- };
77
-
78
- export const FooterOnly: Story = {
79
- render: () => (
80
- <div style={{ height: '480px' }}>
81
- <HeaderFooterLayout footer={<Bar label="Footer" />}>
82
- <ScrollableMain />
83
- </HeaderFooterLayout>
84
- </div>
85
- ),
86
- };
87
-
88
- export const MainOnly: Story = {
89
- render: () => (
90
- <div style={{ height: '480px' }}>
91
- <HeaderFooterLayout>
92
- <ScrollableMain />
93
- </HeaderFooterLayout>
94
- </div>
95
- ),
96
- };
97
-
98
- export const CustomHeights: Story = {
99
- render: () => (
100
- <div style={{ height: '480px' }}>
101
- <HeaderFooterLayout
102
- header={<Bar label="Header (100px)" />}
103
- footer={<Bar label="Footer (48px)" />}
104
- headerHeight={100}
105
- footerHeight={48}
106
- >
107
- <ScrollableMain />
108
- </HeaderFooterLayout>
109
- </div>
110
- ),
111
- };
@@ -1,54 +0,0 @@
1
- 'use client';
2
-
3
- import type { ReactNode } from 'react';
4
- import styles from './HeaderFooterLayout.module.css';
5
-
6
- export interface HeaderFooterLayoutProps {
7
- /** Main content — required, always fills whatever height header/footer don't claim. */
8
- children: ReactNode;
9
- header?: ReactNode;
10
- footer?: ReactNode;
11
- /** px. Fixed height of the header, when present. Default 60 (matches
12
- * MobileHeader/--sv-shell-header-height's own default). */
13
- headerHeight?: number;
14
- /** px. Fixed height of the footer, when present. Default 60 (matches
15
- * MobileFooter/--sv-shell-footer-height's own default). */
16
- footerHeight?: number;
17
- className?: string;
18
- }
19
-
20
- /**
21
- * HeaderFooterLayout — header + main + optional footer, both fixed-height
22
- * and independently optional, with main always claiming the remaining
23
- * height. The vertical counterpart to ThreeColumnLayout: same purely
24
- * structural approach (no color/background opinions, no awareness of what's
25
- * inside each slot, no responsive behavior of its own — a plain flex
26
- * column), just rotated. "Footer always at the bottom" falls out of flex
27
- * layout alone; there is no position: fixed or safe-area handling here, so
28
- * a caller composing this with the platform shell's own chrome still owns
29
- * that separately.
30
- */
31
- export function HeaderFooterLayout({
32
- children,
33
- header,
34
- footer,
35
- headerHeight = 60,
36
- footerHeight = 60,
37
- className,
38
- }: HeaderFooterLayoutProps) {
39
- return (
40
- <div className={[styles.shell, className].filter(Boolean).join(' ')}>
41
- {header && (
42
- <div className={styles.header} style={{ height: headerHeight }}>
43
- {header}
44
- </div>
45
- )}
46
- <div className={styles.main}>{children}</div>
47
- {footer && (
48
- <div className={styles.footer} style={{ height: footerHeight }}>
49
- {footer}
50
- </div>
51
- )}
52
- </div>
53
- );
54
- }
@@ -1,58 +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 { HeaderFooterLayout } from '../HeaderFooterLayout';
5
-
6
- afterEach(cleanup);
7
-
8
- describe('HeaderFooterLayout', () => {
9
- it('renders main content with no header/footer by default', () => {
10
- render(<HeaderFooterLayout>Main content</HeaderFooterLayout>);
11
-
12
- expect(screen.getByText('Main content')).toBeDefined();
13
- expect(screen.queryByText('Header')).toBeNull();
14
- expect(screen.queryByText('Footer')).toBeNull();
15
- });
16
-
17
- it('renders header and footer when given', () => {
18
- render(
19
- <HeaderFooterLayout header={<span>Header</span>} footer={<span>Footer</span>}>
20
- Main content
21
- </HeaderFooterLayout>,
22
- );
23
-
24
- expect(screen.getByText('Header')).toBeDefined();
25
- expect(screen.getByText('Main content')).toBeDefined();
26
- expect(screen.getByText('Footer')).toBeDefined();
27
- });
28
-
29
- it('renders header without a footer', () => {
30
- render(<HeaderFooterLayout header={<span>Header</span>}>Main content</HeaderFooterLayout>);
31
-
32
- expect(screen.getByText('Header')).toBeDefined();
33
- expect(screen.queryByText('Footer')).toBeNull();
34
- });
35
-
36
- it('renders footer without a header', () => {
37
- render(<HeaderFooterLayout footer={<span>Footer</span>}>Main content</HeaderFooterLayout>);
38
-
39
- expect(screen.queryByText('Header')).toBeNull();
40
- expect(screen.getByText('Footer')).toBeDefined();
41
- });
42
-
43
- it('applies headerHeight and footerHeight as inline heights', () => {
44
- render(
45
- <HeaderFooterLayout
46
- header={<span>Header</span>}
47
- footer={<span>Footer</span>}
48
- headerHeight={48}
49
- footerHeight={72}
50
- >
51
- Main content
52
- </HeaderFooterLayout>,
53
- );
54
-
55
- expect(screen.getByText('Header').parentElement?.style.height).toBe('48px');
56
- expect(screen.getByText('Footer').parentElement?.style.height).toBe('72px');
57
- });
58
- });
@@ -1,3 +0,0 @@
1
- .root {
2
- display: inline-flex;
3
- }
@@ -1,66 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { HoverCard } from './HoverCard';
3
- import { Avatar } from '../Avatar/Avatar';
4
-
5
- const meta = {
6
- title: 'Components/HoverCard',
7
- component: HoverCard,
8
- parameters: {
9
- layout: 'padded',
10
- docs: {
11
- description: {
12
- component:
13
- 'Hover-triggered popover on desktop, tap-to-toggle on touch. Built on Popover for positioning/collision detection — this only adds hover-intent timing and the touch fallback. Opens on keyboard focus too.',
14
- },
15
- },
16
- },
17
- args: { trigger: <span />, children: null, 'aria-label': 'Preview' },
18
- } satisfies Meta<typeof HoverCard>;
19
-
20
- export default meta;
21
- type Story = StoryObj<typeof meta>;
22
-
23
- // ---------------------------------------------------------------------------
24
-
25
- export const Default: Story = {
26
- render: () => (
27
- <HoverCard
28
- aria-label="User preview"
29
- trigger={
30
- <button
31
- type="button"
32
- style={{ background: 'none', border: 'none', padding: 0, cursor: 'pointer' }}
33
- >
34
- <Avatar name="Jane Smith" size="sm" />
35
- </button>
36
- }
37
- >
38
- <div style={{ padding: 'var(--sv-space-3)', fontSize: 14 }}>
39
- <div style={{ fontWeight: 600 }}>Jane Smith</div>
40
- <div style={{ color: 'var(--sv-color-text-muted)' }}>jane@example.com</div>
41
- </div>
42
- </HoverCard>
43
- ),
44
- };
45
-
46
- export const WithLink: Story = {
47
- render: () => (
48
- <p style={{ fontSize: 14 }}>
49
- Assigned to{' '}
50
- <HoverCard
51
- aria-label="Assignee preview"
52
- trigger={
53
- <a href="/console/users/jane-smith" style={{ color: 'var(--sv-color-text-primary)' }}>
54
- Jane Smith
55
- </a>
56
- }
57
- >
58
- <div style={{ padding: 'var(--sv-space-3)', fontSize: 14 }}>
59
- <div style={{ fontWeight: 600 }}>Jane Smith</div>
60
- <div style={{ color: 'var(--sv-color-text-muted)' }}>12 tasks completed this month</div>
61
- </div>
62
- </HoverCard>
63
- .
64
- </p>
65
- ),
66
- };
@@ -1,111 +0,0 @@
1
- 'use client';
2
-
3
- import { cloneElement, useEffect, useRef, useState } from 'react';
4
- import type { ReactElement, ReactNode } from 'react';
5
- import { Popover } from '../Popover/Popover';
6
- import styles from './HoverCard.module.css';
7
-
8
- export interface HoverCardProps {
9
- /** The element that opens the card — cloned with hover/focus handlers
10
- * (desktop) or a tap handler (touch). */
11
- trigger: ReactElement;
12
- children: ReactNode;
13
- align?: 'left' | 'right';
14
- width?: number | 'trigger';
15
- 'aria-label': string;
16
- }
17
-
18
- const OPEN_DELAY_MS = 400;
19
- const CLOSE_DELAY_MS = 150;
20
-
21
- /** Whether the primary pointer can hover. Distinct from viewport-width-based
22
- * mobile detection: a touchscreen laptop with a mouse as its primary
23
- * pointer should still get real hover behavior, and a large-viewport tablet
24
- * with only touch should not — viewport width doesn't capture that, `(hover:
25
- * hover)` does, matching the pointer-based gating this design system already
26
- * uses in CSS (e.g. Button/Checkbox's touch-target expansion). Defaults to
27
- * `true`: this only changes which event handlers get attached, not the
28
- * initial DOM shape, so there's no hydration-mismatch risk to guard against
29
- * the way `useIsMobile` does. */
30
- function useHoverCapable(): boolean {
31
- const [hoverCapable, setHoverCapable] = useState(true);
32
-
33
- useEffect(() => {
34
- const mql = window.matchMedia('(hover: hover)');
35
- setHoverCapable(mql.matches);
36
- function handleChange(e: MediaQueryListEvent) {
37
- setHoverCapable(e.matches);
38
- }
39
- mql.addEventListener('change', handleChange);
40
- return () => mql.removeEventListener('change', handleChange);
41
- }, []);
42
-
43
- return hoverCapable;
44
- }
45
-
46
- /**
47
- * HoverCard — hover-triggered popover on desktop, tap-to-toggle on touch.
48
- *
49
- * Built on `Popover` rather than reimplementing positioning/collision
50
- * detection: this only adds the hover-intent open/close timing (avoids
51
- * flicker on an accidental mouse pass-over, and gives the pointer time to
52
- * travel from the trigger to the card itself across the gap between them)
53
- * and the touch fallback. Also opens on keyboard focus and closes on blur —
54
- * a hover-only trigger is a WCAG failure, since keyboard users can't hover.
55
- */
56
- export function HoverCard({
57
- trigger,
58
- children,
59
- align,
60
- width,
61
- 'aria-label': ariaLabel,
62
- }: HoverCardProps) {
63
- const [open, setOpen] = useState(false);
64
- const hoverCapable = useHoverCapable();
65
- const openTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
66
- const closeTimer = useRef<ReturnType<typeof setTimeout> | undefined>(undefined);
67
-
68
- function scheduleOpen() {
69
- clearTimeout(closeTimer.current);
70
- openTimer.current = setTimeout(() => setOpen(true), OPEN_DELAY_MS);
71
- }
72
-
73
- function scheduleClose() {
74
- clearTimeout(openTimer.current);
75
- closeTimer.current = setTimeout(() => setOpen(false), CLOSE_DELAY_MS);
76
- }
77
-
78
- function cancelScheduledClose() {
79
- clearTimeout(closeTimer.current);
80
- }
81
-
82
- const triggerHandlers = hoverCapable
83
- ? {
84
- onMouseEnter: scheduleOpen,
85
- onMouseLeave: scheduleClose,
86
- onFocus: () => setOpen(true),
87
- onBlur: scheduleClose,
88
- }
89
- : { onClick: () => setOpen((o) => !o) };
90
-
91
- const wrappedTrigger = cloneElement(trigger, triggerHandlers);
92
-
93
- return (
94
- <div
95
- className={styles.root}
96
- onMouseEnter={hoverCapable ? cancelScheduledClose : undefined}
97
- onMouseLeave={hoverCapable ? scheduleClose : undefined}
98
- >
99
- <Popover
100
- trigger={wrappedTrigger}
101
- open={open}
102
- onClose={() => setOpen(false)}
103
- align={align}
104
- width={width}
105
- aria-label={ariaLabel}
106
- >
107
- {children}
108
- </Popover>
109
- </div>
110
- );
111
- }
@@ -1,99 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
- import { act, cleanup, render, screen, fireEvent } from '@testing-library/react';
4
- import { HoverCard } from '../HoverCard';
5
-
6
- let matches = true;
7
-
8
- function installMatchMedia() {
9
- vi.stubGlobal(
10
- 'matchMedia',
11
- vi.fn().mockImplementation((query: string) => ({
12
- matches,
13
- media: query,
14
- addEventListener: vi.fn(),
15
- removeEventListener: vi.fn(),
16
- addListener: vi.fn(),
17
- removeListener: vi.fn(),
18
- dispatchEvent: vi.fn(),
19
- })),
20
- );
21
- }
22
-
23
- describe('HoverCard', () => {
24
- beforeEach(() => {
25
- matches = true; // hover-capable by default
26
- installMatchMedia();
27
- vi.useFakeTimers();
28
- });
29
-
30
- afterEach(() => {
31
- vi.runOnlyPendingTimers();
32
- vi.useRealTimers();
33
- vi.unstubAllGlobals();
34
- cleanup();
35
- });
36
-
37
- it('does not open immediately on mouse enter (hover-intent delay)', () => {
38
- render(
39
- <HoverCard trigger={<button type="button">Profile</button>} aria-label="Profile preview">
40
- Card content
41
- </HoverCard>,
42
- );
43
- fireEvent.mouseEnter(screen.getByRole('button', { name: 'Profile' }));
44
- expect(screen.queryByText('Card content')).toBeNull();
45
- });
46
-
47
- it('opens after the hover-intent delay elapses', () => {
48
- render(
49
- <HoverCard trigger={<button type="button">Profile</button>} aria-label="Profile preview">
50
- Card content
51
- </HoverCard>,
52
- );
53
- fireEvent.mouseEnter(screen.getByRole('button', { name: 'Profile' }));
54
- act(() => {
55
- vi.advanceTimersByTime(500);
56
- });
57
- expect(screen.getByText('Card content')).toBeDefined();
58
- });
59
-
60
- it('cancels the open timer if the pointer leaves before the delay elapses', () => {
61
- render(
62
- <HoverCard trigger={<button type="button">Profile</button>} aria-label="Profile preview">
63
- Card content
64
- </HoverCard>,
65
- );
66
- const trigger = screen.getByRole('button', { name: 'Profile' });
67
- fireEvent.mouseEnter(trigger);
68
- fireEvent.mouseLeave(trigger);
69
- act(() => {
70
- vi.advanceTimersByTime(1000);
71
- });
72
- expect(screen.queryByText('Card content')).toBeNull();
73
- });
74
-
75
- it('opens immediately on keyboard focus, for keyboard accessibility', () => {
76
- render(
77
- <HoverCard trigger={<button type="button">Profile</button>} aria-label="Profile preview">
78
- Card content
79
- </HoverCard>,
80
- );
81
- fireEvent.focus(screen.getByRole('button', { name: 'Profile' }));
82
- expect(screen.getByText('Card content')).toBeDefined();
83
- });
84
-
85
- it('falls back to tap-to-toggle when the pointer cannot hover', () => {
86
- matches = false;
87
- installMatchMedia();
88
- render(
89
- <HoverCard trigger={<button type="button">Profile</button>} aria-label="Profile preview">
90
- Card content
91
- </HoverCard>,
92
- );
93
- const trigger = screen.getByRole('button', { name: 'Profile' });
94
- fireEvent.click(trigger);
95
- expect(screen.getByText('Card content')).toBeDefined();
96
- fireEvent.click(trigger);
97
- expect(screen.queryByText('Card content')).toBeNull();
98
- });
99
- });
@@ -1,27 +0,0 @@
1
- .root {
2
- display: inline-block;
3
- flex-shrink: 0;
4
- /* Prevent the inline-block from adding line-height whitespace below the SVG. */
5
- line-height: 0;
6
- /* Color follows the surrounding text via currentColor — no token needed. */
7
- }
8
-
9
- .xs {
10
- width: var(--sv-icon-size-xs);
11
- height: var(--sv-icon-size-xs);
12
- }
13
-
14
- .sm {
15
- width: var(--sv-icon-size-sm);
16
- height: var(--sv-icon-size-sm);
17
- }
18
-
19
- .md {
20
- width: var(--sv-icon-size-md);
21
- height: var(--sv-icon-size-md);
22
- }
23
-
24
- .lg {
25
- width: var(--sv-icon-size-lg);
26
- height: var(--sv-icon-size-lg);
27
- }
@@ -1,95 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { ICONS, type IconName } from './icons';
3
- import { Icon } from './Icon';
4
-
5
- const ALL_NAMES = Object.keys(ICONS) as IconName[];
6
-
7
- const meta = {
8
- title: 'Components/Icon',
9
- component: Icon,
10
- parameters: {
11
- layout: 'centered',
12
- docs: {
13
- description: {
14
- component:
15
- 'SVG icon primitive. Icons are either **decorative** (`aria-hidden`) or **meaningful** (`aria-label`). Size is controlled by `--sv-icon-size-*` tokens.',
16
- },
17
- },
18
- },
19
- argTypes: {
20
- name: { control: 'select', options: ALL_NAMES },
21
- size: { control: 'select', options: ['xs', 'sm', 'md', 'lg'] },
22
- },
23
- } satisfies Meta<typeof Icon>;
24
-
25
- export default meta;
26
- type Story = StoryObj<typeof meta>;
27
-
28
- // ---------------------------------------------------------------------------
29
-
30
- export const Decorative: Story = {
31
- args: { name: 'house', size: 'md', 'aria-hidden': true },
32
- };
33
-
34
- export const Meaningful: Story = {
35
- args: { name: 'settings', size: 'md', 'aria-label': 'Open settings' },
36
- };
37
-
38
- export const SizeExtraSmall: Story = { args: { name: 'bell', size: 'xs', 'aria-hidden': true } };
39
- export const SizeSmall: Story = { args: { name: 'bell', size: 'sm', 'aria-hidden': true } };
40
- export const SizeMedium: Story = { args: { name: 'bell', size: 'md', 'aria-hidden': true } };
41
- export const SizeLarge: Story = { args: { name: 'bell', size: 'lg', 'aria-hidden': true } };
42
-
43
- /** Full icon grid — every name across all four sizes. */
44
- export const AllIcons: Story = {
45
- parameters: { layout: 'padded' },
46
- args: { name: 'house', 'aria-hidden': true },
47
- render: (_args) => (
48
- <div>
49
- {(['xs', 'sm', 'md', 'lg'] as const).map((sz) => (
50
- <section key={sz} style={{ marginBottom: 32 }}>
51
- <h3
52
- style={{
53
- fontFamily: 'system-ui',
54
- fontSize: 13,
55
- fontWeight: 600,
56
- color: 'var(--sv-color-text-muted)',
57
- textTransform: 'uppercase',
58
- letterSpacing: '0.08em',
59
- marginBottom: 12,
60
- }}
61
- >
62
- Size: {sz}
63
- </h3>
64
- <div style={{ display: 'flex', flexWrap: 'wrap', gap: 16 }}>
65
- {ALL_NAMES.map((name) => (
66
- <div
67
- key={name}
68
- style={{
69
- display: 'flex',
70
- flexDirection: 'column',
71
- alignItems: 'center',
72
- gap: 4,
73
- width: 64,
74
- }}
75
- >
76
- <Icon name={name} size={sz} aria-hidden />
77
- <span
78
- style={{
79
- fontFamily: 'monospace',
80
- fontSize: 10,
81
- color: 'var(--sv-color-text-muted)',
82
- textAlign: 'center',
83
- wordBreak: 'break-word',
84
- }}
85
- >
86
- {name}
87
- </span>
88
- </div>
89
- ))}
90
- </div>
91
- </section>
92
- ))}
93
- </div>
94
- ),
95
- };
@@ -1,43 +0,0 @@
1
- import { ICONS, type IconName } from './icons';
2
- import styles from './Icon.module.css';
3
-
4
- export type { IconName };
5
-
6
- /** Decorative icon — visually meaningful but described by surrounding text. */
7
- type DecorativeProps = { 'aria-hidden': true; 'aria-label'?: never };
8
- /** Meaningful icon — standalone affordance that requires a label for screen readers. */
9
- type MeaningfulProps = { 'aria-label': string; 'aria-hidden'?: never };
10
-
11
- export interface IconProps {
12
- /** Name of the icon from the curated Sovereign set. */
13
- name: IconName;
14
- /** Visual size. Defaults to `"md"` (20 px). */
15
- size?: 'xs' | 'sm' | 'md' | 'lg';
16
- /** Additional CSS class applied to the SVG element. */
17
- className?: string;
18
- }
19
-
20
- /**
21
- * `<Icon>` — the Sovereign design system icon primitive.
22
- *
23
- * Icons are either **decorative** (described by surrounding text — pass `aria-hidden`)
24
- * or **meaningful** (standalone affordance — pass `aria-label`):
25
- *
26
- * ```tsx
27
- * <Icon name="house" aria-hidden /> // decorative
28
- * <Icon name="log-out" aria-label="Sign out" /> // meaningful
29
- * ```
30
- *
31
- * Color follows `currentColor` so an icon automatically inherits the text color
32
- * of its container and recolors with theme changes — no extra CSS required.
33
- */
34
- export function Icon({
35
- name,
36
- size = 'md',
37
- className,
38
- ...aria
39
- }: IconProps & (DecorativeProps | MeaningfulProps)) {
40
- const Svg = ICONS[name];
41
- const classes = [styles.root, styles[size], className].filter(Boolean).join(' ');
42
- return <Svg className={classes} role={aria['aria-label'] ? 'img' : undefined} {...aria} />;
43
- }