From 80be7b43001ade289c712d6d7bc9bfd67077c606 Mon Sep 17 00:00:00 2001 From: william garrity Date: Tue, 3 Feb 2026 19:11:27 -0500 Subject: [PATCH] feat(PageHeader): add Lucide icon selector and iconAlign prop Stories improvements: - Add interactive icon dropdown control with 15 Lucide React icons (Home, Settings, User, Users, Calendar, FileText, Building, Briefcase, Chart, Shield, Bell, Search, Stethoscope, Hospital, ClipboardList) - Add iconAlign radio control to toggle between 'top' and 'center' - Disable controls for ReactNode props (actions, children) to prevent Storybook serialization errors Component enhancements: - Add iconAlign prop with 'top' | 'center' options (default: 'center') - When iconAlign='top', icon aligns with the top of title/subtitle instead of vertically centering - Adds subtle mt-1 offset when top-aligned for better visual balance --- .../PageHeader/PageHeader.stories.tsx | 57 +++++++++++++++++++ src/components/PageHeader/PageHeader.tsx | 15 ++++- 2 files changed, 69 insertions(+), 3 deletions(-) diff --git a/src/components/PageHeader/PageHeader.stories.tsx b/src/components/PageHeader/PageHeader.stories.tsx index 0ccd4213..65e4ea65 100644 --- a/src/components/PageHeader/PageHeader.stories.tsx +++ b/src/components/PageHeader/PageHeader.stories.tsx @@ -1,11 +1,68 @@ import type { Meta, StoryObj } from '@storybook/react'; import { PageHeader } from './PageHeader'; import { Button } from '../Button/Button'; +import { + HomeIcon, + SettingsIcon, + UserIcon, + UsersIcon, + CalendarIcon, + FileTextIcon, + BuildingIcon, + BriefcaseIcon, + ChartIcon, + ShieldIcon, + BellIcon, + SearchIcon, + StethoscopeIcon, + HospitalIcon, + ClipboardListIcon, +} from '../Icons'; +import type { LucideIcon } from 'lucide-react'; + +const iconMap: Record = { + Home: HomeIcon, + Settings: SettingsIcon, + User: UserIcon, + Users: UsersIcon, + Calendar: CalendarIcon, + FileText: FileTextIcon, + Building: BuildingIcon, + Briefcase: BriefcaseIcon, + Chart: ChartIcon, + Shield: ShieldIcon, + Bell: BellIcon, + Search: SearchIcon, + Stethoscope: StethoscopeIcon, + Hospital: HospitalIcon, + ClipboardList: ClipboardListIcon, +}; const meta: Meta = { title: 'Components/PageHeader', component: PageHeader, tags: ['autodocs'], + argTypes: { + actions: { control: false }, + icon: { + control: 'select', + options: ['None', ...Object.keys(iconMap)], + mapping: { + None: undefined, + ...Object.fromEntries( + Object.entries(iconMap).map(([name, Icon]) => [ + name, + , + ]) + ), + }, + }, + iconAlign: { + control: 'radio', + options: ['top', 'center'], + }, + children: { control: false }, + }, parameters: { layout: 'padded', }, diff --git a/src/components/PageHeader/PageHeader.tsx b/src/components/PageHeader/PageHeader.tsx index 5516a3e0..88f5a870 100644 --- a/src/components/PageHeader/PageHeader.tsx +++ b/src/components/PageHeader/PageHeader.tsx @@ -9,6 +9,8 @@ export interface PageHeaderProps { subtitle?: string; /** Optional icon to display before the title */ icon?: React.ReactNode; + /** Vertical alignment of the icon */ + iconAlign?: 'top' | 'center'; /** Action buttons or controls to display on the right */ actions?: React.ReactNode; /** Additional content below the title (e.g., breadcrumbs, tabs) */ @@ -29,6 +31,7 @@ export function PageHeader({ title, subtitle, icon, + iconAlign = 'center', actions, children, className = '', @@ -51,10 +54,16 @@ export function PageHeader({
-
-
+
+
{icon && ( -
+
{icon}
)}