@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,57 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { MobileHeader } from './MobileHeader';
3
- import { Avatar } from '../Avatar/Avatar';
4
- import { Icon } from '../Icon/Icon';
5
-
6
- function Logo() {
7
- return (
8
- <span
9
- aria-label="Home"
10
- style={{
11
- display: 'flex',
12
- alignItems: 'center',
13
- justifyContent: 'center',
14
- width: 28,
15
- height: 28,
16
- borderRadius: 'var(--sv-radius-sm)',
17
- background: 'var(--sv-color-accent)',
18
- color: 'var(--sv-color-text-on-accent)',
19
- fontWeight: 700,
20
- fontSize: 13,
21
- flexShrink: 0,
22
- }}
23
- >
24
- S
25
- </span>
26
- );
27
- }
28
-
29
- const meta = {
30
- title: 'Components/MobileHeader',
31
- component: MobileHeader,
32
- parameters: {
33
- layout: 'padded',
34
- docs: {
35
- description: {
36
- component:
37
- 'Mobile shell header content row (RFC 0088). Logo, bell, and avatarMenu are always rendered by the consumer — the optional title is the only overridable part. Presentational only, no data fetching. See Overview/Mobile Patterns for the full immutable/overridable boundary.',
38
- },
39
- },
40
- },
41
- args: {
42
- logo: <Logo />,
43
- bell: <Icon name="bell" size="md" aria-label="Notifications" />,
44
- avatarMenu: <Avatar name="Jamie Doe" size="sm" />,
45
- },
46
- } satisfies Meta<typeof MobileHeader>;
47
-
48
- export default meta;
49
- type Story = StoryObj<typeof meta>;
50
-
51
- export const Default: Story = {};
52
-
53
- export const WithTitle: Story = {
54
- args: {
55
- title: 'Tasks',
56
- },
57
- };
@@ -1,90 +0,0 @@
1
- 'use client';
2
-
3
- import { useRef, type HTMLAttributes, type ReactNode } from 'react';
4
- import { usePublishShellChromeHeight } from '../../hooks/usePublishShellChromeHeight';
5
- import styles from './MobileHeader.module.css';
6
-
7
- export interface MobileHeaderProps extends HTMLAttributes<HTMLDivElement> {
8
- /** The brand/logo element — already a complete, clickable link home (e.g. an
9
- * instance logo wrapped in the consumer's own router `Link`). Always
10
- * rendered. `MobileHeader` stays router-agnostic, so this is provided
11
- * fully built rather than as a bare icon + href. Optional — omit it to get
12
- * a default "S" badge (matching the runtime shell's own fallback brand
13
- * icon when no instance logo is configured), sized and styled to the same
14
- * 36px/radius-md convention a custom logo is expected to follow. */
15
- logo?: ReactNode;
16
- /** Optional contextual title rendered beside the logo (e.g. the active
17
- * plugin's name). Absent by default — this is the one overridable part of
18
- * the header. See RFC 0088. */
19
- title?: string;
20
- /** Notification bell — always rendered; not overridable.
21
- * TODO: this is just an icon slot today (the consumer wires up its own
22
- * click handler/content) — it doesn't yet accommodate a full notification
23
- * feature (unread badge, dropdown panel, etc. — see the runtime shell's
24
- * own NotificationBell). Deferred; revisit once a plugin actually needs
25
- * more than a bare bell icon here. */
26
- bell: ReactNode;
27
- /** Avatar / account menu trigger — always rendered; not overridable. */
28
- avatarMenu: ReactNode;
29
- }
30
-
31
- /** Default fallback logo — matches the runtime shell's own .mobileBrandIcon
32
- * exactly (36px, radius-md, accent background) for the "no instance logo
33
- * configured" case, just with a fixed "S" instead of the instance name's
34
- * first letter (this component can't know the instance name — no data
35
- * fetching, see the component's own doc comment). */
36
- function DefaultLogo() {
37
- return (
38
- <span className={styles.defaultLogo} aria-hidden="true">
39
- S
40
- </span>
41
- );
42
- }
43
-
44
- /**
45
- * The mobile header bar: brand/logo (always shown), an optional contextual
46
- * title, and a fixed bell + avatar-menu cluster. Owns its own chrome —
47
- * background, border-bottom, sticky positioning, safe-area-aware padding,
48
- * and a 768px max-width (so it never stretches full-bleed if mounted outside
49
- * an actual mobile viewport) — matching the runtime shell's own mobile
50
- * header exactly, since this component is meant to replace that hand-rolled
51
- * markup. Presentational only — no data fetching; the consumer supplies
52
- * `bell`/`avatarMenu` (and, optionally, `logo`) as already-wired components
53
- * (their own sizing — 36px logo/avatar, 44px bell tap target — is the
54
- * consumer's responsibility, matching the reference implementation in the
55
- * runtime shell). See RFC 0088 for the immutable/overridable boundary this
56
- * enforces.
57
- *
58
- * Self-measures its own rendered height and publishes it as
59
- * `--sv-shell-header-height` on the shell root — see
60
- * `usePublishShellChromeHeight`'s own doc comment for why this exists (it's
61
- * what makes a self-rendered header, the `shellConfig.mobileHeader: false`
62
- * pattern, correctly position `Dialog`'s inset and any other consumer of
63
- * that variable instead of being overlapped by it).
64
- */
65
- export function MobileHeader({
66
- logo,
67
- title,
68
- bell,
69
- avatarMenu,
70
- className,
71
- ...rest
72
- }: MobileHeaderProps) {
73
- const headerRef = useRef<HTMLDivElement>(null);
74
- usePublishShellChromeHeight(headerRef, '--sv-shell-header-height');
75
-
76
- const cls = [styles.header, className].filter(Boolean).join(' ');
77
-
78
- return (
79
- <div className={cls} {...rest} ref={headerRef}>
80
- <div className={styles.brandGroup}>
81
- {logo ?? <DefaultLogo />}
82
- {title && <span className={styles.title}>{title}</span>}
83
- </div>
84
- <div className={styles.right}>
85
- {bell}
86
- {avatarMenu}
87
- </div>
88
- </div>
89
- );
90
- }
@@ -1,113 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, render, screen } from '@testing-library/react';
4
- import { MobileHeader } from '../MobileHeader';
5
-
6
- afterEach(() => {
7
- cleanup();
8
- });
9
-
10
- describe('MobileHeader self-measured height', () => {
11
- afterEach(() => {
12
- document.getElementById('sv-app-shell')?.remove();
13
- vi.restoreAllMocks();
14
- });
15
-
16
- it('publishes its rendered height as --sv-shell-header-height on #sv-app-shell', () => {
17
- const shell = document.createElement('div');
18
- shell.id = 'sv-app-shell';
19
- document.body.appendChild(shell);
20
- vi.spyOn(Element.prototype, 'getBoundingClientRect').mockReturnValue({
21
- height: 60,
22
- width: 0,
23
- top: 0,
24
- left: 0,
25
- right: 0,
26
- bottom: 0,
27
- x: 0,
28
- y: 0,
29
- toJSON() {},
30
- } as DOMRect);
31
-
32
- render(<MobileHeader bell={<span />} avatarMenu={<span />} />);
33
-
34
- expect(shell.style.getPropertyValue('--sv-shell-header-height')).toBe('60px');
35
- });
36
-
37
- it('removes the override on unmount', () => {
38
- const shell = document.createElement('div');
39
- shell.id = 'sv-app-shell';
40
- document.body.appendChild(shell);
41
- vi.spyOn(Element.prototype, 'getBoundingClientRect').mockReturnValue({
42
- height: 60,
43
- width: 0,
44
- top: 0,
45
- left: 0,
46
- right: 0,
47
- bottom: 0,
48
- x: 0,
49
- y: 0,
50
- toJSON() {},
51
- } as DOMRect);
52
-
53
- const { unmount } = render(<MobileHeader bell={<span />} avatarMenu={<span />} />);
54
- expect(shell.style.getPropertyValue('--sv-shell-header-height')).toBe('60px');
55
-
56
- unmount();
57
- expect(shell.style.getPropertyValue('--sv-shell-header-height')).toBe('');
58
- });
59
-
60
- it('never throws when #sv-app-shell is absent (Storybook, unit tests, other hosts)', () => {
61
- expect(() => render(<MobileHeader bell={<span />} avatarMenu={<span />} />)).not.toThrow();
62
- });
63
- });
64
-
65
- describe('MobileHeader', () => {
66
- it('always renders the logo, bell, and avatar menu slots', () => {
67
- render(
68
- <MobileHeader
69
- logo={<a href="/">logo</a>}
70
- bell={<span data-testid="bell">bell</span>}
71
- avatarMenu={<span data-testid="avatar">avatar</span>}
72
- />,
73
- );
74
-
75
- expect(screen.getByText('logo')).toBeDefined();
76
- expect(screen.getByTestId('bell')).toBeDefined();
77
- expect(screen.getByTestId('avatar')).toBeDefined();
78
- });
79
-
80
- it('renders no title by default', () => {
81
- render(<MobileHeader logo={<a href="/">logo</a>} bell={<span />} avatarMenu={<span />} />);
82
-
83
- expect(screen.queryByText(/tasks/i)).toBeNull();
84
- });
85
-
86
- it('renders the optional title when provided', () => {
87
- render(
88
- <MobileHeader
89
- logo={<a href="/">logo</a>}
90
- title="Tasks"
91
- bell={<span />}
92
- avatarMenu={<span />}
93
- />,
94
- );
95
-
96
- expect(screen.getByText('Tasks')).toBeDefined();
97
- });
98
-
99
- it('renders a default "S" badge when logo is omitted', () => {
100
- render(<MobileHeader bell={<span />} avatarMenu={<span />} />);
101
-
102
- expect(screen.getByText('S')).toBeDefined();
103
- });
104
-
105
- it('renders the supplied logo instead of the default badge when provided', () => {
106
- render(
107
- <MobileHeader logo={<a href="/">custom logo</a>} bell={<span />} avatarMenu={<span />} />,
108
- );
109
-
110
- expect(screen.getByText('custom logo')).toBeDefined();
111
- expect(screen.queryByText('S')).toBeNull();
112
- });
113
- });
@@ -1,130 +0,0 @@
1
- .nav {
2
- display: flex;
3
- flex-direction: column;
4
- gap: var(--sv-space-5);
5
- width: 100%;
6
- }
7
-
8
- .group {
9
- display: flex;
10
- flex-direction: column;
11
- gap: 2px;
12
- }
13
-
14
- .groupLabel {
15
- padding: 0 var(--sv-space-3);
16
- margin-bottom: var(--sv-space-1);
17
- font-size: var(--sv-font-size-xs);
18
- font-weight: var(--sv-font-weight-semibold);
19
- letter-spacing: 0.04em;
20
- text-transform: uppercase;
21
- color: var(--sv-color-text-muted);
22
- }
23
-
24
- .row {
25
- display: flex;
26
- align-items: center;
27
- gap: var(--sv-space-3);
28
- min-height: var(--sv-touch-target-min);
29
- padding: var(--sv-space-2) var(--sv-space-3);
30
- border-radius: var(--sv-radius-md);
31
- color: var(--sv-color-text-muted);
32
- text-decoration: none;
33
- font-size: var(--sv-font-size-sm);
34
- font-weight: var(--sv-font-weight-medium);
35
- }
36
-
37
- .icon {
38
- flex-shrink: 0;
39
- }
40
-
41
- .label {
42
- flex: 1;
43
- min-width: 0;
44
- overflow: hidden;
45
- text-overflow: ellipsis;
46
- white-space: nowrap;
47
- }
48
-
49
- .badge {
50
- flex-shrink: 0;
51
- color: var(--sv-color-text-muted);
52
- font-size: var(--sv-font-size-xs);
53
- }
54
-
55
- .chevron {
56
- flex-shrink: 0;
57
- color: var(--sv-color-text-muted);
58
- }
59
-
60
- /* ── static (desktop sidebar) ─────────────────────────────────────────── */
61
-
62
- .static .row {
63
- transition:
64
- background-color 0.1s ease,
65
- color 0.1s ease;
66
- }
67
-
68
- @media (hover: hover) {
69
- .static .row:hover {
70
- background-color: var(--sv-color-surface-sunken);
71
- color: var(--sv-color-text-primary);
72
- }
73
- }
74
-
75
- .static .row:focus-visible {
76
- outline: 2px solid var(--sv-color-focus-ring);
77
- outline-offset: -2px;
78
- }
79
-
80
- .static .rowActive {
81
- background-color: var(--sv-color-surface-sunken);
82
- color: var(--sv-color-text-primary);
83
- font-weight: var(--sv-font-weight-semibold);
84
- }
85
-
86
- .static .rowActive .icon {
87
- color: var(--sv-color-text-primary);
88
- }
89
-
90
- /* Only meaningful combined with .static — see NavListProps.density's own
91
- doc comment for why .drilldown rows never shrink. */
92
- .compact.static .row {
93
- min-height: 0;
94
- padding: var(--sv-space-2) var(--sv-space-3);
95
- }
96
-
97
- /* ── drilldown (mobile index) — grouped card, native-Settings-app rows ──── */
98
-
99
- .drilldown .group {
100
- gap: 0;
101
- border: 1px solid var(--sv-color-border);
102
- border-radius: var(--sv-radius-lg);
103
- overflow: hidden;
104
- background-color: var(--sv-color-surface-raised);
105
- }
106
-
107
- .drilldown .row {
108
- border-radius: 0;
109
- padding: var(--sv-space-3) var(--sv-space-4);
110
- color: var(--sv-color-text-primary);
111
- }
112
-
113
- .drilldown .row:not(:last-child) {
114
- border-bottom: var(--sv-border-width-hairline) solid var(--sv-color-border);
115
- }
116
-
117
- @media (hover: hover) {
118
- .drilldown .row:hover {
119
- background-color: var(--sv-color-surface-sunken);
120
- }
121
- }
122
-
123
- .drilldown .row:focus-visible {
124
- outline: 2px solid var(--sv-color-focus-ring);
125
- outline-offset: -2px;
126
- }
127
-
128
- .drilldown .icon {
129
- color: var(--sv-color-text-muted);
130
- }
@@ -1,136 +0,0 @@
1
- import { Fragment, type ReactNode } from 'react';
2
- import { Icon } from '../Icon/Icon';
3
- import type { IconName } from '../Icon/Icon';
4
- import styles from './NavList.module.css';
5
-
6
- export interface NavListItem {
7
- id: string;
8
- label: string;
9
- href: string;
10
- icon: IconName;
11
- /** Trailing content, e.g. a count — reserved for a future consumer, not used by `variant="drilldown"`'s own chevron slot. */
12
- badge?: ReactNode;
13
- /**
14
- * Only meaningful for `variant="static"` — whether this row represents the
15
- * current page. Computed by the consumer (e.g. via `usePathname()` plus a
16
- * longest-prefix match against every item's `href`), since this package
17
- * doesn't depend on `next/navigation` — same reasoning as `NavTabs`.
18
- */
19
- active?: boolean;
20
- }
21
-
22
- export interface NavListGroup {
23
- id: string;
24
- /** Omit for an ungrouped leading item/group — e.g. a pinned "Overview" row above the grouped sections. */
25
- label?: string;
26
- items: NavListItem[];
27
- }
28
-
29
- /** Props to spread onto a consumer-supplied link element — mirrors `NavTabs`' `NavTabLinkProps`. */
30
- export interface NavListLinkProps {
31
- href: string;
32
- className: string;
33
- 'aria-current': 'page' | undefined;
34
- children: ReactNode;
35
- }
36
-
37
- export interface NavListProps {
38
- groups: NavListGroup[];
39
- /**
40
- * `"static"`: active row highlighted via `item.active`, no chevron — a
41
- * persistent sidebar nav. `"drilldown"`: every row gets a trailing chevron
42
- * and no active-state, tapping navigates to a full-screen section — a
43
- * native Settings-app style index.
44
- */
45
- variant: 'static' | 'drilldown';
46
- /**
47
- * `"default"`: each row is a full `--sv-touch-target-min` tall tap target
48
- * — the right choice for `variant="drilldown"`'s mobile index, and for any
49
- * `static` sidebar list long enough that scanability matters more than
50
- * density. `"compact"` shrinks row height/padding for a short, always-
51
- * visible `static` list (e.g. 2-4 items above a longer scrollable list of
52
- * something else) where the default's touch-target height reads as
53
- * needlessly spaced out. Only meaningful for `variant="static"` —
54
- * `drilldown` rows stay full-height regardless, since that variant is
55
- * mobile-only and touch-target size there isn't optional. Defaults to
56
- * `"default"` so every existing consumer (e.g. Console's own sidebar) is
57
- * visually unchanged.
58
- */
59
- density?: 'default' | 'compact';
60
- 'aria-label': string;
61
- className?: string;
62
- /**
63
- * Render a row as something other than a plain `<a href>` — e.g. Next's
64
- * `<Link>`. Receives the item plus the class name/aria attributes NavList
65
- * would otherwise apply, matching `NavTabs`' `renderLink` contract.
66
- */
67
- renderLink?: (item: NavListItem, linkProps: NavListLinkProps) => ReactNode;
68
- }
69
-
70
- /**
71
- * NavList — a vertical list of icon+label rows, optionally grouped under
72
- * section headers. Two presentations of the same `groups` data: `static` (a
73
- * persistent sidebar, active item highlighted) and `drilldown` (a
74
- * native-Settings-app style index, every row navigates to a full section).
75
- *
76
- * Framework-agnostic like `NavTabs` — no `next/navigation`/`next/link`
77
- * import, no internal pathname reading. Active state and navigation behavior
78
- * are supplied by the consumer via `item.active` and `renderLink`.
79
- */
80
- export function NavList({
81
- groups,
82
- variant,
83
- density = 'default',
84
- 'aria-label': ariaLabel,
85
- className,
86
- renderLink,
87
- }: NavListProps) {
88
- return (
89
- <nav
90
- className={[styles.nav, styles[variant], density === 'compact' && styles.compact, className]
91
- .filter(Boolean)
92
- .join(' ')}
93
- aria-label={ariaLabel}
94
- >
95
- {groups.map((group) => (
96
- <div key={group.id} className={styles.group}>
97
- {group.label && <div className={styles.groupLabel}>{group.label}</div>}
98
- {group.items.map((item) => {
99
- const isActive = variant === 'static' && !!item.active;
100
- const rowContent = (
101
- <>
102
- <Icon name={item.icon} size="sm" aria-hidden className={styles.icon} />
103
- <span className={styles.label}>{item.label}</span>
104
- {item.badge && <span className={styles.badge}>{item.badge}</span>}
105
- {variant === 'drilldown' && (
106
- <Icon name="chevron-right" size="sm" aria-hidden className={styles.chevron} />
107
- )}
108
- </>
109
- );
110
- const linkProps: NavListLinkProps = {
111
- href: item.href,
112
- className: [styles.row, isActive && styles.rowActive].filter(Boolean).join(' '),
113
- 'aria-current': isActive ? 'page' : undefined,
114
- children: rowContent,
115
- };
116
- return (
117
- <Fragment key={item.id}>
118
- {renderLink ? (
119
- renderLink(item, linkProps)
120
- ) : (
121
- <a
122
- href={linkProps.href}
123
- className={linkProps.className}
124
- aria-current={linkProps['aria-current']}
125
- >
126
- {linkProps.children}
127
- </a>
128
- )}
129
- </Fragment>
130
- );
131
- })}
132
- </div>
133
- ))}
134
- </nav>
135
- );
136
- }
@@ -1,109 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, render, screen } from '@testing-library/react';
4
- import { NavList, type NavListGroup } from '../NavList';
5
- import styles from '../NavList.module.css';
6
-
7
- afterEach(cleanup);
8
-
9
- const groups: NavListGroup[] = [
10
- {
11
- id: 'overview',
12
- items: [{ id: 'overview', label: 'Overview', href: '/console', icon: 'layout-dashboard' }],
13
- },
14
- {
15
- id: 'people',
16
- label: 'People',
17
- items: [
18
- { id: 'users', label: 'Users', href: '/console/users', icon: 'users', active: true },
19
- { id: 'groups', label: 'Groups', href: '/console/groups', icon: 'layers' },
20
- ],
21
- },
22
- ];
23
-
24
- describe('NavList', () => {
25
- it('renders every item as a link with the correct href', () => {
26
- render(<NavList groups={groups} variant="static" aria-label="Sections" />);
27
- expect(screen.getByRole('link', { name: /overview/i }).getAttribute('href')).toBe('/console');
28
- expect(screen.getByRole('link', { name: /users/i }).getAttribute('href')).toBe(
29
- '/console/users',
30
- );
31
- expect(screen.getByRole('link', { name: /groups/i }).getAttribute('href')).toBe(
32
- '/console/groups',
33
- );
34
- });
35
-
36
- it('renders a label for a named group and no label for an ungrouped one', () => {
37
- render(<NavList groups={groups} variant="static" aria-label="Sections" />);
38
- // "People" is the only group.label in the fixture — it must appear exactly
39
- // once. The ungrouped "overview" group renders its item with no group
40
- // header text alongside it (nothing else in the fixture could produce a
41
- // second match).
42
- expect(screen.getAllByText('People')).toHaveLength(1);
43
- });
44
-
45
- describe('variant="static"', () => {
46
- it('marks the active item with aria-current="page"', () => {
47
- render(<NavList groups={groups} variant="static" aria-label="Sections" />);
48
- expect(screen.getByRole('link', { name: /users/i }).getAttribute('aria-current')).toBe(
49
- 'page',
50
- );
51
- expect(screen.getByRole('link', { name: /groups/i }).getAttribute('aria-current')).toBeNull();
52
- });
53
-
54
- it('renders no chevron icons', () => {
55
- const { container } = render(
56
- <NavList groups={groups} variant="static" aria-label="Sections" />,
57
- );
58
- expect(container.querySelectorAll('svg').length).toBe(groups.flatMap((g) => g.items).length);
59
- });
60
- });
61
-
62
- describe('variant="drilldown"', () => {
63
- it('never sets aria-current, even on an item marked active', () => {
64
- render(<NavList groups={groups} variant="drilldown" aria-label="Sections" />);
65
- expect(screen.getByRole('link', { name: /users/i }).getAttribute('aria-current')).toBeNull();
66
- });
67
-
68
- it('renders a trailing chevron for every item', () => {
69
- const { container } = render(
70
- <NavList groups={groups} variant="drilldown" aria-label="Sections" />,
71
- );
72
- const itemCount = groups.flatMap((g) => g.items).length;
73
- // One icon svg + one chevron svg per item.
74
- expect(container.querySelectorAll('svg').length).toBe(itemCount * 2);
75
- });
76
- });
77
-
78
- describe('density', () => {
79
- it('defaults to no compact class', () => {
80
- const { container } = render(
81
- <NavList groups={groups} variant="static" aria-label="Sections" />,
82
- );
83
- expect(container.querySelector('nav')?.className).not.toContain(styles.compact);
84
- });
85
-
86
- it('applies the compact class when density="compact"', () => {
87
- const { container } = render(
88
- <NavList groups={groups} variant="static" density="compact" aria-label="Sections" />,
89
- );
90
- expect(container.querySelector('nav')?.className).toContain(styles.compact);
91
- });
92
- });
93
-
94
- it('calls renderLink with the item and computed link props instead of rendering a plain anchor', () => {
95
- const renderLink = vi.fn((_item, linkProps) => (
96
- <button type="button" aria-current={linkProps['aria-current']}>
97
- {linkProps.children}
98
- </button>
99
- ));
100
- render(
101
- <NavList groups={groups} variant="static" aria-label="Sections" renderLink={renderLink} />,
102
- );
103
- expect(renderLink).toHaveBeenCalledTimes(3);
104
- expect(screen.queryAllByRole('link').length).toBe(0);
105
- expect(screen.getByRole('button', { name: /users/i }).getAttribute('aria-current')).toBe(
106
- 'page',
107
- );
108
- });
109
- });
@@ -1,50 +0,0 @@
1
- .nav {
2
- display: flex;
3
- flex-wrap: wrap;
4
- gap: 0;
5
- border-bottom: var(--sv-border-width-hairline) solid var(--sv-color-border);
6
- }
7
-
8
- .link {
9
- padding: var(--sv-space-2) var(--sv-space-3);
10
- padding-bottom: calc(var(--sv-space-2) + 2px);
11
- border-bottom: 2px solid transparent;
12
- font-size: var(--sv-font-size-sm);
13
- font-weight: var(--sv-font-weight-medium);
14
- color: var(--sv-color-text-muted);
15
- text-decoration: none;
16
- white-space: nowrap;
17
- transition: color 0.1s ease;
18
- }
19
-
20
- @media (hover: hover) {
21
- .link:hover {
22
- color: var(--sv-color-text-primary);
23
- }
24
- }
25
-
26
- .link:focus-visible {
27
- outline: 2px solid var(--sv-color-focus-ring);
28
- outline-offset: -2px;
29
- border-radius: var(--sv-radius-sm);
30
- }
31
-
32
- .active {
33
- color: var(--sv-color-text-primary);
34
- font-weight: var(--sv-font-weight-semibold);
35
- border-bottom-color: var(--sv-color-text-primary);
36
- }
37
-
38
- @media (max-width: 640px) {
39
- .nav {
40
- flex-wrap: nowrap;
41
- overflow-x: auto;
42
- scrollbar-width: none;
43
- -webkit-overflow-scrolling: touch;
44
- mask-image: linear-gradient(to right, black calc(100% - 32px), transparent 100%);
45
- }
46
-
47
- .nav::-webkit-scrollbar {
48
- display: none;
49
- }
50
- }