@sovereignfs/ui 0.54.0 → 0.89.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (473) hide show
  1. package/LICENSE +373 -661
  2. package/NOTICE +8 -0
  3. package/README.md +4 -6
  4. package/dist/Accordion.module.css +1 -1
  5. package/dist/Alert.module.css +1 -1
  6. package/dist/AppsLauncher.module.css +102 -0
  7. package/dist/Avatar.module.css +1 -1
  8. package/dist/Badge.module.css +30 -7
  9. package/dist/BalanceChip.module.css +1 -1
  10. package/dist/Button.module.css +23 -2
  11. package/dist/Card.module.css +7 -1
  12. package/dist/CardTile.module.css +187 -0
  13. package/dist/CheckableListRow.module.css +8 -0
  14. package/dist/Checkbox.module.css +8 -0
  15. package/dist/CodeTextarea.module.css +7 -1
  16. package/dist/Collapsible.module.css +1 -1
  17. package/dist/ColorPicker.module.css +138 -0
  18. package/dist/Combobox.module.css +8 -2
  19. package/dist/Command.module.css +7 -1
  20. package/dist/ConfirmDialog.module.css +8 -2
  21. package/dist/ConsentPrompt.module.css +21 -0
  22. package/dist/DatePicker.module.css +7 -1
  23. package/dist/Dialog.module.css +130 -21
  24. package/dist/DragHandleRow.module.css +6 -0
  25. package/dist/Drawer.module.css +36 -7
  26. package/dist/FileDropzone.module.css +25 -1
  27. package/dist/Header.module.css +68 -0
  28. package/dist/HeaderFooterLayout.module.css +21 -0
  29. package/dist/IconPicker.module.css +15 -5
  30. package/dist/Input.module.css +7 -1
  31. package/dist/Kbd.module.css +1 -1
  32. package/dist/LegalLinks.module.css +9 -2
  33. package/dist/Markdown.module.css +29 -0
  34. package/dist/Menu.module.css +1 -0
  35. package/dist/Message.module.css +10 -1
  36. package/dist/MessageScroller.module.css +12 -1
  37. package/dist/MobileAppsDrawer.module.css +19 -14
  38. package/dist/MobileFooter.module.css +7 -1
  39. package/dist/MobileHeader.module.css +14 -1
  40. package/dist/NavList.module.css +139 -0
  41. package/dist/NavTabs.module.css +8 -2
  42. package/dist/NotificationsPanel.module.css +268 -0
  43. package/dist/OverlayHeader.module.css +1 -1
  44. package/dist/PageContainer.module.css +62 -0
  45. package/dist/PageHeader.module.css +54 -0
  46. package/dist/PageLayout.module.css +51 -0
  47. package/dist/Popover.module.css +1 -1
  48. package/dist/QrCode.module.css +17 -0
  49. package/dist/QuantityStepper.module.css +5 -3
  50. package/dist/RadioGroup.module.css +6 -0
  51. package/dist/Resizable.module.css +3 -3
  52. package/dist/RootLayout.module.css +12 -0
  53. package/dist/SegmentedControl.module.css +7 -1
  54. package/dist/Select.module.css +7 -1
  55. package/dist/Sheet.module.css +20 -2
  56. package/dist/SplitPane.module.css +5 -5
  57. package/dist/StatusBadge.module.css +1 -1
  58. package/dist/StepStrip.module.css +55 -0
  59. package/dist/SuggestionInput.module.css +14 -3
  60. package/dist/SwipableMobileCarousel.module.css +12 -3
  61. package/dist/SwipableMobileCarouselDots.module.css +21 -0
  62. package/dist/SwipeStack.module.css +101 -0
  63. package/dist/SystemBanner.module.css +16 -0
  64. package/dist/Table.module.css +2 -2
  65. package/dist/Tabs.module.css +7 -1
  66. package/dist/TagInput.module.css +8 -2
  67. package/dist/Textarea.module.css +15 -1
  68. package/dist/ThreeColumnLayout.module.css +35 -0
  69. package/dist/Toast.module.css +67 -3
  70. package/dist/Toggle.module.css +7 -0
  71. package/dist/Tooltip.module.css +7 -1
  72. package/dist/UserMenu.module.css +95 -0
  73. package/dist/fonts/OFL.txt +93 -0
  74. package/dist/fonts/hanken-grotesk-cyrillic-ext-wght-normal.woff2 +0 -0
  75. package/dist/fonts/hanken-grotesk-latin-ext-wght-normal.woff2 +0 -0
  76. package/dist/fonts/hanken-grotesk-latin-wght-normal.woff2 +0 -0
  77. package/dist/fonts/hanken-grotesk-vietnamese-wght-normal.woff2 +0 -0
  78. package/dist/index.d.ts +1156 -76
  79. package/dist/index.js +4223 -1513
  80. package/dist/tokens/fonts.css +53 -0
  81. package/dist/tokens/primitives.css +23 -12
  82. package/dist/tokens/semantic.css +32 -0
  83. package/dist/tokens/theme-presets.css +33 -0
  84. package/dist/tokens.css +2 -1
  85. package/package.json +46 -19
  86. package/src/__tests__/motion.test.tsx +0 -105
  87. package/src/components/Accordion/Accordion.module.css +0 -3
  88. package/src/components/Accordion/Accordion.stories.tsx +0 -110
  89. package/src/components/Accordion/Accordion.tsx +0 -53
  90. package/src/components/Accordion/__tests__/Accordion.test.tsx +0 -61
  91. package/src/components/Alert/Alert.module.css +0 -62
  92. package/src/components/Alert/Alert.stories.tsx +0 -96
  93. package/src/components/Alert/Alert.tsx +0 -58
  94. package/src/components/Alert/__tests__/Alert.test.tsx +0 -75
  95. package/src/components/AspectRatio/AspectRatio.module.css +0 -15
  96. package/src/components/AspectRatio/AspectRatio.stories.tsx +0 -78
  97. package/src/components/AspectRatio/AspectRatio.tsx +0 -21
  98. package/src/components/AspectRatio/__tests__/AspectRatio.test.tsx +0 -27
  99. package/src/components/Avatar/Avatar.module.css +0 -38
  100. package/src/components/Avatar/Avatar.tsx +0 -42
  101. package/src/components/Badge/Badge.module.css +0 -154
  102. package/src/components/Badge/Badge.stories.tsx +0 -226
  103. package/src/components/Badge/Badge.tsx +0 -81
  104. package/src/components/Badge/__tests__/Badge.test.tsx +0 -88
  105. package/src/components/BalanceChip/BalanceChip.module.css +0 -32
  106. package/src/components/BalanceChip/BalanceChip.stories.tsx +0 -45
  107. package/src/components/BalanceChip/BalanceChip.tsx +0 -33
  108. package/src/components/Breadcrumb/Breadcrumb.module.css +0 -49
  109. package/src/components/Breadcrumb/Breadcrumb.stories.tsx +0 -47
  110. package/src/components/Breadcrumb/Breadcrumb.tsx +0 -57
  111. package/src/components/Breadcrumb/__tests__/Breadcrumb.test.tsx +0 -52
  112. package/src/components/Button/Button.module.css +0 -153
  113. package/src/components/Button/Button.stories.tsx +0 -83
  114. package/src/components/Button/Button.tsx +0 -52
  115. package/src/components/Button/__tests__/Button.test.tsx +0 -66
  116. package/src/components/ButtonGroup/ButtonGroup.module.css +0 -29
  117. package/src/components/ButtonGroup/ButtonGroup.stories.tsx +0 -57
  118. package/src/components/ButtonGroup/ButtonGroup.tsx +0 -27
  119. package/src/components/ButtonGroup/__tests__/ButtonGroup.test.tsx +0 -29
  120. package/src/components/Calendar/Calendar.module.css +0 -126
  121. package/src/components/Calendar/Calendar.tsx +0 -213
  122. package/src/components/Calendar/__tests__/Calendar.test.tsx +0 -98
  123. package/src/components/Calendar/dateUtils.ts +0 -97
  124. package/src/components/Card/Card.module.css +0 -42
  125. package/src/components/Card/Card.tsx +0 -34
  126. package/src/components/CheckableListRow/CheckableListRow.module.css +0 -95
  127. package/src/components/CheckableListRow/CheckableListRow.stories.tsx +0 -99
  128. package/src/components/CheckableListRow/CheckableListRow.tsx +0 -89
  129. package/src/components/Checkbox/Checkbox.module.css +0 -111
  130. package/src/components/Checkbox/Checkbox.tsx +0 -78
  131. package/src/components/CodeTextarea/CodeTextarea.module.css +0 -53
  132. package/src/components/CodeTextarea/CodeTextarea.stories.tsx +0 -77
  133. package/src/components/CodeTextarea/CodeTextarea.tsx +0 -36
  134. package/src/components/Collapsible/Collapsible.module.css +0 -70
  135. package/src/components/Collapsible/Collapsible.stories.tsx +0 -62
  136. package/src/components/Collapsible/Collapsible.tsx +0 -66
  137. package/src/components/Collapsible/__tests__/Collapsible.test.tsx +0 -71
  138. package/src/components/Combobox/Combobox.module.css +0 -122
  139. package/src/components/Combobox/Combobox.stories.tsx +0 -79
  140. package/src/components/Combobox/Combobox.tsx +0 -186
  141. package/src/components/Combobox/__tests__/Combobox.test.tsx +0 -158
  142. package/src/components/Command/Command.module.css +0 -80
  143. package/src/components/Command/Command.stories.tsx +0 -104
  144. package/src/components/Command/Command.tsx +0 -168
  145. package/src/components/Command/__tests__/Command.test.tsx +0 -162
  146. package/src/components/ConfirmDialog/ConfirmDialog.module.css +0 -113
  147. package/src/components/ConfirmDialog/ConfirmDialog.tsx +0 -124
  148. package/src/components/ConfirmDialog/__tests__/ConfirmDialog.test.tsx +0 -146
  149. package/src/components/ContextMenu/ContextMenu.stories.tsx +0 -81
  150. package/src/components/ContextMenu/ContextMenu.tsx +0 -100
  151. package/src/components/ContextMenu/__tests__/ContextMenu.test.tsx +0 -87
  152. package/src/components/CurrencyInput/CurrencyInput.stories.tsx +0 -50
  153. package/src/components/CurrencyInput/CurrencyInput.tsx +0 -60
  154. package/src/components/DataTable/DataTable.module.css +0 -28
  155. package/src/components/DataTable/DataTable.stories.tsx +0 -74
  156. package/src/components/DataTable/DataTable.tsx +0 -154
  157. package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -123
  158. package/src/components/DatePicker/DatePicker.module.css +0 -61
  159. package/src/components/DatePicker/DatePicker.tsx +0 -103
  160. package/src/components/DatePicker/__tests__/DatePicker.test.tsx +0 -89
  161. package/src/components/DeviceOnlyGate/DeviceOnlyGate.tsx +0 -58
  162. package/src/components/DeviceOnlyGate/__tests__/DeviceOnlyGate.test.tsx +0 -45
  163. package/src/components/DeviceStorageKeyGate/DeviceStorageKeyGate.tsx +0 -100
  164. package/src/components/DeviceStorageKeyGate/__tests__/DeviceStorageKeyGate.test.tsx +0 -119
  165. package/src/components/Dialog/Dialog.module.css +0 -226
  166. package/src/components/Dialog/Dialog.stories.tsx +0 -147
  167. package/src/components/Dialog/Dialog.tsx +0 -160
  168. package/src/components/Dialog/__tests__/Dialog.test.tsx +0 -137
  169. package/src/components/DragHandleRow/DragHandleRow.module.css +0 -57
  170. package/src/components/DragHandleRow/DragHandleRow.tsx +0 -61
  171. package/src/components/Drawer/Drawer.module.css +0 -92
  172. package/src/components/Drawer/Drawer.stories.tsx +0 -132
  173. package/src/components/Drawer/Drawer.tsx +0 -176
  174. package/src/components/Drawer/__tests__/Drawer.test.tsx +0 -199
  175. package/src/components/EmptyState/EmptyState.module.css +0 -27
  176. package/src/components/EmptyState/EmptyState.tsx +0 -27
  177. package/src/components/FileDropzone/FileDropzone.module.css +0 -63
  178. package/src/components/FileDropzone/FileDropzone.tsx +0 -109
  179. package/src/components/FileDropzone/__tests__/FileDropzone.test.tsx +0 -67
  180. package/src/components/FormField/FormField.module.css +0 -33
  181. package/src/components/FormField/FormField.tsx +0 -78
  182. package/src/components/FormField/__tests__/FormField.test.tsx +0 -83
  183. package/src/components/HoverCard/HoverCard.module.css +0 -3
  184. package/src/components/HoverCard/HoverCard.stories.tsx +0 -66
  185. package/src/components/HoverCard/HoverCard.tsx +0 -111
  186. package/src/components/HoverCard/__tests__/HoverCard.test.tsx +0 -99
  187. package/src/components/Icon/Icon.module.css +0 -27
  188. package/src/components/Icon/Icon.stories.tsx +0 -95
  189. package/src/components/Icon/Icon.tsx +0 -43
  190. package/src/components/Icon/__tests__/Icon.test.tsx +0 -40
  191. package/src/components/Icon/icons/activity.tsx +0 -20
  192. package/src/components/Icon/icons/alert-triangle.tsx +0 -22
  193. package/src/components/Icon/icons/apple.tsx +0 -21
  194. package/src/components/Icon/icons/banana.tsx +0 -21
  195. package/src/components/Icon/icons/beef.tsx +0 -22
  196. package/src/components/Icon/icons/beer.tsx +0 -24
  197. package/src/components/Icon/icons/bell.tsx +0 -21
  198. package/src/components/Icon/icons/calendar.tsx +0 -23
  199. package/src/components/Icon/icons/candy.tsx +0 -24
  200. package/src/components/Icon/icons/carrot.tsx +0 -22
  201. package/src/components/Icon/icons/check.tsx +0 -20
  202. package/src/components/Icon/icons/chevron-down.tsx +0 -20
  203. package/src/components/Icon/icons/chevron-left.tsx +0 -20
  204. package/src/components/Icon/icons/chevron-right.tsx +0 -20
  205. package/src/components/Icon/icons/chevron-up.tsx +0 -20
  206. package/src/components/Icon/icons/circle-check.tsx +0 -21
  207. package/src/components/Icon/icons/circle-x.tsx +0 -22
  208. package/src/components/Icon/icons/coffee.tsx +0 -23
  209. package/src/components/Icon/icons/cookie.tsx +0 -25
  210. package/src/components/Icon/icons/croissant.tsx +0 -24
  211. package/src/components/Icon/icons/cup-soda.tsx +0 -23
  212. package/src/components/Icon/icons/drumstick.tsx +0 -21
  213. package/src/components/Icon/icons/egg.tsx +0 -20
  214. package/src/components/Icon/icons/ellipsis-vertical.tsx +0 -22
  215. package/src/components/Icon/icons/external-link.tsx +0 -22
  216. package/src/components/Icon/icons/eye-off.tsx +0 -23
  217. package/src/components/Icon/icons/eye.tsx +0 -21
  218. package/src/components/Icon/icons/file.tsx +0 -21
  219. package/src/components/Icon/icons/fish.tsx +0 -25
  220. package/src/components/Icon/icons/grid-2x2.tsx +0 -22
  221. package/src/components/Icon/icons/house.tsx +0 -21
  222. package/src/components/Icon/icons/index.ts +0 -234
  223. package/src/components/Icon/icons/info.tsx +0 -22
  224. package/src/components/Icon/icons/lock.tsx +0 -21
  225. package/src/components/Icon/icons/log-out.tsx +0 -22
  226. package/src/components/Icon/icons/mail.tsx +0 -21
  227. package/src/components/Icon/icons/menu.tsx +0 -22
  228. package/src/components/Icon/icons/milk.tsx +0 -22
  229. package/src/components/Icon/icons/package.tsx +0 -23
  230. package/src/components/Icon/icons/pencil.tsx +0 -21
  231. package/src/components/Icon/icons/pizza.tsx +0 -24
  232. package/src/components/Icon/icons/plus.tsx +0 -21
  233. package/src/components/Icon/icons/rotate-ccw.tsx +0 -21
  234. package/src/components/Icon/icons/salad.tsx +0 -24
  235. package/src/components/Icon/icons/search.tsx +0 -21
  236. package/src/components/Icon/icons/settings.tsx +0 -21
  237. package/src/components/Icon/icons/shield.tsx +0 -20
  238. package/src/components/Icon/icons/shopping-basket.tsx +0 -26
  239. package/src/components/Icon/icons/sliders-horizontal.tsx +0 -28
  240. package/src/components/Icon/icons/smartphone.tsx +0 -21
  241. package/src/components/Icon/icons/snowflake.tsx +0 -31
  242. package/src/components/Icon/icons/spray-can.tsx +0 -29
  243. package/src/components/Icon/icons/trash-2.tsx +0 -24
  244. package/src/components/Icon/icons/upload.tsx +0 -22
  245. package/src/components/Icon/icons/user.tsx +0 -21
  246. package/src/components/Icon/icons/wine.tsx +0 -23
  247. package/src/components/Icon/icons/x.tsx +0 -21
  248. package/src/components/IconPicker/IconPicker.module.css +0 -63
  249. package/src/components/IconPicker/IconPicker.stories.tsx +0 -84
  250. package/src/components/IconPicker/IconPicker.tsx +0 -90
  251. package/src/components/Input/Input.module.css +0 -52
  252. package/src/components/Input/Input.stories.tsx +0 -86
  253. package/src/components/Input/Input.tsx +0 -14
  254. package/src/components/Input/__tests__/Input.test.tsx +0 -22
  255. package/src/components/Item/Item.module.css +0 -70
  256. package/src/components/Item/Item.stories.tsx +0 -62
  257. package/src/components/Item/Item.tsx +0 -54
  258. package/src/components/Item/__tests__/Item.test.tsx +0 -39
  259. package/src/components/Kbd/Kbd.module.css +0 -14
  260. package/src/components/Kbd/Kbd.stories.tsx +0 -32
  261. package/src/components/Kbd/Kbd.tsx +0 -12
  262. package/src/components/Kbd/__tests__/Kbd.test.tsx +0 -14
  263. package/src/components/Label/Label.module.css +0 -11
  264. package/src/components/Label/Label.stories.tsx +0 -40
  265. package/src/components/Label/Label.tsx +0 -24
  266. package/src/components/Label/__tests__/Label.test.tsx +0 -32
  267. package/src/components/LegalLinks/LegalLinks.module.css +0 -24
  268. package/src/components/LegalLinks/LegalLinks.stories.tsx +0 -22
  269. package/src/components/LegalLinks/LegalLinks.tsx +0 -40
  270. package/src/components/Markdown/Markdown.module.css +0 -49
  271. package/src/components/Markdown/Markdown.stories.tsx +0 -30
  272. package/src/components/Markdown/Markdown.tsx +0 -168
  273. package/src/components/Marker/Marker.module.css +0 -33
  274. package/src/components/Marker/Marker.stories.tsx +0 -39
  275. package/src/components/Marker/Marker.tsx +0 -34
  276. package/src/components/Marker/__tests__/Marker.test.tsx +0 -23
  277. package/src/components/MemberMultiSelect/MemberMultiSelect.module.css +0 -27
  278. package/src/components/MemberMultiSelect/MemberMultiSelect.stories.tsx +0 -74
  279. package/src/components/MemberMultiSelect/MemberMultiSelect.tsx +0 -67
  280. package/src/components/Menu/Menu.module.css +0 -89
  281. package/src/components/Menu/Menu.tsx +0 -159
  282. package/src/components/Menu/__tests__/Menu.test.tsx +0 -197
  283. package/src/components/Menubar/Menubar.stories.tsx +0 -52
  284. package/src/components/Menubar/Menubar.tsx +0 -42
  285. package/src/components/Menubar/__tests__/Menubar.test.tsx +0 -45
  286. package/src/components/Message/Message.module.css +0 -99
  287. package/src/components/Message/Message.stories.tsx +0 -79
  288. package/src/components/Message/Message.tsx +0 -41
  289. package/src/components/Message/__tests__/Message.test.tsx +0 -46
  290. package/src/components/MessageScroller/MessageScroller.module.css +0 -54
  291. package/src/components/MessageScroller/MessageScroller.stories.tsx +0 -84
  292. package/src/components/MessageScroller/MessageScroller.tsx +0 -72
  293. package/src/components/MessageScroller/__tests__/MessageScroller.test.tsx +0 -105
  294. package/src/components/MobileAppsDrawer/MobileAppsDrawer.module.css +0 -81
  295. package/src/components/MobileAppsDrawer/MobileAppsDrawer.tsx +0 -78
  296. package/src/components/MobileAppsDrawer/__tests__/MobileAppsDrawer.test.tsx +0 -80
  297. package/src/components/MobileFooter/MobileFooter.module.css +0 -73
  298. package/src/components/MobileFooter/MobileFooter.stories.tsx +0 -47
  299. package/src/components/MobileFooter/MobileFooter.tsx +0 -109
  300. package/src/components/MobileFooter/__tests__/MobileFooter.test.tsx +0 -71
  301. package/src/components/MobileHeader/MobileHeader.module.css +0 -63
  302. package/src/components/MobileHeader/MobileHeader.stories.tsx +0 -57
  303. package/src/components/MobileHeader/MobileHeader.tsx +0 -77
  304. package/src/components/MobileHeader/__tests__/MobileHeader.test.tsx +0 -58
  305. package/src/components/NavTabs/NavTabs.module.css +0 -50
  306. package/src/components/NavTabs/NavTabs.tsx +0 -61
  307. package/src/components/NavigationMenu/NavigationMenu.module.css +0 -53
  308. package/src/components/NavigationMenu/NavigationMenu.stories.tsx +0 -58
  309. package/src/components/NavigationMenu/NavigationMenu.tsx +0 -125
  310. package/src/components/NavigationMenu/__tests__/NavigationMenu.test.tsx +0 -93
  311. package/src/components/OfflineGate/OfflineGate.tsx +0 -44
  312. package/src/components/OfflineGate/__tests__/OfflineGate.test.tsx +0 -66
  313. package/src/components/OverlayHeader/OverlayHeader.module.css +0 -98
  314. package/src/components/OverlayHeader/OverlayHeader.tsx +0 -62
  315. package/src/components/OverlayHeader/__tests__/OverlayHeader.test.tsx +0 -51
  316. package/src/components/PageContainer/PageContainer.module.css +0 -20
  317. package/src/components/PageContainer/PageContainer.tsx +0 -31
  318. package/src/components/PageContainer/__tests__/PageContainer.test.tsx +0 -37
  319. package/src/components/PageHeader/PageHeader.module.css +0 -32
  320. package/src/components/PageHeader/PageHeader.tsx +0 -35
  321. package/src/components/Pagination/Pagination.module.css +0 -98
  322. package/src/components/Pagination/Pagination.stories.tsx +0 -49
  323. package/src/components/Pagination/Pagination.tsx +0 -87
  324. package/src/components/Pagination/__tests__/Pagination.test.tsx +0 -56
  325. package/src/components/Popover/Popover.module.css +0 -74
  326. package/src/components/Popover/Popover.stories.tsx +0 -357
  327. package/src/components/Popover/Popover.tsx +0 -208
  328. package/src/components/Popover/__tests__/Popover.test.tsx +0 -98
  329. package/src/components/Progress/Progress.module.css +0 -20
  330. package/src/components/Progress/Progress.stories.tsx +0 -40
  331. package/src/components/Progress/Progress.tsx +0 -35
  332. package/src/components/Progress/__tests__/Progress.test.tsx +0 -31
  333. package/src/components/QuantityStepper/QuantityStepper.module.css +0 -67
  334. package/src/components/QuantityStepper/QuantityStepper.stories.tsx +0 -79
  335. package/src/components/QuantityStepper/QuantityStepper.tsx +0 -107
  336. package/src/components/RadioGroup/RadioGroup.module.css +0 -88
  337. package/src/components/RadioGroup/RadioGroup.stories.tsx +0 -69
  338. package/src/components/RadioGroup/RadioGroup.tsx +0 -99
  339. package/src/components/RadioGroup/__tests__/RadioGroup.test.tsx +0 -59
  340. package/src/components/Resizable/Resizable.module.css +0 -70
  341. package/src/components/Resizable/Resizable.stories.tsx +0 -82
  342. package/src/components/Resizable/Resizable.tsx +0 -313
  343. package/src/components/Resizable/__tests__/Resizable.test.tsx +0 -128
  344. package/src/components/ResponsiveSurface/ResponsiveSurface.tsx +0 -24
  345. package/src/components/ResponsiveSurface/__tests__/ResponsiveSurface.test.tsx +0 -73
  346. package/src/components/ScrollArea/ScrollArea.module.css +0 -20
  347. package/src/components/ScrollArea/ScrollArea.stories.tsx +0 -57
  348. package/src/components/ScrollArea/ScrollArea.tsx +0 -27
  349. package/src/components/ScrollArea/__tests__/ScrollArea.test.tsx +0 -39
  350. package/src/components/SegmentedControl/SegmentedControl.module.css +0 -55
  351. package/src/components/SegmentedControl/SegmentedControl.stories.tsx +0 -118
  352. package/src/components/SegmentedControl/SegmentedControl.tsx +0 -56
  353. package/src/components/SegmentedControl/__tests__/SegmentedControl.test.tsx +0 -63
  354. package/src/components/Select/Select.module.css +0 -82
  355. package/src/components/Select/Select.stories.tsx +0 -115
  356. package/src/components/Select/Select.tsx +0 -48
  357. package/src/components/Select/__tests__/Select.test.tsx +0 -59
  358. package/src/components/Sheet/Sheet.module.css +0 -55
  359. package/src/components/Sheet/Sheet.tsx +0 -109
  360. package/src/components/Sheet/__tests__/Sheet.test.tsx +0 -99
  361. package/src/components/Slider/Slider.module.css +0 -95
  362. package/src/components/Slider/Slider.stories.tsx +0 -64
  363. package/src/components/Slider/Slider.tsx +0 -77
  364. package/src/components/Slider/__tests__/Slider.test.tsx +0 -45
  365. package/src/components/Spinner/Spinner.module.css +0 -39
  366. package/src/components/Spinner/Spinner.tsx +0 -23
  367. package/src/components/SplitMethodSelector/SplitMethodSelector.stories.tsx +0 -33
  368. package/src/components/SplitMethodSelector/SplitMethodSelector.tsx +0 -43
  369. package/src/components/SplitPane/SplitPane.module.css +0 -85
  370. package/src/components/SplitPane/SplitPane.stories.tsx +0 -160
  371. package/src/components/SplitPane/SplitPane.tsx +0 -149
  372. package/src/components/SplitPane/__tests__/SplitPane.test.tsx +0 -51
  373. package/src/components/StatusBadge/StatusBadge.module.css +0 -59
  374. package/src/components/StatusBadge/StatusBadge.stories.tsx +0 -74
  375. package/src/components/StatusBadge/StatusBadge.tsx +0 -65
  376. package/src/components/SuggestionInput/SuggestionInput.module.css +0 -103
  377. package/src/components/SuggestionInput/SuggestionInput.stories.tsx +0 -144
  378. package/src/components/SuggestionInput/SuggestionInput.tsx +0 -207
  379. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.module.css +0 -55
  380. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.tsx +0 -227
  381. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlide.tsx +0 -35
  382. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideBody.tsx +0 -42
  383. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideFooter.tsx +0 -18
  384. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideHeader.tsx +0 -21
  385. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideParts.module.css +0 -29
  386. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarousel.test.tsx +0 -133
  387. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarouselDevGuard.test.tsx +0 -61
  388. package/src/components/SwipableMobileCarousel/context.ts +0 -13
  389. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.module.css +0 -49
  390. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.tsx +0 -62
  391. package/src/components/SwipableMobileCarouselDots/__tests__/SwipableMobileCarouselDots.test.tsx +0 -63
  392. package/src/components/SystemBanner/SystemBanner.module.css +0 -69
  393. package/src/components/SystemBanner/SystemBanner.stories.tsx +0 -86
  394. package/src/components/SystemBanner/SystemBanner.tsx +0 -50
  395. package/src/components/SystemBanner/__tests__/SystemBanner.test.tsx +0 -50
  396. package/src/components/Table/Table.module.css +0 -45
  397. package/src/components/Table/Table.stories.tsx +0 -125
  398. package/src/components/Table/Table.tsx +0 -51
  399. package/src/components/Table/__tests__/Table.test.tsx +0 -50
  400. package/src/components/Tabs/Tabs.module.css +0 -56
  401. package/src/components/Tabs/Tabs.stories.tsx +0 -100
  402. package/src/components/Tabs/Tabs.tsx +0 -46
  403. package/src/components/Tabs/__tests__/Tabs.test.tsx +0 -45
  404. package/src/components/TagInput/TagInput.module.css +0 -141
  405. package/src/components/TagInput/TagInput.stories.tsx +0 -109
  406. package/src/components/TagInput/TagInput.tsx +0 -174
  407. package/src/components/TagInput/__tests__/TagInput.test.tsx +0 -69
  408. package/src/components/Textarea/Textarea.module.css +0 -39
  409. package/src/components/Textarea/Textarea.tsx +0 -15
  410. package/src/components/Textarea/__tests__/Textarea.test.tsx +0 -29
  411. package/src/components/Toast/Toast.module.css +0 -132
  412. package/src/components/Toast/Toast.stories.tsx +0 -191
  413. package/src/components/Toast/Toast.tsx +0 -139
  414. package/src/components/Toggle/Toggle.module.css +0 -57
  415. package/src/components/Toggle/Toggle.stories.tsx +0 -95
  416. package/src/components/Toggle/Toggle.tsx +0 -39
  417. package/src/components/Toggle/__tests__/Toggle.test.tsx +0 -47
  418. package/src/components/Tooltip/Tooltip.module.css +0 -56
  419. package/src/components/Tooltip/Tooltip.tsx +0 -30
  420. package/src/components/Typography/Typography.module.css +0 -47
  421. package/src/components/Typography/Typography.stories.tsx +0 -62
  422. package/src/components/Typography/Typography.tsx +0 -30
  423. package/src/components/Typography/__tests__/Typography.test.tsx +0 -34
  424. package/src/css-modules.d.ts +0 -4
  425. package/src/hooks/__tests__/useCarouselRouteSync.test.tsx +0 -126
  426. package/src/hooks/__tests__/useDoubleTap.test.tsx +0 -117
  427. package/src/hooks/__tests__/useIsMobile.test.tsx +0 -80
  428. package/src/hooks/__tests__/useIsOffline.test.tsx +0 -53
  429. package/src/hooks/__tests__/useLongPress.test.tsx +0 -158
  430. package/src/hooks/__tests__/useOfflineTileState.test.tsx +0 -69
  431. package/src/hooks/__tests__/useResponsiveLayout.test.tsx +0 -87
  432. package/src/hooks/__tests__/useSnapCarousel.test.tsx +0 -93
  433. package/src/hooks/__tests__/useSwipeReveal.test.tsx +0 -110
  434. package/src/hooks/index.ts +0 -24
  435. package/src/hooks/useCarouselRouteSync.ts +0 -92
  436. package/src/hooks/useCommitOnEnterOrBlur.ts +0 -39
  437. package/src/hooks/useDoubleTap.ts +0 -91
  438. package/src/hooks/useIsMobile.ts +0 -33
  439. package/src/hooks/useIsOffline.ts +0 -41
  440. package/src/hooks/useLongPress.ts +0 -185
  441. package/src/hooks/useOfflineTileState.ts +0 -45
  442. package/src/hooks/useResponsiveLayout.ts +0 -36
  443. package/src/hooks/useSnapCarousel.ts +0 -79
  444. package/src/hooks/useSwipeReveal.ts +0 -107
  445. package/src/index.ts +0 -251
  446. package/src/motion.ts +0 -78
  447. package/src/overlay-shell.ts +0 -94
  448. package/src/scroll-lock.ts +0 -22
  449. package/src/stories/Avatar.stories.tsx +0 -44
  450. package/src/stories/Card.stories.tsx +0 -35
  451. package/src/stories/Checkbox.stories.tsx +0 -45
  452. package/src/stories/DesignSystemOverview.stories.tsx +0 -3187
  453. package/src/stories/DeviceOnlyGate.stories.tsx +0 -35
  454. package/src/stories/DeviceStorageKeyGate.stories.tsx +0 -57
  455. package/src/stories/DragHandleRow.stories.tsx +0 -41
  456. package/src/stories/EmptyState.stories.tsx +0 -33
  457. package/src/stories/FileDropzone.stories.tsx +0 -69
  458. package/src/stories/FormField.stories.tsx +0 -47
  459. package/src/stories/InteractionHooks.stories.tsx +0 -925
  460. package/src/stories/MobilePatterns.stories.tsx +0 -1536
  461. package/src/stories/NavTabs.stories.tsx +0 -53
  462. package/src/stories/OfflineGate.stories.tsx +0 -42
  463. package/src/stories/PageContainer.stories.tsx +0 -37
  464. package/src/stories/PageHeader.stories.tsx +0 -42
  465. package/src/stories/ResponsiveSurface.stories.tsx +0 -47
  466. package/src/stories/Spinner.stories.tsx +0 -25
  467. package/src/stories/SwipableMobileCarousel.stories.tsx +0 -304
  468. package/src/stories/Textarea.stories.tsx +0 -51
  469. package/src/stories/TokenGallery.stories.tsx +0 -602
  470. package/src/stories/Tooltip.stories.tsx +0 -59
  471. package/src/tokens/primitives.css +0 -157
  472. package/src/tokens/semantic.css +0 -130
  473. package/src/tokens.css +0 -5
