Files
ADS3-Design-System/src/components/templates/FormPage/FormPage.stories.tsx
Richie df7bbba915 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>
2026-06-03 15:22:18 +10:00

176 lines
6.8 KiB
TypeScript

import type { Meta, StoryObj } from '@storybook/react'
import { useState } from 'react'
import { FormPage } from './FormPage'
import { AppShell } from '@/components/templates/AppShell/AppShell'
import { TopBar } from '@/components/organisms/TopBar/TopBar'
import { SideNav, SideNavItem, SideNavGroup, SideNavDivider } from '@/components/organisms/SideNav/SideNav'
import { PageHeader } from '@/components/organisms/PageHeader/PageHeader'
import { Card, CardContent } from '@/components/molecules/Card/Card'
import { Alert } from '@/components/molecules/Alert/Alert'
import { Input } from '@/components/atoms/Input/Input'
import { Select } from '@/components/atoms/Select/Select'
import { Button } from '@/components/atoms/Button/Button'
import { Badge } from '@/components/atoms/Badge/Badge'
import { Avatar } from '@/components/atoms/Avatar/Avatar'
import { NswLogo, TopBarAction } from '@/components/templates/_story-helpers'
import { Menu, Bell, Home, FileText, LayoutGrid, Users, Link, ArrowRight, Settings } from 'lucide-react'
const meta: Meta<typeof FormPage> = {
title: 'Templates/FormPage',
component: FormPage,
tags: ['autodocs', 'template'],
parameters: {
layout: 'fullscreen',
docs: {
description: {
component: 'Form page template with optional vertical stepper and constrained-width form content. Use inside AppShell for the full page layout.',
},
},
},
}
export default meta
type Story = StoryObj<typeof FormPage>
export const WithStepper: Story = {
name: 'With stepper',
render: () => {
const [collapsed, setCollapsed] = useState(false)
return (
<AppShell
topBar={
<TopBar
title="Application Portal"
leading={<TopBarAction icon={<Menu />} label="Menu" onClick={() => setCollapsed(!collapsed)} />}
logo={<NswLogo />}
>
<TopBarAction icon={<Bell />} label="Notifications" />
<Avatar initials="SR" size="sm" />
</TopBar>
}
sideNav={
<SideNav collapsed={collapsed}>
<SideNavItem icon={<Home />}>Home</SideNavItem>
<SideNavItem icon={<Users />}>Profile</SideNavItem>
<SideNavItem icon={<LayoutGrid />}>Workspace</SideNavItem>
<SideNavItem icon={<Link />}>Resources</SideNavItem>
<SideNavItem icon={<FileText />}>Documents</SideNavItem>
<SideNavDivider />
<SideNavGroup icon={<FileText />} label="Applications" defaultOpen active>
<SideNavItem active>New application</SideNavItem>
<SideNavItem>Guidelines</SideNavItem>
<SideNavItem>History</SideNavItem>
<SideNavItem>Support</SideNavItem>
</SideNavGroup>
</SideNav>
}
sideNavCollapsed={collapsed}
>
<FormPage
header={
<PageHeader title="New Application" subtitle="Submit your application for review" theme="dark">
<div className="mt-2 flex items-center gap-4">
<Badge variant="warning">In progress</Badge>
</div>
</PageHeader>
}
actions={
<>
<Select
label=""
variant="stacked"
options={[{ value: '2026', label: '2026 — Application draft' }]}
defaultValue="2026"
/>
<Button variant="secondary">More actions</Button>
</>
}
steps={[
{ label: 'Your details', status: 'current' },
{ label: 'Supporting documents', status: 'upcoming' },
{ label: 'Review & submit', status: 'upcoming' },
]}
>
<Card variant="surface">
<CardContent className="space-y-6 p-6">
<div>
<h2 className="text-h3 font-bold text-text">Your details</h2>
<p className="mt-2 text-body text-text-secondary">
Provide the information below to begin your application. You can save and return at any time.
</p>
</div>
<Alert variant="info" title="Before you start">
Make sure you have your identification documents and contact details ready.
</Alert>
<div className="space-y-4">
<Input label="Full name" placeholder="Enter your full name" />
<Input label="Email address" type="email" placeholder="you@example.com" />
<div>
<p className="text-body font-semibold text-text">Role information</p>
<p className="mb-2 text-small text-text-secondary">Select the role that best describes your position.</p>
<Select
label="Role type"
options={[
{ value: 'manager', label: 'Manager' },
{ value: 'coordinator', label: 'Coordinator' },
{ value: 'specialist', label: 'Specialist' },
]}
/>
</div>
<div>
<p className="text-body font-semibold text-text">Supervisor details</p>
<p className="mb-2 text-small text-text-secondary">
Enter your supervisor's contact details for verification.
</p>
<div className="space-y-4">
<Input label="Supervisor email" type="email" placeholder="supervisor@example.com" />
<Input label="Supervisor location" placeholder="Office or site name" />
</div>
</div>
<Input label="Work location" placeholder="Your primary work location" />
<div className="flex justify-start pt-2">
<Button rightIcon={<ArrowRight size={18} />}>Proceed</Button>
</div>
</div>
</CardContent>
</Card>
</FormPage>
</AppShell>
)
},
}
export const SimpleForm: Story = {
name: 'Simple form (no stepper)',
render: () => (
<FormPage
header={<PageHeader title="Create Account" subtitle="Set up your profile to get started" />}
>
<Card variant="surface">
<CardContent className="space-y-4 p-6">
<Input label="Full name" placeholder="Enter your full name" />
<Input label="Email address" type="email" placeholder="you@example.com" />
<Select
label="Role"
options={[
{ value: 'viewer', label: 'Viewer' },
{ value: 'editor', label: 'Editor' },
{ value: 'admin', label: 'Administrator' },
]}
/>
<div className="flex justify-end gap-3 pt-4">
<Button variant="tertiary">Cancel</Button>
<Button>Create Account</Button>
</div>
</CardContent>
</Card>
</FormPage>
),
}