Extract ComparisonColumnCard + ComparisonTabCard molecules, refine comparison UI
- New molecule: ComparisonColumnCard — desktop column header card extracted from ComparisonTable (~150 lines removed from organism) - New molecule: ComparisonTabCard — mobile tab rail card extracted from ComparisonPage (shared by V1 and V2) - CellValue "unknown" restyled: icon+text in neutral grey (was Badge), InfoOutlinedIcon on right at 14px matching item info icons - Unverified provider story data: all items set to unknown across all story files (no dashes in essentials) - Mobile tab rail: recommended badge (replaces star), package price, shadow/glow, center-on-select scroll, overflow clipping fixed - ComparisonPackageCard: added shadow, reduced CTA button to medium - ComparisonTable first column: inline info icon pattern (non-breaking space + nowrap span) prevents icon orphaning on line wrap Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,159 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import Box from '@mui/material/Box';
|
||||
import { ComparisonColumnCard } from './ComparisonColumnCard';
|
||||
import type { ComparisonPackage } from '../../organisms/ComparisonTable';
|
||||
|
||||
// ─── Mock data ──────────────────────────────────────────────────────────────
|
||||
|
||||
const verifiedPackage: ComparisonPackage = {
|
||||
id: 'wollongong-everyday',
|
||||
name: 'Everyday Funeral Package',
|
||||
price: 6966,
|
||||
provider: {
|
||||
name: 'Wollongong City Funerals',
|
||||
location: 'Wollongong',
|
||||
rating: 4.8,
|
||||
reviewCount: 122,
|
||||
verified: true,
|
||||
},
|
||||
sections: [],
|
||||
};
|
||||
|
||||
const unverifiedPackage: ComparisonPackage = {
|
||||
id: 'inglewood-everyday',
|
||||
name: 'Everyday Funeral Package',
|
||||
price: 7200,
|
||||
provider: {
|
||||
name: 'Inglewood Chapel',
|
||||
location: 'Inglewood',
|
||||
rating: 4.2,
|
||||
reviewCount: 45,
|
||||
verified: false,
|
||||
},
|
||||
sections: [],
|
||||
};
|
||||
|
||||
const recommendedPackage: ComparisonPackage = {
|
||||
id: 'recommended-premium',
|
||||
name: 'Premium Cremation Service',
|
||||
price: 8450,
|
||||
provider: {
|
||||
name: 'H. Parsons Funeral Directors',
|
||||
location: 'Wentworth',
|
||||
rating: 4.9,
|
||||
reviewCount: 203,
|
||||
verified: true,
|
||||
},
|
||||
sections: [],
|
||||
isRecommended: true,
|
||||
};
|
||||
|
||||
const longNamePackage: ComparisonPackage = {
|
||||
id: 'long-name',
|
||||
name: 'Comprehensive Premium Memorial & Cremation Service Package',
|
||||
price: 12500,
|
||||
provider: {
|
||||
name: 'The Very Long Name Funeral Services & Memorial Chapel Pty Ltd',
|
||||
location: 'Wollongong',
|
||||
rating: 4.6,
|
||||
reviewCount: 87,
|
||||
verified: true,
|
||||
},
|
||||
sections: [],
|
||||
};
|
||||
|
||||
const noRatingPackage: ComparisonPackage = {
|
||||
id: 'no-rating',
|
||||
name: 'Basic Funeral Package',
|
||||
price: 4200,
|
||||
provider: {
|
||||
name: 'New Provider',
|
||||
location: 'Sydney',
|
||||
verified: true,
|
||||
},
|
||||
sections: [],
|
||||
};
|
||||
|
||||
// ─── Meta ───────────────────────────────────────────────────────────────────
|
||||
|
||||
const meta: Meta<typeof ComparisonColumnCard> = {
|
||||
title: 'Molecules/ComparisonColumnCard',
|
||||
component: ComparisonColumnCard,
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
layout: 'padded',
|
||||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<Box sx={{ maxWidth: 280, mx: 'auto', pt: 3 }}>
|
||||
<Story />
|
||||
</Box>
|
||||
),
|
||||
],
|
||||
args: {
|
||||
onArrange: (id) => alert(`Arrange: ${id}`),
|
||||
onRemove: (id) => alert(`Remove: ${id}`),
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof ComparisonColumnCard>;
|
||||
|
||||
/** Verified provider — floating "Verified" badge above card */
|
||||
export const Verified: Story = {
|
||||
args: {
|
||||
pkg: verifiedPackage,
|
||||
},
|
||||
};
|
||||
|
||||
/** Unverified provider — "Make Enquiry" CTA + soft button variant, no verified badge */
|
||||
export const Unverified: Story = {
|
||||
args: {
|
||||
pkg: unverifiedPackage,
|
||||
},
|
||||
};
|
||||
|
||||
/** Recommended package — copper banner, warm selected state, no Remove link */
|
||||
export const Recommended: Story = {
|
||||
args: {
|
||||
pkg: recommendedPackage,
|
||||
},
|
||||
};
|
||||
|
||||
/** Long provider name — truncated with tooltip on hover */
|
||||
export const LongName: Story = {
|
||||
args: {
|
||||
pkg: longNamePackage,
|
||||
},
|
||||
};
|
||||
|
||||
/** No rating — provider without rating/review data */
|
||||
export const NoRating: Story = {
|
||||
args: {
|
||||
pkg: noRatingPackage,
|
||||
},
|
||||
};
|
||||
|
||||
/** Side-by-side — multiple cards in a row (as used in ComparisonTable) */
|
||||
export const SideBySide: Story = {
|
||||
decorators: [
|
||||
() => (
|
||||
<Box sx={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: 2, pt: 3 }}>
|
||||
<ComparisonColumnCard
|
||||
pkg={recommendedPackage}
|
||||
onArrange={(id) => alert(`Arrange: ${id}`)}
|
||||
/>
|
||||
<ComparisonColumnCard
|
||||
pkg={verifiedPackage}
|
||||
onArrange={(id) => alert(`Arrange: ${id}`)}
|
||||
onRemove={(id) => alert(`Remove: ${id}`)}
|
||||
/>
|
||||
<ComparisonColumnCard
|
||||
pkg={unverifiedPackage}
|
||||
onArrange={(id) => alert(`Arrange: ${id}`)}
|
||||
onRemove={(id) => alert(`Remove: ${id}`)}
|
||||
/>
|
||||
</Box>
|
||||
),
|
||||
],
|
||||
};
|
||||
Reference in New Issue
Block a user