@wallarm-org/design-system 1.28.0 → 1.28.2-rc-fix-table-window-scroll-root.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 (52) hide show
  1. package/dist/components/RemoteShell/NavPanelContent.d.ts +5 -0
  2. package/dist/components/RemoteShell/NavPanelContent.js +6 -4
  3. package/dist/components/RemoteShell/RemoteShell.d.ts +30 -1
  4. package/dist/components/RemoteShell/RemoteShell.js +35 -18
  5. package/dist/components/RemoteShell/RemoteShellPanel.js +10 -4
  6. package/dist/components/RemoteShell/model/index.d.ts +1 -1
  7. package/dist/components/RemoteShell/model/index.js +1 -1
  8. package/dist/components/RemoteShell/model/useDrillTransition.d.ts +12 -1
  9. package/dist/components/RemoteShell/model/useDrillTransition.js +24 -12
  10. package/dist/components/RemoteShell/model/useLocationPathname.d.ts +2 -0
  11. package/dist/components/RemoteShell/model/useLocationPathname.js +4 -1
  12. package/dist/components/Table/TableBody/TableBodyVirtualizedCore.js +1 -1
  13. package/dist/components/Table/TableBody/TableBodyVirtualizedWindow.js +25 -9
  14. package/dist/components/Table/TableInner/TableInnerWindow.js +1 -0
  15. package/dist/components/Table/hooks/infiniteScroll/useInfiniteScroll.d.ts +1 -1
  16. package/dist/components/Table/hooks/infiniteScroll/usePrependScrollAnchor.d.ts +1 -0
  17. package/dist/components/Table/hooks/infiniteScroll/usePrependScrollAnchor.js +12 -10
  18. package/dist/components/Table/hooks/infiniteScroll/useScrollEdge.d.ts +4 -1
  19. package/dist/components/Table/hooks/infiniteScroll/useScrollEdge.js +4 -17
  20. package/dist/components/Table/lib/index.d.ts +1 -0
  21. package/dist/components/Table/lib/index.js +1 -0
  22. package/dist/components/Table/lib/scrollRoot.d.ts +18 -0
  23. package/dist/components/Table/lib/scrollRoot.js +22 -0
  24. package/dist/components/Table/types.d.ts +4 -1
  25. package/dist/metadata/components.json +26 -8
  26. package/package.json +2 -1
  27. package/dist/components/AppShell/story-content/_storyAccountDropdown.d.ts +0 -11
  28. package/dist/components/AppShell/story-content/_storyAccountDropdown.js +0 -242
  29. package/dist/components/AppShell/story-content/_storyConfigRenderer.d.ts +0 -12
  30. package/dist/components/AppShell/story-content/_storyConfigRenderer.js +0 -81
  31. package/dist/components/AppShell/story-content/_storyHeaderActions.d.ts +0 -1
  32. package/dist/components/AppShell/story-content/_storyHeaderActions.js +0 -59
  33. package/dist/components/AppShell/story-content/_storyHomeContent.d.ts +0 -2
  34. package/dist/components/AppShell/story-content/_storyHomeContent.js +0 -15
  35. package/dist/components/AppShell/story-content/_storyLib.d.ts +0 -9
  36. package/dist/components/AppShell/story-content/_storyLib.js +0 -39
  37. package/dist/components/AppShell/story-content/_storyNavConfigs.d.ts +0 -6
  38. package/dist/components/AppShell/story-content/_storyNavConfigs.js +0 -772
  39. package/dist/components/AppShell/story-content/_storyNavRailFooter.d.ts +0 -13
  40. package/dist/components/AppShell/story-content/_storyNavRailFooter.js +0 -26
  41. package/dist/components/AppShell/story-content/_storyProductNavItems.d.ts +0 -7
  42. package/dist/components/AppShell/story-content/_storyProductNavItems.js +0 -49
  43. package/dist/components/AppShell/story-content/_storyQuickHelpDropdown.d.ts +0 -1
  44. package/dist/components/AppShell/story-content/_storyQuickHelpDropdown.js +0 -144
  45. package/dist/components/AppShell/story-content/_storyRecentDropdown.d.ts +0 -1
  46. package/dist/components/AppShell/story-content/_storyRecentDropdown.js +0 -89
  47. package/dist/components/AppShell/story-content/_storySearchModal.d.ts +0 -1
  48. package/dist/components/AppShell/story-content/_storySearchModal.js +0 -252
  49. package/dist/components/AppShell/story-content/_storyWallarmLogo.d.ts +0 -1
  50. package/dist/components/AppShell/story-content/_storyWallarmLogo.js +0 -21
  51. package/dist/components/AppShell/story-content/index.d.ts +0 -11
  52. package/dist/components/AppShell/story-content/index.js +0 -11
