@sovereignfs/ui 0.54.0 → 0.89.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. package/LICENSE +373 -661
  2. package/NOTICE +8 -0
  3. package/README.md +4 -6
  4. package/dist/Accordion.module.css +1 -1
  5. package/dist/Alert.module.css +1 -1
  6. package/dist/AppsLauncher.module.css +102 -0
  7. package/dist/Avatar.module.css +1 -1
  8. package/dist/Badge.module.css +30 -7
  9. package/dist/BalanceChip.module.css +1 -1
  10. package/dist/Button.module.css +23 -2
  11. package/dist/Card.module.css +7 -1
  12. package/dist/CardTile.module.css +187 -0
  13. package/dist/CheckableListRow.module.css +8 -0
  14. package/dist/Checkbox.module.css +8 -0
  15. package/dist/CodeTextarea.module.css +7 -1
  16. package/dist/Collapsible.module.css +1 -1
  17. package/dist/ColorPicker.module.css +138 -0
  18. package/dist/Combobox.module.css +8 -2
  19. package/dist/Command.module.css +7 -1
  20. package/dist/ConfirmDialog.module.css +8 -2
  21. package/dist/ConsentPrompt.module.css +21 -0
  22. package/dist/DatePicker.module.css +7 -1
  23. package/dist/Dialog.module.css +130 -21
  24. package/dist/DragHandleRow.module.css +6 -0
  25. package/dist/Drawer.module.css +36 -7
  26. package/dist/FileDropzone.module.css +25 -1
  27. package/dist/Header.module.css +68 -0
  28. package/dist/HeaderFooterLayout.module.css +21 -0
  29. package/dist/IconPicker.module.css +15 -5
  30. package/dist/Input.module.css +7 -1
  31. package/dist/Kbd.module.css +1 -1
  32. package/dist/LegalLinks.module.css +9 -2
  33. package/dist/Markdown.module.css +29 -0
  34. package/dist/Menu.module.css +1 -0
  35. package/dist/Message.module.css +10 -1
  36. package/dist/MessageScroller.module.css +12 -1
  37. package/dist/MobileAppsDrawer.module.css +19 -14
  38. package/dist/MobileFooter.module.css +7 -1
  39. package/dist/MobileHeader.module.css +14 -1
  40. package/dist/NavList.module.css +139 -0
  41. package/dist/NavTabs.module.css +8 -2
  42. package/dist/NotificationsPanel.module.css +268 -0
  43. package/dist/OverlayHeader.module.css +1 -1
  44. package/dist/PageContainer.module.css +62 -0
  45. package/dist/PageHeader.module.css +54 -0
  46. package/dist/PageLayout.module.css +51 -0
  47. package/dist/Popover.module.css +1 -1
  48. package/dist/QrCode.module.css +17 -0
  49. package/dist/QuantityStepper.module.css +5 -3
  50. package/dist/RadioGroup.module.css +6 -0
  51. package/dist/Resizable.module.css +3 -3
  52. package/dist/RootLayout.module.css +12 -0
  53. package/dist/SegmentedControl.module.css +7 -1
  54. package/dist/Select.module.css +7 -1
  55. package/dist/Sheet.module.css +20 -2
  56. package/dist/SplitPane.module.css +5 -5
  57. package/dist/StatusBadge.module.css +1 -1
  58. package/dist/StepStrip.module.css +55 -0
  59. package/dist/SuggestionInput.module.css +14 -3
  60. package/dist/SwipableMobileCarousel.module.css +12 -3
  61. package/dist/SwipableMobileCarouselDots.module.css +21 -0
  62. package/dist/SwipeStack.module.css +101 -0
  63. package/dist/SystemBanner.module.css +16 -0
  64. package/dist/Table.module.css +2 -2
  65. package/dist/Tabs.module.css +7 -1
  66. package/dist/TagInput.module.css +8 -2
  67. package/dist/Textarea.module.css +15 -1
  68. package/dist/ThreeColumnLayout.module.css +35 -0
  69. package/dist/Toast.module.css +67 -3
  70. package/dist/Toggle.module.css +7 -0
  71. package/dist/Tooltip.module.css +7 -1
  72. package/dist/UserMenu.module.css +95 -0
  73. package/dist/fonts/OFL.txt +93 -0
  74. package/dist/fonts/hanken-grotesk-cyrillic-ext-wght-normal.woff2 +0 -0
  75. package/dist/fonts/hanken-grotesk-latin-ext-wght-normal.woff2 +0 -0
  76. package/dist/fonts/hanken-grotesk-latin-wght-normal.woff2 +0 -0
  77. package/dist/fonts/hanken-grotesk-vietnamese-wght-normal.woff2 +0 -0
  78. package/dist/index.d.ts +1156 -76
  79. package/dist/index.js +4223 -1513
  80. package/dist/tokens/fonts.css +53 -0
  81. package/dist/tokens/primitives.css +23 -12
  82. package/dist/tokens/semantic.css +32 -0
  83. package/dist/tokens/theme-presets.css +33 -0
  84. package/dist/tokens.css +2 -1
  85. package/package.json +46 -19
  86. package/src/__tests__/motion.test.tsx +0 -105
  87. package/src/components/Accordion/Accordion.module.css +0 -3
  88. package/src/components/Accordion/Accordion.stories.tsx +0 -110
  89. package/src/components/Accordion/Accordion.tsx +0 -53
  90. package/src/components/Accordion/__tests__/Accordion.test.tsx +0 -61
  91. package/src/components/Alert/Alert.module.css +0 -62
  92. package/src/components/Alert/Alert.stories.tsx +0 -96
  93. package/src/components/Alert/Alert.tsx +0 -58
  94. package/src/components/Alert/__tests__/Alert.test.tsx +0 -75
  95. package/src/components/AspectRatio/AspectRatio.module.css +0 -15
  96. package/src/components/AspectRatio/AspectRatio.stories.tsx +0 -78
  97. package/src/components/AspectRatio/AspectRatio.tsx +0 -21
  98. package/src/components/AspectRatio/__tests__/AspectRatio.test.tsx +0 -27
  99. package/src/components/Avatar/Avatar.module.css +0 -38
  100. package/src/components/Avatar/Avatar.tsx +0 -42
  101. package/src/components/Badge/Badge.module.css +0 -154
  102. package/src/components/Badge/Badge.stories.tsx +0 -226
  103. package/src/components/Badge/Badge.tsx +0 -81
  104. package/src/components/Badge/__tests__/Badge.test.tsx +0 -88
  105. package/src/components/BalanceChip/BalanceChip.module.css +0 -32
  106. package/src/components/BalanceChip/BalanceChip.stories.tsx +0 -45
  107. package/src/components/BalanceChip/BalanceChip.tsx +0 -33
  108. package/src/components/Breadcrumb/Breadcrumb.module.css +0 -49
  109. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +0 -47
  110. package/src/components/Breadcrumb/Breadcrumb.tsx +0 -57
  111. package/src/components/Breadcrumb/__tests__/Breadcrumb.test.tsx +0 -52
  112. package/src/components/Button/Button.module.css +0 -153
  113. package/src/components/Button/Button.stories.tsx +0 -83
  114. package/src/components/Button/Button.tsx +0 -52
  115. package/src/components/Button/__tests__/Button.test.tsx +0 -66
  116. package/src/components/ButtonGroup/ButtonGroup.module.css +0 -29
  117. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +0 -57
  118. package/src/components/ButtonGroup/ButtonGroup.tsx +0 -27
  119. package/src/components/ButtonGroup/__tests__/ButtonGroup.test.tsx +0 -29
  120. package/src/components/Calendar/Calendar.module.css +0 -126
  121. package/src/components/Calendar/Calendar.tsx +0 -213
  122. package/src/components/Calendar/__tests__/Calendar.test.tsx +0 -98
  123. package/src/components/Calendar/dateUtils.ts +0 -97
  124. package/src/components/Card/Card.module.css +0 -42
  125. package/src/components/Card/Card.tsx +0 -34
  126. package/src/components/CheckableListRow/CheckableListRow.module.css +0 -95
  127. package/src/components/CheckableListRow/CheckableListRow.stories.tsx +0 -99
  128. package/src/components/CheckableListRow/CheckableListRow.tsx +0 -89
  129. package/src/components/Checkbox/Checkbox.module.css +0 -111
  130. package/src/components/Checkbox/Checkbox.tsx +0 -78
  131. package/src/components/CodeTextarea/CodeTextarea.module.css +0 -53
  132. package/src/components/CodeTextarea/CodeTextarea.stories.tsx +0 -77
  133. package/src/components/CodeTextarea/CodeTextarea.tsx +0 -36
  134. package/src/components/Collapsible/Collapsible.module.css +0 -70
  135. package/src/components/Collapsible/Collapsible.stories.tsx +0 -62
  136. package/src/components/Collapsible/Collapsible.tsx +0 -66
  137. package/src/components/Collapsible/__tests__/Collapsible.test.tsx +0 -71
  138. package/src/components/Combobox/Combobox.module.css +0 -122
  139. package/src/components/Combobox/Combobox.stories.tsx +0 -79
  140. package/src/components/Combobox/Combobox.tsx +0 -186
  141. package/src/components/Combobox/__tests__/Combobox.test.tsx +0 -158
  142. package/src/components/Command/Command.module.css +0 -80
  143. package/src/components/Command/Command.stories.tsx +0 -104
  144. package/src/components/Command/Command.tsx +0 -168
  145. package/src/components/Command/__tests__/Command.test.tsx +0 -162
  146. package/src/components/ConfirmDialog/ConfirmDialog.module.css +0 -113
  147. package/src/components/ConfirmDialog/ConfirmDialog.tsx +0 -124
  148. package/src/components/ConfirmDialog/__tests__/ConfirmDialog.test.tsx +0 -146
  149. package/src/components/ContextMenu/ContextMenu.stories.tsx +0 -81
  150. package/src/components/ContextMenu/ContextMenu.tsx +0 -100
  151. package/src/components/ContextMenu/__tests__/ContextMenu.test.tsx +0 -87
  152. package/src/components/CurrencyInput/CurrencyInput.stories.tsx +0 -50
  153. package/src/components/CurrencyInput/CurrencyInput.tsx +0 -60
  154. package/src/components/DataTable/DataTable.module.css +0 -28
  155. package/src/components/DataTable/DataTable.stories.tsx +0 -74
  156. package/src/components/DataTable/DataTable.tsx +0 -154
  157. package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -123
  158. package/src/components/DatePicker/DatePicker.module.css +0 -61
  159. package/src/components/DatePicker/DatePicker.tsx +0 -103
  160. package/src/components/DatePicker/__tests__/DatePicker.test.tsx +0 -89
  161. package/src/components/DeviceOnlyGate/DeviceOnlyGate.tsx +0 -58
  162. package/src/components/DeviceOnlyGate/__tests__/DeviceOnlyGate.test.tsx +0 -45
  163. package/src/components/DeviceStorageKeyGate/DeviceStorageKeyGate.tsx +0 -100
  164. package/src/components/DeviceStorageKeyGate/__tests__/DeviceStorageKeyGate.test.tsx +0 -119
  165. package/src/components/Dialog/Dialog.module.css +0 -226
  166. package/src/components/Dialog/Dialog.stories.tsx +0 -147
  167. package/src/components/Dialog/Dialog.tsx +0 -160
  168. package/src/components/Dialog/__tests__/Dialog.test.tsx +0 -137
  169. package/src/components/DragHandleRow/DragHandleRow.module.css +0 -57
  170. package/src/components/DragHandleRow/DragHandleRow.tsx +0 -61
  171. package/src/components/Drawer/Drawer.module.css +0 -92
  172. package/src/components/Drawer/Drawer.stories.tsx +0 -132
  173. package/src/components/Drawer/Drawer.tsx +0 -176
  174. package/src/components/Drawer/__tests__/Drawer.test.tsx +0 -199
  175. package/src/components/EmptyState/EmptyState.module.css +0 -27
  176. package/src/components/EmptyState/EmptyState.tsx +0 -27
  177. package/src/components/FileDropzone/FileDropzone.module.css +0 -63
  178. package/src/components/FileDropzone/FileDropzone.tsx +0 -109
  179. package/src/components/FileDropzone/__tests__/FileDropzone.test.tsx +0 -67
  180. package/src/components/FormField/FormField.module.css +0 -33
  181. package/src/components/FormField/FormField.tsx +0 -78
  182. package/src/components/FormField/__tests__/FormField.test.tsx +0 -83
  183. package/src/components/HoverCard/HoverCard.module.css +0 -3
  184. package/src/components/HoverCard/HoverCard.stories.tsx +0 -66
  185. package/src/components/HoverCard/HoverCard.tsx +0 -111
  186. package/src/components/HoverCard/__tests__/HoverCard.test.tsx +0 -99
  187. package/src/components/Icon/Icon.module.css +0 -27
  188. package/src/components/Icon/Icon.stories.tsx +0 -95
  189. package/src/components/Icon/Icon.tsx +0 -43
  190. package/src/components/Icon/__tests__/Icon.test.tsx +0 -40
  191. package/src/components/Icon/icons/activity.tsx +0 -20
  192. package/src/components/Icon/icons/alert-triangle.tsx +0 -22
  193. package/src/components/Icon/icons/apple.tsx +0 -21
  194. package/src/components/Icon/icons/banana.tsx +0 -21
  195. package/src/components/Icon/icons/beef.tsx +0 -22
  196. package/src/components/Icon/icons/beer.tsx +0 -24
  197. package/src/components/Icon/icons/bell.tsx +0 -21
  198. package/src/components/Icon/icons/calendar.tsx +0 -23
  199. package/src/components/Icon/icons/candy.tsx +0 -24
  200. package/src/components/Icon/icons/carrot.tsx +0 -22
  201. package/src/components/Icon/icons/check.tsx +0 -20
  202. package/src/components/Icon/icons/chevron-down.tsx +0 -20
  203. package/src/components/Icon/icons/chevron-left.tsx +0 -20
  204. package/src/components/Icon/icons/chevron-right.tsx +0 -20
  205. package/src/components/Icon/icons/chevron-up.tsx +0 -20
  206. package/src/components/Icon/icons/circle-check.tsx +0 -21
  207. package/src/components/Icon/icons/circle-x.tsx +0 -22
  208. package/src/components/Icon/icons/coffee.tsx +0 -23
  209. package/src/components/Icon/icons/cookie.tsx +0 -25
  210. package/src/components/Icon/icons/croissant.tsx +0 -24
  211. package/src/components/Icon/icons/cup-soda.tsx +0 -23
  212. package/src/components/Icon/icons/drumstick.tsx +0 -21
  213. package/src/components/Icon/icons/egg.tsx +0 -20
  214. package/src/components/Icon/icons/ellipsis-vertical.tsx +0 -22
  215. package/src/components/Icon/icons/external-link.tsx +0 -22
  216. package/src/components/Icon/icons/eye-off.tsx +0 -23
  217. package/src/components/Icon/icons/eye.tsx +0 -21
  218. package/src/components/Icon/icons/file.tsx +0 -21
  219. package/src/components/Icon/icons/fish.tsx +0 -25
  220. package/src/components/Icon/icons/grid-2x2.tsx +0 -22
  221. package/src/components/Icon/icons/house.tsx +0 -21
  222. package/src/components/Icon/icons/index.ts +0 -234
  223. package/src/components/Icon/icons/info.tsx +0 -22
  224. package/src/components/Icon/icons/lock.tsx +0 -21
  225. package/src/components/Icon/icons/log-out.tsx +0 -22
  226. package/src/components/Icon/icons/mail.tsx +0 -21
  227. package/src/components/Icon/icons/menu.tsx +0 -22
  228. package/src/components/Icon/icons/milk.tsx +0 -22
  229. package/src/components/Icon/icons/package.tsx +0 -23
  230. package/src/components/Icon/icons/pencil.tsx +0 -21
  231. package/src/components/Icon/icons/pizza.tsx +0 -24
  232. package/src/components/Icon/icons/plus.tsx +0 -21
  233. package/src/components/Icon/icons/rotate-ccw.tsx +0 -21
  234. package/src/components/Icon/icons/salad.tsx +0 -24
  235. package/src/components/Icon/icons/search.tsx +0 -21
  236. package/src/components/Icon/icons/settings.tsx +0 -21
  237. package/src/components/Icon/icons/shield.tsx +0 -20
  238. package/src/components/Icon/icons/shopping-basket.tsx +0 -26
  239. package/src/components/Icon/icons/sliders-horizontal.tsx +0 -28
  240. package/src/components/Icon/icons/smartphone.tsx +0 -21
  241. package/src/components/Icon/icons/snowflake.tsx +0 -31
  242. package/src/components/Icon/icons/spray-can.tsx +0 -29
  243. package/src/components/Icon/icons/trash-2.tsx +0 -24
  244. package/src/components/Icon/icons/upload.tsx +0 -22
  245. package/src/components/Icon/icons/user.tsx +0 -21
  246. package/src/components/Icon/icons/wine.tsx +0 -23
  247. package/src/components/Icon/icons/x.tsx +0 -21
  248. package/src/components/IconPicker/IconPicker.module.css +0 -63
  249. package/src/components/IconPicker/IconPicker.stories.tsx +0 -84
  250. package/src/components/IconPicker/IconPicker.tsx +0 -90
  251. package/src/components/Input/Input.module.css +0 -52
  252. package/src/components/Input/Input.stories.tsx +0 -86
  253. package/src/components/Input/Input.tsx +0 -14
  254. package/src/components/Input/__tests__/Input.test.tsx +0 -22
  255. package/src/components/Item/Item.module.css +0 -70
  256. package/src/components/Item/Item.stories.tsx +0 -62
  257. package/src/components/Item/Item.tsx +0 -54
  258. package/src/components/Item/__tests__/Item.test.tsx +0 -39
  259. package/src/components/Kbd/Kbd.module.css +0 -14
  260. package/src/components/Kbd/Kbd.stories.tsx +0 -32
  261. package/src/components/Kbd/Kbd.tsx +0 -12
  262. package/src/components/Kbd/__tests__/Kbd.test.tsx +0 -14
  263. package/src/components/Label/Label.module.css +0 -11
  264. package/src/components/Label/Label.stories.tsx +0 -40
  265. package/src/components/Label/Label.tsx +0 -24
  266. package/src/components/Label/__tests__/Label.test.tsx +0 -32
  267. package/src/components/LegalLinks/LegalLinks.module.css +0 -24
  268. package/src/components/LegalLinks/LegalLinks.stories.tsx +0 -22
  269. package/src/components/LegalLinks/LegalLinks.tsx +0 -40
  270. package/src/components/Markdown/Markdown.module.css +0 -49
  271. package/src/components/Markdown/Markdown.stories.tsx +0 -30
  272. package/src/components/Markdown/Markdown.tsx +0 -168
  273. package/src/components/Marker/Marker.module.css +0 -33
  274. package/src/components/Marker/Marker.stories.tsx +0 -39
  275. package/src/components/Marker/Marker.tsx +0 -34
  276. package/src/components/Marker/__tests__/Marker.test.tsx +0 -23
  277. package/src/components/MemberMultiSelect/MemberMultiSelect.module.css +0 -27
  278. package/src/components/MemberMultiSelect/MemberMultiSelect.stories.tsx +0 -74
  279. package/src/components/MemberMultiSelect/MemberMultiSelect.tsx +0 -67
  280. package/src/components/Menu/Menu.module.css +0 -89
  281. package/src/components/Menu/Menu.tsx +0 -159
  282. package/src/components/Menu/__tests__/Menu.test.tsx +0 -197
  283. package/src/components/Menubar/Menubar.stories.tsx +0 -52
  284. package/src/components/Menubar/Menubar.tsx +0 -42
  285. package/src/components/Menubar/__tests__/Menubar.test.tsx +0 -45
  286. package/src/components/Message/Message.module.css +0 -99
  287. package/src/components/Message/Message.stories.tsx +0 -79
  288. package/src/components/Message/Message.tsx +0 -41
  289. package/src/components/Message/__tests__/Message.test.tsx +0 -46
  290. package/src/components/MessageScroller/MessageScroller.module.css +0 -54
  291. package/src/components/MessageScroller/MessageScroller.stories.tsx +0 -84
  292. package/src/components/MessageScroller/MessageScroller.tsx +0 -72
  293. package/src/components/MessageScroller/__tests__/MessageScroller.test.tsx +0 -105
  294. package/src/components/MobileAppsDrawer/MobileAppsDrawer.module.css +0 -81
  295. package/src/components/MobileAppsDrawer/MobileAppsDrawer.tsx +0 -78
  296. package/src/components/MobileAppsDrawer/__tests__/MobileAppsDrawer.test.tsx +0 -80
  297. package/src/components/MobileFooter/MobileFooter.module.css +0 -73
  298. package/src/components/MobileFooter/MobileFooter.stories.tsx +0 -47
  299. package/src/components/MobileFooter/MobileFooter.tsx +0 -109
  300. package/src/components/MobileFooter/__tests__/MobileFooter.test.tsx +0 -71
  301. package/src/components/MobileHeader/MobileHeader.module.css +0 -63
  302. package/src/components/MobileHeader/MobileHeader.stories.tsx +0 -57
  303. package/src/components/MobileHeader/MobileHeader.tsx +0 -77
  304. package/src/components/MobileHeader/__tests__/MobileHeader.test.tsx +0 -58
  305. package/src/components/NavTabs/NavTabs.module.css +0 -50
  306. package/src/components/NavTabs/NavTabs.tsx +0 -61
  307. package/src/components/NavigationMenu/NavigationMenu.module.css +0 -53
  308. package/src/components/NavigationMenu/NavigationMenu.stories.tsx +0 -58
  309. package/src/components/NavigationMenu/NavigationMenu.tsx +0 -125
  310. package/src/components/NavigationMenu/__tests__/NavigationMenu.test.tsx +0 -93
  311. package/src/components/OfflineGate/OfflineGate.tsx +0 -44
  312. package/src/components/OfflineGate/__tests__/OfflineGate.test.tsx +0 -66
  313. package/src/components/OverlayHeader/OverlayHeader.module.css +0 -98
  314. package/src/components/OverlayHeader/OverlayHeader.tsx +0 -62
  315. package/src/components/OverlayHeader/__tests__/OverlayHeader.test.tsx +0 -51
  316. package/src/components/PageContainer/PageContainer.module.css +0 -20
  317. package/src/components/PageContainer/PageContainer.tsx +0 -31
  318. package/src/components/PageContainer/__tests__/PageContainer.test.tsx +0 -37
  319. package/src/components/PageHeader/PageHeader.module.css +0 -32
  320. package/src/components/PageHeader/PageHeader.tsx +0 -35
  321. package/src/components/Pagination/Pagination.module.css +0 -98
  322. package/src/components/Pagination/Pagination.stories.tsx +0 -49
  323. package/src/components/Pagination/Pagination.tsx +0 -87
  324. package/src/components/Pagination/__tests__/Pagination.test.tsx +0 -56
  325. package/src/components/Popover/Popover.module.css +0 -74
  326. package/src/components/Popover/Popover.stories.tsx +0 -357
  327. package/src/components/Popover/Popover.tsx +0 -208
  328. package/src/components/Popover/__tests__/Popover.test.tsx +0 -98
  329. package/src/components/Progress/Progress.module.css +0 -20
  330. package/src/components/Progress/Progress.stories.tsx +0 -40
  331. package/src/components/Progress/Progress.tsx +0 -35
  332. package/src/components/Progress/__tests__/Progress.test.tsx +0 -31
  333. package/src/components/QuantityStepper/QuantityStepper.module.css +0 -67
  334. package/src/components/QuantityStepper/QuantityStepper.stories.tsx +0 -79
  335. package/src/components/QuantityStepper/QuantityStepper.tsx +0 -107
  336. package/src/components/RadioGroup/RadioGroup.module.css +0 -88
  337. package/src/components/RadioGroup/RadioGroup.stories.tsx +0 -69
  338. package/src/components/RadioGroup/RadioGroup.tsx +0 -99
  339. package/src/components/RadioGroup/__tests__/RadioGroup.test.tsx +0 -59
  340. package/src/components/Resizable/Resizable.module.css +0 -70
  341. package/src/components/Resizable/Resizable.stories.tsx +0 -82
  342. package/src/components/Resizable/Resizable.tsx +0 -313
  343. package/src/components/Resizable/__tests__/Resizable.test.tsx +0 -128
  344. package/src/components/ResponsiveSurface/ResponsiveSurface.tsx +0 -24
  345. package/src/components/ResponsiveSurface/__tests__/ResponsiveSurface.test.tsx +0 -73
  346. package/src/components/ScrollArea/ScrollArea.module.css +0 -20
  347. package/src/components/ScrollArea/ScrollArea.stories.tsx +0 -57
  348. package/src/components/ScrollArea/ScrollArea.tsx +0 -27
  349. package/src/components/ScrollArea/__tests__/ScrollArea.test.tsx +0 -39
  350. package/src/components/SegmentedControl/SegmentedControl.module.css +0 -55
  351. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +0 -118
  352. package/src/components/SegmentedControl/SegmentedControl.tsx +0 -56
  353. package/src/components/SegmentedControl/__tests__/SegmentedControl.test.tsx +0 -63
  354. package/src/components/Select/Select.module.css +0 -82
  355. package/src/components/Select/Select.stories.tsx +0 -115
  356. package/src/components/Select/Select.tsx +0 -48
  357. package/src/components/Select/__tests__/Select.test.tsx +0 -59
  358. package/src/components/Sheet/Sheet.module.css +0 -55
  359. package/src/components/Sheet/Sheet.tsx +0 -109
  360. package/src/components/Sheet/__tests__/Sheet.test.tsx +0 -99
  361. package/src/components/Slider/Slider.module.css +0 -95
  362. package/src/components/Slider/Slider.stories.tsx +0 -64
  363. package/src/components/Slider/Slider.tsx +0 -77
  364. package/src/components/Slider/__tests__/Slider.test.tsx +0 -45
  365. package/src/components/Spinner/Spinner.module.css +0 -39
  366. package/src/components/Spinner/Spinner.tsx +0 -23
  367. package/src/components/SplitMethodSelector/SplitMethodSelector.stories.tsx +0 -33
  368. package/src/components/SplitMethodSelector/SplitMethodSelector.tsx +0 -43
  369. package/src/components/SplitPane/SplitPane.module.css +0 -85
  370. package/src/components/SplitPane/SplitPane.stories.tsx +0 -160
  371. package/src/components/SplitPane/SplitPane.tsx +0 -149
  372. package/src/components/SplitPane/__tests__/SplitPane.test.tsx +0 -51
  373. package/src/components/StatusBadge/StatusBadge.module.css +0 -59
  374. package/src/components/StatusBadge/StatusBadge.stories.tsx +0 -74
  375. package/src/components/StatusBadge/StatusBadge.tsx +0 -65
  376. package/src/components/SuggestionInput/SuggestionInput.module.css +0 -103
  377. package/src/components/SuggestionInput/SuggestionInput.stories.tsx +0 -144
  378. package/src/components/SuggestionInput/SuggestionInput.tsx +0 -207
  379. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.module.css +0 -55
  380. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.tsx +0 -227
  381. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlide.tsx +0 -35
  382. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideBody.tsx +0 -42
  383. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideFooter.tsx +0 -18
  384. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideHeader.tsx +0 -21
  385. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideParts.module.css +0 -29
  386. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarousel.test.tsx +0 -133
  387. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarouselDevGuard.test.tsx +0 -61
  388. package/src/components/SwipableMobileCarousel/context.ts +0 -13
  389. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.module.css +0 -49
  390. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.tsx +0 -62
  391. package/src/components/SwipableMobileCarouselDots/__tests__/SwipableMobileCarouselDots.test.tsx +0 -63
  392. package/src/components/SystemBanner/SystemBanner.module.css +0 -69
  393. package/src/components/SystemBanner/SystemBanner.stories.tsx +0 -86
  394. package/src/components/SystemBanner/SystemBanner.tsx +0 -50
  395. package/src/components/SystemBanner/__tests__/SystemBanner.test.tsx +0 -50
  396. package/src/components/Table/Table.module.css +0 -45
  397. package/src/components/Table/Table.stories.tsx +0 -125
  398. package/src/components/Table/Table.tsx +0 -51
  399. package/src/components/Table/__tests__/Table.test.tsx +0 -50
  400. package/src/components/Tabs/Tabs.module.css +0 -56
  401. package/src/components/Tabs/Tabs.stories.tsx +0 -100
  402. package/src/components/Tabs/Tabs.tsx +0 -46
  403. package/src/components/Tabs/__tests__/Tabs.test.tsx +0 -45
  404. package/src/components/TagInput/TagInput.module.css +0 -141
  405. package/src/components/TagInput/TagInput.stories.tsx +0 -109
  406. package/src/components/TagInput/TagInput.tsx +0 -174
  407. package/src/components/TagInput/__tests__/TagInput.test.tsx +0 -69
  408. package/src/components/Textarea/Textarea.module.css +0 -39
  409. package/src/components/Textarea/Textarea.tsx +0 -15
  410. package/src/components/Textarea/__tests__/Textarea.test.tsx +0 -29
  411. package/src/components/Toast/Toast.module.css +0 -132
  412. package/src/components/Toast/Toast.stories.tsx +0 -191
  413. package/src/components/Toast/Toast.tsx +0 -139
  414. package/src/components/Toggle/Toggle.module.css +0 -57
  415. package/src/components/Toggle/Toggle.stories.tsx +0 -95
  416. package/src/components/Toggle/Toggle.tsx +0 -39
  417. package/src/components/Toggle/__tests__/Toggle.test.tsx +0 -47
  418. package/src/components/Tooltip/Tooltip.module.css +0 -56
  419. package/src/components/Tooltip/Tooltip.tsx +0 -30
  420. package/src/components/Typography/Typography.module.css +0 -47
  421. package/src/components/Typography/Typography.stories.tsx +0 -62
  422. package/src/components/Typography/Typography.tsx +0 -30
  423. package/src/components/Typography/__tests__/Typography.test.tsx +0 -34
  424. package/src/css-modules.d.ts +0 -4
  425. package/src/hooks/__tests__/useCarouselRouteSync.test.tsx +0 -126
  426. package/src/hooks/__tests__/useDoubleTap.test.tsx +0 -117
  427. package/src/hooks/__tests__/useIsMobile.test.tsx +0 -80
  428. package/src/hooks/__tests__/useIsOffline.test.tsx +0 -53
  429. package/src/hooks/__tests__/useLongPress.test.tsx +0 -158
  430. package/src/hooks/__tests__/useOfflineTileState.test.tsx +0 -69
  431. package/src/hooks/__tests__/useResponsiveLayout.test.tsx +0 -87
  432. package/src/hooks/__tests__/useSnapCarousel.test.tsx +0 -93
  433. package/src/hooks/__tests__/useSwipeReveal.test.tsx +0 -110
  434. package/src/hooks/index.ts +0 -24
  435. package/src/hooks/useCarouselRouteSync.ts +0 -92
  436. package/src/hooks/useCommitOnEnterOrBlur.ts +0 -39
  437. package/src/hooks/useDoubleTap.ts +0 -91
  438. package/src/hooks/useIsMobile.ts +0 -33
  439. package/src/hooks/useIsOffline.ts +0 -41
  440. package/src/hooks/useLongPress.ts +0 -185
  441. package/src/hooks/useOfflineTileState.ts +0 -45
  442. package/src/hooks/useResponsiveLayout.ts +0 -36
  443. package/src/hooks/useSnapCarousel.ts +0 -79
  444. package/src/hooks/useSwipeReveal.ts +0 -107
  445. package/src/index.ts +0 -251
  446. package/src/motion.ts +0 -78
  447. package/src/overlay-shell.ts +0 -94
  448. package/src/scroll-lock.ts +0 -22
  449. package/src/stories/Avatar.stories.tsx +0 -44
  450. package/src/stories/Card.stories.tsx +0 -35
  451. package/src/stories/Checkbox.stories.tsx +0 -45
  452. package/src/stories/DesignSystemOverview.stories.tsx +0 -3187
  453. package/src/stories/DeviceOnlyGate.stories.tsx +0 -35
  454. package/src/stories/DeviceStorageKeyGate.stories.tsx +0 -57
  455. package/src/stories/DragHandleRow.stories.tsx +0 -41
  456. package/src/stories/EmptyState.stories.tsx +0 -33
  457. package/src/stories/FileDropzone.stories.tsx +0 -69
  458. package/src/stories/FormField.stories.tsx +0 -47
  459. package/src/stories/InteractionHooks.stories.tsx +0 -925
  460. package/src/stories/MobilePatterns.stories.tsx +0 -1536
  461. package/src/stories/NavTabs.stories.tsx +0 -53
  462. package/src/stories/OfflineGate.stories.tsx +0 -42
  463. package/src/stories/PageContainer.stories.tsx +0 -37
  464. package/src/stories/PageHeader.stories.tsx +0 -42
  465. package/src/stories/ResponsiveSurface.stories.tsx +0 -47
  466. package/src/stories/Spinner.stories.tsx +0 -25
  467. package/src/stories/SwipableMobileCarousel.stories.tsx +0 -304
  468. package/src/stories/Textarea.stories.tsx +0 -51
  469. package/src/stories/TokenGallery.stories.tsx +0 -602
  470. package/src/stories/Tooltip.stories.tsx +0 -59
  471. package/src/tokens/primitives.css +0 -157
  472. package/src/tokens/semantic.css +0 -130
  473. package/src/tokens.css +0 -5
