@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,56 +0,0 @@
1
- 'use client';
2
-
3
- import styles from './SegmentedControl.module.css';
4
-
5
- export interface SegmentedOption<T extends string = string> {
6
- label: string;
7
- value: T;
8
- }
9
-
10
- export interface SegmentedControlProps<T extends string = string> {
11
- value: T;
12
- onChange: (value: T) => void;
13
- options: SegmentedOption<T>[];
14
- size?: 'sm' | 'md';
15
- 'aria-label': string;
16
- }
17
-
18
- /**
19
- * SegmentedControl — pill-based 2–3 option picker for inline use in table rows
20
- * and dialogs (e.g. User / Admin / Owner role switcher).
21
- *
22
- * Renders as `<div role="radiogroup">` with `<button role="radio">` children —
23
- * correct semantics without a native `<input type="radio">` (which needs an id/name
24
- * pair and a `<form>` context to function correctly in all browsers).
25
- */
26
- export function SegmentedControl<T extends string = string>({
27
- value,
28
- onChange,
29
- options,
30
- size = 'md',
31
- 'aria-label': ariaLabel,
32
- }: SegmentedControlProps<T>) {
33
- return (
34
- <div
35
- role="radiogroup"
36
- aria-label={ariaLabel}
37
- className={[styles.track, styles[size]].join(' ')}
38
- >
39
- {options.map((opt) => {
40
- const active = opt.value === value;
41
- return (
42
- <button
43
- key={opt.value}
44
- type="button"
45
- role="radio"
46
- aria-checked={active}
47
- className={[styles.segment, active ? styles.active : styles.inactive].join(' ')}
48
- onClick={() => onChange(opt.value)}
49
- >
50
- {opt.label}
51
- </button>
52
- );
53
- })}
54
- </div>
55
- );
56
- }
@@ -1,63 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, render, screen, fireEvent } from '@testing-library/react';
4
-
5
- afterEach(cleanup);
6
- import { SegmentedControl } from '../SegmentedControl';
7
-
8
- const options = [
9
- { label: 'User', value: 'user' as const },
10
- { label: 'Admin', value: 'admin' as const },
11
- { label: 'Owner', value: 'owner' as const },
12
- ];
13
-
14
- describe('SegmentedControl', () => {
15
- it('renders all options as radio buttons', () => {
16
- render(
17
- <SegmentedControl value="user" onChange={() => {}} options={options} aria-label="Role" />,
18
- );
19
- expect(screen.getAllByRole('radio').length).toBe(3);
20
- });
21
-
22
- it('marks the active option as checked', () => {
23
- render(
24
- <SegmentedControl value="admin" onChange={() => {}} options={options} aria-label="Role" />,
25
- );
26
- expect(screen.getByRole('radio', { name: 'Admin' }).getAttribute('aria-checked')).toBe('true');
27
- expect(screen.getByRole('radio', { name: 'User' }).getAttribute('aria-checked')).toBe('false');
28
- });
29
-
30
- it('calls onChange with the selected value on click', () => {
31
- const onChange = vi.fn();
32
- render(
33
- <SegmentedControl value="user" onChange={onChange} options={options} aria-label="Role" />,
34
- );
35
- fireEvent.click(screen.getByRole('radio', { name: 'Admin' }));
36
- expect(onChange).toHaveBeenCalledWith('admin');
37
- });
38
-
39
- it('exposes a radiogroup with the given aria-label', () => {
40
- render(
41
- <SegmentedControl
42
- value="user"
43
- onChange={() => {}}
44
- options={options}
45
- aria-label="Select role"
46
- />,
47
- );
48
- expect(screen.getByRole('radiogroup', { name: 'Select role' })).toBeDefined();
49
- });
50
-
51
- it('applies size class to the track', () => {
52
- const { container } = render(
53
- <SegmentedControl
54
- value="user"
55
- onChange={() => {}}
56
- options={options}
57
- size="sm"
58
- aria-label="Role"
59
- />,
60
- );
61
- expect((container.firstChild as HTMLElement).className).toContain('sm');
62
- });
63
- });
@@ -1,82 +0,0 @@
1
- /* Wrapper provides the positioning context for the custom chevron */
2
- .wrapper {
3
- position: relative;
4
- display: block;
5
- width: 100%;
6
- }
7
-
8
- .select {
9
- display: block;
10
- width: 100%;
11
- /* 36px rendered height. Explicit height + border-box, same technique as
12
- Input. Right-pad to clear the custom chevron. */
13
- height: 36px;
14
- box-sizing: border-box;
15
- padding: 4px var(--sv-space-8) 4px var(--sv-space-3);
16
- font-family: var(--sv-font-family);
17
- font-size: var(--sv-font-size-sm);
18
- line-height: 1.5;
19
- color: var(--sv-color-text-primary);
20
- background-color: var(--sv-color-surface);
21
- border: var(--sv-border-width-hairline) solid var(--sv-color-border-strong);
22
- border-radius: var(--sv-radius-md);
23
- cursor: pointer;
24
- /* Remove native OS chevron */
25
- appearance: none;
26
- transition:
27
- border-color 0.15s ease,
28
- box-shadow 0.15s ease;
29
- }
30
-
31
- /* sm — compact for table cells and inline controls. 32px height. */
32
- .sm .select {
33
- height: 32px;
34
- padding: 2px var(--sv-space-6) 2px var(--sv-space-2);
35
- font-size: var(--sv-font-size-sm);
36
- line-height: 1.4;
37
- border-radius: var(--sv-radius-sm);
38
- }
39
-
40
- /* iOS Safari zooms the page when a <select> under 16px receives focus, exactly
41
- as it does for text inputs. Lift the default size to >=16px on touch devices;
42
- the compact `.sm` variant is for dense desktop tables and is left untouched. */
43
- @media (pointer: coarse) {
44
- .select {
45
- font-size: var(--sv-font-size-md);
46
- }
47
- }
48
-
49
- .select:focus-visible {
50
- outline: none;
51
- border-color: var(--sv-color-accent);
52
- box-shadow: 0 0 0 2px var(--sv-color-focus-ring);
53
- }
54
-
55
- .select:disabled {
56
- opacity: 0.5;
57
- cursor: not-allowed;
58
- }
59
-
60
- /* Compact size variant — reduced padding for table-cell usage */
61
- .sm .select {
62
- padding-top: var(--sv-space-1);
63
- padding-bottom: var(--sv-space-1);
64
- font-size: var(--sv-font-size-sm);
65
- }
66
-
67
- /* SVG chevron — matches the icon stroke style used across the UI */
68
- .chevron {
69
- pointer-events: none;
70
- position: absolute;
71
- right: var(--sv-space-3);
72
- top: 50%;
73
- transform: translateY(-50%);
74
- color: var(--sv-color-text-muted);
75
- flex-shrink: 0;
76
- }
77
-
78
- .sm .chevron {
79
- right: var(--sv-space-2);
80
- width: 10px;
81
- height: 10px;
82
- }
@@ -1,115 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { Select } from './Select';
3
-
4
- const meta = {
5
- title: 'Components/Select',
6
- component: Select,
7
- parameters: {
8
- layout: 'centered',
9
- docs: {
10
- description: {
11
- component:
12
- 'Styled native `<select>` — same visual language as `Input`. Preserves native picker on mobile for maximum accessibility. RSC-safe.',
13
- },
14
- },
15
- },
16
- argTypes: {
17
- disabled: { control: 'boolean' },
18
- },
19
- } satisfies Meta<typeof Select>;
20
-
21
- export default meta;
22
- type Story = StoryObj<typeof meta>;
23
-
24
- // ---------------------------------------------------------------------------
25
-
26
- export const Default: Story = {
27
- render: (_args) => (
28
- <div style={{ width: 280, fontFamily: 'var(--sv-font-family)' }}>
29
- <label
30
- htmlFor="role-select"
31
- style={{
32
- display: 'block',
33
- marginBottom: 4,
34
- fontSize: 'var(--sv-font-size-sm)',
35
- fontWeight: 'var(--sv-font-weight-medium)',
36
- color: 'var(--sv-color-text-primary)',
37
- }}
38
- >
39
- Role
40
- </label>
41
- <Select id="role-select" defaultValue="user">
42
- <option value="user">User</option>
43
- <option value="admin">Admin</option>
44
- <option value="owner">Owner</option>
45
- </Select>
46
- </div>
47
- ),
48
- };
49
-
50
- export const Disabled: Story = {
51
- render: (_args) => (
52
- <div style={{ width: 280 }}>
53
- <Select disabled defaultValue="user">
54
- <option value="user">User</option>
55
- <option value="admin">Admin</option>
56
- </Select>
57
- </div>
58
- ),
59
- };
60
-
61
- /** Form context — several fields together matching the spec layout. */
62
- export const FormContext: Story = {
63
- render: (_args) => {
64
- const fieldStyle: React.CSSProperties = {
65
- display: 'flex',
66
- flexDirection: 'column',
67
- gap: 4,
68
- };
69
- const labelStyle: React.CSSProperties = {
70
- fontSize: 'var(--sv-font-size-sm)',
71
- fontWeight: 'var(--sv-font-weight-medium)',
72
- color: 'var(--sv-color-text-primary)',
73
- fontFamily: 'var(--sv-font-family)',
74
- };
75
-
76
- return (
77
- <div style={{ width: 320, display: 'flex', flexDirection: 'column', gap: 16 }}>
78
- <div style={fieldStyle}>
79
- <label htmlFor="lang-select" style={labelStyle}>
80
- Language
81
- </label>
82
- <Select id="lang-select" defaultValue="en-us">
83
- <option value="en-us">English (US)</option>
84
- <option value="en-gb">English (UK)</option>
85
- <option value="fr">Français</option>
86
- <option value="de">Deutsch</option>
87
- <option value="ja">日本語</option>
88
- </Select>
89
- </div>
90
- <div style={fieldStyle}>
91
- <label htmlFor="tz-select" style={labelStyle}>
92
- Timezone
93
- </label>
94
- <Select id="tz-select" defaultValue="asia-colombo">
95
- <option value="asia-colombo">Asia/Colombo (UTC+5:30)</option>
96
- <option value="utc">UTC</option>
97
- <option value="america-ny">America/New_York (UTC−5)</option>
98
- <option value="europe-london">Europe/London (UTC+0)</option>
99
- </Select>
100
- </div>
101
- <div style={fieldStyle}>
102
- <label htmlFor="poll-select" style={labelStyle}>
103
- Poll interval
104
- </label>
105
- <Select id="poll-select" defaultValue="30">
106
- <option value="15">Every 15 seconds</option>
107
- <option value="30">Every 30 seconds</option>
108
- <option value="60">Every minute</option>
109
- <option value="300">Every 5 minutes</option>
110
- </Select>
111
- </div>
112
- </div>
113
- );
114
- },
115
- };
@@ -1,48 +0,0 @@
1
- import type { SelectHTMLAttributes } from 'react';
2
- import styles from './Select.module.css';
3
-
4
- export type SelectProps = Omit<SelectHTMLAttributes<HTMLSelectElement>, 'size'> & {
5
- /** 'md' (default) — standard form field height. 'sm' — compact for table cells and inline controls. */
6
- size?: 'sm' | 'md';
7
- };
8
-
9
- /**
10
- * Select — styled wrapper around the native `<select>`. Inherits the same
11
- * height, border, radius, and focus ring as `Input` for visual consistency.
12
- * Uses the native picker on mobile — no custom dropdown, maximum a11y coverage.
13
- *
14
- * RSC-safe: presentational, no hooks, forwards all native select props.
15
- *
16
- * `className` sizes the outer box (the wrapper), not the `<select>` itself —
17
- * the chevron is absolutely positioned against the wrapper, so a className
18
- * that constrains only the `<select>` (e.g. `max-width`) shrinks the select
19
- * while the wrapper (and thus the chevron) stays full width, leaving the
20
- * chevron stranded past the visible box.
21
- */
22
- export function Select({ className, size = 'md', children, ...rest }: SelectProps) {
23
- return (
24
- <div
25
- className={[styles.wrapper, size === 'sm' ? styles.sm : undefined, className]
26
- .filter(Boolean)
27
- .join(' ')}
28
- >
29
- <select className={styles.select} {...rest}>
30
- {children}
31
- </select>
32
- <svg
33
- className={styles.chevron}
34
- aria-hidden="true"
35
- width="12"
36
- height="12"
37
- viewBox="0 0 24 24"
38
- fill="none"
39
- stroke="currentColor"
40
- strokeWidth="2"
41
- strokeLinecap="round"
42
- strokeLinejoin="round"
43
- >
44
- <polyline points="6 9 12 15 18 9" />
45
- </svg>
46
- </div>
47
- );
48
- }
@@ -1,59 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, render, screen, fireEvent } from '@testing-library/react';
4
- import { Select } from '../Select';
5
-
6
- afterEach(cleanup);
7
-
8
- describe('Select', () => {
9
- it('renders a combobox', () => {
10
- render(
11
- <Select aria-label="Role">
12
- <option value="user">User</option>
13
- <option value="admin">Admin</option>
14
- </Select>,
15
- );
16
- expect(screen.getByRole('combobox', { name: 'Role' })).toBeDefined();
17
- });
18
-
19
- it('renders provided options', () => {
20
- render(
21
- <Select aria-label="Role">
22
- <option value="user">User</option>
23
- <option value="admin">Admin</option>
24
- <option value="owner">Owner</option>
25
- </Select>,
26
- );
27
- expect(screen.getAllByRole('option').length).toBe(3);
28
- });
29
-
30
- it('forwards value and onChange', () => {
31
- const onChange = vi.fn();
32
- render(
33
- <Select aria-label="Role" value="user" onChange={onChange}>
34
- <option value="user">User</option>
35
- <option value="admin">Admin</option>
36
- </Select>,
37
- );
38
- fireEvent.change(screen.getByRole('combobox'), { target: { value: 'admin' } });
39
- expect(onChange).toHaveBeenCalled();
40
- });
41
-
42
- it('is disabled when the disabled prop is set', () => {
43
- render(
44
- <Select aria-label="Role" disabled>
45
- <option value="user">User</option>
46
- </Select>,
47
- );
48
- expect((screen.getByRole('combobox') as HTMLSelectElement).disabled).toBe(true);
49
- });
50
-
51
- it('renders a decorative chevron element', () => {
52
- const { container } = render(
53
- <Select aria-label="Role">
54
- <option value="user">User</option>
55
- </Select>,
56
- );
57
- expect(container.querySelector('[aria-hidden]')).toBeDefined();
58
- });
59
- });
@@ -1,58 +0,0 @@
1
- /* Sheet — fills the same rect as a plugin's content area (between the shell's
2
- * sticky header and footer nav — see --sv-shell-header-height /
3
- * --sv-shell-footer-height, set by the platform shell or, for a plugin that
4
- * self-renders MobileHeader/MobileFooter instead (shellConfig.mobileHeader/
5
- * mobileFooter: false), by that component itself — see
6
- * usePublishShellChromeHeight), sliding in from an edge
7
- * instead of Dialog's centered box or Drawer's partial-height sheet-over-
8
- * scrim. z-index matches Dialog/Drawer's scrim so it layers consistently
9
- * with any other overlay. No scrim of its own — see the component doc
10
- * comment for why. */
11
-
12
- .panel {
13
- position: fixed;
14
- left: 0;
15
- right: 0;
16
- top: var(--sv-shell-header-height, 0);
17
- bottom: var(--sv-shell-footer-height, 0);
18
- z-index: 100;
19
- display: flex;
20
- flex-direction: column;
21
- background: var(--sv-color-surface);
22
- outline: none;
23
- transform: translateY(100%);
24
- transition: transform var(--sv-motion-duration-base) var(--sv-motion-ease-out);
25
- }
26
-
27
- .panelOpen {
28
- transform: translateY(0);
29
- }
30
-
31
- /* Opt-in top variant (slideFrom="top") — a short options/actions menu opened
32
- * from a header button reads more naturally sliding down from that button's
33
- * edge than traveling up from off-screen bottom. :not(.panelOpen) is what
34
- * lets this coexist with .panelOpen above despite equal-looking single-class
35
- * specificity elsewhere in this file: its (0,2,0) beats .panelOpen's (0,1,0)
36
- * while closed/entering/closing, and yields to it (transform: translateY(0),
37
- * same value either direction) once open. */
38
- .panelFromTop:not(.panelOpen) {
39
- transform: translateY(-100%);
40
- }
41
-
42
- /* See Dialog.module.css's identical rule for why 0.01ms rather than 0. */
43
- @media (prefers-reduced-motion: reduce) {
44
- .panel {
45
- transition-duration: 0.01ms;
46
- }
47
- }
48
-
49
- /* Always the scroll container, with or without OverlayHeader present (see
50
- * Sheet.tsx). No opinionated padding here — matches Drawer's convention of
51
- * leaving horizontal/top padding and safe-area-bottom clearance to the
52
- * content itself, since a Sheet's content shape varies far more than a
53
- * fixed-size Dialog's. */
54
- .content {
55
- flex: 1 1 auto;
56
- overflow-y: auto;
57
- overscroll-behavior: contain;
58
- }
@@ -1,109 +0,0 @@
1
- 'use client';
2
-
3
- import { type ReactNode, useRef } from 'react';
4
- import { useMountTransition, usePrefersReducedMotion } from '../../motion';
5
- import {
6
- OVERLAY_MOTION_DURATION_MS,
7
- useOverlayFocusCapture,
8
- useOverlayKeyboardTrap,
9
- useOverlayScrollLock,
10
- } from '../../overlay-shell';
11
- import { OverlayHeader } from '../OverlayHeader/OverlayHeader';
12
- import styles from './Sheet.module.css';
13
-
14
- export interface SheetProps {
15
- /** Whether the sheet is shown. When false, nothing renders. */
16
- open: boolean;
17
- /** Called on Esc, or the built-in `OverlayHeader`'s close button. There is
18
- * no scrim to tap — a Sheet replaces the content area it fills, not a
19
- * layer floating above it (see the component doc comment). */
20
- onClose: () => void;
21
- /** Accessible name for the sheet. Defaults to `title` when omitted. */
22
- 'aria-label'?: string;
23
- /** Renders a built-in `OverlayHeader` (title + close, optional back button
24
- * and trailing action). Omit when the content supplies its own header —
25
- * e.g. a form whose title doubles as an editable field. */
26
- title?: string;
27
- /** Forwarded to `OverlayHeader` — see its own `onBack` doc. Has no effect
28
- * without `title`. */
29
- onBack?: () => void;
30
- /** Forwarded to `OverlayHeader`'s trailing-action slot. Has no effect
31
- * without `title`. */
32
- headerAction?: ReactNode;
33
- /**
34
- * Which edge the panel slides in from. Defaults to `'bottom'` (detail
35
- * views, forms — content the user is reaching down into). `'top'` suits a
36
- * short options/actions menu opened from a header button near the top of
37
- * the screen, where sliding up from the bottom would travel past empty
38
- * space before reaching content that visually belongs near the trigger.
39
- */
40
- slideFrom?: 'bottom' | 'top';
41
- children: ReactNode;
42
- }
43
-
44
- /**
45
- * Sheet — a full-page overlay that replaces a plugin's content area between
46
- * the shell's fixed header and footer (RFC 0013's mobile chrome stays visible
47
- * and interactive around it), sliding in from an edge instead of centering
48
- * like `Dialog`. Promoted from the tasks plugin's `MobileFullPageOverlay`
49
- * (now the reference pattern for this component). Desktop has no equivalent
50
- * presentation — a desktop layout shows the same content inline (columns,
51
- * panes) instead of mounting a `Sheet` at all; this component is for the
52
- * mobile case specifically.
53
- *
54
- * Unlike `Dialog`/`Drawer` there is no scrim: a Sheet visually *replaces* the
55
- * region it covers rather than floating a layer above it, so there is no
56
- * "outside" to tap-dismiss. Behaviour: Esc dismisses; focus moves into the
57
- * panel on open and is restored on close; Tab is trapped within the panel;
58
- * animated open/close via the same two-phase mount as `Dialog`/`Drawer`,
59
- * respecting `prefers-reduced-motion`.
60
- */
61
- export function Sheet({
62
- open,
63
- onClose,
64
- 'aria-label': ariaLabel,
65
- title,
66
- onBack,
67
- headerAction,
68
- slideFrom = 'bottom',
69
- children,
70
- }: SheetProps) {
71
- const panelRef = useRef<HTMLDivElement>(null);
72
- const reducedMotion = usePrefersReducedMotion();
73
- const { mounted, phase } = useMountTransition(
74
- open,
75
- reducedMotion ? 0 : OVERLAY_MOTION_DURATION_MS,
76
- );
77
-
78
- useOverlayScrollLock(mounted);
79
- useOverlayFocusCapture(panelRef, mounted);
80
- useOverlayKeyboardTrap(panelRef, open, onClose);
81
-
82
- if (!mounted) return null;
83
-
84
- return (
85
- <div
86
- ref={panelRef}
87
- role="dialog"
88
- aria-modal="true"
89
- aria-label={ariaLabel ?? title}
90
- tabIndex={-1}
91
- className={[
92
- styles.panel,
93
- slideFrom === 'top' ? styles.panelFromTop : '',
94
- phase === 'open' ? styles.panelOpen : '',
95
- ]
96
- .filter(Boolean)
97
- .join(' ')}
98
- >
99
- {title && (
100
- <OverlayHeader title={title} onClose={onClose} onBack={onBack} action={headerAction} />
101
- )}
102
- {/* Content is always the scroll container — with or without a header —
103
- so a header's sibling stays fixed and any content-owned internal
104
- sticky positioning (e.g. a form's own sub-header) resolves against
105
- this same scrolling ancestor either way. */}
106
- <div className={styles.content}>{children}</div>
107
- </div>
108
- );
109
- }
@@ -1,99 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, fireEvent, render, screen } from '@testing-library/react';
4
- import { Sheet } from '../Sheet';
5
-
6
- // Sheet's exit animation reads prefers-reduced-motion via matchMedia, which
7
- // jsdom does not implement — see Dialog.test.tsx's identical setup.
8
- function installMatchMedia() {
9
- vi.stubGlobal(
10
- 'matchMedia',
11
- vi.fn().mockImplementation((query: string) => ({
12
- matches: false,
13
- media: query,
14
- addEventListener: vi.fn(),
15
- removeEventListener: vi.fn(),
16
- addListener: vi.fn(),
17
- removeListener: vi.fn(),
18
- dispatchEvent: vi.fn(),
19
- })),
20
- );
21
- }
22
-
23
- describe('Sheet', () => {
24
- beforeEach(installMatchMedia);
25
- afterEach(() => {
26
- vi.unstubAllGlobals();
27
- cleanup();
28
- });
29
-
30
- it('renders nothing when closed', () => {
31
- render(
32
- <Sheet open={false} onClose={() => {}}>
33
- Body
34
- </Sheet>,
35
- );
36
- expect(screen.queryByRole('dialog')).toBeNull();
37
- });
38
-
39
- it('renders the panel with its accessible name when open', () => {
40
- render(
41
- <Sheet open onClose={() => {}} aria-label="Task detail">
42
- Body
43
- </Sheet>,
44
- );
45
- const panel = screen.getByRole('dialog', { name: 'Task detail' });
46
- expect(panel.getAttribute('aria-modal')).toBe('true');
47
- });
48
-
49
- it('falls back to title for the accessible name when aria-label is omitted', () => {
50
- render(
51
- <Sheet open onClose={() => {}} title="Edit list">
52
- Body
53
- </Sheet>,
54
- );
55
- expect(screen.getByRole('dialog', { name: 'Edit list' })).toBeTruthy();
56
- });
57
-
58
- it('does not render OverlayHeader when title is omitted (headerless escape hatch)', () => {
59
- render(
60
- <Sheet open onClose={() => {}} aria-label="Custom">
61
- <button type="button">Own close button</button>
62
- </Sheet>,
63
- );
64
- // Only the content's own button — no OverlayHeader close button.
65
- expect(screen.getAllByRole('button')).toHaveLength(1);
66
- });
67
-
68
- it('renders OverlayHeader (title + close) when title is provided', () => {
69
- const onClose = vi.fn();
70
- render(
71
- <Sheet open onClose={onClose} title="Edit list">
72
- Body
73
- </Sheet>,
74
- );
75
- expect(screen.getByText('Edit list')).toBeTruthy();
76
- fireEvent.click(screen.getByRole('button', { name: 'Close' }));
77
- expect(onClose).toHaveBeenCalledOnce();
78
- });
79
-
80
- it('calls onClose on Escape', () => {
81
- const onClose = vi.fn();
82
- render(
83
- <Sheet open onClose={onClose} aria-label="Panel">
84
- Body
85
- </Sheet>,
86
- );
87
- fireEvent.keyDown(document, { key: 'Escape' });
88
- expect(onClose).toHaveBeenCalledOnce();
89
- });
90
-
91
- it('applies the top slide-from variant class', () => {
92
- render(
93
- <Sheet open onClose={() => {}} aria-label="Menu" slideFrom="top">
94
- Body
95
- </Sheet>,
96
- );
97
- expect(screen.getByRole('dialog').className).toMatch(/panelFromTop/);
98
- });
99
- });