@@ -1,6 +1,6 @@
1
1
  {
2
- "version": "1.27.0",
3
- "generatedAt": "2026-09-30T12:41:24.546Z",
2
+ "version": "1.28.1",
3
+ "generatedAt": "2026-09-30T15:40:03.193Z",
4
4
  "components": [
5
5
  {
6
6
  "name": "Accordion",
@@ -5341,23 +5341,28 @@
5341
5341
  "examples": [
5342
5342
  {
5343
5343
  "name": "Basic",
5344
- "code": "({ ambient }) => <Shell ambient={ambient} />",
5344
+ "code": "({ ambient }) => (\n <StoryRouter>\n <Shell ambient={ambient} />\n </StoryRouter>\n)",
5345
5345
  "description": "The three regions composed once — `AppShellHeader`, `AppShellRail`, `AppShellRemote` — with the content surface being the only part that scrolls. Pick a product in the rail to drill into it, and the account item at the bottom for appearance and sidebar mode."
5346
5346
  },
5347
5347
  {
5348
5348
  "name": "Loading",
5349
- "code": "({ ambient, loading }) => (\n <Shell ambient={ambient} loading={loading} simulateProductLoading />\n)",
5349
+ "code": "({ ambient, loading }) => (\n <StoryRouter>\n <Shell ambient={ambient} loading={loading} simulateProductLoading />\n </StoryRouter>\n)",
5350
5350
  "description": "How the shell looks while the platform loads. The header actions and the product rail hold skeletons that sit exactly where the real items land, so nothing jumps when they arrive. Turn `loading` off in Controls to watch the swap. Opening a product also shows its own panel and content loading."
5351
5351
  },
5352
5352
  {
5353
5353
  "name": "RevealFlow",
5354
- "code": "() => {\n const pathname = useLocationPathname();\n const activeProduct = deriveProduct(pathname);\n\n const [splashDone, setSplashDone] = useState(false);\n const [sidebarMode, setSidebarMode] = useState<SidebarMode>('adaptive');\n const [revealKey, setRevealKey] = useState(0);\n const { theme, setTheme } = useTheme();\n const railMode = railModeFor(sidebarMode, activeProduct === 'home');\n\n useEffect(() => {\n if (splashDone) return;\n const timer = setTimeout(() => setSplashDone(true), 2000);\n return () => clearTimeout(timer);\n }, [splashDone]);\n\n const handleReplay = () => {\n setSplashDone(false);\n setRevealKey(k => k + 1);\n };\n\n if (!splashDone) {\n return (\n <div key={revealKey} className='h-screen w-screen bg-bg-page-bg'>\n <SplashScreen />\n </div>\n );\n }\n\n return (\n <AppShell key={revealKey} reveal>\n <AppShellHeader>\n <TopHeader>\n <TopHeaderLogo href='/'>\n <WallarmLogo />\n </TopHeaderLogo>\n\n <TopHeaderActions>\n <HeaderActions />\n </TopHeaderActions>\n </TopHeader>\n </AppShellHeader>\n\n <AppShellRail>\n <NavRail mode={railMode}>\n <NavRailBody>\n <NavRailItem\n icon={Home}\n label='Home'\n shortcut={['G', 'H']}\n active={activeProduct === 'home'}\n onClick={() => navigateToProduct('home')}\n />\n <RecentDropdown />\n\n <NavRailSeparator />\n\n <ProductNavItems activeProduct={activeProduct} />\n </NavRailBody>\n\n <NavRailFooterContent\n activeProduct={activeProduct}\n sidebarMode={sidebarMode}\n onSidebarModeChange={setSidebarMode}\n theme={theme}\n onThemeChange={setTheme}\n />\n </NavRail>\n </AppShellRail>\n\n <AppShellRemote>\n <div className='flex gap-8 absolute top-4 right-4 z-10'>\n <Button variant='ghost' size='small' color='neutral' onClick={handleReplay}>\n Replay animation\n </Button>\n </div>\n\n <RemoteForProduct product={activeProduct} />\n </AppShellRemote>\n </AppShell>\n );\n}",
5354
+ "code": "() => (\n <StoryRouter>\n <RevealFlowShell />\n </StoryRouter>\n)",
5355
5355
  "description": "`reveal` animates the chrome in on the first application load only. Leave it unset for an ordinary screen; this exists for prototyping the boot moment itself."
5356
5356
  },
5357
5357
  {
5358
5358
  "name": "LoginFlow",
5359
- "code": "() => {\n const pathname = useLocationPathname();\n const activeProduct = deriveProduct(pathname);\n\n const [splashVisible, setSplashVisible] = useState(true);\n const [showShell, setShowShell] = useState(false);\n const [revealed, setRevealed] = useState(false);\n const [flowKey, setFlowKey] = useState(0);\n const [sidebarMode, setSidebarMode] = useState<SidebarMode>('adaptive');\n const { theme, setTheme } = useTheme();\n const railMode = railModeFor(sidebarMode, activeProduct === 'home');\n\n useEffect(() => {\n if (!splashVisible) return;\n const timer = setTimeout(() => setSplashVisible(false), 2000);\n return () => clearTimeout(timer);\n }, [splashVisible]);\n\n const handleSignIn = () => {\n setShowShell(true);\n };\n\n const handleReplay = () => {\n setShowShell(false);\n setRevealed(false);\n setSplashVisible(true);\n setFlowKey(k => k + 1);\n };\n\n return (\n <div\n key={flowKey}\n className='relative h-screen w-screen overflow-hidden bg-component-app-shell-bg'\n >\n {!revealed && (\n <AnimatedBackground\n className='absolute inset-0'\n style={{\n opacity: showShell ? 0 : 1,\n transition: showShell ? 'opacity 400ms cubic-bezier(0.4, 0, 0.2, 1)' : undefined,\n }}\n />\n )}\n\n {!showShell && (\n <div className='absolute inset-0 flex items-center justify-center z-10'>\n <SplashScreen\n visible={splashVisible}\n shrinkTarget={CARD_DIMENSIONS}\n className='bg-bg-page-bg shadow-lg'\n >\n <div className='flex h-full w-full flex-col items-center justify-center gap-16 p-24'>\n <Text size='xl'>Sign In</Text>\n <div className='flex w-full flex-col gap-12'>\n <Input placeholder='Email' />\n <Input placeholder='Password' type='password' />\n </div>\n <Button variant='primary' color='brand' className='w-full' onClick={handleSignIn}>\n Sign In\n </Button>\n </div>\n </SplashScreen>\n </div>\n )}\n\n {showShell && (\n <div className='absolute inset-0'>\n <AppShell expandFrom={CARD_DIMENSIONS} onRevealed={() => setRevealed(true)}>\n <AppShellHeader>\n <TopHeader>\n <TopHeaderLogo href='/'>\n <WallarmLogo />\n </TopHeaderLogo>\n\n <TopHeaderActions>\n <HeaderActions />\n </TopHeaderActions>\n </TopHeader>\n </AppShellHeader>\n\n <AppShellRail>\n <NavRail mode={railMode}>\n <NavRailBody>\n <NavRailItem\n icon={Home}\n label='Home'\n active={activeProduct === 'home'}\n onClick={() => navigateToProduct('home')}\n />\n\n <NavRailSeparator />\n\n <ProductNavItems activeProduct={activeProduct} />\n </NavRailBody>\n <NavRailFooterContent\n activeProduct={activeProduct}\n sidebarMode={sidebarMode}\n onSidebarModeChange={setSidebarMode}\n theme={theme}\n onThemeChange={setTheme}\n />\n </NavRail>\n </AppShellRail>\n\n <AppShellRemote>\n <div className='flex gap-8 absolute top-4 right-4 z-10'>\n <Button variant='ghost' size='small' color='neutral' onClick={handleReplay}>\n Replay animation\n </Button>\n </div>\n <RemoteForProduct product={activeProduct} />\n </AppShellRemote>\n </AppShell>\n </div>\n )}\n </div>\n );\n}",
5359
+ "code": "() => (\n <StoryRouter>\n <LoginFlowShell />\n </StoryRouter>\n)",
5360
5360
  "description": "The whole entrance: the splash hands off, the content surface expands from the sign-in card into the full shell. `onRevealed` fires when it has settled."
5361
+ },
5362
+ {
5363
+ "name": "WithTanStackRouter",
5364
+ "code": "() => {\n const [router] = useState(createShellRouter);\n\n return <RouterProvider router={router} />;\n}",
5365
+ "description": "`AppShell` and a `RemoteShell` per product on one TanStack Router: the root route is\nthe shell (rail → `navigate`, `AppShellRemote` → `<Outlet />`), `/$product` is the\nremote (`RemoteShell` with `pathname` + `onNavigate`, content → `<Outlet />`), and\n`/$product/$` is the page. Every way of moving — the rail, the nav panel, the\nbreadcrumbs, links in the page — goes through the router, and the active items follow."
5361
5366
  }
5362
5367
  ]
5363
5368
  },
@@ -56736,6 +56741,7 @@
56736
56741
  },
56737
56742
  {
56738
56743
  "name": "RemoteShell",
56744
+ "description": "Strips `basePath` only on a segment boundary: `/edge-nodes` is not under `/edge`.",
56739
56745
  "importPath": "@wallarm-org/design-system/RemoteShell",
56740
56746
  "props": [
56741
56747
  {
@@ -56750,6 +56756,12 @@
56750
56756
  "required": false,
56751
56757
  "description": "URL prefix stripped before matching and prepended when navigating (e.g. `\"/edge\"`)."
56752
56758
  },
56759
+ {
56760
+ "name": "pathname",
56761
+ "type": "string | undefined",
56762
+ "required": false,
56763
+ "description": "Current pathname. When set, it is the single source of truth for the active nav\nitem, drill level and breadcrumbs, and `window.location` is ignored.\n\nPass it — **together with `onNavigate`** — whenever a router owns the URL: router\nnavigations (links in page content, `router.navigate`, memory history, the host's\nrail) do not fire `popstate`, so without it the shell can go stale. Without\n`onNavigate` the shell's own navigations would only reach `window.history`, which\na controlled shell ignores (a dev warning flags this).\n\nEither form is accepted: with the `basePath` prefix (what `onNavigate` receives) or\nwithout it — the prefix is stripped only when the pathname starts with a whole\n`basePath` segment. With TanStack Router, `useRouterState({ select: s =>\ns.location.pathname })` is router-relative: it excludes the router's own\n`basepath`. So when the router has `basepath`:\n- omit `basePath` here — `pathname` and `onNavigate` are then both router-relative\n and `onNavigate={to => navigate({ to })}` is correct; or\n- keep `basePath` and strip it in `onNavigate`\n (`to => navigate({ to: to.slice(basePath.length) || '/' })`), otherwise the\n router prefixes it a second time.\n\nOmit it to read `window.location.pathname` (updated on `popstate` and on the\nshell's own navigations)."
56764
+ },
56753
56765
  {
56754
56766
  "name": "defaultChecked",
56755
56767
  "type": "boolean | undefined",
@@ -57870,7 +57882,13 @@
57870
57882
  ]
57871
57883
  }
57872
57884
  ],
57873
- "examples": []
57885
+ "examples": [
57886
+ {
57887
+ "name": "Basic",
57888
+ "code": "() => {\n const navigate = useNavigate();\n const pathname = useRouterState({ select: state => state.location.pathname });\n\n return (\n <div className='h-screen bg-bg-page-bg'>\n <RemoteShell\n config={edgeNavConfig}\n basePath='/edge'\n pathname={pathname}\n onNavigate={to => navigate({ to })}\n >\n <RemoteShellPanel resizable />\n <RemoteShellBreadcrumb />\n <RemoteShellContent>\n <EdgePage />\n </RemoteShellContent>\n </RemoteShell>\n </div>\n );\n}",
57889
+ "description": "A standalone product on TanStack Router — the recommended integration. `pathname` is\nthe router’s `location.pathname` and `onNavigate` calls `navigate`, so the menu, drill\nlevel and breadcrumbs follow every navigation: the panel, the breadcrumbs and the\nrouter links in the page. This router has no `basepath` (its routes include `/edge`),\nso both sides use the full pathname. If your router sets `basepath`, its\n`location.pathname` is router-relative: omit `basePath` on `RemoteShell` (or keep it\nand strip it in `onNavigate`), otherwise `navigate` prefixes it twice."
57890
+ }
57891
+ ]
57874
57892
  },
