Replace domain-specific (education/PDP) recipe stories with generic content. Fix TopBar action buttons using properly styled light-on-dark buttons instead of invisible IconButton tertiary. Use the real NSW waratah SVG logo. Add shared _story-helpers for TopBar actions and logo. Add DetailPage template for single-record/profile/document views with constrained width and tab support. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
99 lines
3.6 KiB
TypeScript
99 lines
3.6 KiB
TypeScript
import type { Meta, StoryObj } from '@storybook/react'
|
|
import { useState } from 'react'
|
|
import { AppShell } from './AppShell'
|
|
import { TopBar } from '@/components/organisms/TopBar/TopBar'
|
|
import { SideNav, SideNavItem, SideNavGroup, SideNavDivider } from '@/components/organisms/SideNav/SideNav'
|
|
import { Avatar } from '@/components/atoms/Avatar/Avatar'
|
|
import { PageHeader } from '@/components/organisms/PageHeader/PageHeader'
|
|
import { NswLogo, TopBarAction } from '@/components/templates/_story-helpers'
|
|
import { Menu, Search, Bell, Home, FileText, LayoutGrid, Settings, Users, Link } from 'lucide-react'
|
|
|
|
const meta: Meta<typeof AppShell> = {
|
|
title: 'Templates/AppShell',
|
|
component: AppShell,
|
|
tags: ['autodocs', 'template'],
|
|
parameters: {
|
|
layout: 'fullscreen',
|
|
docs: {
|
|
description: {
|
|
component: 'Application shell layout that composes TopBar + SideNav + scrollable content area. All page templates should be rendered inside an AppShell.',
|
|
},
|
|
},
|
|
},
|
|
}
|
|
export default meta
|
|
|
|
type Story = StoryObj<typeof AppShell>
|
|
|
|
export const Default: Story = {
|
|
render: () => {
|
|
const [collapsed, setCollapsed] = useState(false)
|
|
return (
|
|
<AppShell
|
|
topBar={
|
|
<TopBar
|
|
title="My Application"
|
|
leading={<TopBarAction icon={<Menu />} label="Toggle menu" onClick={() => setCollapsed(!collapsed)} />}
|
|
logo={<NswLogo />}
|
|
>
|
|
<TopBarAction icon={<Search />} label="Search" />
|
|
<TopBarAction icon={<Bell />} label="Notifications" />
|
|
<Avatar initials="AB" size="sm" />
|
|
</TopBar>
|
|
}
|
|
sideNav={
|
|
<SideNav collapsed={collapsed}>
|
|
<SideNavItem icon={<Home />} active>Home</SideNavItem>
|
|
<SideNavItem icon={<FileText />}>Documents</SideNavItem>
|
|
<SideNavItem icon={<LayoutGrid />}>Workspace</SideNavItem>
|
|
<SideNavDivider />
|
|
<SideNavGroup icon={<Users />} label="Team" defaultOpen>
|
|
<SideNavItem>Members</SideNavItem>
|
|
<SideNavItem>Roles</SideNavItem>
|
|
</SideNavGroup>
|
|
<SideNavItem icon={<Link />}>Resources</SideNavItem>
|
|
<SideNavItem icon={<Settings />}>Settings</SideNavItem>
|
|
</SideNav>
|
|
}
|
|
sideNavCollapsed={collapsed}
|
|
>
|
|
<PageHeader title="Dashboard" subtitle="Welcome back" />
|
|
<div className="p-6">
|
|
<div className="rounded-lg border border-border bg-surface p-8 text-center text-text-secondary">
|
|
Page content goes here
|
|
</div>
|
|
</div>
|
|
</AppShell>
|
|
)
|
|
},
|
|
}
|
|
|
|
export const Collapsed: Story = {
|
|
render: () => (
|
|
<AppShell
|
|
topBar={
|
|
<TopBar title="My Application" leading={<TopBarAction icon={<Menu />} label="Menu" />} logo={<NswLogo />}>
|
|
<TopBarAction icon={<Bell />} label="Notifications" />
|
|
<Avatar initials="AB" size="sm" />
|
|
</TopBar>
|
|
}
|
|
sideNav={
|
|
<SideNav collapsed>
|
|
<SideNavItem icon={<Home />} active>Home</SideNavItem>
|
|
<SideNavItem icon={<FileText />}>Documents</SideNavItem>
|
|
<SideNavItem icon={<LayoutGrid />}>Workspace</SideNavItem>
|
|
<SideNavItem icon={<Settings />}>Settings</SideNavItem>
|
|
</SideNav>
|
|
}
|
|
sideNavCollapsed
|
|
>
|
|
<PageHeader title="Dashboard" subtitle="SideNav collapsed to icon-only mode" />
|
|
<div className="p-6">
|
|
<div className="rounded-lg border border-border bg-surface p-8 text-center text-text-secondary">
|
|
Content area is wider with collapsed sidebar
|
|
</div>
|
|
</div>
|
|
</AppShell>
|
|
),
|
|
}
|