Genericise template stories, fix TopBar icons, and add DetailPage

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>
This commit is contained in:
2026-06-03 15:22:18 +10:00
parent 95f72407f8
commit df7bbba915
10 changed files with 450 additions and 236 deletions

View File

@@ -4,14 +4,10 @@ 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 { IconButton } from '@/components/atoms/IconButton/IconButton'
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 NswLogo = () => (
<div className="flex size-7 items-center justify-center rounded bg-white/20 text-caption font-bold text-white">NSW</div>
)
const meta: Meta<typeof AppShell> = {
title: 'Templates/AppShell',
component: AppShell,
@@ -29,44 +25,39 @@ export default meta
type Story = StoryObj<typeof AppShell>
const SampleTopBar = ({ onMenuClick }: { onMenuClick?: () => void }) => (
<TopBar
title="My Application"
leading={<IconButton icon={<Menu />} aria-label="Toggle menu" variant="tertiary" onClick={onMenuClick} />}
logo={<NswLogo />}
>
<IconButton icon={<Search />} aria-label="Search" variant="tertiary" />
<IconButton icon={<Bell />} aria-label="Notifications" variant="tertiary" />
<Avatar initials="MM" size="sm" />
</TopBar>
)
const SampleSideNav = ({ collapsed }: { collapsed: boolean }) => (
<SideNav collapsed={collapsed}>
<SideNavItem icon={<Home />} active>My status</SideNavItem>
<SideNavItem icon={<FileText />}>My details</SideNavItem>
<SideNavItem icon={<LayoutGrid />}>Workspace</SideNavItem>
<SideNavDivider />
<SideNavGroup icon={<Users />} label="PDP" defaultOpen>
<SideNavItem>My PDP</SideNavItem>
<SideNavItem>PDP guide</SideNavItem>
<SideNavItem>Management</SideNavItem>
</SideNavGroup>
<SideNavItem icon={<Link />}>Resources</SideNavItem>
<SideNavItem icon={<Settings />}>Settings</SideNavItem>
</SideNav>
)
export const Default: Story = {
render: () => {
const [collapsed, setCollapsed] = useState(false)
return (
<AppShell
topBar={<SampleTopBar onMenuClick={() => setCollapsed(!collapsed)} />}
sideNav={<SampleSideNav collapsed={collapsed} />}
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, Myra McKay" />
<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
@@ -80,8 +71,20 @@ export const Default: Story = {
export const Collapsed: Story = {
render: () => (
<AppShell
topBar={<SampleTopBar />}
sideNav={<SampleSideNav collapsed />}
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" />