Upgrade to React 19, MUI v7, Storybook 9

- React 18 → 19, MUI v5 → v7, Storybook 8 → 9
- Fix Grid v2 API in Footer (remove item prop, use size prop)
- Inline provider fixtures (was importing from excluded demo dir)
- Remove consolidated SB addons (essentials, storysource, blocks)
- Update addon-designs to SB9-compatible version
- Add autodocs via tags in preview config
- Add Tailwind v3, PostCSS, autoprefixer dev deps (config next)
- Zero TypeScript errors, Storybook starts clean

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-05-22 13:21:52 +10:00
parent 4cafd84142
commit fcc69446f3
7 changed files with 12398 additions and 49 deletions

View File

@@ -3,28 +3,15 @@ import type { StorybookConfig } from '@storybook/react-vite';
const config: StorybookConfig = {
stories: ['../src/**/*.stories.@(ts|tsx)'],
addons: [
'@storybook/addon-essentials',
'@storybook/addon-a11y',
'@storybook/addon-designs',
{
name: '@storybook/addon-storysource',
options: {
loaderOptions: {
injectStoryParameters: true,
},
},
},
],
framework: {
name: '@storybook/react-vite',
options: {},
},
docs: {
autodocs: 'tag',
},
staticDirs: ['../brandassets'],
viteFinal: async (config) => {
// Inherit aliases from vite.config.ts automatically via react-vite framework
return config;
},
};

View File