@@ -1,146 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, fireEvent, render, screen } from '@testing-library/react';
4
- import { ConfirmDialog } from '../ConfirmDialog';
5
-
6
- // jsdom does not implement HTMLDialogElement.showModal()/close() (a
7
- // long-standing, documented gap) — polyfill the minimum behavior the
8
- // component depends on: the `open` attribute reflecting visibility, and
9
- // close() dispatching the native 'close' event ConfirmDialog listens for.
10
- beforeEach(() => {
11
- HTMLDialogElement.prototype.showModal = function (this: HTMLDialogElement) {
12
- this.setAttribute('open', '');
13
- };
14
- HTMLDialogElement.prototype.close = function (this: HTMLDialogElement) {
15
- this.removeAttribute('open');
16
- this.dispatchEvent(new Event('close'));
17
- };
18
- });
19
-
20
- describe('ConfirmDialog', () => {
21
- afterEach(cleanup);
22
-
23
- it('renders the title and message when open', () => {
24
- render(
25
- <ConfirmDialog
26
- open
27
- onClose={() => {}}
28
- onConfirm={() => {}}
29
- title="Remove passkey"
30
- message="This cannot be undone."
31
- />,
32
- );
33
- expect(screen.getByText('Remove passkey')).toBeTruthy();
34
- expect(screen.getByText('This cannot be undone.')).toBeTruthy();
35
- });
36
-
37
- it('renders rich message content', () => {
38
- render(
39
- <ConfirmDialog
40
- open
41
- onClose={() => {}}
42
- onConfirm={() => {}}
43
- title="Remove plugin"
44
- message={
45
- <>
46
- Remove <strong>Example</strong>?
47
- </>
48
- }
49
- />,
50
- );
51
- expect(screen.getByText('Example').tagName).toBe('STRONG');
52
- });
53
-
54
- it('calls onClose on Cancel', () => {
55
- const onClose = vi.fn();
56
- render(
57
- <ConfirmDialog open onClose={onClose} onConfirm={() => {}} title="Remove" message="Sure?" />,
58
- );
59
- fireEvent.click(screen.getByRole('button', { name: 'Cancel' }));
60
- expect(onClose).toHaveBeenCalledOnce();
61
- });
62
-
63
- it('calls onConfirm on the confirm action, without itself closing', () => {
64
- const onConfirm = vi.fn();
65
- const onClose = vi.fn();
66
- render(
67
- <ConfirmDialog
68
- open
69
- onClose={onClose}
70
- onConfirm={onConfirm}
71
- title="Remove"
72
- message="Sure?"
73
- confirmLabel="Remove"
74
- />,
75
- );
76
- fireEvent.click(screen.getByRole('button', { name: 'Remove' }));
77
- expect(onConfirm).toHaveBeenCalledOnce();
78
- expect(onClose).not.toHaveBeenCalled();
79
- });
80
-
81
- it('uses custom confirm/cancel labels', () => {
82
- render(
83
- <ConfirmDialog
84
- open
85
- onClose={() => {}}
86
- onConfirm={() => {}}
87
- title="Sign out"
88
- message="Sign out of this device?"
89
- confirmLabel="Sign out"
90
- cancelLabel="Stay signed in"
91
- />,
92
- );
93
- expect(screen.getByRole('button', { name: 'Sign out' })).toBeTruthy();
94
- expect(screen.getByRole('button', { name: 'Stay signed in' })).toBeTruthy();
95
- });
96
-
97
- it('disables both actions and shows the error slot when pending', () => {
98
- render(
99
- <ConfirmDialog
100
- open
101
- onClose={() => {}}
102
- onConfirm={() => {}}
103
- title="Remove plugin"
104
- message="Sure?"
105
- confirmLabel="Removing…"
106
- pending
107
- error="Server error — try again."
108
- />,
109
- );
110
- expect((screen.getByRole('button', { name: 'Cancel' }) as HTMLButtonElement).disabled).toBe(
111
- true,
112
- );
113
- expect((screen.getByRole('button', { name: 'Removing…' }) as HTMLButtonElement).disabled).toBe(
114
- true,
115
- );
116
- expect(screen.getByText('Server error — try again.')).toBeTruthy();
117
- });
118
-
119
- it('renders a destructive confirm action distinctly from the default variant', () => {
120
- const { rerender } = render(
121
- <ConfirmDialog
122
- open
123
- onClose={() => {}}
124
- onConfirm={() => {}}
125
- title="Remove"
126
- message="Sure?"
127
- confirmLabel="Remove"
128
- />,
129
- );
130
- const defaultClass = screen.getByRole('button', { name: 'Remove' }).className;
131
-
132
- rerender(
133
- <ConfirmDialog
134
- open
135
- onClose={() => {}}
136
- onConfirm={() => {}}
137
- title="Remove"
138
- message="Sure?"
139
- confirmLabel="Remove"
140
- destructive
141
- />,
142
- );
143
- const destructiveClass = screen.getByRole('button', { name: 'Remove' }).className;
144
- expect(destructiveClass).not.toBe(defaultClass);
145
- });
146
- });
@@ -1,81 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { ContextMenu } from './ContextMenu';
3
-
4
- const meta = {
5
- title: 'Components/ContextMenu',
6
- component: ContextMenu,
7
- parameters: {
8
- layout: 'padded',
9
- docs: {
10
- description: {
11
- component:
12
- "Right-click menu on desktop, long-press on touch. Desktop positioning reuses Popover's existing collision detection anchored to the click point; touch opens the same items in a Drawer bottom sheet — a floating panel at a touch point isn't a pattern touch interfaces have.",
13
- },
14
- },
15
- },
16
- args: {
17
- children: <span />,
18
- items: [
19
- { label: 'Rename', onSelect: () => {} },
20
- { label: 'Duplicate', onSelect: () => {} },
21
- { type: 'separator' },
22
- { label: 'Delete', destructive: true, onSelect: () => {} },
23
- ],
24
- 'aria-label': 'Row actions',
25
- },
26
- } satisfies Meta<typeof ContextMenu>;
27
-
28
- export default meta;
29
- type Story = StoryObj<typeof meta>;
30
-
31
- // ---------------------------------------------------------------------------
32
-
33
- export const Default: Story = {
34
- render: (args) => (
35
- <ContextMenu {...args}>
36
- <div
37
- style={{
38
- width: 240,
39
- padding: 'var(--sv-space-4)',
40
- border: '1px dashed var(--sv-color-border-strong)',
41
- borderRadius: 'var(--sv-radius-md)',
42
- textAlign: 'center',
43
- fontSize: 14,
44
- color: 'var(--sv-color-text-muted)',
45
- }}
46
- >
47
- Right-click here (or long-press on touch)
48
- </div>
49
- </ContextMenu>
50
- ),
51
- };
52
-
53
- export const WithIconsAndChecked: Story = {
54
- args: {
55
- items: [
56
- { type: 'label', label: 'Sort by' },
57
- { label: 'Name', checked: true, onSelect: () => {} },
58
- { label: 'Date modified', checked: false, onSelect: () => {} },
59
- { type: 'separator' },
60
- { label: 'Rename', icon: 'pencil', onSelect: () => {} },
61
- { label: 'Delete', icon: 'trash-2', destructive: true, onSelect: () => {} },
62
- ],
63
- },
64
- render: (args) => (
65
- <ContextMenu {...args}>
66
- <div
67
- style={{
68
- width: 240,
69
- padding: 'var(--sv-space-4)',
70
- border: '1px dashed var(--sv-color-border-strong)',
71
- borderRadius: 'var(--sv-radius-md)',
72
- textAlign: 'center',
73
- fontSize: 14,
74
- color: 'var(--sv-color-text-muted)',
75
- }}
76
- >
77
- Right-click here
78
- </div>
79
- </ContextMenu>
80
- ),
81
- };
@@ -1,100 +0,0 @@
1
- 'use client';
2
-
3
- import { cloneElement, useState } from 'react';
4
- import type { ReactElement } from 'react';
5
- import type { MouseEvent as ReactMouseEvent } from 'react';
6
- import { useIsMobile, useLongPress } from '../../hooks';
7
- import { Popover } from '../Popover/Popover';
8
- import { Drawer } from '../Drawer/Drawer';
9
- import { MenuEntries, type MenuEntry, type MenuItem } from '../Menu/Menu';
10
-
11
- export interface ContextMenuProps {
12
- /** The element that gets right-click (desktop) / long-press (touch)
13
- * behavior — cloned with the trigger handlers, rendered as-is otherwise.
14
- * Typed with `<any>` props (not a bare `ReactElement`, whose implicit
15
- * `unknown` props type makes `cloneElement` reject *both* branches of
16
- * the long-press/onContextMenu union below — an interface value like
17
- * `LongPressHandlers` isn't assignable to an indexed props type without
18
- * its own index signature) — the standard, narrowly-scoped escape hatch
19
- * for "clone an arbitrary child with props not known ahead of time". */
20
- // eslint-disable-next-line @typescript-eslint/no-explicit-any -- see comment above
21
- children: ReactElement<any>;
22
- items: MenuEntry[];
23
- 'aria-label': string;
24
- }
25
-
26
- /**
27
- * ContextMenu — right-click menu on desktop, long-press on touch.
28
- *
29
- * Desktop positioning reuses `Popover`'s existing collision-detection logic
30
- * rather than reimplementing it: the panel is wrapped in a zero-size,
31
- * `position: fixed` anchor placed at the click coordinates, so `Popover`
32
- * measures and flips against *that* point exactly as it would a normal
33
- * trigger element.
34
- *
35
- * Touch uses `useLongPress` (which already handles the OS's own long-press
36
- * callout/context-menu suppression) and opens the same items in a `Drawer`
37
- * bottom sheet — the same adaptive-surface split `Menu` already uses,
38
- * because a floating panel positioned at a touch point isn't a pattern
39
- * touch interfaces have in the first place.
40
- */
41
- export function ContextMenu({ children, items, 'aria-label': ariaLabel }: ContextMenuProps) {
42
- const isMobile = useIsMobile();
43
- const [open, setOpen] = useState(false);
44
- const [point, setPoint] = useState({ x: 0, y: 0 });
45
-
46
- const longPressHandlers = useLongPress({
47
- onLongPress: () => setOpen(true),
48
- disabled: !isMobile,
49
- });
50
-
51
- function handleContextMenu(e: ReactMouseEvent) {
52
- e.preventDefault();
53
- setPoint({ x: e.clientX, y: e.clientY });
54
- setOpen(true);
55
- }
56
-
57
- const wrappedChild = cloneElement(
58
- children,
59
- isMobile ? longPressHandlers : { onContextMenu: handleContextMenu },
60
- );
61
-
62
- const list = (
63
- <MenuEntries
64
- items={items}
65
- onSelect={(entry: MenuItem) => {
66
- setOpen(false);
67
- entry.onSelect();
68
- }}
69
- />
70
- );
71
-
72
- if (isMobile) {
73
- return (
74
- <>
75
- {wrappedChild}
76
- <Drawer open={open} onClose={() => setOpen(false)} aria-label={ariaLabel}>
77
- {list}
78
- </Drawer>
79
- </>
80
- );
81
- }
82
-
83
- return (
84
- <>
85
- {wrappedChild}
86
- {open && (
87
- <div style={{ position: 'fixed', left: point.x, top: point.y, width: 0, height: 0 }}>
88
- <Popover
89
- trigger={<span />}
90
- open={open}
91
- onClose={() => setOpen(false)}
92
- aria-label={ariaLabel}
93
- >
94
- {list}
95
- </Popover>
96
- </div>
97
- )}
98
- </>
99
- );
100
- }
@@ -1,87 +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 { ContextMenu } from '../ContextMenu';
5
-
6
- let isMobileMatches = false;
7
-
8
- function installMatchMedia() {
9
- vi.stubGlobal(
10
- 'matchMedia',
11
- vi.fn().mockImplementation((query: string) => ({
12
- matches: isMobileMatches,
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
- const items = [{ label: 'Delete', onSelect: vi.fn() }];
24
-
25
- describe('ContextMenu', () => {
26
- beforeEach(() => {
27
- isMobileMatches = false;
28
- installMatchMedia();
29
- });
30
-
31
- afterEach(() => {
32
- vi.unstubAllGlobals();
33
- cleanup();
34
- });
35
-
36
- it('does not show the menu before any trigger', () => {
37
- render(
38
- <ContextMenu items={items} aria-label="Row actions">
39
- <div>Row</div>
40
- </ContextMenu>,
41
- );
42
- expect(screen.queryByRole('menu')).toBeNull();
43
- });
44
-
45
- it('opens on right-click (desktop) and prevents the native context menu', () => {
46
- render(
47
- <ContextMenu items={items} aria-label="Row actions">
48
- <div>Row</div>
49
- </ContextMenu>,
50
- );
51
- const target = screen.getByText('Row');
52
- const event = fireEvent.contextMenu(target, { clientX: 100, clientY: 150 });
53
- expect(event).toBe(false); // fireEvent returns false when preventDefault was called
54
- expect(screen.getByRole('menu')).toBeDefined();
55
- });
56
-
57
- it('selecting an item calls onSelect and closes the menu', () => {
58
- const onSelect = vi.fn();
59
- render(
60
- <ContextMenu items={[{ label: 'Delete', onSelect }]} aria-label="Row actions">
61
- <div>Row</div>
62
- </ContextMenu>,
63
- );
64
- fireEvent.contextMenu(screen.getByText('Row'), { clientX: 10, clientY: 10 });
65
- fireEvent.click(screen.getByRole('menuitem', { name: 'Delete' }));
66
- expect(onSelect).toHaveBeenCalled();
67
- expect(screen.queryByRole('menu')).toBeNull();
68
- });
69
-
70
- it('opens via long-press on touch instead of right-click', () => {
71
- vi.useFakeTimers();
72
- isMobileMatches = true;
73
- installMatchMedia();
74
- render(
75
- <ContextMenu items={items} aria-label="Row actions">
76
- <div>Row</div>
77
- </ContextMenu>,
78
- );
79
- const target = screen.getByText('Row');
80
- fireEvent.pointerDown(target, { pointerType: 'touch', clientX: 10, clientY: 10 });
81
- act(() => {
82
- vi.advanceTimersByTime(600);
83
- });
84
- expect(screen.getByRole('menu')).toBeDefined();
85
- vi.useRealTimers();
86
- });
87
- });
@@ -1,50 +0,0 @@
1
- import { useState } from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react-vite';
3
- import { CurrencyInput } from './CurrencyInput';
4
-
5
- const meta = {
6
- title: 'Components/CurrencyInput',
7
- component: CurrencyInput,
8
- parameters: {
9
- layout: 'padded',
10
- docs: {
11
- description: {
12
- component:
13
- 'Decimal amount entry that reports its value as integer cents, matching the "amounts are always smallest-unit integers" data-model convention. Preserves in-progress typing (e.g. a trailing decimal point) instead of reformatting on every keystroke.',
14
- },
15
- },
16
- },
17
- args: {
18
- valueCents: null,
19
- onValueChange: () => {},
20
- },
21
- } satisfies Meta<typeof CurrencyInput>;
22
-
23
- export default meta;
24
- type Story = StoryObj<typeof meta>;
25
-
26
- function ControlledCurrencyInput({ initialCents }: { initialCents: number | null }) {
27
- const [cents, setCents] = useState<number | null>(initialCents);
28
- return (
29
- <CurrencyInput
30
- valueCents={cents}
31
- onValueChange={setCents}
32
- placeholder="0.00"
33
- aria-label="Amount"
34
- />
35
- );
36
- }
37
-
38
- export const Empty: Story = {
39
- render: () => <ControlledCurrencyInput initialCents={null} />,
40
- };
41
-
42
- export const Prefilled: Story = {
43
- render: () => <ControlledCurrencyInput initialCents={4250} />,
44
- };
45
-
46
- export const Disabled: Story = {
47
- render: () => (
48
- <CurrencyInput valueCents={1000} onValueChange={() => {}} aria-label="Amount" disabled />
49
- ),
50
- };
@@ -1,60 +0,0 @@
1
- 'use client';
2
-
3
- import { useState } from 'react';
4
- import { Input, type InputProps } from '../Input/Input';
5
-
6
- export interface CurrencyInputProps extends Omit<
7
- InputProps,
8
- 'value' | 'onChange' | 'type' | 'inputMode'
9
- > {
10
- /** Smallest currency unit (cents) — never a float. Null when the field is empty or unparsable. */
11
- valueCents: number | null;
12
- onValueChange: (cents: number | null) => void;
13
- }
14
-
15
- function centsToText(cents: number): string {
16
- return (cents / 100).toFixed(2);
17
- }
18
-
19
- function textToCents(text: string): number | null {
20
- const trimmed = text.trim();
21
- if (!trimmed) return null;
22
- const parsed = Number(trimmed);
23
- if (!Number.isFinite(parsed)) return null;
24
- return Math.round(parsed * 100);
25
- }
26
-
27
- /**
28
- * CurrencyInput — decimal amount entry that reports its value as integer
29
- * cents, matching Sovereign's "amounts are always smallest-unit integers"
30
- * data-model convention (never a float in application state).
31
- *
32
- * Keeps its own text buffer rather than deriving display text from
33
- * `valueCents` on every keystroke — reformatting mid-type (e.g. "12." → the
34
- * trailing decimal point) would fight the user's cursor. It only
35
- * re-syncs from `valueCents` when the prop changes to something the current
36
- * text doesn't already represent (an external reset/prefill), so typing
37
- * remains uninterrupted while the parsed amount stays in lockstep with the
38
- * parent's state.
39
- */
40
- export function CurrencyInput({ valueCents, onValueChange, ...rest }: CurrencyInputProps) {
41
- const [text, setText] = useState(() => (valueCents != null ? centsToText(valueCents) : ''));
42
-
43
- if (textToCents(text) !== valueCents) {
44
- setText(valueCents != null ? centsToText(valueCents) : '');
45
- }
46
-
47
- return (
48
- <Input
49
- {...rest}
50
- type="text"
51
- inputMode="decimal"
52
- value={text}
53
- onChange={(e) => {
54
- const next = e.currentTarget.value;
55
- setText(next);
56
- onValueChange(textToCents(next));
57
- }}
58
- />
59
- );
60
- }
@@ -1,28 +0,0 @@
1
- .sortButton {
2
- display: inline-flex;
3
- align-items: center;
4
- gap: var(--sv-space-1);
5
- border: none;
6
- background: transparent;
7
- padding: 0;
8
- margin: 0;
9
- color: inherit;
10
- font: inherit;
11
- font-weight: inherit;
12
- cursor: pointer;
13
- }
14
-
15
- .sortButton:focus-visible {
16
- outline: 2px solid var(--sv-color-focus-ring);
17
- outline-offset: 2px;
18
- border-radius: var(--sv-radius-sm);
19
- }
20
-
21
- .sortIcon {
22
- display: inline-flex;
23
- flex-shrink: 0;
24
- width: var(--sv-icon-size-sm);
25
- height: var(--sv-icon-size-sm);
26
- align-items: center;
27
- justify-content: center;
28
- }
@@ -1,74 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { DataTable, type DataTableColumn } from './DataTable';
3
- import { StatusBadge } from '../StatusBadge/StatusBadge';
4
-
5
- interface PluginRow {
6
- id: string;
7
- name: string;
8
- installs: number;
9
- status: 'synced' | 'draft';
10
- }
11
-
12
- const ROWS: PluginRow[] = [
13
- { id: 'tasks', name: 'sovereign-tasks', installs: 482, status: 'synced' },
14
- { id: 'ledger', name: 'sovereign-ledger', installs: 219, status: 'synced' },
15
- { id: 'shopper', name: 'sovereign-shopper', installs: 37, status: 'draft' },
16
- { id: 'healthlog', name: 'sovereign-healthlog', installs: 1204, status: 'synced' },
17
- ];
18
-
19
- const columns: DataTableColumn<PluginRow>[] = [
20
- { key: 'name', header: 'Plugin', sortable: true },
21
- { key: 'installs', header: 'Installs', sortable: true, align: 'end' },
22
- {
23
- key: 'status',
24
- header: 'Status',
25
- render: (row) => <StatusBadge status={row.status} />,
26
- },
27
- ];
28
-
29
- const meta = {
30
- title: 'Components/DataTable',
31
- component: DataTable,
32
- parameters: {
33
- layout: 'padded',
34
- docs: {
35
- description: {
36
- component:
37
- 'Sortable table built on Table. Column-driven: pass columns + data instead of composing TableRow/TableCell by hand. Clicking a sortable header cycles ascending → descending → unsorted.',
38
- },
39
- },
40
- },
41
- args: { columns: [], data: [], getRowKey: (row: PluginRow) => row.id },
42
- } satisfies Meta<typeof DataTable<PluginRow>>;
43
-
44
- export default meta;
45
- type Story = StoryObj<typeof meta>;
46
-
47
- // ---------------------------------------------------------------------------
48
-
49
- export const Default: Story = {
50
- render: () => <DataTable columns={columns} data={ROWS} getRowKey={(row) => row.id} />,
51
- };
52
-
53
- export const DefaultSorted: Story = {
54
- render: () => (
55
- <DataTable
56
- columns={columns}
57
- data={ROWS}
58
- getRowKey={(row) => row.id}
59
- defaultSortKey="installs"
60
- defaultSortDirection="desc"
61
- />
62
- ),
63
- };
64
-
65
- export const Empty: Story = {
66
- render: () => (
67
- <DataTable
68
- columns={columns}
69
- data={[]}
70
- getRowKey={(row) => row.id}
71
- emptyMessage="No plugins installed"
72
- />
73
- ),
74
- };