import React, { useState } from 'react'; import type { Meta, StoryObj } from '@storybook/react'; import { Chip } from './Chip'; import { Card } from '../Card'; import { Typography } from '../Typography'; import Box from '@mui/material/Box'; import LocalOfferIcon from '@mui/icons-material/LocalOffer'; import FaceIcon from '@mui/icons-material/Face'; import CheckIcon from '@mui/icons-material/Check'; import FilterListIcon from '@mui/icons-material/FilterList'; import ChurchIcon from '@mui/icons-material/Church'; import LocalFloristIcon from '@mui/icons-material/LocalFlorist'; import DirectionsCarIcon from '@mui/icons-material/DirectionsCar'; import RestaurantIcon from '@mui/icons-material/Restaurant'; import MusicNoteIcon from '@mui/icons-material/MusicNote'; import PhotoCameraIcon from '@mui/icons-material/PhotoCamera'; const meta: Meta = { title: 'Atoms/Chip', component: Chip, tags: ['autodocs'], parameters: { layout: 'centered', }, argTypes: { variant: { control: 'select', options: ['filled', 'outlined'], description: 'Visual style variant', table: { defaultValue: { summary: 'filled' } }, }, color: { control: 'select', options: ['default', 'primary'], description: 'Colour intent', table: { defaultValue: { summary: 'default' } }, }, size: { control: 'select', options: ['small', 'medium'], description: 'Size preset', table: { defaultValue: { summary: 'medium' } }, }, selected: { control: 'boolean', description: 'Selected/active state', table: { defaultValue: { summary: 'false' } }, }, clickable: { control: 'boolean', description: 'Whether the chip is clickable', }, }, }; export default meta; type Story = StoryObj; // ─── Default ──────────────────────────────────────────────────────────────── /** Default chip — filled variant, neutral colour */ export const Default: Story = { args: { label: 'Chip label', }, }; // ─── Variants ─────────────────────────────────────────────────────────────── /** Both visual variants with default and primary colour */ export const Variants: Story = { render: () => ( ), }; // ─── Sizes ────────────────────────────────────────────────────────────────── /** Small and medium sizes side by side */ export const Sizes: Story = { render: () => ( } /> } /> } /> } /> ), }; // ─── With Icons ───────────────────────────────────────────────────────────── /** Chips with leading icons */ export const WithIcons: Story = { name: 'With Icons', render: () => ( } label="Chapel" /> } label="Flowers" color="primary" /> } label="Transport" variant="outlined" /> } label="Family" variant="outlined" color="primary" /> ), }; // ─── Clickable ────────────────────────────────────────────────────────────── /** Clickable chips respond to click events (for filtering/toggling) */ export const Clickable: Story = { render: () => ( {}} /> {}} /> {}} /> {}} /> ), }; // ─── Deletable ────────────────────────────────────────────────────────────── /** Deletable chips show a close icon */ export const Deletable: Story = { render: () => ( {}} /> {}} /> {}} /> } onDelete={() => {}} /> ), }; // ─── Selected State ───────────────────────────────────────────────────────── /** Selected state promotes chip to brand colour */ export const Selected: Story = { render: () => ( Filled {}} /> {}} /> Outlined {}} /> {}} /> ), }; // ─── Interactive: Filter Chips ────────────────────────────────────────────── /** * Toggle filter pattern — commonly used for service category filtering. * Click chips to toggle selection. */ export const FilterChips: Story = { name: 'Interactive — Filter Chips', render: () => { const categories = [ { label: 'Chapel', icon: }, { label: 'Flowers', icon: }, { label: 'Transport', icon: }, { label: 'Catering', icon: }, { label: 'Music', icon: }, { label: 'Photography', icon: }, ]; const FilterDemo = () => { const [selected, setSelected] = useState>(new Set(['Chapel', 'Flowers'])); const toggle = (label: string) => { setSelected((prev) => { const next = new Set(prev); if (next.has(label)) next.delete(label); else next.add(label); return next; }); }; return ( Filter services {categories.map(({ label, icon }) => ( : icon} selected={selected.has(label)} onClick={() => toggle(label)} variant="outlined" /> ))} Selected: {selected.size === 0 ? 'None' : Array.from(selected).join(', ')} ); }; return ; }, }; // ─── Interactive: Removable Tags ──────────────────────────────────────────── /** * Removable tag pattern — for selected items that can be dismissed. * Click the × icon to remove a tag. */ export const RemovableTags: Story = { name: 'Interactive — Removable Tags', render: () => { const TagDemo = () => { const [tags, setTags] = useState([ 'White roses', 'Organ music', 'Prayer cards', 'Memorial video', 'Guest book', ]); const remove = (tag: string) => { setTags((prev) => prev.filter((t) => t !== tag)); }; return ( Selected additions ({tags.length}) {tags.length === 0 ? ( No items selected ) : ( tags.map((tag) => ( remove(tag)} /> )) )} ); }; return ; }, }; // ─── In Context: Service Option ───────────────────────────────────────────── /** * Chips used inside a ServiceOption-style card layout, * showing service tags and category labels. */ export const InServiceOption: Story = { name: 'In Context — Service Option', render: () => ( Chapel Ceremony $1,200 Traditional chapel service with celebrant and music of your choosing. } label="Indoor" /> } label="Music included" /> Graveside Service $900 Intimate outdoor farewell at the burial site. ), }; // ─── Complete Matrix ──────────────────────────────────────────────────────── /** Full variant × colour × size × state matrix for visual QA */ export const CompleteMatrix: Story = { name: 'Complete Matrix', render: () => { const variants = ['filled', 'outlined'] as const; const colors = ['default', 'primary'] as const; const sizes = ['medium', 'small'] as const; return ( {variants.map((variant) => ( {variant} {sizes.map((size) => ( {size} {colors.map((color) => ( } /> {}} /> ))} ))} ))} Selected state {}} /> {}} /> } onClick={() => {}} /> ); }, };