@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,213 +0,0 @@
1
- 'use client';
2
-
3
- import { type KeyboardEvent as ReactKeyboardEvent, useRef, useState } from 'react';
4
- import { Icon } from '../Icon/Icon';
5
- import {
6
- addDays,
7
- addMonths,
8
- formatDateLabel,
9
- formatMonthYear,
10
- formatWeekdayShort,
11
- getMonthGrid,
12
- isSameDay,
13
- isSameMonth,
14
- isWithinRange,
15
- startOfMonth,
16
- } from './dateUtils';
17
- import styles from './Calendar.module.css';
18
-
19
- export interface CalendarProps {
20
- /** Selected date, or `null` for no selection. */
21
- value: Date | null;
22
- onChange: (date: Date) => void;
23
- /** Dates before this are disabled and unselectable. */
24
- minDate?: Date;
25
- /** Dates after this are disabled and unselectable. */
26
- maxDate?: Date;
27
- 'aria-label'?: string;
28
- }
29
-
30
- // A week's worth of dates, used once to derive the weekday header labels —
31
- // any Sunday-starting week works since only the day-of-week repeats.
32
- // getMonthGrid always returns 6 weeks (see its own doc comment), so index 0
33
- // is guaranteed to exist — the `?? []` is purely to satisfy the lint rule
34
- // against non-null assertions, not a real runtime possibility.
35
- const WEEKDAY_LABEL_WEEK = getMonthGrid(new Date(2026, 0, 1))[0] ?? [];
36
-
37
- /**
38
- * Calendar — a keyboard-navigable month grid. Date-only (no time or range
39
- * selection — decision D6 in the mobile design-system plan); a `DatePicker`
40
- * field wraps this in a `Popover` (desktop) or `Drawer` (mobile).
41
- *
42
- * Keyboard (WAI-ARIA APG grid pattern, roving tabindex — exactly one day
43
- * button is ever tab-stoppable): arrow keys move focus by day/week, Home/End
44
- * jump to the start/end of the focused week, PageUp/PageDown change month,
45
- * Enter/Space selects the focused date. Navigating into an adjacent month
46
- * (arrow keys at a week's edge, or PageUp/PageDown) updates the displayed
47
- * month to follow focus.
48
- */
49
- export function Calendar({
50
- value,
51
- onChange,
52
- minDate,
53
- maxDate,
54
- 'aria-label': ariaLabel,
55
- }: CalendarProps) {
56
- const [displayedMonth, setDisplayedMonth] = useState(() => startOfMonth(value ?? new Date()));
57
- // The roving-tabindex date. Independent of `value` — you can arrow around
58
- // without selecting; Enter/Space is what commits a selection.
59
- const [focusedDate, setFocusedDate] = useState(() => value ?? new Date());
60
- const gridRef = useRef<HTMLDivElement>(null);
61
-
62
- const weeks = getMonthGrid(displayedMonth);
63
-
64
- function goToMonth(next: Date) {
65
- setDisplayedMonth(startOfMonth(next));
66
- }
67
-
68
- function moveFocus(next: Date) {
69
- setFocusedDate(next);
70
- if (!isSameMonth(next, displayedMonth)) goToMonth(next);
71
- // Focus is applied after the grid re-renders with the new roving
72
- // tabindex target — see the ref callback below on each day button,
73
- // which focuses itself when it becomes the tabIndex=0 cell following a
74
- // keyboard-driven focus change (queued via requestAnimationFrame so the
75
- // DOM has committed the new grid first).
76
- requestAnimationFrame(() => {
77
- gridRef.current?.querySelector<HTMLButtonElement>('[tabindex="0"]')?.focus();
78
- });
79
- }
80
-
81
- function selectDate(date: Date) {
82
- if (!isWithinRange(date, minDate, maxDate)) return;
83
- onChange(date);
84
- setFocusedDate(date);
85
- }
86
-
87
- function handleKeyDown(e: ReactKeyboardEvent) {
88
- switch (e.key) {
89
- case 'ArrowLeft':
90
- e.preventDefault();
91
- moveFocus(addDays(focusedDate, -1));
92
- return;
93
- case 'ArrowRight':
94
- e.preventDefault();
95
- moveFocus(addDays(focusedDate, 1));
96
- return;
97
- case 'ArrowUp':
98
- e.preventDefault();
99
- moveFocus(addDays(focusedDate, -7));
100
- return;
101
- case 'ArrowDown':
102
- e.preventDefault();
103
- moveFocus(addDays(focusedDate, 7));
104
- return;
105
- case 'Home':
106
- e.preventDefault();
107
- moveFocus(addDays(focusedDate, -focusedDate.getDay()));
108
- return;
109
- case 'End':
110
- e.preventDefault();
111
- moveFocus(addDays(focusedDate, 6 - focusedDate.getDay()));
112
- return;
113
- case 'PageUp':
114
- e.preventDefault();
115
- moveFocus(addMonths(focusedDate, -1));
116
- return;
117
- case 'PageDown':
118
- e.preventDefault();
119
- moveFocus(addMonths(focusedDate, 1));
120
- return;
121
- case 'Enter':
122
- case ' ':
123
- e.preventDefault();
124
- selectDate(focusedDate);
125
- return;
126
- default:
127
- }
128
- }
129
-
130
- return (
131
- <div className={styles.calendar} aria-label={ariaLabel}>
132
- <div className={styles.header}>
133
- <button
134
- type="button"
135
- className={styles.navButton}
136
- aria-label="Previous month"
137
- onClick={() => goToMonth(addMonths(displayedMonth, -1))}
138
- >
139
- <Icon name="chevron-left" size="sm" aria-hidden />
140
- </button>
141
- <span className={styles.monthLabel}>{formatMonthYear(displayedMonth)}</span>
142
- <button
143
- type="button"
144
- className={styles.navButton}
145
- aria-label="Next month"
146
- onClick={() => goToMonth(addMonths(displayedMonth, 1))}
147
- >
148
- <Icon name="chevron-right" size="sm" aria-hidden />
149
- </button>
150
- </div>
151
-
152
- <div
153
- ref={gridRef}
154
- role="grid"
155
- aria-label={formatMonthYear(displayedMonth)}
156
- className={styles.grid}
157
- onKeyDown={handleKeyDown}
158
- // Keyboard handling relies on roving tabindex on the day buttons
159
- // (real DOM focus + bubbling), not on this container being a tab
160
- // stop itself — tabIndex={-1} only satisfies jsx-a11y's expectation
161
- // that an element carrying a keydown handler + interactive role be
162
- // focusable; it does not change Tab-key reachability.
163
- tabIndex={-1}
164
- >
165
- <div role="row" className={styles.weekdayRow}>
166
- {WEEKDAY_LABEL_WEEK.map((d) => (
167
- <span key={d.getDay()} role="columnheader" className={styles.weekday} aria-hidden>
168
- {formatWeekdayShort(d)}
169
- </span>
170
- ))}
171
- </div>
172
- {weeks.map((week) => {
173
- const firstDayOfWeek = week[0];
174
- if (!firstDayOfWeek) return null;
175
- return (
176
- <div role="row" className={styles.week} key={firstDayOfWeek.toISOString()}>
177
- {week.map((date) => {
178
- const isCurrentMonth = isSameMonth(date, displayedMonth);
179
- const isSelected = value !== null && isSameDay(date, value);
180
- const isToday = isSameDay(date, new Date());
181
- const isFocusTarget = isSameDay(date, focusedDate);
182
- const disabled = !isWithinRange(date, minDate, maxDate);
183
- return (
184
- <div role="gridcell" aria-selected={isSelected} key={date.toISOString()}>
185
- <button
186
- type="button"
187
- tabIndex={isFocusTarget ? 0 : -1}
188
- disabled={disabled}
189
- aria-current={isToday ? 'date' : undefined}
190
- aria-label={formatDateLabel(date)}
191
- className={[
192
- styles.day,
193
- !isCurrentMonth ? styles.dayOutside : '',
194
- isSelected ? styles.daySelected : '',
195
- isToday && !isSelected ? styles.dayToday : '',
196
- ]
197
- .filter(Boolean)
198
- .join(' ')}
199
- onClick={() => selectDate(date)}
200
- onFocus={() => setFocusedDate(date)}
201
- >
202
- {date.getDate()}
203
- </button>
204
- </div>
205
- );
206
- })}
207
- </div>
208
- );
209
- })}
210
- </div>
211
- </div>
212
- );
213
- }
@@ -1,98 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, fireEvent, render, screen } from '@testing-library/react';
4
- import { Calendar } from '../Calendar';
5
-
6
- // A fixed reference date so tests are deterministic regardless of when they run.
7
- const JAN_15_2026 = new Date(2026, 0, 15); // Thursday
8
-
9
- describe('Calendar', () => {
10
- afterEach(cleanup);
11
-
12
- it('renders the displayed month and year', () => {
13
- render(<Calendar value={JAN_15_2026} onChange={() => {}} />);
14
- expect(screen.getByText('January 2026')).toBeTruthy();
15
- });
16
-
17
- it('marks the selected date', () => {
18
- render(<Calendar value={JAN_15_2026} onChange={() => {}} />);
19
- const button = screen.getByRole('button', { name: /Thursday, January 15, 2026/ });
20
- // aria-selected lives on the gridcell (the button's parent), not the
21
- // button itself — the button role doesn't support aria-selected.
22
- expect(button.parentElement?.getAttribute('aria-selected')).toBe('true');
23
- });
24
-
25
- it('calls onChange with the clicked date', () => {
26
- const onChange = vi.fn();
27
- render(<Calendar value={JAN_15_2026} onChange={onChange} />);
28
- fireEvent.click(screen.getByRole('button', { name: /January 20, 2026/ }));
29
- expect(onChange).toHaveBeenCalledOnce();
30
- const called = onChange.mock.calls[0]?.[0] as Date;
31
- expect(called.getDate()).toBe(20);
32
- expect(called.getMonth()).toBe(0);
33
- expect(called.getFullYear()).toBe(2026);
34
- });
35
-
36
- it('navigates to the next and previous month', () => {
37
- render(<Calendar value={JAN_15_2026} onChange={() => {}} />);
38
- fireEvent.click(screen.getByRole('button', { name: 'Next month' }));
39
- expect(screen.getByText('February 2026')).toBeTruthy();
40
- fireEvent.click(screen.getByRole('button', { name: 'Previous month' }));
41
- fireEvent.click(screen.getByRole('button', { name: 'Previous month' }));
42
- expect(screen.getByText('December 2025')).toBeTruthy();
43
- });
44
-
45
- it('disables and does not select dates outside minDate/maxDate', () => {
46
- const onChange = vi.fn();
47
- render(
48
- <Calendar
49
- value={JAN_15_2026}
50
- onChange={onChange}
51
- minDate={new Date(2026, 0, 10)}
52
- maxDate={new Date(2026, 0, 20)}
53
- />,
54
- );
55
- const outOfRange = screen.getByRole('button', { name: /January 5, 2026/ });
56
- expect(outOfRange.hasAttribute('disabled')).toBe(true);
57
- fireEvent.click(outOfRange);
58
- expect(onChange).not.toHaveBeenCalled();
59
- });
60
-
61
- it('exposes exactly one roving tabIndex=0 day at a time', () => {
62
- render(<Calendar value={JAN_15_2026} onChange={() => {}} />);
63
- const zeroTabIndex = document.querySelectorAll('[role="gridcell"] button[tabindex="0"]');
64
- expect(zeroTabIndex.length).toBe(1);
65
- expect(zeroTabIndex[0]?.getAttribute('aria-label')).toMatch(/January 15, 2026/);
66
- });
67
-
68
- it('moves the roving tabIndex with ArrowRight and selects with Enter', () => {
69
- const onChange = vi.fn();
70
- render(<Calendar value={JAN_15_2026} onChange={onChange} />);
71
- const grid = screen.getByRole('grid');
72
- fireEvent.keyDown(grid, { key: 'ArrowRight' });
73
- const zeroTabIndex = document.querySelector('[role="gridcell"] button[tabindex="0"]');
74
- expect(zeroTabIndex?.getAttribute('aria-label')).toMatch(/January 16, 2026/);
75
- fireEvent.keyDown(grid, { key: 'Enter' });
76
- expect(onChange).toHaveBeenCalledOnce();
77
- const called = onChange.mock.calls[0]?.[0] as Date;
78
- expect(called.getDate()).toBe(16);
79
- });
80
-
81
- it('PageDown advances the focused date and displayed month by one month', () => {
82
- render(<Calendar value={JAN_15_2026} onChange={() => {}} />);
83
- const grid = screen.getByRole('grid');
84
- fireEvent.keyDown(grid, { key: 'PageDown' });
85
- expect(screen.getByText('February 2026')).toBeTruthy();
86
- });
87
-
88
- it('marks today distinctly from an ordinary day', () => {
89
- const today = new Date();
90
- render(<Calendar value={null} onChange={() => {}} />);
91
- const todayLabel = screen.getByRole('button', {
92
- name: new RegExp(
93
- `${today.toLocaleDateString(undefined, { month: 'long' })} ${today.getDate()}, ${today.getFullYear()}`,
94
- ),
95
- });
96
- expect(todayLabel.getAttribute('aria-current')).toBe('date');
97
- });
98
- });
@@ -1,97 +0,0 @@
1
- // Plain-Date helpers for Calendar — deliberately self-contained (no date
2
- // library dependency, matching @sovereignfs/ui's zero-extra-dependency
3
- // philosophy). Every function operates on local calendar dates only; there is
4
- // no timezone or time-of-day handling here — Calendar is date-only (decision
5
- // D6 in the mobile design-system plan). Time and range selection are future
6
- // scope.
7
-
8
- export function startOfMonth(date: Date): Date {
9
- return new Date(date.getFullYear(), date.getMonth(), 1);
10
- }
11
-
12
- export function addMonths(date: Date, count: number): Date {
13
- return new Date(date.getFullYear(), date.getMonth() + count, date.getDate());
14
- }
15
-
16
- export function addDays(date: Date, count: number): Date {
17
- return new Date(date.getFullYear(), date.getMonth(), date.getDate() + count);
18
- }
19
-
20
- export function isSameDay(a: Date, b: Date): boolean {
21
- return (
22
- a.getFullYear() === b.getFullYear() &&
23
- a.getMonth() === b.getMonth() &&
24
- a.getDate() === b.getDate()
25
- );
26
- }
27
-
28
- export function isSameMonth(a: Date, b: Date): boolean {
29
- return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth();
30
- }
31
-
32
- export function isBeforeDay(a: Date, b: Date): boolean {
33
- return (
34
- a.getFullYear() < b.getFullYear() ||
35
- (a.getFullYear() === b.getFullYear() &&
36
- (a.getMonth() < b.getMonth() || (a.getMonth() === b.getMonth() && a.getDate() < b.getDate())))
37
- );
38
- }
39
-
40
- export function isAfterDay(a: Date, b: Date): boolean {
41
- return isBeforeDay(b, a);
42
- }
43
-
44
- export function isWithinRange(date: Date, min?: Date, max?: Date): boolean {
45
- if (min && isBeforeDay(date, min)) return false;
46
- if (max && isAfterDay(date, max)) return false;
47
- return true;
48
- }
49
-
50
- /**
51
- * A 6x7 grid of dates covering `month` (any date within the target month),
52
- * padded with the trailing days of the previous month and the leading days
53
- * of the next so every week is a full row — Sunday-first. 6 rows always
54
- * (rather than the 4-6 a month strictly needs) so the grid's own height never
55
- * changes as the displayed month changes, avoiding a layout jump.
56
- */
57
- export function getMonthGrid(month: Date): Date[][] {
58
- const first = startOfMonth(month);
59
- const startOffset = first.getDay(); // 0 (Sun) .. 6 (Sat)
60
- const gridStart = addDays(first, -startOffset);
61
-
62
- const weeks: Date[][] = [];
63
- for (let week = 0; week < 6; week++) {
64
- const days: Date[] = [];
65
- for (let day = 0; day < 7; day++) {
66
- days.push(addDays(gridStart, week * 7 + day));
67
- }
68
- weeks.push(days);
69
- }
70
- return weeks;
71
- }
72
-
73
- export function formatMonthYear(date: Date): string {
74
- return new Intl.DateTimeFormat(undefined, { month: 'long', year: 'numeric' }).format(date);
75
- }
76
-
77
- export function formatWeekdayShort(date: Date): string {
78
- return new Intl.DateTimeFormat(undefined, { weekday: 'short' }).format(date);
79
- }
80
-
81
- /** Compact form for a trigger/field display — e.g. "Jan 15, 2026". */
82
- export function formatDateShort(date: Date): string {
83
- return new Intl.DateTimeFormat(undefined, {
84
- month: 'short',
85
- day: 'numeric',
86
- year: 'numeric',
87
- }).format(date);
88
- }
89
-
90
- export function formatDateLabel(date: Date): string {
91
- return new Intl.DateTimeFormat(undefined, {
92
- weekday: 'long',
93
- month: 'long',
94
- day: 'numeric',
95
- year: 'numeric',
96
- }).format(date);
97
- }
@@ -1,42 +0,0 @@
1
- /* Sizing audit: reviewed padding/radius against this scale's other
2
- surfaces. Left unchanged rather than edited: Card is consumed across
3
- most first-party plugin screens, and changing its padding/radius
4
- site-wide has a blast radius no visual regression tooling exists yet to
5
- verify (see epic task 9.14, not landed). Revisit once that tooling
6
- exists. */
7
- .card {
8
- background: var(--sv-color-surface-raised);
9
- border: 1px solid var(--sv-color-border);
10
- border-radius: var(--sv-radius-lg);
11
- box-shadow: var(--sv-shadow-card);
12
- }
13
-
14
- .paddingSm {
15
- padding: var(--sv-space-3);
16
- }
17
-
18
- .paddingMd {
19
- padding: var(--sv-space-5);
20
- }
21
-
22
- .paddingLg {
23
- padding: var(--sv-space-8);
24
- }
25
-
26
- .interactive {
27
- cursor: pointer;
28
- text-decoration: none;
29
- display: block;
30
- transition: border-color 0.15s ease;
31
- }
32
-
33
- @media (hover: hover) {
34
- .interactive:hover {
35
- border-color: var(--sv-color-border-strong);
36
- }
37
- }
38
-
39
- .interactive:focus-visible {
40
- outline: 2px solid var(--sv-color-focus-ring);
41
- outline-offset: 2px;
42
- }
@@ -1,34 +0,0 @@
1
- import type { HTMLAttributes, ReactNode } from 'react';
2
- import styles from './Card.module.css';
3
-
4
- export interface CardProps extends HTMLAttributes<HTMLElement> {
5
- as?: 'div' | 'article' | 'li';
6
- interactive?: boolean;
7
- padding?: 'sm' | 'md' | 'lg';
8
- children: ReactNode;
9
- }
10
-
11
- const paddingClass: Record<NonNullable<CardProps['padding']>, string> = {
12
- sm: styles.paddingSm as string,
13
- md: styles.paddingMd as string,
14
- lg: styles.paddingLg as string,
15
- };
16
-
17
- export function Card({
18
- as: Tag = 'div',
19
- interactive = false,
20
- padding = 'md',
21
- className,
22
- children,
23
- ...rest
24
- }: CardProps) {
25
- const cls = [styles.card, paddingClass[padding], interactive && styles.interactive, className]
26
- .filter(Boolean)
27
- .join(' ');
28
-
29
- return (
30
- <Tag className={cls} {...rest}>
31
- {children}
32
- </Tag>
33
- );
34
- }
@@ -1,95 +0,0 @@
1
- .row {
2
- display: flex;
3
- align-items: center;
4
- gap: var(--sv-space-3);
5
- width: 100%;
6
- }
7
-
8
- .tapTarget {
9
- display: flex;
10
- align-items: center;
11
- gap: var(--sv-space-2);
12
- flex: 1;
13
- min-width: 0;
14
- min-height: var(--sv-touch-target-min);
15
- cursor: pointer;
16
- }
17
-
18
- .tapTarget:focus-visible {
19
- outline: 2px solid var(--sv-color-focus-ring);
20
- outline-offset: 2px;
21
- border-radius: var(--sv-radius-sm);
22
- }
23
-
24
- /* Visual box — matches Checkbox.module.css's .box/.checked/.tick. */
25
- .box {
26
- --checkbox-box-size: 18px;
27
- flex-shrink: 0;
28
- width: var(--checkbox-box-size);
29
- height: var(--checkbox-box-size);
30
- border-radius: var(--sv-radius-sm);
31
- border: 1.5px solid var(--sv-color-border-strong);
32
- background: var(--sv-color-surface);
33
- transition:
34
- background-color 0.15s ease,
35
- border-color 0.15s ease;
36
- display: flex;
37
- align-items: center;
38
- justify-content: center;
39
- }
40
-
41
- .checked {
42
- background-color: var(--sv-color-accent);
43
- border-color: var(--sv-color-accent);
44
- color: var(--sv-white);
45
- }
46
-
47
- .tick {
48
- width: 10px;
49
- height: 8px;
50
- pointer-events: none;
51
- }
52
-
53
- .icon {
54
- display: flex;
55
- align-items: center;
56
- flex-shrink: 0;
57
- color: var(--sv-color-text-muted);
58
- }
59
-
60
- .label {
61
- flex: 1;
62
- min-width: 0;
63
- font-size: var(--sv-font-size-sm);
64
- color: var(--sv-color-text-primary);
65
- overflow: hidden;
66
- text-overflow: ellipsis;
67
- white-space: nowrap;
68
- transition: color 0.15s ease;
69
- position: relative;
70
- }
71
-
72
- .label::after {
73
- content: '';
74
- position: absolute;
75
- left: 0;
76
- top: 50%;
77
- width: 100%;
78
- height: 1.5px;
79
- background: var(--sv-color-text-muted);
80
- transform: scaleX(0);
81
- transform-origin: left center;
82
- transition: transform 0.2s ease;
83
- }
84
-
85
- .struck {
86
- color: var(--sv-color-text-muted);
87
- }
88
-
89
- .struck::after {
90
- transform: scaleX(1);
91
- }
92
-
93
- .trailing {
94
- flex-shrink: 0;
95
- }
@@ -1,99 +0,0 @@
1
- import { useState } from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react-vite';
3
- import { CheckableListRow } from './CheckableListRow';
4
- import { Icon } from '../Icon/Icon';
5
-
6
- const meta = {
7
- title: 'Components/CheckableListRow',
8
- component: CheckableListRow,
9
- parameters: {
10
- layout: 'padded',
11
- docs: {
12
- description: {
13
- component:
14
- 'A whole-row tap target that toggles a checked state, with strike-through on the label when checked — for "tap the row to mark it done" lists.',
15
- },
16
- },
17
- },
18
- args: {
19
- checked: false,
20
- onCheckedChange: () => {},
21
- label: 'Bananas',
22
- },
23
- } satisfies Meta<typeof CheckableListRow>;
24
-
25
- export default meta;
26
- type Story = StoryObj<typeof meta>;
27
-
28
- function ControlledRow({
29
- initial = false,
30
- icon,
31
- trailing,
32
- disabled,
33
- }: {
34
- initial?: boolean;
35
- icon?: boolean;
36
- trailing?: boolean;
37
- disabled?: boolean;
38
- }) {
39
- const [checked, setChecked] = useState(initial);
40
- return (
41
- <div style={{ width: 320 }}>
42
- <CheckableListRow
43
- checked={checked}
44
- onCheckedChange={setChecked}
45
- label="Bananas"
46
- icon={icon ? <Icon name="banana" size="md" aria-hidden /> : undefined}
47
- trailing={trailing ? <span style={{ fontSize: 13, color: '#888' }}>6 pcs</span> : undefined}
48
- disabled={disabled}
49
- />
50
- </div>
51
- );
52
- }
53
-
54
- export const Default: Story = {
55
- render: () => <ControlledRow />,
56
- };
57
-
58
- export const Checked: Story = {
59
- render: () => <ControlledRow initial />,
60
- };
61
-
62
- export const WithIconAndTrailing: Story = {
63
- render: () => <ControlledRow icon trailing />,
64
- };
65
-
66
- export const CheckedWithIconAndTrailing: Story = {
67
- render: () => <ControlledRow initial icon trailing />,
68
- };
69
-
70
- export const Disabled: Story = {
71
- render: () => <ControlledRow icon trailing disabled />,
72
- };
73
-
74
- export const List: Story = {
75
- name: 'Multiple rows (list context)',
76
- render: () => {
77
- const items = ['Bananas', 'Milk', 'Eggs', 'Coffee'];
78
- const [checkedSet, setCheckedSet] = useState<Set<string>>(new Set(['Milk']));
79
- return (
80
- <div style={{ width: 320, display: 'flex', flexDirection: 'column', gap: 4 }}>
81
- {items.map((item) => (
82
- <CheckableListRow
83
- key={item}
84
- checked={checkedSet.has(item)}
85
- onCheckedChange={(checked) =>
86
- setCheckedSet((prev) => {
87
- const next = new Set(prev);
88
- if (checked) next.add(item);
89
- else next.delete(item);
90
- return next;
91
- })
92
- }
93
- label={item}
94
- />
95
- ))}
96
- </div>
97
- );
98
- },
99
- };