@@ -6,6 +6,7 @@ import { theme } from '../src/theme';
import '../src/theme/generated/tokens.css';
const preview: Preview = {
tags: ['autodocs'],
decorators: [
(Story) => (
<ThemeProvider theme={theme}>

12282
package-lock.json generated Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
{
"name": "fa-design-system",
"version": "0.1.0",
"version": "1.0.0",
"private": true,
"type": "module",
"description": "Funeral Arranger Design System — React + MUI + Storybook",
"description": "Funeral Arranger Design System — React 19 + MUI v7 + Storybook 9 + Tailwind v3",
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
@@ -17,53 +17,45 @@
"format": "prettier --write 'src/**/*.{ts,tsx}'",
"format:check": "prettier --check 'src/**/*.{ts,tsx}'",
"test": "vitest run --passWithNoTests",
"test:watch": "vitest",
"chromatic": "chromatic --exit-zero-on-changes --build-script-name=build:storybook",
"demo:dev": "vite -c vite.demo.config.ts --mode arrangement",
"demo:build": "vite build -c vite.demo.config.ts",
"demo:publish": "npm run demo:build -- --mode arrangement && ./scripts/deploy-demo.sh arrangement",
"prepare": "husky"
"test:watch": "vitest"
},
"dependencies": {
"@emotion/react": "^11.13.0",
"@emotion/styled": "^11.13.0",
"@googlemaps/markerclusterer": "^2.6.2",
"@mui/icons-material": "^5.16.0",
"@mui/material": "^5.16.0",
"@mui/system": "^5.16.0",
"@mui/icons-material": "^7.0.0",
"@mui/material": "^7.0.0",
"@mui/system": "^7.0.0",
"@vis.gl/react-google-maps": "^1.8.3",
"react": "^18.3.0",
"react-dom": "^18.3.0",
"react": "^19.0.0",
"react-dom": "^19.0.0",
"react-router-dom": "^7.14.1",
"zustand": "^5.0.12"
},
"devDependencies": {
"@eslint/js": "^9.39.4",
"@playwright/mcp": "^0.0.68",
"@storybook/addon-a11y": "^8.6.14",
"@storybook/addon-designs": "^8.0.0",
"@storybook/addon-essentials": "^8.4.0",
"@storybook/addon-storysource": "^8.6.14",
"@storybook/blocks": "^8.4.0",
"@storybook/react": "^8.4.0",
"@storybook/react-vite": "^8.4.0",
"@storybook/addon-a11y": "^9.0.0",
"@storybook/addon-designs": "^9.0.0-next.3",
"@storybook/react": "^9.0.0",
"@storybook/react-vite": "^9.0.0",
"@testing-library/jest-dom": "^6.9.1",
"@testing-library/react": "^16.3.2",
"@types/react": "^18.3.0",
"@types/react-dom": "^18.3.0",
"@types/react": "^19.0.0",
"@types/react-dom": "^19.0.0",
"@vitejs/plugin-react": "^4.3.0",
"chromatic": "^11.29.0",
"autoprefixer": "^10.4.0",
"eslint": "^9.39.4",
"eslint-config-prettier": "^10.1.8",
"eslint-plugin-jsx-a11y": "^6.10.2",
"eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.0.1",
"husky": "^9.1.7",
"jsdom": "^29.0.1",
"lint-staged": "^16.4.0",
"postcss": "^8.4.0",
"prettier": "^3.8.1",
"storybook": "^8.4.0",
"storybook": "^9.0.0",
"style-dictionary": "^4.2.0",
"tailwindcss": "^3.4.0",
"typescript": "^5.5.0",
"typescript-eslint": "^8.57.2",
"vite": "^5.4.0",

View File

@@ -99,7 +99,7 @@ export const Footer = React.forwardRef<HTMLDivElement, FooterProps>(
{/* Main footer content */}
<Grid container spacing={{ xs: 4, md: 6 }}>
{/* Logo + tagline column */}
<Grid item xs={12} md={4}>
<Grid size={{ xs: 12, md: 4 }}>
<Box sx={{ mb: 2 }}>{logo}</Box>
{tagline && (
<Typography
@@ -157,10 +157,7 @@ export const Footer = React.forwardRef<HTMLDivElement, FooterProps>(
{/* Link group columns */}
{linkGroups.map((group) => (
<Grid
item
xs={6}
sm={4}
md
size={{ xs: 6, sm: 4, md: 'grow' }}
key={group.heading}
component="nav"
aria-label={group.heading}

View File

@@ -2,8 +2,7 @@ import { useState } from 'react';
import type { Meta, StoryObj } from '@storybook/react';
import Box from '@mui/material/Box';
import { ProviderMap } from './ProviderMap';
import { providers as demoProviders } from '../../../demo/shared/fixtures/providers';
import type { ProviderData } from '../../pages/ProvidersStep';
import { providers } from '../../../fixtures/providers';
const meta: Meta<typeof ProviderMap> = {
title: 'Organisms/ProviderMap',
@@ -29,9 +28,6 @@ const meta: Meta<typeof ProviderMap> = {
export default meta;
type Story = StoryObj<typeof ProviderMap>;
// Cast: DemoProvider adds `tier` over ProviderData, structural subset for the map
const providers = demoProviders as ProviderData[];
// ────────────────────────────────────────────────────────────────────────────
/** All 7 demo providers with real NSW/QLD coordinates. Map fits bounds across them. */

94
src/fixtures/providers.ts Normal file
View File

@@ -0,0 +1,94 @@
import type { ProviderData } from '../components/pages/ProvidersStep';
import { assetUrl } from '../utils/assetUrl';
export const providers: ProviderData[] = [
{
id: 'parsons',
name: 'H.Parsons Funeral Directors',
location: 'Wentworth, NSW',
verified: true,
imageUrl: assetUrl('/images/venues/hparsons-funeral-home-wollongong/01.jpg'),
logoUrl: assetUrl('/images/providers/hparsons-funeral-directors/logo.png'),
rating: 4.6,
reviewCount: 7,
startingPrice: 1800,
distanceKm: 2.3,
coords: { lat: -34.1074, lng: 141.9166 },
description:
'H.Parsons delivers premium funeral services with exceptional care and support, guiding families through every step with empathy and expertise.',
},
{
id: 'rankins',
name: 'Rankins Funeral Services',
location: 'Wollongong, NSW',
verified: true,
imageUrl: assetUrl('/images/venues/rankins-funeral-home-warrawong/01.jpg'),
logoUrl: assetUrl('/images/providers/rankins-funerals/logo.png'),
rating: 4.8,
reviewCount: 23,
startingPrice: 2450,
distanceKm: 5.1,
coords: { lat: -34.487, lng: 150.897 },
},
{
id: 'wollongong-city',
name: 'Wollongong City Funerals',
location: 'Wollongong, NSW',
verified: false,
rating: 4.2,
reviewCount: 15,
startingPrice: 3400,
distanceKm: 6.8,
coords: { lat: -34.4278, lng: 150.8931 },
},
{
id: 'killick',
name: 'Killick Family Funerals',
location: 'Kingaroy, QLD',
verified: true,
imageUrl: assetUrl('/images/venues/killick-family-funerals-chapel-kingaroy/01.jpg'),
logoUrl: assetUrl('/images/providers/killick-family-funerals/logo.png'),
rating: 4.9,
reviewCount: 15,
startingPrice: 3100,
distanceKm: 8.4,
coords: { lat: -26.5408, lng: 151.8388 },
},
{
id: 'mackay',
name: 'Mackay Family Funeral Directors',
location: 'Ourimbah, NSW',
verified: true,
imageUrl: assetUrl('/images/venues/mackay-family-garden-estate/01.jpg'),
logoUrl: assetUrl('/images/providers/mackay-family-funerals/logo.webp'),
rating: 4.6,
reviewCount: 87,
startingPrice: 2800,
distanceKm: 18.2,
coords: { lat: -33.3644, lng: 151.3728 },
},
{
id: 'mannings',
name: 'Mannings Funerals',
location: 'Bega, NSW',
verified: true,
imageUrl: assetUrl('/images/venues/mannings-chapel/01.jpg'),
logoUrl: assetUrl('/images/providers/mannings-funerals/logo.png'),
rating: 4.7,
reviewCount: 31,
startingPrice: 2600,
distanceKm: 22.0,
coords: { lat: -36.6742, lng: 149.8417 },
},
{
id: 'botanical',
name: 'Botanical Funerals',
location: 'Newtown, NSW',
verified: false,
rating: 4.9,
reviewCount: 8,
startingPrice: 5200,
distanceKm: 15.0,
coords: { lat: -33.8988, lng: 151.1794 },
},
];