Skip to content

Commit

Permalink
Create Default ProductCard story
Browse files Browse the repository at this point in the history
  • Loading branch information
Youakeem committed Sep 19, 2024
1 parent 87f4db6 commit e0b05cd
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 0 deletions.
14 changes: 14 additions & 0 deletions apps/store/src/components/ProductCard/Divider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { tokens } from 'ui'

export const Divider = () => {
return (
<div
style={{
height: 1,
borderBottomWidth: 1,
borderBottomStyle: 'solid',
borderBottomColor: tokens.colors.borderOpaque1,
}}
/>
)
}
123 changes: 123 additions & 0 deletions apps/store/src/components/ProductCard/ProductCard.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@

import type { Meta, StoryObj } from '@storybook/react'
import { type ComponentProps } from 'react'
import { Badge, BasePillow, Button, Card, CrossIcon, IconButton, sprinkles, Text, tokens } from 'ui'
import { CurrencyCode } from '@/services/graphql/graphql'
import { InputStartDay } from '../InputDay/InputStartDay'
import { Price } from '../Price'
import { DetailsList } from './DetailsList/DetailsList'
import { Divider } from './Divider'
import { ProductCardDetails } from './ProductCardDetails'

type Controls = ComponentProps<typeof Card.Root>

const meta: Meta<Controls> = {
title: 'Components / ProductCard',
component: Card.Root,
argTypes: {
variant: {
options: ['primary', 'secondary'],
control: { type: 'select' },
},
},
parameters: {
design: {
allowFullscreen: true,
type: 'figma',
url: 'https://www.figma.com/file/5kmmDdh6StpXzbEfr7WevV/Hedvig-UI-Kit?type=design&node-id=18673-5100',
},
},
}
export default meta

type Story = StoryObj<Controls>

export const Default: Story = {
render: (args: Controls) => (
<div style={{ maxWidth: '400px' }}>
<Card.Root variant={args.variant}>
<Card.Aside>
<IconButton variant="secondary">
<CrossIcon />
</IconButton>
</Card.Aside>
<Card.Header>
<Card.Media>
<BasePillow shouldFallback fill={tokens.colors.amber300} />
</Card.Media>
<Card.Heading>
<Card.Title>Homeowner Insurance</Card.Title>
<Card.Subtitle>Bellmansgatan 19A</Card.Subtitle>
</Card.Heading>
</Card.Header>

<ProductCardDetails.Root>
<ProductCardDetails.Trigger>
<ProductCardDetails.CollapsedLabel>Show details</ProductCardDetails.CollapsedLabel>
<ProductCardDetails.ExpandedLabel>Hide details</ProductCardDetails.ExpandedLabel>
</ProductCardDetails.Trigger>

<ProductCardDetails.Content className={sprinkles({ paddingBlock: 'md' })}>
<Text className={sprinkles({ mb: 'xxs' })}>Details</Text>
<DetailsList.Root size="md" className={sprinkles({ mb: 'md' })}>
<DetailsList.Item>
<DetailsList.Label>Home type</DetailsList.Label>
<DetailsList.Value>Homeowner</DetailsList.Value>
</DetailsList.Item>

<DetailsList.Item>
<DetailsList.Label>Address</DetailsList.Label>
<DetailsList.Value>Bellmansgatan 19A</DetailsList.Value>
</DetailsList.Item>

<DetailsList.Item>
<DetailsList.Label>Zip code</DetailsList.Label>
<DetailsList.Value>118 47</DetailsList.Value>
</DetailsList.Item>
</DetailsList.Root>
<Button variant="secondary" size="medium" fullWidth>
Edit information
</Button>
</ProductCardDetails.Content>
</ProductCardDetails.Root>

<InputStartDay />

<DetailsList.Root>
<DetailsList.Item>
<DetailsList.Label>
Homeowner Insurance{' '}
<Badge color="pinkFill1" size="tiny">
Max
</Badge>
</DetailsList.Label>
<DetailsList.Value>379 kr/mo</DetailsList.Value>
</DetailsList.Item>

<DetailsList.Item>
<DetailsList.Label>Extended travel 60 days</DetailsList.Label>
<DetailsList.Value>79 kr/mo</DetailsList.Value>
</DetailsList.Item>
</DetailsList.Root>

<Divider />

<DetailsList.Root size="md">
<DetailsList.Item className={sprinkles({ color: 'textPrimary' })}>
<DetailsList.Label>Total</DetailsList.Label>
<DetailsList.Value>
<Price
className={sprinkles({ justifyContent: 'flex-end' })}
currencyCode={CurrencyCode.Sek}
amount={458}
/>
</DetailsList.Value>
</DetailsList.Item>
</DetailsList.Root>
</Card.Root>
</div>
),
args: {
variant: 'primary',
},
}
86 changes: 86 additions & 0 deletions apps/store/src/components/ProductCard/ProductCardDetails.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
import { type ComponentProps, createContext, type PropsWithChildren, useContext, useState } from 'react'
import { Button } from 'ui'
import Collapsible from '@/components/Collapsible/Collapsible'

type ContextValue = {
isOpen: boolean
toggle: () => void
}

const Context = createContext<ContextValue | null>(null)

const useProductDetails = () => {
const context = useContext(Context)

if (!context) {
throw new Error('useProductDetails must be used inside ProductCardDetails')
}

return context
}

type RootProps = ComponentProps<typeof Collapsible.Root>
const Root = ({ children, ...props }: RootProps) => {
const [isOpen, setIsOpen] = useState(false)

const toggle = () => {
setIsOpen((isOpen) => !isOpen)
}

return (
<Collapsible.Root {...props} open={isOpen}>
<Context.Provider value={{ isOpen, toggle }}>{children}</Context.Provider>
</Collapsible.Root>
)
}

type TriggerProps = ComponentProps<typeof Collapsible.Trigger>
const Trigger = ({ children, ...props }: TriggerProps) => {
const { toggle } = useProductDetails()

return (
<Collapsible.Trigger asChild {...props}>
<Button variant="outline" size="medium" onClick={toggle} fullWidth>
{children}
</Button>
</Collapsible.Trigger>
)
}

type ContentProps = ComponentProps<'div'>
const Content = ({ children, ...props }: ContentProps) => {
return (
<Collapsible.Content>
{/* This `div` wraps all content not to conflict with `Collapsible.Content` animation */}
<div {...props}>{children}</div>
</Collapsible.Content>
)
}

const ExpandedLabel = ({ children }: PropsWithChildren) => {
const { isOpen } = useProductDetails()

if (!isOpen) {
return null
}

return children
}

const CollapsedLabel = ({ children }: PropsWithChildren) => {
const { isOpen } = useProductDetails()

if (isOpen) {
return null
}

return children
}

export const ProductCardDetails = {
Root,
Trigger,
Content,
ExpandedLabel,
CollapsedLabel,
}

0 comments on commit e0b05cd

Please sign in to comment.