@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.
- package/dist/Accordion.module.css +1 -1
- package/dist/Alert.module.css +1 -1
- package/dist/AppsLauncher.module.css +96 -0
- package/dist/Avatar.module.css +1 -1
- package/dist/Badge.module.css +30 -7
- package/dist/BalanceChip.module.css +1 -1
- package/dist/Button.module.css +18 -2
- package/dist/Card.module.css +1 -1
- package/dist/CardTile.module.css +181 -0
- package/dist/CodeTextarea.module.css +1 -1
- package/dist/Collapsible.module.css +1 -1
- package/dist/ColorPicker.module.css +132 -0
- package/dist/Combobox.module.css +2 -2
- package/dist/Command.module.css +1 -1
- package/dist/ConfirmDialog.module.css +2 -2
- package/dist/ConsentPrompt.module.css +21 -0
- package/dist/DatePicker.module.css +1 -1
- package/dist/Dialog.module.css +130 -21
- package/dist/Drawer.module.css +36 -7
- package/dist/Header.module.css +62 -0
- package/dist/HeaderFooterLayout.module.css +21 -0
- package/dist/IconPicker.module.css +1 -1
- package/dist/Input.module.css +1 -1
- package/dist/Kbd.module.css +1 -1
- package/dist/LegalLinks.module.css +24 -0
- package/dist/Markdown.module.css +73 -0
- package/dist/Menu.module.css +1 -0
- package/dist/Message.module.css +1 -1
- package/dist/MessageScroller.module.css +12 -1
- package/dist/MobileAppsDrawer.module.css +82 -0
- package/dist/MobileFooter.module.css +73 -0
- package/dist/MobileHeader.module.css +76 -0
- package/dist/NavList.module.css +130 -0
- package/dist/NavTabs.module.css +1 -1
- package/dist/NotificationsPanel.module.css +258 -0
- package/dist/OverlayHeader.module.css +1 -1
- package/dist/PageContainer.module.css +82 -0
- package/dist/PageHeader.module.css +54 -0
- package/dist/PageLayout.module.css +51 -0
- package/dist/Popover.module.css +1 -1
- package/dist/QuantityStepper.module.css +1 -1
- package/dist/Resizable.module.css +3 -3
- package/dist/RootLayout.module.css +12 -0
- package/dist/SegmentedControl.module.css +1 -1
- package/dist/Select.module.css +1 -1
- package/dist/Sheet.module.css +4 -1
- package/dist/SplitPane.module.css +4 -4
- package/dist/StatusBadge.module.css +1 -1
- package/dist/StepStrip.module.css +53 -0
- package/dist/SuggestionInput.module.css +2 -2
- package/dist/SwipableMobileCarousel.module.css +64 -0
- package/dist/SwipableMobileCarouselDots.module.css +64 -0
- package/dist/SwipableMobileCarouselSlideParts.module.css +29 -0
- package/dist/SwipeStack.module.css +101 -0
- package/dist/SystemBanner.module.css +10 -0
- package/dist/Table.module.css +2 -2
- package/dist/Tabs.module.css +1 -1
- package/dist/TagInput.module.css +2 -2
- package/dist/Textarea.module.css +9 -1
- package/dist/ThreeColumnLayout.module.css +35 -0
- package/dist/Toast.module.css +62 -3
- package/dist/Tooltip.module.css +1 -1
- package/dist/UserMenu.module.css +90 -0
- package/dist/index.d.ts +1680 -30
- package/dist/index.js +4618 -1443
- package/dist/tokens/primitives.css +36 -0
- package/dist/tokens/semantic.css +32 -0
- package/dist/tokens/theme-presets.css +33 -0
- package/package.json +32 -12
- package/src/__tests__/package-json.test.ts +8 -0
- package/src/components/Accordion/Accordion.module.css +1 -1
- package/src/components/Alert/Alert.module.css +1 -1
- package/src/components/AppsLauncher/AppsLauncher.module.css +96 -0
- package/src/components/AppsLauncher/AppsLauncher.stories.tsx +58 -0
- package/src/components/AppsLauncher/AppsLauncher.tsx +117 -0
- package/src/components/AppsLauncher/__tests__/AppsLauncher.test.tsx +52 -0
- package/src/components/Avatar/Avatar.module.css +1 -1
- package/src/components/Badge/Badge.module.css +30 -7
- package/src/components/Badge/Badge.stories.tsx +16 -4
- package/src/components/Badge/Badge.tsx +8 -11
- package/src/components/Badge/__tests__/Badge.test.tsx +4 -2
- package/src/components/BalanceChip/BalanceChip.module.css +1 -1
- package/src/components/Button/Button.module.css +18 -2
- package/src/components/Card/Card.module.css +1 -1
- package/src/components/CardTile/CardTile.module.css +181 -0
- package/src/components/CardTile/CardTile.stories.tsx +86 -0
- package/src/components/CardTile/CardTile.tsx +128 -0
- package/src/components/CardTile/__tests__/CardTile.test.tsx +56 -0
- package/src/components/CodeTextarea/CodeTextarea.module.css +1 -1
- package/src/components/Collapsible/Collapsible.module.css +1 -1
- package/src/components/ColorPicker/ColorPicker.module.css +132 -0
- package/src/components/ColorPicker/ColorPicker.stories.tsx +80 -0
- package/src/components/ColorPicker/ColorPicker.tsx +157 -0
- package/src/components/ColorPicker/__tests__/ColorPicker.test.tsx +117 -0
- package/src/components/Combobox/Combobox.module.css +2 -2
- package/src/components/Command/Command.module.css +1 -1
- package/src/components/ConfirmDialog/ConfirmDialog.module.css +2 -2
- package/src/components/ConfirmDialog/ConfirmDialog.tsx +28 -2
- package/src/components/ConfirmDialog/__tests__/ConfirmDialog.test.tsx +71 -3
- package/src/components/ConsentPrompt/ConsentPrompt.module.css +21 -0
- package/src/components/ConsentPrompt/ConsentPrompt.stories.tsx +31 -0
- package/src/components/ConsentPrompt/ConsentPrompt.tsx +66 -0
- package/src/components/ContextMenu/ContextMenu.tsx +1 -1
- package/src/components/DatePicker/DatePicker.module.css +1 -1
- package/src/components/DeviceOnlyGate/DeviceOnlyGate.tsx +58 -0
- package/src/components/DeviceOnlyGate/__tests__/DeviceOnlyGate.test.tsx +45 -0
- package/src/components/DeviceStorageKeyGate/DeviceStorageKeyGate.tsx +100 -0
- package/src/components/DeviceStorageKeyGate/__tests__/DeviceStorageKeyGate.test.tsx +119 -0
- package/src/components/Dialog/Dialog.module.css +130 -21
- package/src/components/Dialog/Dialog.stories.tsx +179 -2
- package/src/components/Dialog/Dialog.tsx +137 -94
- package/src/components/Dialog/__tests__/Dialog.test.tsx +190 -9
- package/src/components/DragHandleRow/DragHandleRow.tsx +2 -21
- package/src/components/Drawer/Drawer.module.css +36 -7
- package/src/components/Drawer/Drawer.stories.tsx +44 -0
- package/src/components/Drawer/Drawer.tsx +27 -66
- package/src/components/Drawer/__tests__/Drawer.test.tsx +55 -6
- package/src/components/GripIcon/GripIcon.tsx +27 -0
- package/src/components/Header/Header.module.css +62 -0
- package/src/components/Header/Header.stories.tsx +452 -0
- package/src/components/Header/Header.tsx +102 -0
- package/src/components/Header/__tests__/Header.test.tsx +104 -0
- package/src/components/HeaderFooterLayout/HeaderFooterLayout.module.css +21 -0
- package/src/components/HeaderFooterLayout/HeaderFooterLayout.stories.tsx +111 -0
- package/src/components/HeaderFooterLayout/HeaderFooterLayout.tsx +54 -0
- package/src/components/HeaderFooterLayout/__tests__/HeaderFooterLayout.test.tsx +58 -0
- package/src/components/Icon/icons/arrow-left-right.tsx +23 -0
- package/src/components/Icon/icons/bold.tsx +20 -0
- package/src/components/Icon/icons/calendar.tsx +4 -4
- package/src/components/Icon/icons/carrot.tsx +3 -3
- package/src/components/Icon/icons/circle-chevron-left.tsx +21 -0
- package/src/components/Icon/icons/code.tsx +21 -0
- package/src/components/Icon/icons/copy.tsx +21 -0
- package/src/components/Icon/icons/credit-card.tsx +21 -0
- package/src/components/Icon/icons/database.tsx +22 -0
- package/src/components/Icon/icons/download.tsx +22 -0
- package/src/components/Icon/icons/file-text.tsx +24 -0
- package/src/components/Icon/icons/folder-closed.tsx +21 -0
- package/src/components/Icon/icons/folder-open.tsx +20 -0
- package/src/components/Icon/icons/folder.tsx +20 -0
- package/src/components/Icon/icons/folders.tsx +21 -0
- package/src/components/Icon/icons/hat-glasses.tsx +24 -0
- package/src/components/Icon/icons/history.tsx +22 -0
- package/src/components/Icon/icons/inbox.tsx +21 -0
- package/src/components/Icon/icons/index.ts +169 -1
- package/src/components/Icon/icons/italic.tsx +22 -0
- package/src/components/Icon/icons/layers.tsx +22 -0
- package/src/components/Icon/icons/layout-dashboard.tsx +23 -0
- package/src/components/Icon/icons/layout-grid.tsx +23 -0
- package/src/components/Icon/icons/link.tsx +21 -0
- package/src/components/Icon/icons/list-ordered.tsx +25 -0
- package/src/components/Icon/icons/list.tsx +25 -0
- package/src/components/Icon/icons/luggage.tsx +24 -0
- package/src/components/Icon/icons/map-pin.tsx +21 -0
- package/src/components/Icon/icons/menu.tsx +22 -0
- package/src/components/Icon/icons/minus.tsx +20 -0
- package/src/components/Icon/icons/paint-bucket.tsx +23 -0
- package/src/components/Icon/icons/panel-left.tsx +21 -0
- package/src/components/Icon/icons/pin.tsx +21 -0
- package/src/components/Icon/icons/rectangle-ellipsis.tsx +23 -0
- package/src/components/Icon/icons/refresh-cw.tsx +23 -0
- package/src/components/Icon/icons/rotate-cw.tsx +21 -0
- package/src/components/Icon/icons/route.tsx +22 -0
- package/src/components/Icon/icons/send.tsx +21 -0
- package/src/components/Icon/icons/share-2.tsx +24 -0
- package/src/components/Icon/icons/sheet.tsx +24 -0
- package/src/components/Icon/icons/smartphone.tsx +21 -0
- package/src/components/Icon/icons/square-kanban.tsx +23 -0
- package/src/components/Icon/icons/table.tsx +23 -0
- package/src/components/Icon/icons/user-round-plus.tsx +23 -0
- package/src/components/Icon/icons/users.tsx +23 -0
- package/src/components/IconPicker/IconPicker.module.css +1 -1
- package/src/components/Input/Input.module.css +1 -1
- package/src/components/Input/Input.tsx +8 -2
- package/src/components/Kbd/Kbd.module.css +1 -1
- package/src/components/LegalLinks/LegalLinks.module.css +24 -0
- package/src/components/LegalLinks/LegalLinks.stories.tsx +22 -0
- package/src/components/LegalLinks/LegalLinks.tsx +40 -0
- package/src/components/Markdown/Markdown.module.css +73 -0
- package/src/components/Markdown/Markdown.stories.tsx +40 -0
- package/src/components/Markdown/Markdown.tsx +305 -0
- package/src/components/Markdown/__tests__/Markdown.test.tsx +144 -0
- package/src/components/Menu/Menu.module.css +1 -0
- package/src/components/Menu/Menu.tsx +72 -22
- package/src/components/Menu/__tests__/Menu.test.tsx +30 -0
- package/src/components/Menubar/Menubar.tsx +1 -1
- package/src/components/Message/Message.module.css +1 -1
- package/src/components/MessageScroller/MessageScroller.module.css +12 -1
- package/src/components/MessageScroller/MessageScroller.tsx +12 -0
- package/src/components/MobileAppsDrawer/MobileAppsDrawer.module.css +82 -0
- package/src/components/MobileAppsDrawer/MobileAppsDrawer.tsx +78 -0
- package/src/components/MobileAppsDrawer/__tests__/MobileAppsDrawer.test.tsx +80 -0
- package/src/components/MobileFooter/MobileFooter.module.css +73 -0
- package/src/components/MobileFooter/MobileFooter.stories.tsx +47 -0
- package/src/components/MobileFooter/MobileFooter.tsx +122 -0
- package/src/components/MobileFooter/__tests__/MobileFooter.test.tsx +129 -0
- package/src/components/MobileHeader/MobileHeader.module.css +76 -0
- package/src/components/MobileHeader/MobileHeader.stories.tsx +57 -0
- package/src/components/MobileHeader/MobileHeader.tsx +90 -0
- package/src/components/MobileHeader/__tests__/MobileHeader.test.tsx +113 -0
- package/src/components/NavList/NavList.module.css +130 -0
- package/src/components/NavList/NavList.tsx +136 -0
- package/src/components/NavList/__tests__/NavList.test.tsx +109 -0
- package/src/components/NavTabs/NavTabs.module.css +1 -1
- package/src/components/NavTabs/NavTabs.tsx +39 -11
- package/src/components/NotificationsPanel/NotificationsPanel.module.css +258 -0
- package/src/components/NotificationsPanel/NotificationsPanel.stories.tsx +61 -0
- package/src/components/NotificationsPanel/NotificationsPanel.tsx +187 -0
- package/src/components/NotificationsPanel/__tests__/NotificationsPanel.test.tsx +78 -0
- package/src/components/OfflineGate/OfflineGate.tsx +44 -0
- package/src/components/OfflineGate/__tests__/OfflineGate.test.tsx +66 -0
- package/src/components/OverlayHeader/OverlayHeader.module.css +1 -1
- package/src/components/OverlayHeader/OverlayHeader.tsx +19 -4
- package/src/components/OverlayHeader/__tests__/OverlayHeader.test.tsx +18 -0
- package/src/components/PageContainer/PageContainer.module.css +82 -0
- package/src/components/PageContainer/PageContainer.tsx +64 -0
- package/src/components/PageContainer/__tests__/PageContainer.test.tsx +70 -0
- package/src/components/PageHeader/PageHeader.module.css +54 -0
- package/src/components/PageHeader/PageHeader.tsx +157 -2
- package/src/components/PageHeader/__tests__/PageHeader.test.tsx +103 -0
- package/src/components/PageLayout/PageLayout.module.css +51 -0
- package/src/components/PageLayout/PageLayout.stories.tsx +73 -0
- package/src/components/PageLayout/PageLayout.tsx +51 -0
- package/src/components/PageLayout/__tests__/PageLayout.test.tsx +34 -0
- package/src/components/Popover/Popover.module.css +1 -1
- package/src/components/Popover/Popover.tsx +86 -4
- package/src/components/Popover/__tests__/Popover.test.tsx +165 -0
- package/src/components/QuantityStepper/QuantityStepper.module.css +1 -1
- package/src/components/Resizable/Resizable.module.css +3 -3
- package/src/components/ResponsiveSurface/ResponsiveSurface.tsx +24 -0
- package/src/components/ResponsiveSurface/__tests__/ResponsiveSurface.test.tsx +73 -0
- package/src/components/RootLayout/RootLayout.module.css +12 -0
- package/src/components/RootLayout/RootLayout.stories.tsx +125 -0
- package/src/components/RootLayout/RootLayout.tsx +185 -0
- package/src/components/RootLayout/__tests__/RootLayout.test.tsx +161 -0
- package/src/components/SegmentedControl/SegmentedControl.module.css +1 -1
- package/src/components/Select/Select.module.css +1 -1
- package/src/components/Sheet/Sheet.module.css +4 -1
- package/src/components/Sheet/Sheet.tsx +14 -56
- package/src/components/SplitPane/SplitPane.module.css +4 -4
- package/src/components/StatusBadge/StatusBadge.module.css +1 -1
- package/src/components/StepStrip/StepStrip.module.css +53 -0
- package/src/components/StepStrip/StepStrip.tsx +74 -0
- package/src/components/SuggestionInput/SuggestionInput.module.css +2 -2
- package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.module.css +64 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarousel.tsx +243 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlide.tsx +35 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideBody.tsx +42 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideFooter.tsx +18 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideHeader.tsx +21 -0
- package/src/components/SwipableMobileCarousel/SwipableMobileCarouselSlideParts.module.css +29 -0
- package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarousel.test.tsx +214 -0
- package/src/components/SwipableMobileCarousel/__tests__/SwipableMobileCarouselDevGuard.test.tsx +61 -0
- package/src/components/SwipableMobileCarousel/context.ts +13 -0
- package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.module.css +64 -0
- package/src/components/SwipableMobileCarouselDots/SwipableMobileCarouselDots.tsx +73 -0
- package/src/components/SwipableMobileCarouselDots/__tests__/SwipableMobileCarouselDots.test.tsx +63 -0
- package/src/components/SwipeStack/SwipeStack.module.css +101 -0
- package/src/components/SwipeStack/SwipeStack.tsx +199 -0
- package/src/components/SwipeStack/SwipeStackCard.tsx +22 -0
- package/src/components/SwipeStack/__tests__/SwipeStack.test.tsx +169 -0
- package/src/components/SystemBanner/SystemBanner.module.css +10 -0
- package/src/components/Table/Table.module.css +2 -2
- package/src/components/Tabs/Tabs.module.css +1 -1
- package/src/components/TagInput/TagInput.module.css +2 -2
- package/src/components/Textarea/Textarea.module.css +9 -1
- package/src/components/Textarea/Textarea.tsx +28 -5
- package/src/components/Textarea/__tests__/Textarea.test.tsx +23 -1
- package/src/components/ThreeColumnLayout/ThreeColumnLayout.module.css +35 -0
- package/src/components/ThreeColumnLayout/ThreeColumnLayout.stories.tsx +152 -0
- package/src/components/ThreeColumnLayout/ThreeColumnLayout.tsx +87 -0
- package/src/components/ThreeColumnLayout/__tests__/ThreeColumnLayout.test.tsx +78 -0
- package/src/components/Toast/Toast.module.css +62 -3
- package/src/components/Toast/Toast.stories.tsx +1 -1
- package/src/components/Tooltip/Tooltip.module.css +1 -1
- package/src/components/UserMenu/UserMenu.module.css +90 -0
- package/src/components/UserMenu/UserMenu.stories.tsx +49 -0
- package/src/components/UserMenu/UserMenu.tsx +132 -0
- package/src/components/UserMenu/__tests__/UserMenu.test.tsx +77 -0
- package/src/hooks/__tests__/useCarouselRouteSync.test.tsx +126 -0
- package/src/hooks/__tests__/useIsOffline.test.tsx +53 -0
- package/src/hooks/__tests__/useOfflineTileState.test.tsx +69 -0
- package/src/hooks/__tests__/usePublishShellChromeHeight.test.tsx +118 -0
- package/src/hooks/__tests__/useReorderSensors.test.ts +26 -0
- package/src/hooks/__tests__/useResponsiveLayout.test.tsx +87 -0
- package/src/hooks/__tests__/useSnapCarousel.test.tsx +175 -0
- package/src/hooks/__tests__/useSwipeReveal.test.tsx +110 -0
- package/src/hooks/__tests__/useSwipeStack.test.tsx +155 -0
- package/src/hooks/index.ts +27 -0
- package/src/hooks/useCarouselRouteSync.ts +92 -0
- package/src/hooks/useIsOffline.ts +41 -0
- package/src/hooks/useOfflineTileState.ts +45 -0
- package/src/hooks/usePublishShellChromeHeight.ts +96 -0
- package/src/hooks/useReorderSensors.ts +88 -0
- package/src/hooks/useResponsiveLayout.ts +36 -0
- package/src/hooks/useSnapCarousel.ts +284 -0
- package/src/hooks/useSwipeReveal.ts +107 -0
- package/src/hooks/useSwipeStack.ts +235 -0
- package/src/index.ts +124 -3
- package/src/overlay-shell.ts +159 -0
- package/src/stories/DesignSystemOverview.stories.tsx +933 -6
- package/src/stories/DeviceOnlyGate.stories.tsx +35 -0
- package/src/stories/DeviceStorageKeyGate.stories.tsx +57 -0
- package/src/stories/GripIcon.stories.tsx +29 -0
- package/src/stories/InteractionHooks.stories.tsx +483 -0
- package/src/stories/LayoutSystem.stories.tsx +639 -0
- package/src/stories/MenuEntries.stories.tsx +86 -0
- package/src/stories/MobilePatterns.stories.tsx +247 -2
- package/src/stories/NavList.stories.tsx +147 -0
- package/src/stories/NavTabs.stories.tsx +18 -0
- package/src/stories/OfflineGate.stories.tsx +42 -0
- package/src/stories/PageContainer.stories.tsx +82 -0
- package/src/stories/PageHeader.stories.tsx +65 -1
- package/src/stories/ResponsiveSurface.stories.tsx +47 -0
- package/src/stories/StepStrip.stories.tsx +76 -0
- package/src/stories/SwipableMobileCarousel.stories.tsx +362 -0
- package/src/stories/SwipeStack.stories.tsx +200 -0
- package/src/stories/Textarea.stories.tsx +12 -0
- package/src/stories/TokenGallery.stories.tsx +115 -0
- package/src/tokens/primitives.css +36 -0
- package/src/tokens/semantic.css +32 -0
- package/src/tokens/theme-presets.css +33 -0
- 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="sidebar"</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 = {};
|