57875
57893
  {
57876
57894
  "name": "Resizable",
@@ -85736,7 +85754,7 @@
85736
85754
  "name": "virtualized",
85737
85755
  "type": "TableVirtualized | undefined",
85738
85756
  "required": false,
85739
- "description": "Enable row virtualization. `'container'` virtualizes within the scroll container; `'window'` virtualizes against the browser window."
85757
+ "description": "Enable row virtualization. `'container'` virtualizes within the table's own scroll container;\n`'window'` follows the page scroll — the nearest scrollable ancestor, or the browser window."
85740
85758
  },
85741
85759
  {
85742
85760
  "name": "stretch",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wallarm-org/design-system",
3
- "version": "1.28.0",
3
+ "version": "1.28.2-rc-fix-table-window-scroll-root.1",
4
4
  "description": "Core design system library with React components and Storybook documentation",
5
5
  "publishConfig": {
6
6
  "access": "public",
@@ -97,6 +97,7 @@
97
97
  "@storybook/addon-docs": "10.4.6",
98
98
  "@storybook/addon-themes": "10.4.6",
99
99
  "@tailwindcss/postcss": "4.3.3",
100
+ "@tanstack/react-router": "1.170.21",
100
101
  "@testing-library/jest-dom": "7.0.0",
101
102
  "@testing-library/react": "catalog:",
102
103
  "@testing-library/user-event": "catalog:",
@@ -1,11 +0,0 @@
1
- import { type NavRailMode } from '../../NavRail';
2
- import { type Theme } from '../../ThemeProvider';
3
- export type SidebarMode = 'adaptive' | 'expanded' | 'collapsed' | 'compact';
4
- /** Adaptive collapses the rail inside a product and expands it on Home; the other modes pin it. */
5
- export declare const railModeFor: (mode: SidebarMode, onHome: boolean) => NavRailMode;
6
- export declare const AccountDropdown: ({ sidebarMode, onSidebarModeChange, theme, onThemeChange, }: {
7
- sidebarMode: SidebarMode;
8
- onSidebarModeChange: (mode: SidebarMode) => void;
9
- theme: Theme;
10
- onThemeChange: (theme: Theme) => void;
11
- }) => import("react").JSX.Element;
@@ -1,242 +0,0 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- import { Fragment } from "react";
3
- import { LogOut, PanelLeftDashed, PencilRuler, Settings, User, UserRound } from "../../../icons/index.js";
4
- import { cn } from "../../../utils/cn.js";
5
- import { DropdownMenu, DropdownMenuContent, DropdownMenuItem, DropdownMenuItemContent, DropdownMenuItemIcon, DropdownMenuItemText, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuTrigger, DropdownMenuTriggerItem } from "../../DropdownMenu/index.js";
6
- import { NavRailItem } from "../../NavRail/index.js";
7
- import { HStack, VStack } from "../../Stack/index.js";
8
- import { Text } from "../../Text/index.js";
9
- import { useTheme } from "../../ThemeProvider/index.js";
10
- const railModeFor = (mode, onHome)=>{
11
- if ('adaptive' === mode) return onHome ? 'expanded' : 'collapsed';
12
- return mode;
13
- };
14
- const USER_NAME = 'Meow Meow';
15
- const USER_EMAIL = 'meow@meow.com';
16
- const THEMES = [
17
- 'light',
18
- 'dark'
19
- ];
20
- const SIDEBAR_MODE_GROUPS = [
21
- [
22
- 'adaptive'
23
- ],
24
- [
25
- 'expanded',
26
- 'collapsed'
27
- ],
28
- [
29
- 'compact'
30
- ]
31
- ];
32
- const SIDEBAR_MODES = SIDEBAR_MODE_GROUPS.flat();
33
- const THEME_LABELS = {
34
- light: 'Light',
35
- dark: 'Dark'
36
- };
37
- const FRAME_STYLES = [
38
- 'neutral',
39
- 'branded'
40
- ];
41
- const FRAME_STYLE_LABELS = {
42
- neutral: 'Neutral',
43
- branded: 'Branded'
44
- };
45
- const FRAME_STYLE_SWATCH = {
46
- neutral: 'bg-icon-secondary',
47
- branded: 'bg-icon-brand'
48
- };
49
- const SIDEBAR_MODE_LABELS = {
50
- adaptive: 'Adaptive',
51
- expanded: 'Always expanded',
52
- collapsed: 'Always collapsed',
53
- compact: 'Compact'
54
- };
55
- const AccountDropdown = ({ sidebarMode, onSidebarModeChange, theme, onThemeChange })=>{
56
- const { frameStyle, setFrameStyle } = useTheme();
57
- return /*#__PURE__*/ jsxs(DropdownMenu, {
58
- positioning: {
59
- placement: 'right-end',
60
- gutter: 6,
61
- offset: {
62
- crossAxis: 12
63
- }
64
- },
65
- children: [
66
- /*#__PURE__*/ jsx(DropdownMenuTrigger, {
67
- children: /*#__PURE__*/ jsx(NavRailItem, {
68
- icon: UserRound,
69
- label: USER_NAME,
70
- avatar: true
71
- })
72
- }),
73
- /*#__PURE__*/ jsxs(DropdownMenuContent, {
74
- className: "w-256",
75
- children: [
76
- /*#__PURE__*/ jsx("div", {
77
- className: "rounded-6 border border-border-primary-light bg-states-primary-hover px-8 py-8 mb-4",
78
- children: /*#__PURE__*/ jsxs(HStack, {
79
- gap: 8,
80
- align: "start",
81
- children: [
82
- /*#__PURE__*/ jsx("div", {
83
- children: /*#__PURE__*/ jsx(User, {})
84
- }),
85
- /*#__PURE__*/ jsxs(VStack, {
86
- gap: 0,
87
- children: [
88
- /*#__PURE__*/ jsx(Text, {
89
- size: "sm",
90
- color: "primary",
91
- children: USER_NAME
92
- }),
93
- /*#__PURE__*/ jsx(Text, {
94
- size: "xs",
95
- color: "secondary",
96
- children: USER_EMAIL
97
- })
98
- ]
99
- })
100
- ]
101
- })
102
- }),
103
- /*#__PURE__*/ jsxs(DropdownMenuItem, {
104
- children: [
105
- /*#__PURE__*/ jsx(DropdownMenuItemIcon, {
106
- children: /*#__PURE__*/ jsx(Settings, {})
107
- }),
108
- /*#__PURE__*/ jsx(DropdownMenuItemText, {
109
- children: "Profile settings"
110
- })
111
- ]
112
- }),
113
- /*#__PURE__*/ jsxs(DropdownMenu, {
114
- children: [
115
- /*#__PURE__*/ jsxs(DropdownMenuTriggerItem, {
116
- children: [
117
- /*#__PURE__*/ jsx(DropdownMenuItemIcon, {
118
- children: /*#__PURE__*/ jsx(PencilRuler, {})
119
- }),
120
- /*#__PURE__*/ jsxs(DropdownMenuItemContent, {
121
- children: [
122
- /*#__PURE__*/ jsx(DropdownMenuItemText, {
123
- children: "Appearance"
124
- }),
125
- /*#__PURE__*/ jsxs(Text, {
126
- size: "xs",
127
- color: "secondary",
128
- children: [
129
- THEME_LABELS[theme],
130
- " and ",
131
- FRAME_STYLE_LABELS[frameStyle].toLowerCase()
132
- ]
133
- })
134
- ]
135
- })
136
- ]
137
- }),
138
- /*#__PURE__*/ jsxs(DropdownMenuContent, {
139
- className: "w-132",
140
- children: [
141
- /*#__PURE__*/ jsx(DropdownMenuRadioGroup, {
142
- value: theme,
143
- onValueChange: ({ value })=>{
144
- const next = THEMES.find((t)=>t === value);
145
- if (next) onThemeChange(next);
146
- },
147
- children: THEMES.map((t)=>/*#__PURE__*/ jsx(DropdownMenuRadioItem, {
148
- value: t,
149
- children: /*#__PURE__*/ jsx(DropdownMenuItemText, {
150
- children: THEME_LABELS[t]
151
- })
152
- }, t))
153
- }),
154
- /*#__PURE__*/ jsx(DropdownMenuSeparator, {}),
155
- /*#__PURE__*/ jsx(DropdownMenuRadioGroup, {
156
- value: frameStyle,
157
- onValueChange: ({ value })=>{
158
- const next = FRAME_STYLES.find((s)=>s === value);
159
- if (next) setFrameStyle(next);
160
- },
161
- children: FRAME_STYLES.map((s)=>/*#__PURE__*/ jsxs(DropdownMenuRadioItem, {
162
- value: s,
163
- children: [
164
- /*#__PURE__*/ jsx(DropdownMenuItemIcon, {
165
- children: /*#__PURE__*/ jsx("span", {
166
- className: "flex size-16 items-center justify-center",
167
- children: /*#__PURE__*/ jsx("span", {
168
- className: cn('size-8 rounded-full', FRAME_STYLE_SWATCH[s])
169
- })
170
- })
171
- }),
172
- /*#__PURE__*/ jsx(DropdownMenuItemText, {
173
- children: FRAME_STYLE_LABELS[s]
174
- })
175
- ]
176
- }, s))
177
- })
178
- ]
179
- })
180
- ]
181
- }),
182
- /*#__PURE__*/ jsxs(DropdownMenu, {
183
- children: [
184
- /*#__PURE__*/ jsxs(DropdownMenuTriggerItem, {
185
- children: [
186
- /*#__PURE__*/ jsx(DropdownMenuItemIcon, {
187
- children: /*#__PURE__*/ jsx(PanelLeftDashed, {})
188
- }),
189
- /*#__PURE__*/ jsxs(DropdownMenuItemContent, {
190
- children: [
191
- /*#__PURE__*/ jsx(DropdownMenuItemText, {
192
- children: "Sidebar mode"
193
- }),
194
- /*#__PURE__*/ jsx(Text, {
195
- size: "xs",
196
- color: "secondary",
197
- children: SIDEBAR_MODE_LABELS[sidebarMode]
198
- })
199
- ]
200
- })
201
- ]
202
- }),
203
- /*#__PURE__*/ jsx(DropdownMenuContent, {
204
- className: "w-200",
205
- children: /*#__PURE__*/ jsx(DropdownMenuRadioGroup, {
206
- value: sidebarMode,
207
- onValueChange: ({ value })=>{
208
- const next = SIDEBAR_MODES.find((m)=>m === value);
209
- if (next) onSidebarModeChange(next);
210
- },
211
- children: SIDEBAR_MODE_GROUPS.map((group, index)=>/*#__PURE__*/ jsxs(Fragment, {
212
- children: [
213
- index > 0 && /*#__PURE__*/ jsx(DropdownMenuSeparator, {}),
214
- group.map((m)=>/*#__PURE__*/ jsx(DropdownMenuRadioItem, {
215
- value: m,
216
- children: /*#__PURE__*/ jsx(DropdownMenuItemText, {
217
- children: SIDEBAR_MODE_LABELS[m]
218
- })
219
- }, m))
220
- ]
221
- }, group.join('-')))
222
- })
223
- })
224
- ]
225
- }),
226
- /*#__PURE__*/ jsx(DropdownMenuSeparator, {}),
227
- /*#__PURE__*/ jsxs(DropdownMenuItem, {
228
- children: [
229
- /*#__PURE__*/ jsx(DropdownMenuItemIcon, {
230
- children: /*#__PURE__*/ jsx(LogOut, {})
231
- }),
232
- /*#__PURE__*/ jsx(DropdownMenuItemText, {
233
- children: "Sign out"
234
- })
235
- ]
236
- })
237
- ]
238
- })
239
- ]
240
- });
241
- };
242
- export { AccountDropdown, railModeFor };
@@ -1,12 +0,0 @@
1
- import { type NavConfig } from '../../RemoteShell';
2
- import { type Product } from './_storyLib';
3
- export interface ConfigRemoteProps {
4
- config: NavConfig;
5
- basePath?: string;
6
- /** Fake a 2s load whenever the product changes, to show the panel and content skeletons. */
7
- simulateLoading?: boolean;
8
- }
9
- export declare const RemoteForProduct: ({ product, simulateLoading, }: {
10
- product: Product;
11
- simulateLoading?: boolean;
12
- }) => import("react").JSX.Element;
@@ -1,81 +0,0 @@
1
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { useEffect, useState } from "react";
3
- import { Page, PageContent, PageHeader, PageTitle } from "../../Page/index.js";
4
- import { RemoteShell, RemoteShellBreadcrumb, RemoteShellContent, RemoteShellPanel, useRemoteShellContext } from "../../RemoteShell/index.js";
5
- import { HomeContent } from "./_storyHomeContent.js";
6
- import { PRODUCT_CONFIGS } from "./_storyLib.js";
7
- const RemotePageContent = ()=>{
8
- const { breadcrumbSegments } = useRemoteShellContext();
9
- const lastSegment = breadcrumbSegments[breadcrumbSegments.length - 1];
10
- const pageTitle = lastSegment?.label ?? '';
11
- const fullPath = breadcrumbSegments.map((s)=>s.label).join(' / ');
12
- return /*#__PURE__*/ jsxs(Page, {
13
- title: pageTitle,
14
- fixedHeight: true,
15
- children: [
16
- /*#__PURE__*/ jsx(PageHeader, {
17
- children: /*#__PURE__*/ jsx(PageTitle, {
18
- children: pageTitle
19
- })
20
- }),
21
- /*#__PURE__*/ jsx(PageContent, {
22
- children: /*#__PURE__*/ jsxs("p", {
23
- className: "text-sm text-text-secondary",
24
- children: [
25
- "Placeholder page for ",
26
- fullPath,
27
- "."
28
- ]
29
- })
30
- })
31
- ]
32
- });
33
- };
34
- const ConfigRemote = ({ config, basePath, simulateLoading = true })=>{
35
- const [loading, setLoading] = useState(simulateLoading);
36
- useEffect(()=>{
37
- if (!simulateLoading) return;
38
- setLoading(true);
39
- const timer = setTimeout(()=>{
40
- setLoading(false);
41
- }, 2000);
42
- return ()=>clearTimeout(timer);
43
- }, [
44
- config.productLabel,
45
- simulateLoading
46
- ]);
47
- return /*#__PURE__*/ jsx(RemoteShell, {
48
- config: config,
49
- basePath: basePath,
50
- children: loading ? /*#__PURE__*/ jsxs(Fragment, {
51
- children: [
52
- /*#__PURE__*/ jsx(RemoteShellPanel, {
53
- isLoading: true
54
- }),
55
- /*#__PURE__*/ jsx(RemoteShellContent, {
56
- isLoading: true
57
- })
58
- ]
59
- }) : /*#__PURE__*/ jsxs(Fragment, {
60
- children: [
61
- /*#__PURE__*/ jsx(RemoteShellPanel, {
62
- resizable: true
63
- }),
64
- /*#__PURE__*/ jsx(RemoteShellBreadcrumb, {}),
65
- /*#__PURE__*/ jsx(RemoteShellContent, {
66
- children: /*#__PURE__*/ jsx(RemotePageContent, {})
67
- })
68
- ]
69
- })
70
- });
71
- };
72
- const RemoteForProduct = ({ product, simulateLoading = true })=>{
73
- if ('home' === product) return /*#__PURE__*/ jsx(HomeContent, {});
74
- const { config } = PRODUCT_CONFIGS[product];
75
- return /*#__PURE__*/ jsx(ConfigRemote, {
76
- config: config,
77
- basePath: `/${product}`,
78
- simulateLoading: simulateLoading
79
- });
80
- };
81
- export { RemoteForProduct };
@@ -1 +0,0 @@
1
- export declare const HeaderActions: () => import("react").JSX.Element;
@@ -1,59 +0,0 @@
1
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
2
- import { Bell, ChevronUpDown } from "../../../icons/index.js";
3
- import { Button } from "../../Button/index.js";
4
- import { Code } from "../../Code/index.js";
5
- import { Text } from "../../Text/index.js";
6
- import { Tooltip, TooltipContent, TooltipTrigger } from "../../Tooltip/index.js";
7
- import { TopHeaderSeparator } from "../../TopHeader/index.js";
8
- import { QuickHelpDropdown } from "./_storyQuickHelpDropdown.js";
9
- import { StorySearchModal } from "./_storySearchModal.js";
10
- const HeaderActions = ()=>/*#__PURE__*/ jsxs(Fragment, {
11
- children: [
12
- /*#__PURE__*/ jsx(StorySearchModal, {}),
13
- /*#__PURE__*/ jsx(TopHeaderSeparator, {}),
14
- /*#__PURE__*/ jsxs(Button, {
15
- variant: "ghost",
16
- size: "small",
17
- color: "neutral",
18
- className: "py-4 rounded-6",
19
- children: [
20
- /*#__PURE__*/ jsx(Text, {
21
- size: "xs",
22
- weight: "medium",
23
- children: "Tenant Name"
24
- }),
25
- /*#__PURE__*/ jsx("span", {
26
- className: "text-text-tertiary mx-[-2px]",
27
- children: "•"
28
- }),
29
- /*#__PURE__*/ jsx(Code, {
30
- size: "s",
31
- color: "secondary",
32
- children: "12345"
33
- }),
34
- /*#__PURE__*/ jsx(ChevronUpDown, {
35
- className: "!icon-sm"
36
- })
37
- ]
38
- }),
39
- /*#__PURE__*/ jsxs(Tooltip, {
40
- children: [
41
- /*#__PURE__*/ jsx(TooltipTrigger, {
42
- asChild: true,
43
- children: /*#__PURE__*/ jsx(Button, {
44
- variant: "ghost",
45
- size: "small",
46
- color: "neutral",
47
- "aria-label": "Wallarm Updates",
48
- children: /*#__PURE__*/ jsx(Bell, {})
49
- })
50
- }),
51
- /*#__PURE__*/ jsx(TooltipContent, {
52
- children: "Wallarm updates"
53
- })
54
- ]
55
- }),
56
- /*#__PURE__*/ jsx(QuickHelpDropdown, {})
57
- ]
58
- });
59
- export { HeaderActions };
@@ -1,2 +0,0 @@
1
- import type { FC } from 'react';
2
- export declare const HomeContent: FC;
@@ -1,15 +0,0 @@
1
- import { jsx, jsxs } from "react/jsx-runtime";
2
- const HomeContent = ()=>/*#__PURE__*/ jsxs("div", {
3
- className: "p-24",
4
- children: [
5
- /*#__PURE__*/ jsx("h1", {
6
- className: "text-xl font-semibold text-text-primary",
7
- children: "Home"
8
- }),
9
- /*#__PURE__*/ jsx("p", {
10
- className: "mt-4 text-sm text-text-secondary",
11
- children: "Cross-product summary. Click any product in the rail to drill into it."
12
- })
13
- ]
14
- });
15
- export { HomeContent };
@@ -1,9 +0,0 @@
1
- import { edgeNavConfig } from './_storyNavConfigs';
2
- declare const KNOWN_PRODUCTS: readonly ['home', 'edge', 'ai-hypervisor', 'infra-discovery', 'security-testing', 'settings'];
3
- export type Product = (typeof KNOWN_PRODUCTS)[number];
4
- export declare const PRODUCT_CONFIGS: Record<Exclude<Product, 'home'>, {
5
- config: typeof edgeNavConfig;
6
- }>;
7
- export declare function deriveProduct(pathname: string): Product;
8
- export declare function navigateToProduct(product: Product): void;
9
- export {};
@@ -1,39 +0,0 @@
1
- import { findFirstLinkPath, pushPathname } from "../../RemoteShell/index.js";
2
- import { aiHypervisorNavConfig, edgeNavConfig, infraDiscoveryNavConfig, securityTestingNavConfig, settingsNavConfig } from "./_storyNavConfigs.js";
3
- const KNOWN_PRODUCTS = [
4
- 'home',
5
- 'edge',
6
- 'ai-hypervisor',
7
- 'infra-discovery',
8
- 'security-testing',
9
- 'settings'
10
- ];
11
- const PRODUCT_CONFIGS = {
12
- edge: {
13
- config: edgeNavConfig
14
- },
15
- 'ai-hypervisor': {
16
- config: aiHypervisorNavConfig
17
- },
18
- 'infra-discovery': {
19
- config: infraDiscoveryNavConfig
20
- },
21
- 'security-testing': {
22
- config: securityTestingNavConfig
23
- },
24
- settings: {
25
- config: settingsNavConfig
26
- }
27
- };
28
- function deriveProduct(pathname) {
29
- const segment = pathname.split('/').filter(Boolean)[0];
30
- if (segment && KNOWN_PRODUCTS.includes(segment)) return segment;
31
- return 'home';
32
- }
33
- function navigateToProduct(product) {
34
- if ('home' === product) return void pushPathname('/home');
35
- const { config } = PRODUCT_CONFIGS[product];
36
- const firstPath = findFirstLinkPath(config.items) ?? '';
37
- pushPathname(`/${product}/${firstPath}`);
38
- }
39
- export { PRODUCT_CONFIGS, deriveProduct, navigateToProduct };
@@ -1,6 +0,0 @@
1
- import type { NavConfig } from '../../RemoteShell';
2
- export declare const edgeNavConfig: NavConfig;
3
- export declare const aiHypervisorNavConfig: NavConfig;
4
- export declare const infraDiscoveryNavConfig: NavConfig;
5
- export declare const securityTestingNavConfig: NavConfig;
6
- export declare const settingsNavConfig: NavConfig;