@sovereignfs/ui 0.45.0 → 0.83.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 (323) hide show
  1. package/dist/Accordion.module.css +1 -1
  2. package/dist/Alert.module.css +1 -1
  3. package/dist/AppsLauncher.module.css +96 -0
  4. package/dist/Avatar.module.css +1 -1
  5. package/dist/Badge.module.css +30 -7
  6. package/dist/BalanceChip.module.css +1 -1
  7. package/dist/Button.module.css +18 -2
  8. package/dist/Card.module.css +1 -1
  9. package/dist/CardTile.module.css +181 -0
  10. package/dist/CodeTextarea.module.css +1 -1
  11. package/dist/Collapsible.module.css +1 -1
  12. package/dist/ColorPicker.module.css +132 -0
  13. package/dist/Combobox.module.css +2 -2
  14. package/dist/Command.module.css +1 -1
  15. package/dist/ConfirmDialog.module.css +2 -2
  16. package/dist/ConsentPrompt.module.css +21 -0
  17. package/dist/DatePicker.module.css +1 -1
  18. package/dist/Dialog.module.css +130 -21
  19. package/dist/Drawer.module.css +36 -7
  20. package/dist/Header.module.css +62 -0
  21. package/dist/HeaderFooterLayout.module.css +21 -0
  22. package/dist/IconPicker.module.css +1 -1
  23. package/dist/Input.module.css +1 -1
  24. package/dist/Kbd.module.css +1 -1
  25. package/dist/LegalLinks.module.css +24 -0
  26. package/dist/Markdown.module.css +73 -0
  27. package/dist/Menu.module.css +1 -0
  28. package/dist/Message.module.css +1 -1
  29. package/dist/MessageScroller.module.css +12 -1
  30. package/dist/MobileAppsDrawer.module.css +82 -0
  31. package/dist/MobileFooter.module.css +73 -0
  32. package/dist/MobileHeader.module.css +76 -0
  33. package/dist/NavList.module.css +130 -0
  34. package/dist/NavTabs.module.css +1 -1
  35. package/dist/NotificationsPanel.module.css +258 -0
  36. package/dist/OverlayHeader.module.css +1 -1
  37. package/dist/PageContainer.module.css +82 -0
  38. package/dist/PageHeader.module.css +54 -0
  39. package/dist/PageLayout.module.css +51 -0
  40. package/dist/Popover.module.css +1 -1
  41. package/dist/QuantityStepper.module.css +1 -1
  42. package/dist/Resizable.module.css +3 -3
  43. package/dist/RootLayout.module.css +12 -0
  44. package/dist/SegmentedControl.module.css +1 -1
  45. package/dist/Select.module.css +1 -1
  46. package/dist/Sheet.module.css +4 -1
  47. package/dist/SplitPane.module.css +4 -4
  48. package/dist/StatusBadge.module.css +1 -1
  49. package/dist/StepStrip.module.css +53 -0
  50. package/dist/SuggestionInput.module.css +2 -2
  51. package/dist/SwipableMobileCarousel.module.css +64 -0
  52. package/dist/SwipableMobileCarouselDots.module.css +64 -0
  53. package/dist/SwipableMobileCarouselSlideParts.module.css +29 -0
  54. package/dist/SwipeStack.module.css +101 -0
  55. package/dist/SystemBanner.module.css +10 -0
  56. package/dist/Table.module.css +2 -2
  57. package/dist/Tabs.module.css +1 -1
  58. package/dist/TagInput.module.css +2 -2
  59. package/dist/Textarea.module.css +9 -1
  60. package/dist/ThreeColumnLayout.module.css +35 -0
  61. package/dist/Toast.module.css +62 -3
  62. package/dist/Tooltip.module.css +1 -1
  63. package/dist/UserMenu.module.css +90 -0
  64. package/dist/index.d.ts +1680 -30
  65. package/dist/index.js +4618 -1443
  66. package/dist/tokens/primitives.css +36 -0
  67. package/dist/tokens/semantic.css +32 -0
  68. package/dist/tokens/theme-presets.css +33 -0
  69. package/package.json +32 -12
  70. package/src/__tests__/package-json.test.ts +8 -0
  71. package/src/components/Accordion/Accordion.module.css +1 -1
  72. package/src/components/Alert/Alert.module.css +1 -1
  73. package/src/components/AppsLauncher/AppsLauncher.module.css +96 -0
  74. package/src/components/AppsLauncher/AppsLauncher.stories.tsx +58 -0
  75. package/src/components/AppsLauncher/AppsLauncher.tsx +117 -0
  76. package/src/components/AppsLauncher/__tests__/AppsLauncher.test.tsx +52 -0
  77. package/src/components/Avatar/Avatar.module.css +1 -1
  78. package/src/components/Badge/Badge.module.css +30 -7
  79. package/src/components/Badge/Badge.stories.tsx +16 -4
  80. package/src/components/Badge/Badge.tsx +8 -11
  81. package/src/components/Badge/__tests__/Badge.test.tsx +4 -2
  82. package/src/components/BalanceChip/BalanceChip.module.css +1 -1
  83. package/src/components/Button/Button.module.css +18 -2
  84. package/src/components/Card/Card.module.css +1 -1
  85. package/src/components/CardTile/CardTile.module.css +181 -0
  86. package/src/components/CardTile/CardTile.stories.tsx +86 -0
  87. package/src/components/CardTile/CardTile.tsx +128 -0
  88. package/src/components/CardTile/__tests__/CardTile.test.tsx +56 -0
  89. package/src/components/CodeTextarea/CodeTextarea.module.css +1 -1
  90. package/src/components/Collapsible/Collapsible.module.css +1 -1
  91. package/src/components/ColorPicker/ColorPicker.module.css +132 -0
  92. package/src/components/ColorPicker/ColorPicker.stories.tsx +80 -0
  93. package/src/components/ColorPicker/ColorPicker.tsx +157 -0
  94. package/src/components/ColorPicker/__tests__/ColorPicker.test.tsx +117 -0
  95. package/src/components/Combobox/Combobox.module.css +2 -2
  96. package/src/components/Command/Command.module.css +1 -1
  97. package/src/components/ConfirmDialog/ConfirmDialog.module.css +2 -2
  98. package/src/components/ConfirmDialog/ConfirmDialog.tsx +28 -2
  99. package/src/components/ConfirmDialog/__tests__/ConfirmDialog.test.tsx +71 -3
  100. package/src/components/ConsentPrompt/ConsentPrompt.module.css +21 -0
  101. package/src/components/ConsentPrompt/ConsentPrompt.stories.tsx +31 -0
  102. package/src/components/ConsentPrompt/ConsentPrompt.tsx +66 -0
  103. package/src/components/ContextMenu/ContextMenu.tsx +1 -1
  104. package/src/components/DatePicker/DatePicker.module.css +1 -1
  105. package/src/components/DeviceOnlyGate/DeviceOnlyGate.tsx +58 -0
  106. package/src/components/DeviceOnlyGate/__tests__/DeviceOnlyGate.test.tsx +45 -0
  107. package/src/components/DeviceStorageKeyGate/DeviceStorageKeyGate.tsx +100 -0
  108. package/src/components/DeviceStorageKeyGate/__tests__/DeviceStorageKeyGate.test.tsx +119 -0
  109. package/src/components/Dialog/Dialog.module.css +130 -21
  110. package/src/components/Dialog/Dialog.stories.tsx +179 -2
  111. package/src/components/Dialog/Dialog.tsx +137 -94
  112. package/src/components/Dialog/__tests__/Dialog.test.tsx +190 -9
  113. package/src/components/DragHandleRow/DragHandleRow.tsx +2 -21
  114. package/src/components/Drawer/Drawer.module.css +36 -7
  115. package/src/components/Drawer/Drawer.stories.tsx +44 -0
  116. package/src/components/Drawer/Drawer.tsx +27 -66
  117. package/src/components/Drawer/__tests__/Drawer.test.tsx +55 -6
  118. package/src/components/GripIcon/GripIcon.tsx +27 -0
  119. package/src/components/Header/Header.module.css +62 -0
  120. package/src/components/Header/Header.stories.tsx +452 -0
  121. package/src/components/Header/Header.tsx +102 -0
  122. package/src/components/Header/__tests__/Header.test.tsx +104 -0
  123. package/src/components/HeaderFooterLayout/HeaderFooterLayout.module.css +21 -0
  124. package/src/components/HeaderFooterLayout/HeaderFooterLayout.stories.tsx +111 -0
  125. package/src/components/HeaderFooterLayout/HeaderFooterLayout.tsx +54 -0
  126. package/src/components/HeaderFooterLayout/__tests__/HeaderFooterLayout.test.tsx +58 -0
  127. package/src/components/Icon/icons/arrow-left-right.tsx +23 -0
  128. package/src/components/Icon/icons/bold.tsx +20 -0
  129. package/src/components/Icon/icons/calendar.tsx +4 -4
  130. package/src/components/Icon/icons/carrot.tsx +3 -3
  131. package/src/components/Icon/icons/circle-chevron-left.tsx +21 -0
  132. package/src/components/Icon/icons/code.tsx +21 -0
  133. package/src/components/Icon/icons/copy.tsx +21 -0
  134. package/src/components/Icon/icons/credit-card.tsx +21 -0
  135. package/src/components/Icon/icons/database.tsx +22 -0
  136. package/src/components/Icon/icons/download.tsx +22 -0
  137. package/src/components/Icon/icons/file-text.tsx +24 -0
  138. package/src/components/Icon/icons/folder-closed.tsx +21 -0
  139. package/src/components/Icon/icons/folder-open.tsx +20 -0
  140. package/src/components/Icon/icons/folder.tsx +20 -0
  141. package/src/components/Icon/icons/folders.tsx +21 -0
  142. package/src/components/Icon/icons/hat-glasses.tsx +24 -0
  143. package/src/components/Icon/icons/history.tsx +22 -0
  144. package/src/components/Icon/icons/inbox.tsx +21 -0
  145. package/src/components/Icon/icons/index.ts +169 -1
  146. package/src/components/Icon/icons/italic.tsx +22 -0
  147. package/src/components/Icon/icons/layers.tsx +22 -0
  148. package/src/components/Icon/icons/layout-dashboard.tsx +23 -0
  149. package/src/components/Icon/icons/layout-grid.tsx +23 -0
  150. package/src/components/Icon/icons/link.tsx +21 -0
  151. package/src/components/Icon/icons/list-ordered.tsx +25 -0
  152. package/src/components/Icon/icons/list.tsx +25 -0
  153. package/src/components/Icon/icons/luggage.tsx +24 -0
  154. package/src/components/Icon/icons/map-pin.tsx +21 -0
  155. package/src/components/Icon/icons/menu.tsx +22 -0
  156. package/src/components/Icon/icons/minus.tsx +20 -0
  157. package/src/components/Icon/icons/paint-bucket.tsx +23 -0
  158. package/src/components/Icon/icons/panel-left.tsx +21 -0
  159. package/src/components/Icon/icons/pin.tsx +21 -0
  160. package/src/components/Icon/icons/rectangle-ellipsis.tsx +23 -0
  161. package/src/components/Icon/icons/refresh-cw.tsx +23 -0
  162. package/src/components/Icon/icons/rotate-cw.tsx +21 -0
  163. package/src/components/Icon/icons/route.tsx +22 -0
  164. package/src/components/Icon/icons/send.tsx +21 -0
  165. package/src/components/Icon/icons/share-2.tsx +24 -0
  166. package/src/components/Icon/icons/sheet.tsx +24 -0
  167. package/src/components/Icon/icons/smartphone.tsx +21 -0
  168. package/src/components/Icon/icons/square-kanban.tsx +23 -0
  169. package/src/components/Icon/icons/table.tsx +23 -0
  170. package/src/components/Icon/icons/user-round-plus.tsx +23 -0
  171. package/src/components/Icon/icons/users.tsx +23 -0
  172. package/src/components/IconPicker/IconPicker.module.css +1 -1
  173. package/src/components/Input/Input.module.css +1 -1
  174. package/src/components/Input/Input.tsx +8 -2
  175. package/src/components/Kbd/Kbd.module.css +1 -1
  176. package/src/components/LegalLinks/LegalLinks.module.css +24 -0
  177. package/src/components/LegalLinks/LegalLinks.stories.tsx +22 -0
  178. package/src/components/LegalLinks/LegalLinks.tsx +40 -0
  179. package/src/components/Markdown/Markdown.module.css +73 -0
  180. package/src/components/Markdown/Markdown.stories.tsx +40 -0
  181. package/src/components/Markdown/Markdown.tsx +305 -0
  182. package/src/components/Markdown/__tests__/Markdown.test.tsx +144 -0
  183. package/src/components/Menu/Menu.module.css +1 -0
  184. package/src/components/Menu/Menu.tsx +72 -22
  185. package/src/components/Menu/__tests__/Menu.test.tsx +30 -0
  186. package/src/components/Menubar/Menubar.tsx +1 -1
  187. package/src/components/Message/Message.module.css +1 -1
  188. package/src/components/MessageScroller/MessageScroller.module.css +12 -1
  189. package/src/components/MessageScroller/MessageScroller.tsx +12 -0
  190. package/src/components/MobileAppsDrawer/MobileAppsDrawer.module.css +82 -0
  191. package/src/components/MobileAppsDrawer/MobileAppsDrawer.tsx +78 -0
  192. package/src/components/MobileAppsDrawer/__tests__/MobileAppsDrawer.test.tsx +80 -0
  193. package/src/components/MobileFooter/MobileFooter.module.css +73 -0
  194. package/src/components/MobileFooter/MobileFooter.stories.tsx +47 -0
  195. package/src/components/MobileFooter/MobileFooter.tsx +122 -0
  196. package/src/components/MobileFooter/__tests__/MobileFooter.test.tsx +129 -0
  197. package/src/components/MobileHeader/MobileHeader.module.css +76 -0
  198. package/src/components/MobileHeader/MobileHeader.stories.tsx +57 -0
  199. package/src/components/MobileHeader/MobileHeader.tsx +90 -0
  200. package/src/components/MobileHeader/__tests__/MobileHeader.test.tsx +113 -0
  201. package/src/components/NavList/NavList.module.css +130 -0
  202. package/src/components/NavList/NavList.tsx +136 -0
  203. package/src/components/NavList/__tests__/NavList.test.tsx +109 -0
  204. package/src/components/NavTabs/NavTabs.module.css +1 -1
  205. package/src/components/NavTabs/NavTabs.tsx +39 -11
  206. package/src/components/NotificationsPanel/NotificationsPanel.module.css +258 -0
  207. package/src/components/NotificationsPanel/NotificationsPanel.stories.tsx +61 -0
  208. package/src/components/NotificationsPanel/NotificationsPanel.tsx +187 -0
  209. package/src/components/NotificationsPanel/__tests__/NotificationsPanel.test.tsx +78 -0
  210. package/src/components/OfflineGate/OfflineGate.tsx +44 -0
  211. package/src/components/OfflineGate/__tests__/OfflineGate.test.tsx +66 -0
  212. package/src/components/OverlayHeader/OverlayHeader.module.css +1 -1
  213. package/src/components/OverlayHeader/OverlayHeader.tsx +19 -4
  214. package/src/components/OverlayHeader/__tests__/OverlayHeader.test.tsx +18 -0
  215. package/src/components/PageContainer/PageContainer.module.css +82 -0
  216. package/src/components/PageContainer/PageContainer.tsx +64 -0
  217. package/src/components/PageContainer/__tests__/PageContainer.test.tsx +70 -0
  218. package/src/components/PageHeader/PageHeader.module.css +54 -0
  219. package/src/components/PageHeader/PageHeader.tsx +157 -2
  220. package/src/components/PageHeader/__tests__/PageHeader.test.tsx +103 -0
  221. package/src/components/PageLayout/PageLayout.module.css +51 -0
  222. package/src/components/PageLayout/PageLayout.stories.tsx +73 -0
  223. package/src/components/PageLayout/PageLayout.tsx +51 -0
  224. package/src/components/PageLayout/__tests__/PageLayout.test.tsx +34 -0
  225. package/src/components/Popover/Popover.module.css +1 -1
  226. package/src/components/Popover/Popover.tsx +86 -4
  227. package/src/components/Popover/__tests__/Popover.test.tsx +165 -0
  228. package/src/components/QuantityStepper/QuantityStepper.module.css +1 -1
  229. package/src/components/Resizable/Resizable.module.css +3 -3
  230. package/src/components/ResponsiveSurface/ResponsiveSurface.tsx +24 -0
  231. package/src/components/ResponsiveSurface/__tests__/ResponsiveSurface.test.tsx +73 -0
  232. package/src/components/RootLayout/RootLayout.module.css +12 -0
  233. package/src/components/RootLayout/RootLayout.stories.tsx +125 -0
  234. package/src/components/RootLayout/RootLayout.tsx +185 -0
  235. package/src/components/RootLayout/__tests__/RootLayout.test.tsx +161 -0
  236. package/src/components/SegmentedControl/SegmentedControl.module.css +1 -1
  237. package/src/components/Select/Select.module.css +1 -1
  238. package/src/components/Sheet/Sheet.module.css +4 -1
  239. package/src/components/Sheet/Sheet.tsx +14 -56
  240. package/src/components/SplitPane/SplitPane.module.css +4 -4
  241. package/src/components/StatusBadge/StatusBadge.module.css +1 -1
  242. package/src/components/StepStrip/StepStrip.module.css +53 -0
  243. package/src/components/StepStrip/StepStrip.tsx +74 -0
  244. package/src/components/SuggestionInput/SuggestionInput.module.css +2 -2
  245. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.module.css +64 -0
  246. package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.tsx +243 -0
  247. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlide.tsx +35 -0
  248. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideBody.tsx +42 -0
  249. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideFooter.tsx +18 -0
  250. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideHeader.tsx +21 -0
  251. package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideParts.module.css +29 -0
  252. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarousel.test.tsx +214 -0
  253. package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarouselDevGuard.test.tsx +61 -0
  254. package/src/components/SwipableMobileCarousel/context.ts +13 -0
  255. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.module.css +64 -0
  256. package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.tsx +73 -0
  257. package/src/components/SwipableMobileCarouselDots/__tests__/SwipableMobileCarouselDots.test.tsx +63 -0
  258. package/src/components/SwipeStack/SwipeStack.module.css +101 -0
  259. package/src/components/SwipeStack/SwipeStack.tsx +199 -0
  260. package/src/components/SwipeStack/SwipeStackCard.tsx +22 -0
  261. package/src/components/SwipeStack/__tests__/SwipeStack.test.tsx +169 -0
  262. package/src/components/SystemBanner/SystemBanner.module.css +10 -0
  263. package/src/components/Table/Table.module.css +2 -2
  264. package/src/components/Tabs/Tabs.module.css +1 -1
  265. package/src/components/TagInput/TagInput.module.css +2 -2
  266. package/src/components/Textarea/Textarea.module.css +9 -1
  267. package/src/components/Textarea/Textarea.tsx +28 -5
  268. package/src/components/Textarea/__tests__/Textarea.test.tsx +23 -1
  269. package/src/components/ThreeColumnLayout/ThreeColumnLayout.module.css +35 -0
  270. package/src/components/ThreeColumnLayout/ThreeColumnLayout.stories.tsx +152 -0
  271. package/src/components/ThreeColumnLayout/ThreeColumnLayout.tsx +87 -0
  272. package/src/components/ThreeColumnLayout/__tests__/ThreeColumnLayout.test.tsx +78 -0
  273. package/src/components/Toast/Toast.module.css +62 -3
  274. package/src/components/Toast/Toast.stories.tsx +1 -1
  275. package/src/components/Tooltip/Tooltip.module.css +1 -1
  276. package/src/components/UserMenu/UserMenu.module.css +90 -0
  277. package/src/components/UserMenu/UserMenu.stories.tsx +49 -0
  278. package/src/components/UserMenu/UserMenu.tsx +132 -0
  279. package/src/components/UserMenu/__tests__/UserMenu.test.tsx +77 -0
  280. package/src/hooks/__tests__/useCarouselRouteSync.test.tsx +126 -0
  281. package/src/hooks/__tests__/useIsOffline.test.tsx +53 -0
  282. package/src/hooks/__tests__/useOfflineTileState.test.tsx +69 -0
  283. package/src/hooks/__tests__/usePublishShellChromeHeight.test.tsx +118 -0
  284. package/src/hooks/__tests__/useReorderSensors.test.ts +26 -0
  285. package/src/hooks/__tests__/useResponsiveLayout.test.tsx +87 -0
  286. package/src/hooks/__tests__/useSnapCarousel.test.tsx +175 -0
  287. package/src/hooks/__tests__/useSwipeReveal.test.tsx +110 -0
  288. package/src/hooks/__tests__/useSwipeStack.test.tsx +155 -0
  289. package/src/hooks/index.ts +27 -0
  290. package/src/hooks/useCarouselRouteSync.ts +92 -0
  291. package/src/hooks/useIsOffline.ts +41 -0
  292. package/src/hooks/useOfflineTileState.ts +45 -0
  293. package/src/hooks/usePublishShellChromeHeight.ts +96 -0
  294. package/src/hooks/useReorderSensors.ts +88 -0
  295. package/src/hooks/useResponsiveLayout.ts +36 -0
  296. package/src/hooks/useSnapCarousel.ts +284 -0
  297. package/src/hooks/useSwipeReveal.ts +107 -0
  298. package/src/hooks/useSwipeStack.ts +235 -0
  299. package/src/index.ts +124 -3
  300. package/src/overlay-shell.ts +159 -0
  301. package/src/stories/DesignSystemOverview.stories.tsx +933 -6
  302. package/src/stories/DeviceOnlyGate.stories.tsx +35 -0
  303. package/src/stories/DeviceStorageKeyGate.stories.tsx +57 -0
  304. package/src/stories/GripIcon.stories.tsx +29 -0
  305. package/src/stories/InteractionHooks.stories.tsx +483 -0
  306. package/src/stories/LayoutSystem.stories.tsx +639 -0
  307. package/src/stories/MenuEntries.stories.tsx +86 -0
  308. package/src/stories/MobilePatterns.stories.tsx +247 -2
  309. package/src/stories/NavList.stories.tsx +147 -0
  310. package/src/stories/NavTabs.stories.tsx +18 -0
  311. package/src/stories/OfflineGate.stories.tsx +42 -0
  312. package/src/stories/PageContainer.stories.tsx +82 -0
  313. package/src/stories/PageHeader.stories.tsx +65 -1
  314. package/src/stories/ResponsiveSurface.stories.tsx +47 -0
  315. package/src/stories/StepStrip.stories.tsx +76 -0
  316. package/src/stories/SwipableMobileCarousel.stories.tsx +362 -0
  317. package/src/stories/SwipeStack.stories.tsx +200 -0
  318. package/src/stories/Textarea.stories.tsx +12 -0
  319. package/src/stories/TokenGallery.stories.tsx +115 -0
  320. package/src/tokens/primitives.css +36 -0
  321. package/src/tokens/semantic.css +32 -0
  322. package/src/tokens/theme-presets.css +33 -0
  323. package/src/tokens/theme-presets.ts +72 -0
