@sovereignfs/ui 0.83.1 → 0.89.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (556) hide show
  1. package/LICENSE +373 -661
  2. package/NOTICE +8 -0
  3. package/README.md +4 -6
  4. package/dist/AppsLauncher.module.css +6 -0
  5. package/dist/Button.module.css +5 -0
  6. package/dist/Card.module.css +6 -0
  7. package/dist/CardTile.module.css +6 -0
  8. package/dist/CheckableListRow.module.css +8 -0
  9. package/dist/Checkbox.module.css +8 -0
  10. package/dist/CodeTextarea.module.css +6 -0
  11. package/dist/ColorPicker.module.css +6 -0
  12. package/dist/Combobox.module.css +6 -0
  13. package/dist/Command.module.css +6 -0
  14. package/dist/ConfirmDialog.module.css +6 -0
  15. package/dist/DatePicker.module.css +6 -0
  16. package/dist/Dialog.module.css +1 -1
  17. package/dist/DragHandleRow.module.css +6 -0
  18. package/dist/FileDropzone.module.css +25 -1
  19. package/dist/Header.module.css +6 -0
  20. package/dist/IconPicker.module.css +14 -4
  21. package/dist/Input.module.css +6 -0
  22. package/dist/LegalLinks.module.css +9 -2
  23. package/dist/Markdown.module.css +5 -0
  24. package/dist/Message.module.css +9 -0
  25. package/dist/MobileAppsDrawer.module.css +9 -5
  26. package/dist/MobileFooter.module.css +6 -0
  27. package/dist/NavList.module.css +11 -2
  28. package/dist/NavTabs.module.css +7 -1
  29. package/dist/NotificationsPanel.module.css +10 -0
  30. package/dist/QrCode.module.css +17 -0
  31. package/dist/QuantityStepper.module.css +4 -2
  32. package/dist/RadioGroup.module.css +6 -0
  33. package/dist/SegmentedControl.module.css +6 -0
  34. package/dist/Select.module.css +6 -0
  35. package/dist/Sheet.module.css +16 -1
  36. package/dist/SplitPane.module.css +1 -1
  37. package/dist/StepStrip.module.css +5 -3
  38. package/dist/SuggestionInput.module.css +12 -1
  39. package/dist/SwipableMobileCarouselDots.module.css +6 -0
  40. package/dist/SystemBanner.module.css +6 -0
  41. package/dist/Tabs.module.css +6 -0
  42. package/dist/TagInput.module.css +6 -0
  43. package/dist/Textarea.module.css +6 -0
  44. package/dist/Toast.module.css +5 -0
  45. package/dist/Toggle.module.css +7 -0
  46. package/dist/Tooltip.module.css +6 -0
  47. package/dist/UserMenu.module.css +5 -0
  48. package/dist/fonts/OFL.txt +93 -0
  49. package/dist/fonts/hanken-grotesk-cyrillic-ext-wght-normal.woff2 +0 -0
  50. package/dist/fonts/hanken-grotesk-latin-ext-wght-normal.woff2 +0 -0
  51. package/dist/fonts/hanken-grotesk-latin-wght-normal.woff2 +0 -0
  52. package/dist/fonts/hanken-grotesk-vietnamese-wght-normal.woff2 +0 -0
  53. package/dist/index.d.ts +121 -43
  54. package/dist/index.js +1410 -1152
  55. package/dist/tokens/fonts.css +53 -0
  56. package/dist/tokens/primitives.css +12 -12
  57. package/dist/tokens.css +2 -1
  58. package/package.json +24 -13
  59. package/src/__tests__/motion.test.tsx +0 -105
  60. package/src/__tests__/package-json.test.ts +0 -8
  61. package/src/components/Accordion/Accordion.module.css +0 -3
  62. package/src/components/Accordion/Accordion.stories.tsx +0 -110
  63. package/src/components/Accordion/Accordion.tsx +0 -53
  64. package/src/components/Accordion/__tests__/Accordion.test.tsx +0 -61
  65. package/src/components/Alert/Alert.module.css +0 -62
  66. package/src/components/Alert/Alert.stories.tsx +0 -96
  67. package/src/components/Alert/Alert.tsx +0 -58
  68. package/src/components/Alert/__tests__/Alert.test.tsx +0 -75
  69. package/src/components/AppsLauncher/AppsLauncher.module.css +0 -96
  70. package/src/components/AppsLauncher/AppsLauncher.stories.tsx +0 -58
  71. package/src/components/AppsLauncher/AppsLauncher.tsx +0 -117
  72. package/src/components/AppsLauncher/__tests__/AppsLauncher.test.tsx +0 -52
  73. package/src/components/AspectRatio/AspectRatio.module.css +0 -15
  74. package/src/components/AspectRatio/AspectRatio.stories.tsx +0 -78
  75. package/src/components/AspectRatio/AspectRatio.tsx +0 -21
  76. package/src/components/AspectRatio/__tests__/AspectRatio.test.tsx +0 -27
  77. package/src/components/Avatar/Avatar.module.css +0 -38
  78. package/src/components/Avatar/Avatar.tsx +0 -42
  79. package/src/components/Badge/Badge.module.css +0 -177
  80. package/src/components/Badge/Badge.stories.tsx +0 -238
  81. package/src/components/Badge/Badge.tsx +0 -84
  82. package/src/components/Badge/__tests__/Badge.test.tsx +0 -90
  83. package/src/components/BalanceChip/BalanceChip.module.css +0 -32
  84. package/src/components/BalanceChip/BalanceChip.stories.tsx +0 -45
  85. package/src/components/BalanceChip/BalanceChip.tsx +0 -33
  86. package/src/components/Breadcrumb/Breadcrumb.module.css +0 -49
  87. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +0 -47
  88. package/src/components/Breadcrumb/Breadcrumb.tsx +0 -57
  89. package/src/components/Breadcrumb/__tests__/Breadcrumb.test.tsx +0 -52
  90. package/src/components/Button/Button.module.css +0 -169
  91. package/src/components/Button/Button.stories.tsx +0 -83
  92. package/src/components/Button/Button.tsx +0 -52
  93. package/src/components/Button/__tests__/Button.test.tsx +0 -66
  94. package/src/components/ButtonGroup/ButtonGroup.module.css +0 -29
  95. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +0 -57
  96. package/src/components/ButtonGroup/ButtonGroup.tsx +0 -27
  97. package/src/components/ButtonGroup/__tests__/ButtonGroup.test.tsx +0 -29
  98. package/src/components/Calendar/Calendar.module.css +0 -126
  99. package/src/components/Calendar/Calendar.tsx +0 -213
  100. package/src/components/Calendar/__tests__/Calendar.test.tsx +0 -98
  101. package/src/components/Calendar/dateUtils.ts +0 -97
  102. package/src/components/Card/Card.module.css +0 -42
  103. package/src/components/Card/Card.tsx +0 -34
  104. package/src/components/CardTile/CardTile.module.css +0 -181
  105. package/src/components/CardTile/CardTile.stories.tsx +0 -86
  106. package/src/components/CardTile/CardTile.tsx +0 -128
  107. package/src/components/CardTile/__tests__/CardTile.test.tsx +0 -56
  108. package/src/components/CheckableListRow/CheckableListRow.module.css +0 -95
  109. package/src/components/CheckableListRow/CheckableListRow.stories.tsx +0 -99
  110. package/src/components/CheckableListRow/CheckableListRow.tsx +0 -89
  111. package/src/components/Checkbox/Checkbox.module.css +0 -111
  112. package/src/components/Checkbox/Checkbox.tsx +0 -78
  113. package/src/components/CodeTextarea/CodeTextarea.module.css +0 -53
  114. package/src/components/CodeTextarea/CodeTextarea.stories.tsx +0 -77
  115. package/src/components/CodeTextarea/CodeTextarea.tsx +0 -36
  116. package/src/components/Collapsible/Collapsible.module.css +0 -70
  117. package/src/components/Collapsible/Collapsible.stories.tsx +0 -62
  118. package/src/components/Collapsible/Collapsible.tsx +0 -66
  119. package/src/components/Collapsible/__tests__/Collapsible.test.tsx +0 -71
  120. package/src/components/ColorPicker/ColorPicker.module.css +0 -132
  121. package/src/components/ColorPicker/ColorPicker.stories.tsx +0 -80
  122. package/src/components/ColorPicker/ColorPicker.tsx +0 -157
  123. package/src/components/ColorPicker/__tests__/ColorPicker.test.tsx +0 -117
  124. package/src/components/Combobox/Combobox.module.css +0 -122
  125. package/src/components/Combobox/Combobox.stories.tsx +0 -79
  126. package/src/components/Combobox/Combobox.tsx +0 -186
  127. package/src/components/Combobox/__tests__/Combobox.test.tsx +0 -158
  128. package/src/components/Command/Command.module.css +0 -80
  129. package/src/components/Command/Command.stories.tsx +0 -104
  130. package/src/components/Command/Command.tsx +0 -168
  131. package/src/components/Command/__tests__/Command.test.tsx +0 -162
  132. package/src/components/ConfirmDialog/ConfirmDialog.module.css +0 -113
  133. package/src/components/ConfirmDialog/ConfirmDialog.tsx +0 -150
  134. package/src/components/ConfirmDialog/__tests__/ConfirmDialog.test.tsx +0 -214
  135. package/src/components/ConsentPrompt/ConsentPrompt.module.css +0 -21
  136. package/src/components/ConsentPrompt/ConsentPrompt.stories.tsx +0 -31
  137. package/src/components/ConsentPrompt/ConsentPrompt.tsx +0 -66
  138. package/src/components/ContextMenu/ContextMenu.stories.tsx +0 -81
  139. package/src/components/ContextMenu/ContextMenu.tsx +0 -100
  140. package/src/components/ContextMenu/__tests__/ContextMenu.test.tsx +0 -87
  141. package/src/components/CurrencyInput/CurrencyInput.stories.tsx +0 -50
  142. package/src/components/CurrencyInput/CurrencyInput.tsx +0 -60
  143. package/src/components/DataTable/DataTable.module.css +0 -28
  144. package/src/components/DataTable/DataTable.stories.tsx +0 -74
  145. package/src/components/DataTable/DataTable.tsx +0 -154
  146. package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -123
  147. package/src/components/DatePicker/DatePicker.module.css +0 -61
  148. package/src/components/DatePicker/DatePicker.tsx +0 -103
  149. package/src/components/DatePicker/__tests__/DatePicker.test.tsx +0 -89
  150. package/src/components/DeviceOnlyGate/DeviceOnlyGate.tsx +0 -58
  151. package/src/components/DeviceOnlyGate/__tests__/DeviceOnlyGate.test.tsx +0 -45
  152. package/src/components/DeviceStorageKeyGate/DeviceStorageKeyGate.tsx +0 -100
  153. package/src/components/DeviceStorageKeyGate/__tests__/DeviceStorageKeyGate.test.tsx +0 -119
  154. package/src/components/Dialog/Dialog.module.css +0 -335
  155. package/src/components/Dialog/Dialog.stories.tsx +0 -324
  156. package/src/components/Dialog/Dialog.tsx +0 -254
  157. package/src/components/Dialog/__tests__/Dialog.test.tsx +0 -318
  158. package/src/components/DragHandleRow/DragHandleRow.module.css +0 -57
  159. package/src/components/DragHandleRow/DragHandleRow.tsx +0 -42
  160. package/src/components/Drawer/Drawer.module.css +0 -121
  161. package/src/components/Drawer/Drawer.stories.tsx +0 -132
  162. package/src/components/Drawer/Drawer.tsx +0 -175
  163. package/src/components/Drawer/__tests__/Drawer.test.tsx +0 -226
  164. package/src/components/EmptyState/EmptyState.module.css +0 -27
  165. package/src/components/EmptyState/EmptyState.tsx +0 -27
  166. package/src/components/FileDropzone/FileDropzone.module.css +0 -63
  167. package/src/components/FileDropzone/FileDropzone.tsx +0 -109
  168. package/src/components/FileDropzone/__tests__/FileDropzone.test.tsx +0 -67
  169. package/src/components/FormField/FormField.module.css +0 -33
  170. package/src/components/FormField/FormField.tsx +0 -78
  171. package/src/components/FormField/__tests__/FormField.test.tsx +0 -83
  172. package/src/components/GripIcon/GripIcon.tsx +0 -27
  173. package/src/components/Header/Header.module.css +0 -62
  174. package/src/components/Header/Header.stories.tsx +0 -452
  175. package/src/components/Header/Header.tsx +0 -102
  176. package/src/components/Header/__tests__/Header.test.tsx +0 -104
  177. package/src/components/HeaderFooterLayout/HeaderFooterLayout.module.css +0 -21
  178. package/src/components/HeaderFooterLayout/HeaderFooterLayout.stories.tsx +0 -111
  179. package/src/components/HeaderFooterLayout/HeaderFooterLayout.tsx +0 -54
  180. package/src/components/HeaderFooterLayout/__tests__/HeaderFooterLayout.test.tsx +0 -58
  181. package/src/components/HoverCard/HoverCard.module.css +0 -3
  182. package/src/components/HoverCard/HoverCard.stories.tsx +0 -66
  183. package/src/components/HoverCard/HoverCard.tsx +0 -111
  184. package/src/components/HoverCard/__tests__/HoverCard.test.tsx +0 -99
  185. package/src/components/Icon/Icon.module.css +0 -27
  186. package/src/components/Icon/Icon.stories.tsx +0 -95
  187. package/src/components/Icon/Icon.tsx +0 -43
  188. package/src/components/Icon/__tests__/Icon.test.tsx +0 -40
  189. package/src/components/Icon/icons/activity.tsx +0 -20
  190. package/src/components/Icon/icons/alert-triangle.tsx +0 -22
  191. package/src/components/Icon/icons/apple.tsx +0 -21
  192. package/src/components/Icon/icons/arrow-left-right.tsx +0 -23
  193. package/src/components/Icon/icons/banana.tsx +0 -21
  194. package/src/components/Icon/icons/beef.tsx +0 -22
  195. package/src/components/Icon/icons/beer.tsx +0 -24
  196. package/src/components/Icon/icons/bell.tsx +0 -21
  197. package/src/components/Icon/icons/bold.tsx +0 -20
  198. package/src/components/Icon/icons/calendar.tsx +0 -23
  199. package/src/components/Icon/icons/candy.tsx +0 -24
  200. package/src/components/Icon/icons/carrot.tsx +0 -22
  201. package/src/components/Icon/icons/check.tsx +0 -20
  202. package/src/components/Icon/icons/chevron-down.tsx +0 -20
  203. package/src/components/Icon/icons/chevron-left.tsx +0 -20
  204. package/src/components/Icon/icons/chevron-right.tsx +0 -20
  205. package/src/components/Icon/icons/chevron-up.tsx +0 -20
  206. package/src/components/Icon/icons/circle-check.tsx +0 -21
  207. package/src/components/Icon/icons/circle-chevron-left.tsx +0 -21
  208. package/src/components/Icon/icons/circle-x.tsx +0 -22
  209. package/src/components/Icon/icons/code.tsx +0 -21
  210. package/src/components/Icon/icons/coffee.tsx +0 -23
  211. package/src/components/Icon/icons/cookie.tsx +0 -25
  212. package/src/components/Icon/icons/copy.tsx +0 -21
  213. package/src/components/Icon/icons/credit-card.tsx +0 -21
  214. package/src/components/Icon/icons/croissant.tsx +0 -24
  215. package/src/components/Icon/icons/cup-soda.tsx +0 -23
  216. package/src/components/Icon/icons/database.tsx +0 -22
  217. package/src/components/Icon/icons/download.tsx +0 -22
  218. package/src/components/Icon/icons/drumstick.tsx +0 -21
  219. package/src/components/Icon/icons/egg.tsx +0 -20
  220. package/src/components/Icon/icons/ellipsis-vertical.tsx +0 -22
  221. package/src/components/Icon/icons/external-link.tsx +0 -22
  222. package/src/components/Icon/icons/eye-off.tsx +0 -23
  223. package/src/components/Icon/icons/eye.tsx +0 -21
  224. package/src/components/Icon/icons/file-text.tsx +0 -24
  225. package/src/components/Icon/icons/file.tsx +0 -21
  226. package/src/components/Icon/icons/fish.tsx +0 -25
  227. package/src/components/Icon/icons/folder-closed.tsx +0 -21
  228. package/src/components/Icon/icons/folder-open.tsx +0 -20
  229. package/src/components/Icon/icons/folder.tsx +0 -20
  230. package/src/components/Icon/icons/folders.tsx +0 -21
  231. package/src/components/Icon/icons/grid-2x2.tsx +0 -22
  232. package/src/components/Icon/icons/hat-glasses.tsx +0 -24
  233. package/src/components/Icon/icons/history.tsx +0 -22
  234. package/src/components/Icon/icons/house.tsx +0 -21
  235. package/src/components/Icon/icons/inbox.tsx +0 -21
  236. package/src/components/Icon/icons/index.ts +0 -394
  237. package/src/components/Icon/icons/info.tsx +0 -22
  238. package/src/components/Icon/icons/italic.tsx +0 -22
  239. package/src/components/Icon/icons/layers.tsx +0 -22
  240. package/src/components/Icon/icons/layout-dashboard.tsx +0 -23
  241. package/src/components/Icon/icons/layout-grid.tsx +0 -23
  242. package/src/components/Icon/icons/link.tsx +0 -21
  243. package/src/components/Icon/icons/list-ordered.tsx +0 -25
  244. package/src/components/Icon/icons/list.tsx +0 -25
  245. package/src/components/Icon/icons/lock.tsx +0 -21
  246. package/src/components/Icon/icons/log-out.tsx +0 -22
  247. package/src/components/Icon/icons/luggage.tsx +0 -24
  248. package/src/components/Icon/icons/mail.tsx +0 -21
  249. package/src/components/Icon/icons/map-pin.tsx +0 -21
  250. package/src/components/Icon/icons/menu.tsx +0 -22
  251. package/src/components/Icon/icons/milk.tsx +0 -22
  252. package/src/components/Icon/icons/minus.tsx +0 -20
  253. package/src/components/Icon/icons/package.tsx +0 -23
  254. package/src/components/Icon/icons/paint-bucket.tsx +0 -23
  255. package/src/components/Icon/icons/panel-left.tsx +0 -21
  256. package/src/components/Icon/icons/pencil.tsx +0 -21
  257. package/src/components/Icon/icons/pin.tsx +0 -21
  258. package/src/components/Icon/icons/pizza.tsx +0 -24
  259. package/src/components/Icon/icons/plus.tsx +0 -21
  260. package/src/components/Icon/icons/rectangle-ellipsis.tsx +0 -23
  261. package/src/components/Icon/icons/refresh-cw.tsx +0 -23
  262. package/src/components/Icon/icons/rotate-ccw.tsx +0 -21
  263. package/src/components/Icon/icons/rotate-cw.tsx +0 -21
  264. package/src/components/Icon/icons/route.tsx +0 -22
  265. package/src/components/Icon/icons/salad.tsx +0 -24
  266. package/src/components/Icon/icons/search.tsx +0 -21
  267. package/src/components/Icon/icons/send.tsx +0 -21
  268. package/src/components/Icon/icons/settings.tsx +0 -21
  269. package/src/components/Icon/icons/share-2.tsx +0 -24
  270. package/src/components/Icon/icons/sheet.tsx +0 -24
  271. package/src/components/Icon/icons/shield.tsx +0 -20
  272. package/src/components/Icon/icons/shopping-basket.tsx +0 -26
  273. package/src/components/Icon/icons/sliders-horizontal.tsx +0 -28
  274. package/src/components/Icon/icons/smartphone.tsx +0 -21
  275. package/src/components/Icon/icons/snowflake.tsx +0 -31
  276. package/src/components/Icon/icons/spray-can.tsx +0 -29
  277. package/src/components/Icon/icons/square-kanban.tsx +0 -23
  278. package/src/components/Icon/icons/table.tsx +0 -23
  279. package/src/components/Icon/icons/trash-2.tsx +0 -24
  280. package/src/components/Icon/icons/upload.tsx +0 -22
  281. package/src/components/Icon/icons/user-round-plus.tsx +0 -23
  282. package/src/components/Icon/icons/user.tsx +0 -21
  283. package/src/components/Icon/icons/users.tsx +0 -23
  284. package/src/components/Icon/icons/wine.tsx +0 -23
  285. package/src/components/Icon/icons/x.tsx +0 -21
  286. package/src/components/IconPicker/IconPicker.module.css +0 -63
  287. package/src/components/IconPicker/IconPicker.stories.tsx +0 -84
  288. package/src/components/IconPicker/IconPicker.tsx +0 -90
  289. package/src/components/Input/Input.module.css +0 -52
  290. package/src/components/Input/Input.stories.tsx +0 -86
  291. package/src/components/Input/Input.tsx +0 -20
  292. package/src/components/Input/__tests__/Input.test.tsx +0 -22
  293. package/src/components/Item/Item.module.css +0 -70
  294. package/src/components/Item/Item.stories.tsx +0 -62
  295. package/src/components/Item/Item.tsx +0 -54
  296. package/src/components/Item/__tests__/Item.test.tsx +0 -39
  297. package/src/components/Kbd/Kbd.module.css +0 -14
  298. package/src/components/Kbd/Kbd.stories.tsx +0 -32
  299. package/src/components/Kbd/Kbd.tsx +0 -12
  300. package/src/components/Kbd/__tests__/Kbd.test.tsx +0 -14
  301. package/src/components/Label/Label.module.css +0 -11
  302. package/src/components/Label/Label.stories.tsx +0 -40
  303. package/src/components/Label/Label.tsx +0 -24
  304. package/src/components/Label/__tests__/Label.test.tsx +0 -32
  305. package/src/components/LegalLinks/LegalLinks.module.css +0 -24
  306. package/src/components/LegalLinks/LegalLinks.stories.tsx +0 -22
  307. package/src/components/LegalLinks/LegalLinks.tsx +0 -40
  308. package/src/components/Markdown/Markdown.module.css +0 -73
  309. package/src/components/Markdown/Markdown.stories.tsx +0 -40
  310. package/src/components/Markdown/Markdown.tsx +0 -305
  311. package/src/components/Markdown/__tests__/Markdown.test.tsx +0 -144
  312. package/src/components/Marker/Marker.module.css +0 -33
  313. package/src/components/Marker/Marker.stories.tsx +0 -39
  314. package/src/components/Marker/Marker.tsx +0 -34
  315. package/src/components/Marker/__tests__/Marker.test.tsx +0 -23
  316. package/src/components/MemberMultiSelect/MemberMultiSelect.module.css +0 -27
  317. package/src/components/MemberMultiSelect/MemberMultiSelect.stories.tsx +0 -74
  318. package/src/components/MemberMultiSelect/MemberMultiSelect.tsx +0 -67
  319. package/src/components/Menu/Menu.module.css +0 -90
  320. package/src/components/Menu/Menu.tsx +0 -209
  321. package/src/components/Menu/__tests__/Menu.test.tsx +0 -227
  322. package/src/components/Menubar/Menubar.stories.tsx +0 -52
  323. package/src/components/Menubar/Menubar.tsx +0 -42
  324. package/src/components/Menubar/__tests__/Menubar.test.tsx +0 -45
  325. package/src/components/Message/Message.module.css +0 -99
  326. package/src/components/Message/Message.stories.tsx +0 -79
  327. package/src/components/Message/Message.tsx +0 -41
  328. package/src/components/Message/__tests__/Message.test.tsx +0 -46
  329. package/src/components/MessageScroller/MessageScroller.module.css +0 -65
  330. package/src/components/MessageScroller/MessageScroller.stories.tsx +0 -84
  331. package/src/components/MessageScroller/MessageScroller.tsx +0 -84
  332. package/src/components/MessageScroller/__tests__/MessageScroller.test.tsx +0 -105
  333. package/src/components/MobileAppsDrawer/MobileAppsDrawer.module.css +0 -82
  334. package/src/components/MobileAppsDrawer/MobileAppsDrawer.tsx +0 -78
  335. package/src/components/MobileAppsDrawer/__tests__/MobileAppsDrawer.test.tsx +0 -80
  336. package/src/components/MobileFooter/MobileFooter.module.css +0 -73
  337. package/src/components/MobileFooter/MobileFooter.stories.tsx +0 -47
  338. package/src/components/MobileFooter/MobileFooter.tsx +0 -122
  339. package/src/components/MobileFooter/__tests__/MobileFooter.test.tsx +0 -129
  340. package/src/components/MobileHeader/MobileHeader.module.css +0 -76
  341. package/src/components/MobileHeader/MobileHeader.stories.tsx +0 -57
  342. package/src/components/MobileHeader/MobileHeader.tsx +0 -90
  343. package/src/components/MobileHeader/__tests__/MobileHeader.test.tsx +0 -113
  344. package/src/components/NavList/NavList.module.css +0 -130
  345. package/src/components/NavList/NavList.tsx +0 -136
  346. package/src/components/NavList/__tests__/NavList.test.tsx +0 -109
  347. package/src/components/NavTabs/NavTabs.module.css +0 -50
  348. package/src/components/NavTabs/NavTabs.tsx +0 -61
  349. package/src/components/NavigationMenu/NavigationMenu.module.css +0 -53
  350. package/src/components/NavigationMenu/NavigationMenu.stories.tsx +0 -58
  351. package/src/components/NavigationMenu/NavigationMenu.tsx +0 -125
  352. package/src/components/NavigationMenu/__tests__/NavigationMenu.test.tsx +0 -93
  353. package/src/components/NotificationsPanel/NotificationsPanel.module.css +0 -258
  354. package/src/components/NotificationsPanel/NotificationsPanel.stories.tsx +0 -61
  355. package/src/components/NotificationsPanel/NotificationsPanel.tsx +0 -187
  356. package/src/components/NotificationsPanel/__tests__/NotificationsPanel.test.tsx +0 -78
  357. package/src/components/OfflineGate/OfflineGate.tsx +0 -44
  358. package/src/components/OfflineGate/__tests__/OfflineGate.test.tsx +0 -66
  359. package/src/components/OverlayHeader/OverlayHeader.module.css +0 -98
  360. package/src/components/OverlayHeader/OverlayHeader.tsx +0 -77
  361. package/src/components/OverlayHeader/__tests__/OverlayHeader.test.tsx +0 -69
  362. package/src/components/PageContainer/PageContainer.module.css +0 -82
  363. package/src/components/PageContainer/PageContainer.tsx +0 -64
  364. package/src/components/PageContainer/__tests__/PageContainer.test.tsx +0 -70
  365. package/src/components/PageHeader/PageHeader.module.css +0 -86
  366. package/src/components/PageHeader/PageHeader.tsx +0 -176
  367. package/src/components/PageHeader/__tests__/PageHeader.test.tsx +0 -103
  368. package/src/components/PageLayout/PageLayout.module.css +0 -51
  369. package/src/components/PageLayout/PageLayout.stories.tsx +0 -73
  370. package/src/components/PageLayout/PageLayout.tsx +0 -51
  371. package/src/components/PageLayout/__tests__/PageLayout.test.tsx +0 -34
  372. package/src/components/Pagination/Pagination.module.css +0 -98
  373. package/src/components/Pagination/Pagination.stories.tsx +0 -49
  374. package/src/components/Pagination/Pagination.tsx +0 -87
  375. package/src/components/Pagination/__tests__/Pagination.test.tsx +0 -56
  376. package/src/components/Popover/Popover.module.css +0 -74
  377. package/src/components/Popover/Popover.stories.tsx +0 -357
  378. package/src/components/Popover/Popover.tsx +0 -290
  379. package/src/components/Popover/__tests__/Popover.test.tsx +0 -263
  380. package/src/components/Progress/Progress.module.css +0 -20
  381. package/src/components/Progress/Progress.stories.tsx +0 -40
  382. package/src/components/Progress/Progress.tsx +0 -35
  383. package/src/components/Progress/__tests__/Progress.test.tsx +0 -31
  384. package/src/components/QuantityStepper/QuantityStepper.module.css +0 -67
  385. package/src/components/QuantityStepper/QuantityStepper.stories.tsx +0 -79
  386. package/src/components/QuantityStepper/QuantityStepper.tsx +0 -107
  387. package/src/components/RadioGroup/RadioGroup.module.css +0 -88
  388. package/src/components/RadioGroup/RadioGroup.stories.tsx +0 -69
  389. package/src/components/RadioGroup/RadioGroup.tsx +0 -99
  390. package/src/components/RadioGroup/__tests__/RadioGroup.test.tsx +0 -59
  391. package/src/components/Resizable/Resizable.module.css +0 -70
  392. package/src/components/Resizable/Resizable.stories.tsx +0 -82
  393. package/src/components/Resizable/Resizable.tsx +0 -313
  394. package/src/components/Resizable/__tests__/Resizable.test.tsx +0 -128
  395. package/src/components/ResponsiveSurface/ResponsiveSurface.tsx +0 -24
  396. package/src/components/ResponsiveSurface/__tests__/ResponsiveSurface.test.tsx +0 -73
  397. package/src/components/RootLayout/RootLayout.module.css +0 -12
  398. package/src/components/RootLayout/RootLayout.stories.tsx +0 -125
  399. package/src/components/RootLayout/RootLayout.tsx +0 -185
  400. package/src/components/RootLayout/__tests__/RootLayout.test.tsx +0 -161
  401. package/src/components/ScrollArea/ScrollArea.module.css +0 -20
  402. package/src/components/ScrollArea/ScrollArea.stories.tsx +0 -57
  403. package/src/components/ScrollArea/ScrollArea.tsx +0 -27
  404. package/src/components/ScrollArea/__tests__/ScrollArea.test.tsx +0 -39
  405. package/src/components/SegmentedControl/SegmentedControl.module.css +0 -55
  406. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +0 -118
  407. package/src/components/SegmentedControl/SegmentedControl.tsx +0 -56
  408. package/src/components/SegmentedControl/__tests__/SegmentedControl.test.tsx +0 -63
  409. package/src/components/Select/Select.module.css +0 -82
  410. package/src/components/Select/Select.stories.tsx +0 -115
  411. package/src/components/Select/Select.tsx +0 -48
  412. package/src/components/Select/__tests__/Select.test.tsx +0 -59
  413. package/src/components/Sheet/Sheet.module.css +0 -58
  414. package/src/components/Sheet/Sheet.tsx +0 -109
  415. package/src/components/Sheet/__tests__/Sheet.test.tsx +0 -99
  416. package/src/components/Slider/Slider.module.css +0 -95
  417. package/src/components/Slider/Slider.stories.tsx +0 -64
  418. package/src/components/Slider/Slider.tsx +0 -77
  419. package/src/components/Slider/__tests__/Slider.test.tsx +0 -45
  420. package/src/components/Spinner/Spinner.module.css +0 -39
  421. package/src/components/Spinner/Spinner.tsx +0 -23
  422. package/src/components/SplitMethodSelector/SplitMethodSelector.stories.tsx +0 -33
  423. package/src/components/SplitMethodSelector/SplitMethodSelector.tsx +0 -43
  424. package/src/components/SplitPane/SplitPane.module.css +0 -85
  425. package/src/components/SplitPane/SplitPane.stories.tsx +0 -160
  426. package/src/components/SplitPane/SplitPane.tsx +0 -149
  427. package/src/components/SplitPane/__tests__/SplitPane.test.tsx +0 -51
  428. package/src/components/StatusBadge/StatusBadge.module.css +0 -59
  429. package/src/components/StatusBadge/StatusBadge.stories.tsx +0 -74
  430. package/src/components/StatusBadge/StatusBadge.tsx +0 -65
  431. package/src/components/StepStrip/StepStrip.module.css +0 -53
  432. package/src/components/StepStrip/StepStrip.tsx +0 -74
  433. package/src/components/SuggestionInput/SuggestionInput.module.css +0 -103
  434. package/src/components/SuggestionInput/SuggestionInput.stories.tsx +0 -144
  435. package/src/components/SuggestionInput/SuggestionInput.tsx +0 -207
  436. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.module.css +0 -64
  437. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.tsx +0 -243
  438. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlide.tsx +0 -35
  439. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideBody.tsx +0 -42
  440. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideFooter.tsx +0 -18
  441. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideHeader.tsx +0 -21
  442. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideParts.module.css +0 -29
  443. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarousel.test.tsx +0 -214
  444. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarouselDevGuard.test.tsx +0 -61
  445. package/src/components/SwipableMobileCarousel/context.ts +0 -13
  446. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.module.css +0 -64
  447. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.tsx +0 -73
  448. package/src/components/SwipableMobileCarouselDots/__tests__/SwipableMobileCarouselDots.test.tsx +0 -63
  449. package/src/components/SwipeStack/SwipeStack.module.css +0 -101
  450. package/src/components/SwipeStack/SwipeStack.tsx +0 -199
  451. package/src/components/SwipeStack/SwipeStackCard.tsx +0 -22
  452. package/src/components/SwipeStack/__tests__/SwipeStack.test.tsx +0 -169
  453. package/src/components/SystemBanner/SystemBanner.module.css +0 -79
  454. package/src/components/SystemBanner/SystemBanner.stories.tsx +0 -86
  455. package/src/components/SystemBanner/SystemBanner.tsx +0 -50
  456. package/src/components/SystemBanner/__tests__/SystemBanner.test.tsx +0 -50
  457. package/src/components/Table/Table.module.css +0 -45
  458. package/src/components/Table/Table.stories.tsx +0 -125
  459. package/src/components/Table/Table.tsx +0 -51
  460. package/src/components/Table/__tests__/Table.test.tsx +0 -50
  461. package/src/components/Tabs/Tabs.module.css +0 -56
  462. package/src/components/Tabs/Tabs.stories.tsx +0 -100
  463. package/src/components/Tabs/Tabs.tsx +0 -46
  464. package/src/components/Tabs/__tests__/Tabs.test.tsx +0 -45
  465. package/src/components/TagInput/TagInput.module.css +0 -141
  466. package/src/components/TagInput/TagInput.stories.tsx +0 -109
  467. package/src/components/TagInput/TagInput.tsx +0 -174
  468. package/src/components/TagInput/__tests__/TagInput.test.tsx +0 -69
  469. package/src/components/Textarea/Textarea.module.css +0 -47
  470. package/src/components/Textarea/Textarea.tsx +0 -38
  471. package/src/components/Textarea/__tests__/Textarea.test.tsx +0 -51
  472. package/src/components/ThreeColumnLayout/ThreeColumnLayout.module.css +0 -35
  473. package/src/components/ThreeColumnLayout/ThreeColumnLayout.stories.tsx +0 -152
  474. package/src/components/ThreeColumnLayout/ThreeColumnLayout.tsx +0 -87
  475. package/src/components/ThreeColumnLayout/__tests__/ThreeColumnLayout.test.tsx +0 -78
  476. package/src/components/Toast/Toast.module.css +0 -191
  477. package/src/components/Toast/Toast.stories.tsx +0 -191
  478. package/src/components/Toast/Toast.tsx +0 -139
  479. package/src/components/Toggle/Toggle.module.css +0 -57
  480. package/src/components/Toggle/Toggle.stories.tsx +0 -95
  481. package/src/components/Toggle/Toggle.tsx +0 -39
  482. package/src/components/Toggle/__tests__/Toggle.test.tsx +0 -47
  483. package/src/components/Tooltip/Tooltip.module.css +0 -56
  484. package/src/components/Tooltip/Tooltip.tsx +0 -30
  485. package/src/components/Typography/Typography.module.css +0 -47
  486. package/src/components/Typography/Typography.stories.tsx +0 -62
  487. package/src/components/Typography/Typography.tsx +0 -30
  488. package/src/components/Typography/__tests__/Typography.test.tsx +0 -34
  489. package/src/components/UserMenu/UserMenu.module.css +0 -90
  490. package/src/components/UserMenu/UserMenu.stories.tsx +0 -49
  491. package/src/components/UserMenu/UserMenu.tsx +0 -132
  492. package/src/components/UserMenu/__tests__/UserMenu.test.tsx +0 -77
  493. package/src/css-modules.d.ts +0 -4
  494. package/src/hooks/__tests__/useCarouselRouteSync.test.tsx +0 -126
  495. package/src/hooks/__tests__/useDoubleTap.test.tsx +0 -117
  496. package/src/hooks/__tests__/useIsMobile.test.tsx +0 -80
  497. package/src/hooks/__tests__/useIsOffline.test.tsx +0 -53
  498. package/src/hooks/__tests__/useLongPress.test.tsx +0 -158
  499. package/src/hooks/__tests__/useOfflineTileState.test.tsx +0 -69
  500. package/src/hooks/__tests__/usePublishShellChromeHeight.test.tsx +0 -118
  501. package/src/hooks/__tests__/useReorderSensors.test.ts +0 -26
  502. package/src/hooks/__tests__/useResponsiveLayout.test.tsx +0 -87
  503. package/src/hooks/__tests__/useSnapCarousel.test.tsx +0 -175
  504. package/src/hooks/__tests__/useSwipeReveal.test.tsx +0 -110
  505. package/src/hooks/__tests__/useSwipeStack.test.tsx +0 -155
  506. package/src/hooks/index.ts +0 -33
  507. package/src/hooks/useCarouselRouteSync.ts +0 -92
  508. package/src/hooks/useCommitOnEnterOrBlur.ts +0 -39
  509. package/src/hooks/useDoubleTap.ts +0 -91
  510. package/src/hooks/useIsMobile.ts +0 -33
  511. package/src/hooks/useIsOffline.ts +0 -41
  512. package/src/hooks/useLongPress.ts +0 -185
  513. package/src/hooks/useOfflineTileState.ts +0 -45
  514. package/src/hooks/usePublishShellChromeHeight.ts +0 -96
  515. package/src/hooks/useReorderSensors.ts +0 -88
  516. package/src/hooks/useResponsiveLayout.ts +0 -36
  517. package/src/hooks/useSnapCarousel.ts +0 -284
  518. package/src/hooks/useSwipeReveal.ts +0 -107
  519. package/src/hooks/useSwipeStack.ts +0 -235
  520. package/src/index.ts +0 -311
  521. package/src/motion.ts +0 -78
  522. package/src/overlay-shell.ts +0 -159
  523. package/src/scroll-lock.ts +0 -22
  524. package/src/stories/Avatar.stories.tsx +0 -44
  525. package/src/stories/Card.stories.tsx +0 -35
  526. package/src/stories/Checkbox.stories.tsx +0 -45
  527. package/src/stories/DesignSystemOverview.stories.tsx +0 -3793
  528. package/src/stories/DeviceOnlyGate.stories.tsx +0 -35
  529. package/src/stories/DeviceStorageKeyGate.stories.tsx +0 -57
  530. package/src/stories/DragHandleRow.stories.tsx +0 -41
  531. package/src/stories/EmptyState.stories.tsx +0 -33
  532. package/src/stories/FileDropzone.stories.tsx +0 -69
  533. package/src/stories/FormField.stories.tsx +0 -47
  534. package/src/stories/GripIcon.stories.tsx +0 -29
  535. package/src/stories/InteractionHooks.stories.tsx +0 -925
  536. package/src/stories/LayoutSystem.stories.tsx +0 -639
  537. package/src/stories/MenuEntries.stories.tsx +0 -86
  538. package/src/stories/MobilePatterns.stories.tsx +0 -1536
  539. package/src/stories/NavList.stories.tsx +0 -147
  540. package/src/stories/NavTabs.stories.tsx +0 -53
  541. package/src/stories/OfflineGate.stories.tsx +0 -42
  542. package/src/stories/PageContainer.stories.tsx +0 -82
  543. package/src/stories/PageHeader.stories.tsx +0 -95
  544. package/src/stories/ResponsiveSurface.stories.tsx +0 -47
  545. package/src/stories/Spinner.stories.tsx +0 -25
  546. package/src/stories/StepStrip.stories.tsx +0 -76
  547. package/src/stories/SwipableMobileCarousel.stories.tsx +0 -362
  548. package/src/stories/SwipeStack.stories.tsx +0 -200
  549. package/src/stories/Textarea.stories.tsx +0 -63
  550. package/src/stories/TokenGallery.stories.tsx +0 -652
  551. package/src/stories/Tooltip.stories.tsx +0 -59
  552. package/src/tokens/primitives.css +0 -168
  553. package/src/tokens/semantic.css +0 -162
  554. package/src/tokens/theme-presets.css +0 -33
  555. package/src/tokens/theme-presets.ts +0 -72
  556. package/src/tokens.css +0 -5
