Add MapPin atom — price-pill map markers with verified/unverified distinction
Airbnb-style markers: pill variant (price label + nub) and dot variant (no price). Verified = brand palette, unverified = neutral grey. Active state inverts colours + scale-up. Pure CSS for map overlay use. Keyboard accessible with role="button" and focus ring. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
141
src/components/atoms/MapPin/MapPin.stories.tsx
Normal file
141
src/components/atoms/MapPin/MapPin.stories.tsx
Normal file
@@ -0,0 +1,141 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
import Box from '@mui/material/Box';
|
||||
import { MapPin } from './MapPin';
|
||||
|
||||
const meta: Meta<typeof MapPin> = {
|
||||
title: 'Atoms/MapPin',
|
||||
component: MapPin,
|
||||
tags: ['autodocs'],
|
||||
parameters: {
|
||||
layout: 'centered',
|
||||
backgrounds: {
|
||||
default: 'map',
|
||||
values: [{ name: 'map', value: '#E5E3DF' }],
|
||||
},
|
||||
},
|
||||
argTypes: {
|
||||
onClick: { action: 'clicked' },
|
||||
},
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof MapPin>;
|
||||
|
||||
/** Verified provider with price — warm brand pill */
|
||||
export const VerifiedWithPrice: Story = {
|
||||
args: {
|
||||
price: 900,
|
||||
verified: true,
|
||||
},
|
||||
};
|
||||
|
||||
/** Unverified provider with price — neutral grey pill */
|
||||
export const UnverifiedWithPrice: Story = {
|
||||
args: {
|
||||
price: 1200,
|
||||
verified: false,
|
||||
},
|
||||
};
|
||||
|
||||
/** Active/selected state — inverted colours, slight scale-up */
|
||||
export const Active: Story = {
|
||||
args: {
|
||||
price: 900,
|
||||
verified: true,
|
||||
active: true,
|
||||
},
|
||||
};
|
||||
|
||||
/** Active unverified */
|
||||
export const ActiveUnverified: Story = {
|
||||
args: {
|
||||
price: 1200,
|
||||
verified: false,
|
||||
active: true,
|
||||
},
|
||||
};
|
||||
|
||||
/** Dot marker — no price, verified */
|
||||
export const DotVerified: Story = {
|
||||
args: {
|
||||
verified: true,
|
||||
},
|
||||
};
|
||||
|
||||
/** Dot marker — no price, unverified */
|
||||
export const DotUnverified: Story = {
|
||||
args: {
|
||||
verified: false,
|
||||
},
|
||||
};
|
||||
|
||||
/** Dot marker — active */
|
||||
export const DotActive: Story = {
|
||||
args: {
|
||||
verified: true,
|
||||
active: true,
|
||||
},
|
||||
};
|
||||
|
||||
/** Custom price label */
|
||||
export const CustomLabel: Story = {
|
||||
args: {
|
||||
priceLabel: 'POA',
|
||||
verified: true,
|
||||
},
|
||||
};
|
||||
|
||||
/** High price — wider pill */
|
||||
export const HighPrice: Story = {
|
||||
args: {
|
||||
price: 12500,
|
||||
verified: true,
|
||||
},
|
||||
};
|
||||
|
||||
/** Map simulation — multiple pins on a mock map background */
|
||||
export const MapSimulation: Story = {
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<Box
|
||||
sx={{
|
||||
position: 'relative',
|
||||
width: 600,
|
||||
height: 400,
|
||||
bgcolor: '#E5E3DF',
|
||||
borderRadius: 2,
|
||||
overflow: 'hidden',
|
||||
}}
|
||||
>
|
||||
<Story />
|
||||
</Box>
|
||||
),
|
||||
],
|
||||
render: () => (
|
||||
<>
|
||||
{/* Verified providers */}
|
||||
<Box sx={{ position: 'absolute', top: 80, left: 120 }}>
|
||||
<MapPin price={900} verified onClick={() => {}} />
|
||||
</Box>
|
||||
<Box sx={{ position: 'absolute', top: 160, left: 300 }}>
|
||||
<MapPin price={1450} verified active onClick={() => {}} />
|
||||
</Box>
|
||||
<Box sx={{ position: 'absolute', top: 240, left: 180 }}>
|
||||
<MapPin price={2200} verified onClick={() => {}} />
|
||||
</Box>
|
||||
|
||||
{/* Unverified providers */}
|
||||
<Box sx={{ position: 'absolute', top: 120, left: 420 }}>
|
||||
<MapPin price={1100} onClick={() => {}} />
|
||||
</Box>
|
||||
<Box sx={{ position: 'absolute', top: 280, left: 380 }}>
|
||||
<MapPin onClick={() => {}} />
|
||||
</Box>
|
||||
|
||||
{/* Dot markers */}
|
||||
<Box sx={{ position: 'absolute', top: 60, left: 480 }}>
|
||||
<MapPin verified onClick={() => {}} />
|
||||
</Box>
|
||||
</>
|
||||
),
|
||||
};
|
||||
Reference in New Issue
Block a user