@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,318 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
3
- import { useState } from 'react';
4
- import { act, cleanup, fireEvent, render, screen } from '@testing-library/react';
5
- import { ConfirmDialog } from '../../ConfirmDialog/ConfirmDialog';
6
- import { Dialog, useOverlaySecondRow } from '../Dialog';
7
-
8
- // Dialog's exit animation reads prefers-reduced-motion via matchMedia, which
9
- // jsdom does not implement. `matches: false` (motion enabled) exercises the
10
- // normal animated path; the actual reduced-motion behaviour is covered by
11
- // motion.ts's own tests.
12
- function installMatchMedia() {
13
- vi.stubGlobal(
14
- 'matchMedia',
15
- vi.fn().mockImplementation((query: string) => ({
16
- matches: false,
17
- media: query,
18
- addEventListener: vi.fn(),
19
- removeEventListener: vi.fn(),
20
- addListener: vi.fn(),
21
- removeListener: vi.fn(),
22
- dispatchEvent: vi.fn(),
23
- })),
24
- );
25
- }
26
-
27
- describe('Dialog', () => {
28
- beforeEach(installMatchMedia);
29
- afterEach(() => {
30
- vi.unstubAllGlobals();
31
- cleanup();
32
- });
33
-
34
- it('renders nothing when closed', () => {
35
- render(
36
- <Dialog open={false} onClose={() => {}}>
37
- Body
38
- </Dialog>,
39
- );
40
- expect(screen.queryByRole('dialog')).toBeNull();
41
- });
42
-
43
- it('renders the panel with its accessible name when open', () => {
44
- render(
45
- <Dialog open onClose={() => {}} aria-label="Settings">
46
- Body
47
- </Dialog>,
48
- );
49
- const dialog = screen.getByRole('dialog', { name: 'Settings' });
50
- expect(dialog.getAttribute('aria-modal')).toBe('true');
51
- });
52
-
53
- it('calls onClose exactly once on Escape with focus inside the panel', () => {
54
- const onClose = vi.fn();
55
- render(
56
- <Dialog open onClose={onClose} aria-label="Panel">
57
- <button>Focus me</button>
58
- </Dialog>,
59
- );
60
- // Dispatched from the actually-focused element (matching real usage,
61
- // where useOverlayFocusCapture moves focus into the panel on open) so the
62
- // keydown bubbles through the scrim on its way to document — the exact
63
- // path that used to trigger both the scrim's own (now-removed) Escape
64
- // handler and useOverlayKeyboardTrap's document-level listener, double-
65
- // firing onClose. Dispatching straight on `document` (the previous form
66
- // of this test) skips that bubble path and would pass even if the bug
67
- // were reintroduced.
68
- const button = screen.getByRole('button', { name: 'Focus me' });
69
- button.focus();
70
- fireEvent.keyDown(button, { key: 'Escape' });
71
- expect(onClose).toHaveBeenCalledOnce();
72
- });
73
-
74
- it('calls onClose on scrim click but not on panel click', () => {
75
- const onClose = vi.fn();
76
- render(
77
- <Dialog open onClose={onClose} aria-label="Panel">
78
- Body
79
- </Dialog>,
80
- );
81
- fireEvent.click(screen.getByRole('dialog')); // panel — should not close
82
- expect(onClose).not.toHaveBeenCalled();
83
- const closeButtons = screen.getAllByRole('button', { name: 'Close' });
84
- expect(closeButtons.length).toBeGreaterThan(0);
85
- fireEvent.click(closeButtons[0] as HTMLElement);
86
- expect(onClose).toHaveBeenCalledOnce();
87
- });
88
-
89
- it('applies the size class', () => {
90
- render(
91
- <Dialog open onClose={() => {}} size="lg" aria-label="Big">
92
- Body
93
- </Dialog>,
94
- );
95
- expect(screen.getByRole('dialog').className).toContain('lg');
96
- });
97
-
98
- it('supports the sm size', () => {
99
- render(
100
- <Dialog open onClose={() => {}} size="sm" aria-label="Small">
101
- Body
102
- </Dialog>,
103
- );
104
- expect(screen.getByRole('dialog').className).toContain('sm');
105
- });
106
-
107
- it('supports the auto size', () => {
108
- render(
109
- <Dialog open onClose={() => {}} size="auto" aria-label="Auto-sized">
110
- Body
111
- </Dialog>,
112
- );
113
- expect(screen.getByRole('dialog').className).toContain('auto');
114
- });
115
-
116
- it('supports the fixed size (epic task 14.5)', () => {
117
- render(
118
- <Dialog open onClose={() => {}} size="fixed" aria-label="Fixed-size">
119
- Body
120
- </Dialog>,
121
- );
122
- expect(screen.getByRole('dialog').className).toContain('fixed');
123
- });
124
-
125
- it('renders a descendant-supplied secondRow via useOverlaySecondRow', () => {
126
- function TabStrip() {
127
- useOverlaySecondRow(<nav>Tab strip</nav>);
128
- return null;
129
- }
130
- render(
131
- <Dialog open onClose={() => {}} title="Account" aria-label="Account">
132
- <TabStrip />
133
- </Dialog>,
134
- );
135
- expect(screen.getByText('Tab strip')).toBeTruthy();
136
- });
137
-
138
- it('removes the secondRow when the supplying descendant unmounts', () => {
139
- function TabStrip() {
140
- useOverlaySecondRow(<nav>Tab strip</nav>);
141
- return null;
142
- }
143
- function Harness({ showTabs }: { showTabs: boolean }) {
144
- return (
145
- <Dialog open onClose={() => {}} title="Account" aria-label="Account">
146
- {showTabs && <TabStrip />}
147
- </Dialog>
148
- );
149
- }
150
- const { rerender } = render(<Harness showTabs />);
151
- expect(screen.getByText('Tab strip')).toBeTruthy();
152
- rerender(<Harness showTabs={false} />);
153
- expect(screen.queryByText('Tab strip')).toBeNull();
154
- });
155
-
156
- it('is a no-op when called outside a Dialog', () => {
157
- function Standalone() {
158
- useOverlaySecondRow(<nav>Tab strip</nav>);
159
- return <span>Standalone content</span>;
160
- }
161
- render(<Standalone />);
162
- expect(screen.getByText('Standalone content')).toBeTruthy();
163
- expect(screen.queryByText('Tab strip')).toBeNull();
164
- });
165
-
166
- describe('Body only (default — no header/footer props)', () => {
167
- it('renders exactly one close button and no footer', () => {
168
- render(
169
- <Dialog open onClose={() => {}} title="Settings" aria-label="Settings">
170
- Body
171
- </Dialog>,
172
- );
173
- // Both the mobile-only OverlayHeader's close button and the
174
- // desktop-only floating one are always in the DOM (CSS toggles which
175
- // is visible per breakpoint, not React) — unchanged from before this
176
- // task, since this is the `header`-omitted branch.
177
- expect(screen.getAllByRole('button', { name: 'Close' })).toHaveLength(2);
178
- expect(screen.getByText('Settings')).toBeTruthy();
179
- });
180
- });
181
-
182
- describe('Header + Body (header prop)', () => {
183
- it('renders header content via a single OverlayHeader, on both breakpoints, instead of the mobile-only title bar', () => {
184
- render(
185
- <Dialog open onClose={() => {}} header={<span>Card detail</span>} aria-label="Card detail">
186
- Body
187
- </Dialog>,
188
- );
189
- expect(screen.getByText('Card detail')).toBeTruthy();
190
- // Only one close button now — the header branch skips the separate
191
- // desktop .close button entirely (see Dialog.tsx's own comment).
192
- expect(screen.getAllByRole('button', { name: 'Close' })).toHaveLength(1);
193
- });
194
-
195
- it('supersedes title for visible content but keeps title as the aria-label fallback', () => {
196
- render(
197
- <Dialog open onClose={() => {}} title="Fallback name" header={<span>Visible header</span>}>
198
- Body
199
- </Dialog>,
200
- );
201
- expect(screen.getByText('Visible header')).toBeTruthy();
202
- expect(screen.queryByText('Fallback name')).toBeNull();
203
- expect(screen.getByRole('dialog', { name: 'Fallback name' })).toBeTruthy();
204
- });
205
- });
206
-
207
- describe('Header + Body + Footer (header and footer props)', () => {
208
- it('renders footer content as a non-scrolling sibling of the body', () => {
209
- render(
210
- <Dialog
211
- open
212
- onClose={() => {}}
213
- header={<span>Card detail</span>}
214
- footer={<button type="button">Save</button>}
215
- aria-label="Card detail"
216
- >
217
- <p>Body content</p>
218
- </Dialog>,
219
- );
220
- const footerButton = screen.getByRole('button', { name: 'Save' });
221
- const bodyText = screen.getByText('Body content');
222
- expect(footerButton).toBeTruthy();
223
- // Footer is a sibling of .content (the scroll region), not nested
224
- // inside it — it must never scroll away with the body.
225
- expect(bodyText.closest('[class*="content"]')?.contains(footerButton)).toBe(false);
226
- });
227
-
228
- it('omits the footer row entirely when footer is not provided', () => {
229
- render(
230
- <Dialog open onClose={() => {}} header={<span>Card detail</span>} aria-label="Card detail">
231
- Body
232
- </Dialog>,
233
- );
234
- expect(screen.queryByRole('button', { name: 'Save' })).toBeNull();
235
- });
236
- });
237
- });
238
-
239
- describe('Dialog Escape precedence with a nested ConfirmDialog', () => {
240
- beforeEach(() => {
241
- installMatchMedia();
242
- // jsdom does not implement HTMLDialogElement — see ConfirmDialog.test.tsx
243
- // for the full rationale on the guard + deferred dispatch (both matter
244
- // here too: without the guard, this file's own reuse of the mock across
245
- // renders would double-dispatch; without deferring, ConfirmDialog's
246
- // unregister-on-close wouldn't have run yet by the time this test reads
247
- // the outer Dialog's response to a second Escape).
248
- HTMLDialogElement.prototype.showModal = function (this: HTMLDialogElement) {
249
- this.setAttribute('open', '');
250
- };
251
- HTMLDialogElement.prototype.close = function (this: HTMLDialogElement) {
252
- if (!this.hasAttribute('open')) return;
253
- this.removeAttribute('open');
254
- queueMicrotask(() => this.dispatchEvent(new Event('close')));
255
- };
256
- });
257
- afterEach(() => {
258
- vi.unstubAllGlobals();
259
- cleanup();
260
- });
261
-
262
- async function flush() {
263
- await act(async () => {
264
- await new Promise((resolve) => setTimeout(resolve, 0));
265
- });
266
- }
267
-
268
- it('defers Escape to a nested open ConfirmDialog instead of closing the outer Dialog', async () => {
269
- const outerOnClose = vi.fn();
270
-
271
- function NestedHarness() {
272
- // Starts closed and opens via a later click — matching the real
273
- // sequence (CardDetailOverlay: the outer Dialog is already mounted and
274
- // registered before the user ever triggers the nested confirm).
275
- // Mounting both already-open in the same initial render would instead
276
- // have React fire the child's (ConfirmDialog's) registration effect
277
- // before the parent's (Dialog's) in that one shared commit — the one
278
- // case this stack-order approach doesn't handle, and not the shape of
279
- // the bug this task fixes.
280
- const [confirmOpen, setConfirmOpen] = useState(false);
281
- return (
282
- <Dialog open onClose={outerOnClose} aria-label="Card detail">
283
- <button onClick={() => setConfirmOpen(true)}>Delete card…</button>
284
- <ConfirmDialog
285
- open={confirmOpen}
286
- onClose={() => setConfirmOpen(false)}
287
- onConfirm={() => {}}
288
- title="Delete card?"
289
- message="This can't be undone."
290
- />
291
- </Dialog>
292
- );
293
- }
294
-
295
- render(<NestedHarness />);
296
- fireEvent.click(screen.getByRole('button', { name: 'Delete card…' }));
297
- await flush();
298
- expect(screen.getByRole('button', { name: 'Cancel' })).toBeTruthy();
299
-
300
- // The nested ConfirmDialog is topmost — the outer Dialog's document-level
301
- // Escape listener must not act while it's open.
302
- fireEvent.keyDown(document, { key: 'Escape' });
303
- await flush();
304
- expect(outerOnClose).not.toHaveBeenCalled();
305
- expect(screen.getByRole('button', { name: 'Cancel' })).toBeTruthy();
306
-
307
- // Dismiss the nested confirm (unregisters it from the open-overlay
308
- // stack) — the outer Dialog is now topmost again.
309
- fireEvent.click(screen.getByRole('button', { name: 'Cancel' }));
310
- await flush();
311
- expect(screen.queryByRole('button', { name: 'Cancel' })).toBeNull();
312
-
313
- // A second Escape now reaches the outer Dialog.
314
- fireEvent.keyDown(document, { key: 'Escape' });
315
- await flush();
316
- expect(outerOnClose).toHaveBeenCalledOnce();
317
- });
318
- });
@@ -1,57 +0,0 @@
1
- .row {
2
- display: flex;
3
- align-items: flex-start;
4
- gap: var(--sv-space-1);
5
- position: relative;
6
- }
7
-
8
- /* Hover-reveal only where hover genuinely exists — on touch the handle would
9
- otherwise never become visible (tap-generated hover doesn't count as a
10
- sustained hover state, and :not(:hover) is always true with no hover
11
- capability at all), so it stays visible by default there. */
12
- @media (hover: hover) {
13
- .row:not(:hover) .handle,
14
- .row:not(:focus-within) .handle {
15
- opacity: 0;
16
- }
17
- }
18
-
19
- .handle {
20
- flex-shrink: 0;
21
- display: flex;
22
- align-items: center;
23
- justify-content: center;
24
- width: 24px;
25
- height: 24px;
26
- margin-top: 2px;
27
- border: none;
28
- background: none;
29
- padding: 0;
30
- border-radius: var(--sv-radius-sm);
31
- color: var(--sv-color-text-muted);
32
- cursor: grab;
33
- opacity: 1;
34
- transition: opacity 0.1s ease;
35
- }
36
-
37
- .handle:focus-visible {
38
- outline: 2px solid var(--sv-color-focus-ring);
39
- outline-offset: 2px;
40
- }
41
-
42
- .handle:active {
43
- cursor: grabbing;
44
- }
45
-
46
- .icon {
47
- pointer-events: none;
48
- }
49
-
50
- .content {
51
- flex: 1;
52
- min-width: 0;
53
- }
54
-
55
- .dragging {
56
- opacity: 0.5;
57
- }
@@ -1,42 +0,0 @@
1
- import type { HTMLAttributes, ReactNode } from 'react';
2
- import { GripIcon } from '../GripIcon/GripIcon';
3
- import styles from './DragHandleRow.module.css';
4
-
5
- export interface DragHandleRowProps extends HTMLAttributes<HTMLDivElement> {
6
- children: ReactNode;
7
- /** Pass drag-listener and drag-control props from dnd-kit here. */
8
- handleProps?: HTMLAttributes<HTMLButtonElement>;
9
- isDragging?: boolean;
10
- }
11
-
12
- /**
13
- * A row wrapper that surfaces a drag handle on the left.
14
- * Consumers attach dnd-kit's useSortable listeners to `handleProps`.
15
- */
16
- export function DragHandleRow({
17
- children,
18
- handleProps,
19
- isDragging,
20
- className,
21
- ...rest
22
- }: DragHandleRowProps) {
23
- return (
24
- <div
25
- {...rest}
26
- className={[styles.row, isDragging ? styles.dragging : '', className]
27
- .filter(Boolean)
28
- .join(' ')}
29
- >
30
- <button
31
- type="button"
32
- aria-label="Drag to reorder"
33
- className={styles.handle}
34
- tabIndex={-1}
35
- {...handleProps}
36
- >
37
- <GripIcon className={styles.icon} />
38
- </button>
39
- <div className={styles.content}>{children}</div>
40
- </div>
41
- );
42
- }
@@ -1,121 +0,0 @@
1
- /* Drawer — bottom-sheet surface (RFC 0013). Shares scrim/shadow tokens with
2
- * Dialog but slides up from the bottom instead of centering. The panel has no
3
- * fixed height — it sizes to content, capped at 80dvh so some page context
4
- * remains visible above. Safe-area-aware: bottom padding clears the home
5
- * indicator in standalone/fullscreen mode. */
6
-
7
- .scrim {
8
- position: fixed;
9
- inset: 0;
10
- /* When --sv-shell-footer-height is set (mobile nav bar — by the platform
11
- shell, or by a self-rendered MobileFooter via usePublishShellChromeHeight
12
- for a shellConfig.mobileFooter: false plugin), stop the scrim above the
13
- footer so the panel never hides behind it. */
14
- bottom: var(--sv-shell-footer-height, 0);
15
- z-index: 100;
16
- display: flex;
17
- align-items: flex-end;
18
- background: var(--sv-color-scrim);
19
- /* Entrance/exit fade — same two-phase-mount pattern as Dialog (see motion.ts
20
- and Drawer.tsx). */
21
- opacity: 0;
22
- transition: opacity var(--sv-motion-duration-base) var(--sv-motion-ease-out);
23
- }
24
-
25
- .scrimOpen {
26
- opacity: 1;
27
- }
28
-
29
- .panel {
30
- width: 100%;
31
- max-height: 80dvh;
32
- /* The panel itself no longer scrolls — see .body below. display: flex
33
- (column) lets .handle (and OverlayHeader, when title is set) stay
34
- fixed while .body's own overflow-y handles content taller than the
35
- 80dvh cap, the same fixed-header/scrollable-body split Sheet.module.css
36
- already establishes (its .panel/.content pair). Before this, the whole
37
- .panel scrolled as one block, so a tall drawer (e.g. many installed
38
- plugins in the Apps grid) scrolled the grab handle itself out of view
39
- along with the content — reachable in the DOM, invisible on screen. */
40
- display: flex;
41
- flex-direction: column;
42
- overflow: hidden;
43
- background: var(--sv-color-surface-raised);
44
- border-top: var(--sv-border-width-hairline) solid var(--sv-color-border);
45
- border-radius: var(--sv-radius-3xl) var(--sv-radius-3xl) 0 0;
46
- box-shadow: var(--sv-shadow-overlay);
47
- outline: none;
48
- /* Slide up from below the viewport. Always a bottom sheet, so unlike Dialog
49
- there's no desktop-vs-mobile fork here. */
50
- transform: translateY(100%);
51
- transition: transform var(--sv-motion-duration-base) var(--sv-motion-ease-out);
52
- }
53
-
54
- /* The scroll container — everything below the fixed handle/OverlayHeader.
55
- Scrollbar hidden (not overflow removed) the same way Tabs.module.css's
56
- .tablist already does for this design system; scroll-driven UI here reads
57
- as a native swipe list, not a document needing a visible scroll affordance. */
58
- .body {
59
- flex: 1 1 auto;
60
- min-height: 0;
61
- overflow-y: auto;
62
- overscroll-behavior: contain;
63
- scrollbar-width: none;
64
- /* Pull content above the home indicator / bottom bar in standalone mode —
65
- moved here from .panel now that this is the element whose bottom edge
66
- is the actual scrollable content boundary. */
67
- padding-bottom: env(safe-area-inset-bottom);
68
- }
69
-
70
- .body::-webkit-scrollbar {
71
- display: none;
72
- }
73
-
74
- .panelOpen {
75
- transform: translateY(0);
76
- }
77
-
78
- /* 'half' snapHeight — a fixed height instead of the default content-sized cap
79
- * above. Per the design-system's "half screen or less" convention for
80
- * Drawer; content taller than this belongs in Sheet instead. */
81
- .panelHalf {
82
- height: 50dvh;
83
- max-height: 50dvh;
84
- }
85
-
86
- /* See Dialog.module.css's identical rule for why 0.01ms rather than 0. */
87
- @media (prefers-reduced-motion: reduce) {
88
- .scrim,
89
- .panel {
90
- transition-duration: 0.01ms;
91
- }
92
- }
93
-
94
- /* Grab handle — the sole drag-initiation region for swipe-down-to-dismiss
95
- * (see Drawer.tsx's doc comment for why not the whole panel). The visual bar
96
- * (::before) stays the small, established 36x4px size; only the hit area
97
- * grows to a comfortable touch target. */
98
- .handle {
99
- display: flex;
100
- align-items: center;
101
- justify-content: center;
102
- width: 100%;
103
- height: var(--sv-touch-target-min, 44px);
104
- flex-shrink: 0;
105
- cursor: grab;
106
- /* JS-driven drag — the browser must not treat a press here as a
107
- scroll/pan gesture that would fight it. */
108
- touch-action: none;
109
- }
110
-
111
- .handle:active {
112
- cursor: grabbing;
113
- }
114
-
115
- .handle::before {
116
- content: '';
117
- width: 36px;
118
- height: 4px;
119
- border-radius: var(--sv-radius-full);
120
- background: var(--sv-color-border-strong);
121
- }
@@ -1,132 +0,0 @@
1
- import type { Meta, StoryObj } from '@storybook/react-vite';
2
- import { expect, userEvent, within } from 'storybook/test';
3
- import { useState } from 'react';
4
- import { Button } from '../Button/Button';
5
- import { Icon } from '../Icon/Icon';
6
- import { Drawer } from './Drawer';
7
-
8
- function DrawerDemo({ label = 'Navigation' }: { label?: string }) {
9
- const [open, setOpen] = useState(false);
10
- return (
11
- <>
12
- <Button onClick={() => setOpen(true)}>Open drawer</Button>
13
- <Drawer open={open} onClose={() => setOpen(false)} aria-label={label}>
14
- <ul style={{ listStyle: 'none', margin: 0, padding: '8px 0' }}>
15
- {(['house', 'grid-2x2', 'settings', 'user'] as const).map((icon) => (
16
- <li key={icon}>
17
- <button
18
- onClick={() => setOpen(false)}
19
- style={{
20
- display: 'flex',
21
- alignItems: 'center',
22
- gap: 12,
23
- width: '100%',
24
- padding: '12px 20px',
25
- background: 'none',
26
- border: 'none',
27
- cursor: 'pointer',
28
- fontSize: 15,
29
- color: 'var(--sv-color-text-primary)',
30
- fontFamily: 'system-ui',
31
- }}
32
- >
33
- <Icon name={icon} size="md" aria-hidden />
34
- {icon.replace(/-/g, ' ')}
35
- </button>
36
- </li>
37
- ))}
38
- </ul>
39
- </Drawer>
40
- </>
41
- );
42
- }
43
-
44
- const meta = {
45
- title: 'Components/Drawer',
46
- component: Drawer,
47
- parameters: {
48
- layout: 'centered',
49
- docs: {
50
- description: {
51
- component:
52
- 'Dismissable bottom-sheet panel. Used by the mobile shell for plugin navigation. Supports Esc, scrim-click, focus trap. Respects `env(safe-area-inset-bottom)`. Use the viewport addon at 375px to see the intended mobile context.',
53
- },
54
- },
55
- viewport: { defaultViewport: 'mobile' },
56
- },
57
- } satisfies Meta<typeof Drawer>;
58
-
59
- export default meta;
60
- type Story = StoryObj<typeof meta>;
61
-
62
- // ---------------------------------------------------------------------------
63
-
64
- export const Default: Story = {
65
- args: { open: false, onClose: () => {}, children: null },
66
- render: (_args) => <DrawerDemo />,
67
- };
68
-
69
- export const Closed: Story = {
70
- args: { open: false, onClose: () => {}, children: null },
71
- render: (_args) => (
72
- <Drawer open={false} onClose={() => {}} aria-label="Closed drawer">
73
- <p>Never seen</p>
74
- </Drawer>
75
- ),
76
- };
77
-
78
- function DrawerWithTitleDemo() {
79
- const [open, setOpen] = useState(false);
80
- return (
81
- <>
82
- <Button onClick={() => setOpen(true)}>Open drawer</Button>
83
- <Drawer open={open} onClose={() => setOpen(false)} title="Apps">
84
- <ul style={{ listStyle: 'none', margin: 0, padding: '8px 0' }}>
85
- {(['house', 'grid-2x2', 'settings', 'user'] as const).map((icon) => (
86
- <li key={icon}>
87
- <button
88
- onClick={() => setOpen(false)}
89
- style={{
90
- display: 'flex',
91
- alignItems: 'center',
92
- gap: 12,
93
- width: '100%',
94
- padding: '12px 20px',
95
- background: 'none',
96
- border: 'none',
97
- cursor: 'pointer',
98
- fontSize: 15,
99
- color: 'var(--sv-color-text-primary)',
100
- fontFamily: 'system-ui',
101
- }}
102
- >
103
- <Icon name={icon} size="md" aria-hidden />
104
- {icon.replace(/-/g, ' ')}
105
- </button>
106
- </li>
107
- ))}
108
- </ul>
109
- </Drawer>
110
- </>
111
- );
112
- }
113
-
114
- /** Opt-in `title` prop renders a built-in `OverlayHeader` (title + close)
115
- * below the grab handle — hidden by default (see the `Default` story), for
116
- * consumers that want one instead of building their own header markup. */
117
- export const WithTitle: Story = {
118
- args: { open: false, onClose: () => {}, children: null },
119
- render: (_args) => <DrawerWithTitleDemo />,
120
- };
121
-
122
- /** Play function opens the drawer and asserts its list items are visible. */
123
- export const OpenViaInteraction: Story = {
124
- args: { open: false, onClose: () => {}, children: null },
125
- render: (_args) => <DrawerDemo label="Navigation menu" />,
126
- play: async ({ canvasElement }) => {
127
- const canvas = within(canvasElement);
128
- await userEvent.click(canvas.getByRole('button', { name: /open drawer/i }));
129
- const drawer = canvas.getByRole('navigation');
130
- await expect(drawer).toBeVisible();
131
- },
132
- };