From 075ab0ddb293b0fcff9f700b363a65d02a426f67 Mon Sep 17 00:00:00 2001 From: melvinchia3636 Date: Sun, 19 Apr 2026 18:09:40 +0800 Subject: [PATCH] feat(ui): enhance ModuleWrapper layout and add stories for testing --- .../ModuleWrapper/ModuleWrapper.stories.tsx | 95 +++++++++++++++++++ .../layout/ModuleWrapper/ModuleWrapper.tsx | 26 +++-- 2 files changed, 113 insertions(+), 8 deletions(-) create mode 100644 packages/lifeforge-ui/src/components/layout/ModuleWrapper/ModuleWrapper.stories.tsx diff --git a/packages/lifeforge-ui/src/components/layout/ModuleWrapper/ModuleWrapper.stories.tsx b/packages/lifeforge-ui/src/components/layout/ModuleWrapper/ModuleWrapper.stories.tsx new file mode 100644 index 000000000..a8c41d4a2 --- /dev/null +++ b/packages/lifeforge-ui/src/components/layout/ModuleWrapper/ModuleWrapper.stories.tsx @@ -0,0 +1,95 @@ +import type { Meta, StoryObj } from '@storybook/react-vite' + +import { ModuleHeader } from '@components/layout' +import { Box, Flex, Grid, Text } from '@components/primitives' + +import ModuleWrapper from './index' + +const meta = { + component: ModuleWrapper, + argTypes: { + children: { control: false } + } +} satisfies Meta + +export default meta + +type Story = StoryObj + +// ─── Helpers ────────────────────────────────────────────────────────────────── + +function StatCard({ label, value }: { label: string; value: string }) { + return ( + + + {label} + + + {value} + + + ) +} + +function ContentCard({ title, body }: { title: string; body: string }) { + return ( + + + {title} + + + {body} + + + ) +} + +// ─── Stories ────────────────────────────────────────────────────────────────── + +/** + * The default `ModuleWrapper` sets up the module header context, a scrollable + * content area, and proper padding. Pair it with `ModuleHeader` as the first + * child to render the icon, title, and description bar. + */ +export const Default: Story = { + args: { + children: <>, + config: { + title: 'Demo Module', + icon: 'tabler:cube', + clearQueryOnUnmount: false + } + }, + render: args => ( + + + + + + + + + + + + + + + + + + + ) +} diff --git a/packages/lifeforge-ui/src/components/layout/ModuleWrapper/ModuleWrapper.tsx b/packages/lifeforge-ui/src/components/layout/ModuleWrapper/ModuleWrapper.tsx index 7e38c9e6c..25414b35a 100644 --- a/packages/lifeforge-ui/src/components/layout/ModuleWrapper/ModuleWrapper.tsx +++ b/packages/lifeforge-ui/src/components/layout/ModuleWrapper/ModuleWrapper.tsx @@ -7,8 +7,12 @@ import { normalizeSubnamespace } from 'shared' +import { Flex } from '@components/primitives' import { Scrollbar } from '@components/utilities' +/** + * The wrapper component for all modules in the app. It provides the layout and context for the module header and sidebar, as well as handling query cleanup on unmount if specified. If being used within LifeForge instance, it will be automatically wrapped around the module content. Therefore, no explicit usage is needed in most cases. + */ function ModuleWrapper({ children, config: { title, icon, clearQueryOnUnmount = true } @@ -38,14 +42,20 @@ function ModuleWrapper({ value={{ title: normalizeSubnamespace(title).replace('__', '$'), icon }} > - -
- {children} -
-
+ + + + {children} + + +
)