@@ -1,168 +0,0 @@
1
- import type { ReactNode } from 'react';
2
- import { Typography } from '../Typography/Typography';
3
- import styles from './Markdown.module.css';
4
-
5
- export interface MarkdownProps {
6
- /** Raw markdown source. Supports the subset used by Sovereign's own
7
- * long-form content pages: headings (#/##/###), paragraphs, **bold**,
8
- * *italic*, `code`, [links](url), unordered lists (-), and blockquotes
9
- * (>), including soft-wrapped continuation lines within a paragraph or
10
- * list item. Not a general-purpose CommonMark parser — no tables,
11
- * images, ordered lists, or nested blocks. */
12
- content: string;
13
- className?: string;
14
- }
15
-
16
- let inlineKey = 0;
17
-
18
- /** Parses **bold**, *italic*, `code`, and [text](url) within a line of text. */
19
- function parseInline(text: string): ReactNode[] {
20
- const nodes: ReactNode[] = [];
21
- const pattern = /\[([^\]]+)\]\(([^)]+)\)|\*\*([^*]+)\*\*|\*([^*]+)\*|`([^`]+)`/;
22
- let remaining = text;
23
-
24
- while (remaining.length > 0) {
25
- const match = pattern.exec(remaining);
26
- if (!match) {
27
- nodes.push(remaining);
28
- break;
29
- }
30
- if (match.index > 0) nodes.push(remaining.slice(0, match.index));
31
-
32
- const [full, linkText, linkHref, boldText, italicText, codeText] = match;
33
- const key = `md-inline-${inlineKey++}`;
34
- if (linkHref !== undefined) {
35
- nodes.push(
36
- <a key={key} href={linkHref}>
37
- {linkText}
38
- </a>,
39
- );
40
- } else if (boldText !== undefined) {
41
- nodes.push(<strong key={key}>{boldText}</strong>);
42
- } else if (italicText !== undefined) {
43
- nodes.push(<em key={key}>{italicText}</em>);
44
- } else if (codeText !== undefined) {
45
- nodes.push(<code key={key}>{codeText}</code>);
46
- }
47
- remaining = remaining.slice(match.index + full.length);
48
- }
49
-
50
- return nodes;
51
- }
52
-
53
- const isQuote = (l: string) => l.startsWith('> ') || l === '>';
54
- const isListItem = (l: string) => l.startsWith('- ');
55
- const isHeading = (l: string) => /^#{1,3}\s+/.test(l);
56
- /** A line that ends the current *paragraph* run — a blank line, or the
57
- * start of a heading, quote, or list block. Anything else (including an
58
- * indented continuation line) is folded into the paragraph, matching how
59
- * the source markdown soft-wraps prose across lines. */
60
- const endsParagraph = (l: string) => l.trim() === '' || isHeading(l) || isQuote(l) || isListItem(l);
61
- /** A line that ends the current *list* run — a blank line, or the start of
62
- * a heading or quote. Deliberately does NOT include `isListItem`: a list
63
- * item's own opening line legitimately satisfies `isListItem`, so reusing
64
- * `endsParagraph` here (which does) would treat the first line of every
65
- * list as ending the list before it started — the list-collection loop
66
- * would then never advance, looping forever. */
67
- const endsList = (l: string) => l.trim() === '' || isHeading(l) || isQuote(l);
68
-
69
- function parseBlocks(content: string): ReactNode[] {
70
- const lines = content.replace(/\r\n/g, '\n').split('\n');
71
- const blocks: ReactNode[] = [];
72
- let i = 0;
73
- let blockKey = 0;
74
-
75
- while (i < lines.length) {
76
- const line = lines[i] ?? '';
77
-
78
- if (line.trim() === '') {
79
- i++;
80
- continue;
81
- }
82
-
83
- const heading = /^(#{1,3})\s+(.*)$/.exec(line);
84
- if (heading) {
85
- const level = (heading[1]?.length ?? 1) as 1 | 2 | 3;
86
- blocks.push(
87
- <div key={blockKey++} className={styles.block} data-heading>
88
- <Typography variant={`h${level}` as 'h1' | 'h2' | 'h3'}>
89
- {parseInline(heading[2] ?? '')}
90
- </Typography>
91
- </div>,
92
- );
93
- i++;
94
- continue;
95
- }
96
-
97
- if (isQuote(line)) {
98
- const quoteLines: string[] = [];
99
- while (i < lines.length && isQuote(lines[i] ?? '')) {
100
- quoteLines.push((lines[i] ?? '').slice(2));
101
- i++;
102
- }
103
- blocks.push(
104
- <div key={blockKey++} className={styles.block}>
105
- <blockquote className={styles.blockquote}>
106
- <Typography variant="body" as="p">
107
- {parseInline(quoteLines.join(' '))}
108
- </Typography>
109
- </blockquote>
110
- </div>,
111
- );
112
- continue;
113
- }
114
-
115
- if (isListItem(line)) {
116
- const items: string[] = [];
117
- while (i < lines.length && !endsList(lines[i] ?? '')) {
118
- const current = lines[i] ?? '';
119
- if (isListItem(current)) {
120
- items.push(current.slice(2));
121
- } else {
122
- // Continuation of the previous item's wrapped text.
123
- const lastIndex = items.length - 1;
124
- items[lastIndex] = `${items[lastIndex] ?? ''} ${current.trim()}`;
125
- }
126
- i++;
127
- }
128
- blocks.push(
129
- <div key={blockKey++} className={styles.block}>
130
- <ul className={styles.list}>
131
- {items.map((item, idx) => (
132
- <Typography key={idx} variant="body" as="li">
133
- {parseInline(item)}
134
- </Typography>
135
- ))}
136
- </ul>
137
- </div>,
138
- );
139
- continue;
140
- }
141
-
142
- const paraLines: string[] = [];
143
- while (i < lines.length && !endsParagraph(lines[i] ?? '')) {
144
- paraLines.push((lines[i] ?? '').trim());
145
- i++;
146
- }
147
- blocks.push(
148
- <div key={blockKey++} className={styles.block}>
149
- <Typography variant="body" as="p">
150
- {parseInline(paraLines.join(' '))}
151
- </Typography>
152
- </div>,
153
- );
154
- }
155
-
156
- return blocks;
157
- }
158
-
159
- /** Renders a constrained markdown subset (see MarkdownProps) as styled React
160
- * elements built from Typography — no HTML string injection. Meant for
161
- * long-form, first-party content pages (privacy policy, terms of service)
162
- * sourced from a single markdown file, not for rendering arbitrary or
163
- * user-supplied markdown. */
164
- export function Markdown({ content, className }: MarkdownProps) {
165
- return (
166
- <div className={[styles.root, className].filter(Boolean).join(' ')}>{parseBlocks(content)}</div>
167
- );
168
- }
@@ -1,33 +0,0 @@
1
- .marker {
2
- display: inline-flex;
3
- align-items: center;
4
- justify-content: center;
5
- min-width: 16px;
6
- height: 16px;
7
- padding: 0 4px;
8
- margin: 0 1px;
9
- border: none;
10
- border-radius: var(--sv-radius-full);
11
- background: var(--sv-color-accent-subtle);
12
- color: var(--sv-color-accent);
13
- font-family: var(--sv-font-family);
14
- font-size: var(--sv-font-size-label);
15
- font-weight: var(--sv-font-weight-semibold);
16
- line-height: 1;
17
- vertical-align: super;
18
- }
19
-
20
- button.marker {
21
- cursor: pointer;
22
- }
23
-
24
- button.marker:focus-visible {
25
- outline: 2px solid var(--sv-color-focus-ring);
26
- outline-offset: 1px;
27
- }
28
-
29
- @media (hover: hover) {
30
- button.marker:hover {
31
- background: color-mix(in srgb, var(--sv-color-accent-subtle) 70%, var(--sv-color-accent) 30%);
32
- }
33
- }
@@ -1,39 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { Marker } from './Marker';
3
-
4
- const meta = {
5
- title: 'Components/Marker',
6
- component: Marker,
7
- parameters: {
8
- layout: 'padded',
9
- docs: {
10
- description: {
11
- component:
12
- 'Inline citation/reference marker, for attributing part of an assistant answer to a source (Sovereign Harness "source trace").',
13
- },
14
- },
15
- },
16
- args: { index: 1, label: 'Source: Notes' },
17
- } satisfies Meta<typeof Marker>;
18
-
19
- export default meta;
20
- type Story = StoryObj<typeof meta>;
21
-
22
- // ---------------------------------------------------------------------------
23
-
24
- export const Static: Story = {};
25
-
26
- export const Clickable: Story = {
27
- args: { onClick: () => {} },
28
- };
29
-
30
- export const InContext: Story = {
31
- render: () => (
32
- <p style={{ fontSize: 14, maxWidth: 400 }}>
33
- Your next task deadline is Thursday
34
- <Marker index={1} label="Source: Tasks" onClick={() => {}} />, and you have two unread
35
- messages from the team
36
- <Marker index={2} label="Source: Notes" onClick={() => {}} />.
37
- </p>
38
- ),
39
- };
@@ -1,34 +0,0 @@
1
- import styles from './Marker.module.css';
2
-
3
- export interface MarkerProps {
4
- /** The number shown in the marker, e.g. 1, 2, 3. */
5
- index: number;
6
- /** Accessible label describing the citation, e.g. "Source: Notes". */
7
- label: string;
8
- /** Reveals source details (e.g. opens a source trace panel) when given. */
9
- onClick?: () => void;
10
- className?: string;
11
- }
12
-
13
- /**
14
- * Marker — inline citation/reference marker, for attributing part of an
15
- * assistant's answer to a source (matches RFC 0040's "source trace" —
16
- * Harness shows which plugin/data source informed an answer).
17
- */
18
- export function Marker({ index, label, onClick, className }: MarkerProps) {
19
- const classes = [styles.marker, className].filter(Boolean).join(' ');
20
-
21
- if (onClick) {
22
- return (
23
- <button type="button" onClick={onClick} aria-label={label} className={classes}>
24
- {index}
25
- </button>
26
- );
27
- }
28
-
29
- return (
30
- <span aria-label={label} className={classes}>
31
- {index}
32
- </span>
33
- );
34
- }
@@ -1,23 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, describe, expect, it, vi } from 'vitest';
3
- import { cleanup, render, screen } from '@testing-library/react';
4
- import { Marker } from '../Marker';
5
-
6
- afterEach(cleanup);
7
-
8
- describe('Marker', () => {
9
- it('renders as a static span with an accessible label when no onClick is given', () => {
10
- render(<Marker index={1} label="Source: Notes" />);
11
- const el = screen.getByLabelText('Source: Notes');
12
- expect(el.tagName).toBe('SPAN');
13
- expect(el.textContent).toBe('1');
14
- });
15
-
16
- it('renders as a button and fires onClick when given', () => {
17
- const onClick = vi.fn();
18
- render(<Marker index={2} label="Source: Tasks" onClick={onClick} />);
19
- const el = screen.getByRole('button', { name: 'Source: Tasks' });
20
- el.click();
21
- expect(onClick).toHaveBeenCalled();
22
- });
23
- });
@@ -1,27 +0,0 @@
1
- .group {
2
- display: grid;
3
- gap: var(--sv-space-2);
4
- }
5
-
6
- .label {
7
- font-size: var(--sv-font-size-xs);
8
- font-weight: var(--sv-font-weight-semibold);
9
- color: var(--sv-color-text-muted);
10
- }
11
-
12
- .row {
13
- display: flex;
14
- align-items: center;
15
- justify-content: space-between;
16
- gap: var(--sv-space-2);
17
- }
18
-
19
- .trailing {
20
- flex-shrink: 0;
21
- max-width: 8rem;
22
- }
23
-
24
- .hint {
25
- font-size: var(--sv-font-size-xs);
26
- color: var(--sv-color-text-muted);
27
- }
@@ -1,74 +0,0 @@
1
- import { useState } from 'react';
2
- import type { Meta, StoryObj } from '@storybook/react-vite';
3
- import { CurrencyInput } from '../CurrencyInput/CurrencyInput';
4
- import { MemberMultiSelect, type MemberMultiSelectOption } from './MemberMultiSelect';
5
-
6
- const meta = {
7
- title: 'Components/MemberMultiSelect',
8
- component: MemberMultiSelect,
9
- parameters: {
10
- layout: 'padded',
11
- docs: {
12
- description: {
13
- component:
14
- 'Checkbox list for picking any number of people from an already-resolved set of options. Domain-agnostic about who an option represents — instance users and guest members are both just `{id, label}`, so nothing special is needed to include guests. Not a directory search or invite flow; pair with SuggestionInput for that.',
15
- },
16
- },
17
- },
18
- args: {
19
- options: [],
20
- selectedIds: new Set(),
21
- onToggle: () => {},
22
- },
23
- } satisfies Meta<typeof MemberMultiSelect>;
24
-
25
- export default meta;
26
- type Story = StoryObj<typeof meta>;
27
-
28
- const OPTIONS: MemberMultiSelectOption[] = [
29
- { id: '1', label: 'Priya' },
30
- { id: '2', label: 'Jamie (guest)' },
31
- { id: '3', label: 'Sam' },
32
- ];
33
-
34
- function ControlledMultiSelect({ withTrailing = false }: { withTrailing?: boolean }) {
35
- const [selected, setSelected] = useState<Set<string>>(new Set(['1', '3']));
36
- const [amounts, setAmounts] = useState<Record<string, number | null>>({});
37
-
38
- return (
39
- <MemberMultiSelect
40
- options={OPTIONS}
41
- selectedIds={selected}
42
- onToggle={(id, checked) => {
43
- setSelected((prev) => {
44
- const next = new Set(prev);
45
- if (checked) next.add(id);
46
- else next.delete(id);
47
- return next;
48
- });
49
- }}
50
- label="Split between"
51
- hint={withTrailing ? 'Remaining: 0.00' : undefined}
52
- renderTrailing={
53
- withTrailing
54
- ? (id) => (
55
- <CurrencyInput
56
- valueCents={amounts[id] ?? null}
57
- onValueChange={(cents) => setAmounts((prev) => ({ ...prev, [id]: cents }))}
58
- placeholder="0.00"
59
- aria-label={`Amount for ${OPTIONS.find((o) => o.id === id)?.label}`}
60
- />
61
- )
62
- : undefined
63
- }
64
- />
65
- );
66
- }
67
-
68
- export const Default: Story = {
69
- render: () => <ControlledMultiSelect />,
70
- };
71
-
72
- export const WithTrailingAmountInput: Story = {
73
- render: () => <ControlledMultiSelect withTrailing />,
74
- };
@@ -1,67 +0,0 @@
1
- 'use client';
2
-
3
- import type { ReactNode } from 'react';
4
- import { Checkbox } from '../Checkbox/Checkbox';
5
- import styles from './MemberMultiSelect.module.css';
6
-
7
- export interface MemberMultiSelectOption {
8
- id: string;
9
- label: string;
10
- }
11
-
12
- export interface MemberMultiSelectProps {
13
- options: MemberMultiSelectOption[];
14
- selectedIds: Set<string>;
15
- onToggle: (id: string, checked: boolean) => void;
16
- /** Rendered to the right of a selected row only — e.g. a per-person `CurrencyInput` or share count. */
17
- renderTrailing?: (id: string) => ReactNode;
18
- /** Section label above the list, e.g. "Paid by" or "Split between". */
19
- label?: string;
20
- /** Helper/validation text below the list, e.g. a running total. */
21
- hint?: ReactNode;
22
- className?: string;
23
- }
24
-
25
- /**
26
- * MemberMultiSelect — checkbox list for picking any number of people from an
27
- * already-resolved set of options (group/project members, collaborators,
28
- * etc.). Deliberately domain-agnostic about *who* an option represents —
29
- * instance users and guest members are both just `{id, label}` here, so
30
- * nothing special is needed to include guests alongside instance users; the
31
- * caller's `options` array is the only place that distinction exists.
32
- *
33
- * Not a directory search or an "add a new guest" flow — pair with
34
- * `SuggestionInput` (search + add) for that; this component only selects
35
- * among options already passed in.
36
- */
37
- export function MemberMultiSelect({
38
- options,
39
- selectedIds,
40
- onToggle,
41
- renderTrailing,
42
- label,
43
- hint,
44
- className,
45
- }: MemberMultiSelectProps) {
46
- return (
47
- <div className={[styles.group, className].filter(Boolean).join(' ')}>
48
- {label && <span className={styles.label}>{label}</span>}
49
- {options.map((option) => {
50
- const checked = selectedIds.has(option.id);
51
- return (
52
- <div key={option.id} className={styles.row}>
53
- <Checkbox
54
- checked={checked}
55
- onChange={(next) => onToggle(option.id, next)}
56
- label={option.label}
57
- />
58
- {checked && renderTrailing && (
59
- <span className={styles.trailing}>{renderTrailing(option.id)}</span>
60
- )}
61
- </div>
62
- );
63
- })}
64
- {hint && <span className={styles.hint}>{hint}</span>}
65
- </div>
66
- );
67
- }
@@ -1,89 +0,0 @@
1
- /* Menu — the item list shared by both presentations (Popover panel on
2
- * desktop, Drawer panel on mobile); the presentational chrome around it is
3
- * entirely owned by those two components, not duplicated here.
4
- *
5
- * Sizing audit: reviewed against this scale's other compact controls —
6
- * --sv-radius-sm (6px) and --sv-font-size-sm (14px) already fit. The 44px
7
- * min-height is a deliberate design choice, kept unconditional (not gated
8
- * to pointer:coarse like Button/Checkbox) because this menu doubles as a
9
- * full Drawer sheet on mobile, where every item must stay comfortably
10
- * tappable. */
11
-
12
- .list {
13
- list-style: none;
14
- margin: 0;
15
- padding: var(--sv-space-1);
16
- display: flex;
17
- flex-direction: column;
18
- }
19
-
20
- .item {
21
- display: flex;
22
- align-items: center;
23
- gap: var(--sv-space-2);
24
- width: 100%;
25
- /* Min touch target (WCAG 2.5.5 / Apple HIG) — this menu renders as a
26
- Drawer sheet on mobile, so every item must be comfortably tappable. */
27
- min-height: var(--sv-touch-target-min, 44px);
28
- padding: var(--sv-space-2) var(--sv-space-3);
29
- border: none;
30
- border-radius: var(--sv-radius-sm);
31
- background: transparent;
32
- color: var(--sv-color-text-primary);
33
- font: inherit;
34
- font-size: var(--sv-font-size-sm);
35
- text-align: left;
36
- cursor: pointer;
37
- }
38
-
39
- @media (hover: hover) {
40
- .item:hover:not(:disabled) {
41
- background: var(--sv-color-surface-sunken);
42
- }
43
- }
44
-
45
- .item:focus-visible {
46
- outline: 2px solid var(--sv-color-focus-ring);
47
- outline-offset: -2px;
48
- }
49
-
50
- .item:disabled {
51
- opacity: 0.5;
52
- cursor: not-allowed;
53
- }
54
-
55
- .itemDestructive {
56
- color: var(--sv-color-error-text);
57
- }
58
-
59
- @media (hover: hover) {
60
- .itemDestructive:hover:not(:disabled) {
61
- background: var(--sv-color-error-surface);
62
- }
63
- }
64
-
65
- /* Reserved checkmark gutter for a checkable item — sized so unchecked
66
- siblings in the same group still align with the checked one's icon. */
67
- .check {
68
- display: inline-flex;
69
- flex-shrink: 0;
70
- width: var(--sv-icon-size-sm);
71
- height: var(--sv-icon-size-sm);
72
- align-items: center;
73
- justify-content: center;
74
- }
75
-
76
- .label {
77
- padding: var(--sv-space-2) var(--sv-space-3) var(--sv-space-1);
78
- font-size: var(--sv-font-size-label);
79
- font-weight: var(--sv-font-weight-semibold);
80
- color: var(--sv-color-text-muted);
81
- text-transform: uppercase;
82
- letter-spacing: 0.04em;
83
- }
84
-
85
- .separator {
86
- height: 1px;
87
- margin: var(--sv-space-1) var(--sv-space-2);
88
- background: var(--sv-color-border);
89
- }