@@ -1,29 +0,0 @@
1
- .root {
2
- display: inline-flex;
3
- }
4
-
5
- .root > :global(button),
6
- .root > :global(a) {
7
- border-radius: 0;
8
- margin-left: -1px;
9
- }
10
-
11
- .root > :global(button):first-child,
12
- .root > :global(a):first-child {
13
- margin-left: 0;
14
- border-top-left-radius: var(--sv-radius-md);
15
- border-bottom-left-radius: var(--sv-radius-md);
16
- }
17
-
18
- .root > :global(button):last-child,
19
- .root > :global(a):last-child {
20
- border-top-right-radius: var(--sv-radius-md);
21
- border-bottom-right-radius: var(--sv-radius-md);
22
- }
23
-
24
- /* Keep the focus ring above sibling borders instead of being clipped by them. */
25
- .root > :global(button):focus-visible,
26
- .root > :global(a):focus-visible {
27
- position: relative;
28
- z-index: 1;
29
- }
@@ -1,57 +0,0 @@
1
- import { useState } from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react-vite';
3
- import { ButtonGroup } from './ButtonGroup';
4
- import { Button } from '../Button/Button';
5
-
6
- const meta = {
7
- title: 'Components/ButtonGroup',
8
- component: ButtonGroup,
9
- parameters: { layout: 'padded' },
10
- args: { children: null },
11
- } satisfies Meta<typeof ButtonGroup>;
12
-
13
- export default meta;
14
- type Story = StoryObj<typeof meta>;
15
-
16
- // ---------------------------------------------------------------------------
17
-
18
- export const Default: Story = {
19
- render: () => (
20
- <ButtonGroup aria-label="View">
21
- <Button variant="secondary" size="sm">
22
- Day
23
- </Button>
24
- <Button variant="secondary" size="sm">
25
- Week
26
- </Button>
27
- <Button variant="secondary" size="sm">
28
- Month
29
- </Button>
30
- </ButtonGroup>
31
- ),
32
- };
33
-
34
- export const WithActiveSelection: Story = {
35
- render: () => {
36
- const [view, setView] = useState<'day' | 'week' | 'month'>('week');
37
- const options: { value: typeof view; label: string }[] = [
38
- { value: 'day', label: 'Day' },
39
- { value: 'week', label: 'Week' },
40
- { value: 'month', label: 'Month' },
41
- ];
42
- return (
43
- <ButtonGroup aria-label="View">
44
- {options.map((option) => (
45
- <Button
46
- key={option.value}
47
- variant={option.value === view ? 'primary' : 'secondary'}
48
- size="sm"
49
- onClick={() => setView(option.value)}
50
- >
51
- {option.label}
52
- </Button>
53
- ))}
54
- </ButtonGroup>
55
- );
56
- },
57
- };
@@ -1,27 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import styles from './ButtonGroup.module.css';
3
-
4
- export interface ButtonGroupProps {
5
- /** Adjacent Button elements. */
6
- children: ReactNode;
7
- className?: string;
8
- 'aria-label'?: string;
9
- }
10
-
11
- /**
12
- * ButtonGroup — visually joins adjacent `Button`s into one control (shared
13
- * border, connected corners). Targets its children's rendered `<button>`/
14
- * `<a>` elements directly rather than requiring a special child component,
15
- * so it works with plain `Button`.
16
- */
17
- export function ButtonGroup({ children, className, 'aria-label': ariaLabel }: ButtonGroupProps) {
18
- return (
19
- <div
20
- role="group"
21
- aria-label={ariaLabel}
22
- className={[styles.root, className].filter(Boolean).join(' ')}
23
- >
24
- {children}
25
- </div>
26
- );
27
- }
@@ -1,29 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it } from 'vitest';
3
- import { cleanup, render, screen } from '@testing-library/react';
4
- import { ButtonGroup } from '../ButtonGroup';
5
-
6
- afterEach(cleanup);
7
-
8
- describe('ButtonGroup', () => {
9
- it('exposes a group role with the given aria-label', () => {
10
- render(
11
- <ButtonGroup aria-label="View">
12
- <button type="button">Day</button>
13
- <button type="button">Week</button>
14
- </ButtonGroup>,
15
- );
16
- expect(screen.getByRole('group', { name: 'View' })).toBeDefined();
17
- });
18
-
19
- it('renders every child button', () => {
20
- render(
21
- <ButtonGroup aria-label="View">
22
- <button type="button">Day</button>
23
- <button type="button">Week</button>
24
- <button type="button">Month</button>
25
- </ButtonGroup>,
26
- );
27
- expect(screen.getAllByRole('button').length).toBe(3);
28
- });
29
- });
@@ -1,126 +0,0 @@
1
- /* Calendar — month grid. Tokens only. Grid columns are equal-width via
2
- * `1fr` repeated 7 times rather than a fixed px size, so the component
3
- * scales cleanly inside both a Popover panel (desktop) and a full-width
4
- * Drawer sheet (mobile). */
5
-
6
- .calendar {
7
- display: flex;
8
- flex-direction: column;
9
- gap: var(--sv-space-3);
10
- font-family: var(--sv-font-family);
11
- }
12
-
13
- .header {
14
- display: flex;
15
- align-items: center;
16
- justify-content: space-between;
17
- gap: var(--sv-space-2);
18
- }
19
-
20
- .navButton {
21
- display: inline-flex;
22
- align-items: center;
23
- justify-content: center;
24
- width: var(--sv-touch-target-min, 44px);
25
- height: var(--sv-touch-target-min, 44px);
26
- flex-shrink: 0;
27
- border: none;
28
- border-radius: var(--sv-radius-md);
29
- background: transparent;
30
- color: var(--sv-color-text-muted);
31
- cursor: pointer;
32
- }
33
-
34
- @media (hover: hover) {
35
- .navButton:hover {
36
- background: var(--sv-color-surface-sunken);
37
- color: var(--sv-color-text-primary);
38
- }
39
- }
40
-
41
- .navButton:focus-visible {
42
- outline: 2px solid var(--sv-color-focus-ring);
43
- outline-offset: -2px;
44
- }
45
-
46
- .monthLabel {
47
- font-size: var(--sv-font-size-sm);
48
- font-weight: var(--sv-font-weight-semibold);
49
- color: var(--sv-color-text-primary);
50
- }
51
-
52
- .grid {
53
- display: flex;
54
- flex-direction: column;
55
- gap: var(--sv-space-1);
56
- }
57
-
58
- .weekdayRow,
59
- .week {
60
- display: grid;
61
- grid-template-columns: repeat(7, 1fr);
62
- }
63
-
64
- .weekday {
65
- display: flex;
66
- align-items: center;
67
- justify-content: center;
68
- height: var(--sv-space-6);
69
- font-size: var(--sv-font-size-xs);
70
- font-weight: var(--sv-font-weight-medium);
71
- color: var(--sv-color-text-subtle);
72
- text-transform: uppercase;
73
- }
74
-
75
- .day {
76
- display: flex;
77
- align-items: center;
78
- justify-content: center;
79
- width: 100%;
80
- /* Square-ish cell that also clears the touch-target minimum — height
81
- drives the grid's row size; width fills its 1fr column. */
82
- min-height: var(--sv-touch-target-min, 44px);
83
- border: none;
84
- border-radius: var(--sv-radius-md);
85
- background: transparent;
86
- color: var(--sv-color-text-primary);
87
- font-size: var(--sv-font-size-sm);
88
- cursor: pointer;
89
- }
90
-
91
- @media (hover: hover) {
92
- .day:hover:not(:disabled) {
93
- background: var(--sv-color-surface-sunken);
94
- }
95
- }
96
-
97
- .day:focus-visible {
98
- outline: 2px solid var(--sv-color-focus-ring);
99
- outline-offset: -2px;
100
- }
101
-
102
- .day:disabled {
103
- color: var(--sv-color-text-subtle);
104
- cursor: not-allowed;
105
- }
106
-
107
- .dayOutside {
108
- color: var(--sv-color-text-subtle);
109
- }
110
-
111
- .dayToday {
112
- font-weight: var(--sv-font-weight-semibold);
113
- box-shadow: inset 0 0 0 1px var(--sv-color-border-strong);
114
- }
115
-
116
- .daySelected,
117
- .daySelected:disabled {
118
- background: var(--sv-color-accent);
119
- color: var(--sv-color-text-on-accent);
120
- }
121
-
122
- @media (hover: hover) {
123
- .daySelected:hover:not(:disabled) {
124
- background: var(--sv-color-accent-hover);
125
- }
126
- }
@@ -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
- }