@@ -0,0 +1,639 @@
1
+ import type { Meta, StoryObj } from '@storybook/react-vite';
2
+ import { AppsLauncher } from '../components/AppsLauncher/AppsLauncher';
3
+ import { Header } from '../components/Header/Header';
4
+ import { Icon } from '../components/Icon/Icon';
5
+ import { MobileFooter } from '../components/MobileFooter/MobileFooter';
6
+ import { MobileHeader } from '../components/MobileHeader/MobileHeader';
7
+ import { NotificationsPanel } from '../components/NotificationsPanel/NotificationsPanel';
8
+ import { OverlayHeader } from '../components/OverlayHeader/OverlayHeader';
9
+ import { PageHeader } from '../components/PageHeader/PageHeader';
10
+ import { PageLayout } from '../components/PageLayout/PageLayout';
11
+ import { RootLayout } from '../components/RootLayout/RootLayout';
12
+ import { UserMenu } from '../components/UserMenu/UserMenu';
13
+
14
+ // ---------------------------------------------------------------------------
15
+ // Shared primitives (mirrors the conventions in Overview/Mobile Patterns)
16
+ // ---------------------------------------------------------------------------
17
+
18
+ const ff = 'var(--sv-font-family)';
19
+
20
+ function Heading({ level = 2, children }: { level?: 1 | 2 | 3; children: React.ReactNode }) {
21
+ const sizes: Record<number, string> = { 1: '1.75rem', 2: '1.125rem', 3: '0.9375rem' };
22
+ const weights: Record<number, number> = { 1: 700, 2: 600, 3: 600 };
23
+ const Tag = `h${level}` as 'h1' | 'h2' | 'h3';
24
+ return (
25
+ <Tag
26
+ style={{
27
+ fontFamily: ff,
28
+ fontSize: sizes[level],
29
+ fontWeight: weights[level],
30
+ color: 'var(--sv-color-text-primary)',
31
+ margin: 0,
32
+ lineHeight: 1.3,
33
+ }}
34
+ >
35
+ {children}
36
+ </Tag>
37
+ );
38
+ }
39
+
40
+ function Body({ children }: { children: React.ReactNode }) {
41
+ return (
42
+ <p
43
+ style={{
44
+ fontFamily: ff,
45
+ fontSize: 'var(--sv-font-size-sm)',
46
+ color: 'var(--sv-color-text-muted)',
47
+ margin: '0.5rem 0 0',
48
+ lineHeight: 1.6,
49
+ }}
50
+ >
51
+ {children}
52
+ </p>
53
+ );
54
+ }
55
+
56
+ function SectionHeader({
57
+ title,
58
+ subtitle,
59
+ source,
60
+ }: {
61
+ title: string;
62
+ subtitle?: string;
63
+ source: string;
64
+ }) {
65
+ return (
66
+ <div
67
+ style={{
68
+ paddingBottom: 'var(--sv-space-3)',
69
+ borderBottom: '2px solid var(--sv-color-accent)',
70
+ marginBottom: 'var(--sv-space-5)',
71
+ }}
72
+ >
73
+ <Heading level={2}>{title}</Heading>
74
+ {subtitle && <Body>{subtitle}</Body>}
75
+ <p
76
+ style={{
77
+ fontFamily: 'var(--sv-font-family-mono)',
78
+ fontSize: '0.75rem',
79
+ color: 'var(--sv-color-text-muted)',
80
+ margin: '0.5rem 0 0',
81
+ }}
82
+ >
83
+ {source}
84
+ </p>
85
+ </div>
86
+ );
87
+ }
88
+
89
+ function Callout({ type, children }: { type: 'warn' | 'tip'; children: React.ReactNode }) {
90
+ const map = {
91
+ warn: {
92
+ bg: 'var(--sv-color-warning-surface)',
93
+ border: 'var(--sv-color-warning-border)',
94
+ text: 'var(--sv-color-warning-text)',
95
+ label: '⚠',
96
+ },
97
+ tip: {
98
+ bg: 'var(--sv-color-success-surface)',
99
+ border: 'var(--sv-color-success-border)',
100
+ text: 'var(--sv-color-success-text)',
101
+ label: '✓',
102
+ },
103
+ };
104
+ const c = map[type];
105
+ return (
106
+ <div
107
+ style={{
108
+ background: c.bg,
109
+ border: `1px solid ${c.border}`,
110
+ borderRadius: 'var(--sv-radius-md)',
111
+ padding: 'var(--sv-space-3) var(--sv-space-4)',
112
+ display: 'flex',
113
+ gap: 'var(--sv-space-2)',
114
+ alignItems: 'flex-start',
115
+ marginTop: 'var(--sv-space-4)',
116
+ }}
117
+ >
118
+ <span style={{ color: c.text, fontWeight: 700, flexShrink: 0, fontSize: '0.875rem' }}>
119
+ {c.label}
120
+ </span>
121
+ <p
122
+ style={{
123
+ fontFamily: ff,
124
+ fontSize: 'var(--sv-font-size-sm)',
125
+ color: c.text,
126
+ margin: 0,
127
+ lineHeight: 1.55,
128
+ }}
129
+ >
130
+ {children}
131
+ </p>
132
+ </div>
133
+ );
134
+ }
135
+
136
+ function Frame({ children }: { children: React.ReactNode }) {
137
+ return (
138
+ <div
139
+ style={{
140
+ border: '1px solid var(--sv-color-border)',
141
+ borderRadius: 'var(--sv-radius-lg)',
142
+ overflow: 'hidden',
143
+ fontFamily: ff,
144
+ fontSize: 'var(--sv-font-size-sm)',
145
+ }}
146
+ >
147
+ {children}
148
+ </div>
149
+ );
150
+ }
151
+
152
+ function ContentPlaceholder({ label = 'Plugin content area' }: { label?: string }) {
153
+ return (
154
+ <div
155
+ style={{
156
+ background: 'var(--sv-color-surface-sunken)',
157
+ padding: 'var(--sv-space-6) var(--sv-space-4)',
158
+ textAlign: 'center',
159
+ color: 'var(--sv-color-text-muted)',
160
+ fontSize: 'var(--sv-font-size-xs)',
161
+ }}
162
+ >
163
+ {label}
164
+ </div>
165
+ );
166
+ }
167
+
168
+ function IconButton({ name, label }: { name: Parameters<typeof Icon>[0]['name']; label: string }) {
169
+ return (
170
+ <span
171
+ aria-label={label}
172
+ style={{
173
+ display: 'inline-flex',
174
+ alignItems: 'center',
175
+ justifyContent: 'center',
176
+ width: 32,
177
+ height: 32,
178
+ borderRadius: 'var(--sv-radius-md)',
179
+ color: 'var(--sv-color-text-muted)',
180
+ }}
181
+ >
182
+ <Icon name={name} size="md" aria-hidden />
183
+ </span>
184
+ );
185
+ }
186
+
187
+ function Avatar({ initials, size = 32 }: { initials: string; size?: number }) {
188
+ return (
189
+ <span
190
+ aria-label={initials}
191
+ style={{
192
+ display: 'inline-flex',
193
+ alignItems: 'center',
194
+ justifyContent: 'center',
195
+ width: size,
196
+ height: size,
197
+ borderRadius: 'var(--sv-radius-full)',
198
+ background: 'var(--sv-color-accent)',
199
+ color: 'var(--sv-color-text-on-accent)',
200
+ fontSize: 'var(--sv-font-size-xs)',
201
+ fontWeight: 'var(--sv-font-weight-semibold)',
202
+ flexShrink: 0,
203
+ }}
204
+ >
205
+ {initials}
206
+ </span>
207
+ );
208
+ }
209
+
210
+ function BrandBadge({ size = 36 }: { size?: number }) {
211
+ return (
212
+ <span
213
+ aria-hidden="true"
214
+ style={{
215
+ display: 'inline-flex',
216
+ alignItems: 'center',
217
+ justifyContent: 'center',
218
+ width: size,
219
+ height: size,
220
+ borderRadius: 'var(--sv-radius-md)',
221
+ background: 'var(--sv-color-accent)',
222
+ color: 'var(--sv-color-text-on-accent)',
223
+ fontWeight: 700,
224
+ fontSize: size * 0.4,
225
+ flexShrink: 0,
226
+ }}
227
+ >
228
+ S
229
+ </span>
230
+ );
231
+ }
232
+
233
+ // ---------------------------------------------------------------------------
234
+ // 1. Web with Sidebar
235
+ // ---------------------------------------------------------------------------
236
+
237
+ function WebWithSidebar() {
238
+ return (
239
+ <Frame>
240
+ <div style={{ display: 'flex', minHeight: 240 }}>
241
+ <div
242
+ style={{
243
+ width: 64,
244
+ flexShrink: 0,
245
+ background: 'var(--sv-color-surface)',
246
+ borderRight: '1px solid var(--sv-color-border)',
247
+ display: 'flex',
248
+ flexDirection: 'column',
249
+ alignItems: 'center',
250
+ gap: 'var(--sv-space-3)',
251
+ padding: 'var(--sv-space-3) 0',
252
+ }}
253
+ >
254
+ <BrandBadge />
255
+ <hr
256
+ style={{
257
+ width: 32,
258
+ border: 'none',
259
+ borderTop: '1px solid var(--sv-color-border)',
260
+ margin: 0,
261
+ }}
262
+ />
263
+ <IconButton name="file" label="Notes" />
264
+ <IconButton name="house" label="Launcher" />
265
+ <div style={{ flex: 1 }} />
266
+ <IconButton name="bell" label="Notifications" />
267
+ <IconButton name="layout-dashboard" label="Console" />
268
+ <Avatar initials="KB" size={32} />
269
+ </div>
270
+ <div style={{ flex: 1 }}>
271
+ <ContentPlaceholder />
272
+ </div>
273
+ </div>
274
+ </Frame>
275
+ );
276
+ }
277
+
278
+ // ---------------------------------------------------------------------------
279
+ // 2. Web with Header
280
+ // ---------------------------------------------------------------------------
281
+
282
+ const layoutSystemLauncherItems = [
283
+ {
284
+ key: 'home',
285
+ icon: <Icon name="house" size="md" aria-hidden />,
286
+ label: 'Home',
287
+ href: '/launcher',
288
+ },
289
+ {
290
+ key: 'notes',
291
+ icon: <Icon name="file" size="md" aria-hidden />,
292
+ label: 'Notes',
293
+ href: '/notes',
294
+ },
295
+ ];
296
+
297
+ const layoutSystemAccountItems = [
298
+ { label: 'Account', icon: 'user' as const, href: '/account' },
299
+ { label: 'Sign out', icon: 'log-out' as const, destructive: true, onSelect: () => {} },
300
+ ];
301
+
302
+ function WebWithHeader() {
303
+ return (
304
+ <Frame>
305
+ <Header
306
+ instanceName="Sovereign"
307
+ homeHref="/launcher"
308
+ plugin={{
309
+ name: 'Notes',
310
+ // The plugin icon is 28px — same size as the brand badge next to
311
+ // it, not a smaller inline glyph.
312
+ icon: (
313
+ <span
314
+ aria-hidden="true"
315
+ style={{
316
+ display: 'inline-flex',
317
+ alignItems: 'center',
318
+ justifyContent: 'center',
319
+ width: 28,
320
+ height: 28,
321
+ }}
322
+ >
323
+ <span style={{ display: 'inline-flex', transform: 'scale(1.15)' }}>
324
+ <Icon name="file" size="lg" aria-hidden />
325
+ </span>
326
+ </span>
327
+ ),
328
+ href: '/notes',
329
+ }}
330
+ launcher={<AppsLauncher items={layoutSystemLauncherItems} />}
331
+ notifications={<NotificationsPanel items={[]} unreadCount={0} />}
332
+ avatarMenu={<UserMenu name="Kasun Benthara" items={layoutSystemAccountItems} size="sm" />}
333
+ />
334
+ <ContentPlaceholder />
335
+ </Frame>
336
+ );
337
+ }
338
+
339
+ // ---------------------------------------------------------------------------
340
+ // 3. Mobile Header and Footer
341
+ // ---------------------------------------------------------------------------
342
+
343
+ function MobileHeaderAndFooter() {
344
+ return (
345
+ <Frame>
346
+ <MobileHeader
347
+ title="Tasks"
348
+ bell={<IconButton name="bell" label="Notifications" />}
349
+ avatarMenu={<Avatar initials="JD" size={36} />}
350
+ />
351
+ <ContentPlaceholder />
352
+ <MobileFooter
353
+ onOpenApps={() => {}}
354
+ launcherOpen={false}
355
+ leftIcons={[
356
+ { icon: <Icon name="house" size="md" aria-hidden />, label: 'Home', active: true },
357
+ ]}
358
+ rightIcons={[{ icon: <Icon name="search" size="md" aria-hidden />, label: 'Search' }]}
359
+ />
360
+ </Frame>
361
+ );
362
+ }
363
+
364
+ // ---------------------------------------------------------------------------
365
+ // 4. Mobile Header, Secondary Header (Page Header)
366
+ // ---------------------------------------------------------------------------
367
+
368
+ function MobileSecondaryPageHeader() {
369
+ return (
370
+ <Frame>
371
+ <MobileHeader
372
+ title="Sovereign"
373
+ bell={<IconButton name="bell" label="Notifications" />}
374
+ avatarMenu={<Avatar initials="KB" size={36} />}
375
+ />
376
+ <div
377
+ style={{
378
+ display: 'flex',
379
+ alignItems: 'center',
380
+ gap: 'var(--sv-space-2)',
381
+ padding: 'var(--sv-space-2) var(--sv-space-3)',
382
+ background: 'var(--sv-color-surface)',
383
+ borderBottom: '1px solid var(--sv-color-border)',
384
+ }}
385
+ >
386
+ <IconButton name="circle-chevron-left" label="Back to boards" />
387
+ <span
388
+ style={{
389
+ flex: 1,
390
+ fontWeight: 600,
391
+ fontSize: 'var(--sv-font-size-md)',
392
+ color: 'var(--sv-color-text-primary)',
393
+ }}
394
+ >
395
+ Infra Migration
396
+ </span>
397
+ <IconButton name="ellipsis-vertical" label="Board options" />
398
+ </div>
399
+ <ContentPlaceholder label="Board content (lists/cards)" />
400
+ </Frame>
401
+ );
402
+ }
403
+
404
+ // ---------------------------------------------------------------------------
405
+ // 5. Mobile Header, Secondary Header (Dialog Header)
406
+ // ---------------------------------------------------------------------------
407
+
408
+ function MobileSecondaryDialogHeader() {
409
+ return (
410
+ <Frame>
411
+ <MobileHeader
412
+ bell={<IconButton name="bell" label="Notifications" />}
413
+ avatarMenu={<Avatar initials="KB" size={36} />}
414
+ />
415
+ <OverlayHeader
416
+ title="Console"
417
+ onClose={() => {}}
418
+ secondRow={
419
+ <nav aria-label="Console sections" style={{ display: 'flex', gap: 'var(--sv-space-4)' }}>
420
+ {['Overview', 'Users', 'Settings'].map((label, i) => (
421
+ <span
422
+ key={label}
423
+ style={{
424
+ fontSize: 'var(--sv-font-size-sm)',
425
+ fontWeight: i === 0 ? 600 : 400,
426
+ color: i === 0 ? 'var(--sv-color-text-primary)' : 'var(--sv-color-text-muted)',
427
+ paddingBottom: 'var(--sv-space-2)',
428
+ borderBottom: i === 0 ? '2px solid var(--sv-color-accent)' : 'none',
429
+ }}
430
+ >
431
+ {label}
432
+ </span>
433
+ ))}
434
+ </nav>
435
+ }
436
+ />
437
+ <ContentPlaceholder label="Console page content" />
438
+ </Frame>
439
+ );
440
+ }
441
+
442
+ // ---------------------------------------------------------------------------
443
+ // 6. Structural Layout Primitives
444
+ // ---------------------------------------------------------------------------
445
+
446
+ function StructuralLayoutPrimitives() {
447
+ return (
448
+ <Frame>
449
+ <div style={{ height: 320 }}>
450
+ <RootLayout variant="sidebar">
451
+ <div
452
+ style={{
453
+ width: '100%',
454
+ height: '100%',
455
+ background: 'var(--sv-color-surface)',
456
+ borderRight: '1px solid var(--sv-color-border)',
457
+ display: 'flex',
458
+ flexDirection: 'column',
459
+ alignItems: 'center',
460
+ gap: 'var(--sv-space-3)',
461
+ padding: 'var(--sv-space-3) 0',
462
+ }}
463
+ >
464
+ <BrandBadge />
465
+ <IconButton name="house" label="Home" />
466
+ <IconButton name="layers" label="Boards" />
467
+ </div>
468
+ <PageLayout
469
+ padding="md"
470
+ header={
471
+ <PageHeader
472
+ title="Boards"
473
+ description="Everything you're tracking."
474
+ action={<IconButton name="search" label="Search" />}
475
+ />
476
+ }
477
+ >
478
+ <ContentPlaceholder label="Page content" />
479
+ </PageLayout>
480
+ </RootLayout>
481
+ </div>
482
+ </Frame>
483
+ );
484
+ }
485
+
486
+ // ---------------------------------------------------------------------------
487
+ // Main story component
488
+ // ---------------------------------------------------------------------------
489
+
490
+ function LayoutSystemDoc() {
491
+ return (
492
+ <div
493
+ style={{
494
+ padding: 'var(--sv-space-6)',
495
+ background: 'var(--sv-color-surface)',
496
+ minHeight: '100vh',
497
+ fontFamily: ff,
498
+ maxWidth: 760,
499
+ }}
500
+ >
501
+ <div style={{ marginBottom: 'var(--sv-space-8)' }}>
502
+ <Heading level={1}>Layout System</Heading>
503
+ <Body>
504
+ The shell-chrome archetypes in use across the platform and its plugins today. Sections 1–5
505
+ each show the actual anatomy shipping in the code, cite their source, and flag where the
506
+ pattern is a shared design-system component versus a per-plugin reimplementation still
507
+ waiting to be extracted. Section 6 introduces a newer, general-purpose layer built on top
508
+ of that: structural layout primitives any plugin can compose directly, rather than
509
+ reimplementing shell chrome from scratch.
510
+ </Body>
511
+ </div>
512
+
513
+ <section style={{ marginBottom: 'var(--sv-space-10)' }}>
514
+ <SectionHeader
515
+ title="1. Web with Sidebar"
516
+ subtitle="The default desktop shell — a fixed vertical icon rail. shell: default (most plugins)."
517
+ source="runtime/app/(platform)/layout.tsx"
518
+ />
519
+ <WebWithSidebar />
520
+ <Callout type="warn">
521
+ Hand-rolled directly in the runtime shell — never extracted into <code>packages/ui</code>,
522
+ unlike <code>MobileHeader</code>/<code>MobileFooter</code> (RFC 0088). A general-purpose
523
+ version of this exact shape now exists as <code>RootLayout</code>'s{' '}
524
+ <code>variant=&quot;sidebar&quot;</code> (see Section 6 and{' '}
525
+ <code>Components/RootLayout</code>) — the runtime shell itself hasn't been migrated onto
526
+ it yet, so this section still documents its own hand-rolled markup as the source of truth
527
+ for what's actually shipping.
528
+ </Callout>
529
+ </section>
530
+
531
+ <section style={{ marginBottom: 'var(--sv-space-10)' }}>
532
+ <SectionHeader
533
+ title="2. Web with Header"
534
+ subtitle="A full-width top bar in place of the sidebar. shell: minimal plugins that own their whole viewport."
535
+ source="@sovereignfs/ui — Header, generalized from a real shell: minimal plugin's own hand-rolled top bar"
536
+ />
537
+ <WebWithHeader />
538
+ <Callout type="tip">
539
+ The chrome/layout, the apps switcher, notifications, and the account dropdown are all now
540
+ shared design-system components (<code>Header</code>, <code>AppsLauncher</code>,{' '}
541
+ <code>NotificationsPanel</code>, <code>UserMenu</code>) — generalized from a real{' '}
542
+ <code>shell: minimal</code> plugin's own hand-rolled top bar, apps switcher, notification
543
+ bell, and account menu. A future <code>shell: minimal</code> plugin no longer has to
544
+ rebuild any of this from scratch.
545
+ </Callout>
546
+ </section>
547
+
548
+ <section style={{ marginBottom: 'var(--sv-space-10)' }}>
549
+ <SectionHeader
550
+ title="3. Mobile Header and Footer"
551
+ subtitle="Brand/title + bell + avatar on top; a single Apps launcher button on the bottom."
552
+ source="@sovereignfs/ui — MobileHeader, MobileFooter (RFC 0088)"
553
+ />
554
+ <MobileHeaderAndFooter />
555
+ <Callout type="tip">
556
+ Already a shared design-system component, consumed by both the platform shell and{' '}
557
+ <code>shell: minimal</code> plugins. See the interactive prop playground in{' '}
558
+ <code>Overview/Mobile Patterns</code>.
559
+ </Callout>
560
+ </section>
561
+
562
+ <section style={{ marginBottom: 'var(--sv-space-10)' }}>
563
+ <SectionHeader
564
+ title="4. Mobile Header, Secondary Header (Page Header)"
565
+ subtitle="A contextual second row — back + title + options — stacked directly under MobileHeader as ordinary page content."
566
+ source="A real shell: minimal plugin's own bespoke board-detail header"
567
+ />
568
+ <MobileSecondaryPageHeader />
569
+ <Callout type="tip">
570
+ The API gap flagged here is now closed: <code>PageHeader</code>'s mobile fork (
571
+ <code>onBack</code> + <code>onMenuClick</code>, see <code>Components/PageHeader</code>)
572
+ was generalized directly from this plugin's own <code>MobileBoardHeader</code> and renders
573
+ this exact back + title + ellipsis-vertical shape. The plugin itself hasn't been migrated
574
+ onto it yet — its own hand-rolled version, shown above, is still what's actually shipping
575
+ — but any new mobile secondary header no longer needs to reimplement this from scratch.
576
+ </Callout>
577
+ </section>
578
+
579
+ <section style={{ marginBottom: 'var(--sv-space-10)' }}>
580
+ <SectionHeader
581
+ title="5. Mobile Header, Secondary Header (Dialog Header)"
582
+ subtitle="The same contextual second row, but lifted into the enclosing overlay's own header when the plugin is soft-navigated as a Dialog."
583
+ source="packages/ui — useOverlaySecondRow + Dialog's OverlayHeader; see plugins/console, plugins/account"
584
+ />
585
+ <MobileSecondaryDialogHeader />
586
+ <Callout type="tip">
587
+ Already a shared pattern — <code>useOverlaySecondRow</code> hands a plugin's own nav strip
588
+ up into <code>Dialog</code>'s <code>OverlayHeader.secondRow</code> whenever the plugin is
589
+ opened as an overlay, with no duplicated markup.
590
+ </Callout>
591
+ </section>
592
+
593
+ <section style={{ marginBottom: 'var(--sv-space-10)' }}>
594
+ <SectionHeader
595
+ title="6. Structural Layout Primitives"
596
+ subtitle="RootLayout + PageLayout + PageHeader composed together — the sidebar shape from Section 1, with a page-level header and content area nested inside."
597
+ source="@sovereignfs/ui — RootLayout, ThreeColumnLayout, HeaderFooterLayout, PageLayout, PageHeader"
598
+ />
599
+ <StructuralLayoutPrimitives />
600
+ <Callout type="tip">
601
+ Unlike sections 1–5, these aren't documenting one specific plugin's shipped code — they're
602
+ general-purpose primitives any plugin can adopt directly today. <code>RootLayout</code> is
603
+ the root a plugin's page tree sits in (<code>variant</code>: plain, sidebar, header, or
604
+ shell — each a fixed web+mobile pairing); <code>ThreeColumnLayout</code> and{' '}
605
+ <code>HeaderFooterLayout</code> are the positional primitives it composes internally, also
606
+ usable standalone for a list-app's own nested split view; <code>PageLayout</code> is a
607
+ single page's content area nested inside <code>RootLayout</code>'s main slot, intended to
608
+ eventually replace <code>PageContainer</code> entirely; <code>PageHeader</code> is that
609
+ page's title section, with its own web/mobile fork (see the Section 1 and 4 callouts above
610
+ for exactly which real shell-chrome gaps it closes). Each has its own interactive
611
+ Storybook page under <code>Components/</code> with the full prop playground.
612
+ </Callout>
613
+ </section>
614
+ </div>
615
+ );
616
+ }
617
+
618
+ // ---------------------------------------------------------------------------
619
+ // Story
620
+ // ---------------------------------------------------------------------------
621
+
622
+ const meta = {
623
+ title: 'Overview/Layout System',
624
+ component: LayoutSystemDoc,
625
+ parameters: {
626
+ layout: 'fullscreen',
627
+ docs: {
628
+ description: {
629
+ component:
630
+ 'Catalog of the shell-chrome layout archetypes in use across the platform and its plugins — which are shared design-system components and which are still per-plugin reimplementations.',
631
+ },
632
+ },
633
+ },
634
+ } satisfies Meta<typeof LayoutSystemDoc>;
635
+
636
+ export default meta;
637
+ type Story = StoryObj<typeof meta>;
638
+
639
+ export const Default: Story = {};