Reorganise components into atoms/molecules/organisms and fix Input icon colours
Moved all 17 components from ui/ into atomic design tiers: atoms (Button, IconButton, Input, Textarea, Select, Checkbox, Radio, Switch, Badge, Tag, Chip, Tooltip) and molecules (Alert, Accordion, Card, Dialog, Popover). Updated all Storybook titles and cross-component imports. Changed Input icons to primary-dark and replaced palette token references with semantic tokens. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
155
src/components/molecules/Popover/Popover.stories.tsx
Normal file
155
src/components/molecules/Popover/Popover.stories.tsx
Normal file
@@ -0,0 +1,155 @@
|
||||
import type { Meta, StoryObj } from '@storybook/react-vite'
|
||||
import { Settings, Filter, MoreVertical } from 'lucide-react'
|
||||
import { Popover, PopoverTrigger, PopoverContent, PopoverClose } from './Popover'
|
||||
import { Button } from '@/components/atoms/Button'
|
||||
import { IconButton } from '@/components/atoms/IconButton'
|
||||
import { Input } from '@/components/atoms/Input'
|
||||
import { Checkbox } from '@/components/atoms/Checkbox'
|
||||
|
||||
const meta: Meta<typeof Popover> = {
|
||||
title: 'Molecules/Popover',
|
||||
component: Popover,
|
||||
tags: ['autodocs'],
|
||||
argTypes: {
|
||||
placement: {
|
||||
control: 'select',
|
||||
options: ['top', 'right', 'bottom', 'left', 'bottom-start', 'bottom-end'],
|
||||
},
|
||||
},
|
||||
decorators: [
|
||||
(Story) => (
|
||||
<div className="flex min-h-80 items-start justify-center p-16">
|
||||
<Story />
|
||||
</div>
|
||||
),
|
||||
],
|
||||
}
|
||||
|
||||
export default meta
|
||||
type Story = StoryObj<typeof meta>
|
||||
|
||||
export const Default: Story = {
|
||||
render: () => (
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<Button variant="secondary">Open popover</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<p className="text-body font-bold text-text">Popover title</p>
|
||||
<p className="mt-1 text-small text-text-secondary">
|
||||
This is a popover with rich content. It can contain text, forms, or any components.
|
||||
</p>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
),
|
||||
}
|
||||
|
||||
// --- With form ---
|
||||
|
||||
export const WithForm: Story = {
|
||||
render: () => (
|
||||
<Popover>
|
||||
<PopoverTrigger>
|
||||
<Button leftIcon={<Settings className="size-4" />}>Settings</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-80">
|
||||
<p className="mb-3 text-body font-bold text-text">Display settings</p>
|
||||
<div className="space-y-3">
|
||||
<Input label="Items per page" type="number" defaultValue="25" />
|
||||
<Checkbox label="Show archived items" />
|
||||
<Checkbox label="Compact view" />
|
||||
</div>
|
||||
<div className="mt-4 flex justify-end gap-2">
|
||||
<PopoverClose className="rounded-full px-3 py-1.5 text-small font-bold text-text-secondary hover:bg-bg">
|
||||
Cancel
|
||||
</PopoverClose>
|
||||
<PopoverClose className="rounded-full bg-primary-dark px-3 py-1.5 text-small font-bold text-white hover:bg-primary-dark/90">
|
||||
Apply
|
||||
</PopoverClose>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
),
|
||||
}
|
||||
|
||||
// --- Filter popover ---
|
||||
|
||||
export const FilterPopover: Story = {
|
||||
render: () => (
|
||||
<Popover placement="bottom-start">
|
||||
<PopoverTrigger>
|
||||
<Button variant="secondary" intent="neutral" leftIcon={<Filter className="size-4" />}>
|
||||
Filters
|
||||
</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-64">
|
||||
<p className="mb-3 text-small font-bold text-text">Filter by status</p>
|
||||
<div className="space-y-2">
|
||||
<Checkbox label="Active" defaultChecked />
|
||||
<Checkbox label="Completed" defaultChecked />
|
||||
<Checkbox label="Archived" />
|
||||
<Checkbox label="Draft" />
|
||||
</div>
|
||||
<div className="mt-4 border-t border-border pt-3">
|
||||
<PopoverClose className="text-small font-bold text-primary-dark hover:underline">
|
||||
Clear all filters
|
||||
</PopoverClose>
|
||||
</div>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
),
|
||||
}
|
||||
|
||||
// --- Context menu style ---
|
||||
|
||||
export const ActionMenu: Story = {
|
||||
render: () => (
|
||||
<Popover placement="bottom-end">
|
||||
<PopoverTrigger>
|
||||
<IconButton variant="tertiary" intent="neutral" icon={<MoreVertical />} aria-label="More actions" />
|
||||
</PopoverTrigger>
|
||||
<PopoverContent className="w-48 p-1">
|
||||
{['Edit', 'Duplicate', 'Move to folder'].map((item) => (
|
||||
<PopoverClose
|
||||
key={item}
|
||||
className="flex w-full rounded-md px-3 py-2 text-left text-small text-text hover:bg-bg"
|
||||
>
|
||||
{item}
|
||||
</PopoverClose>
|
||||
))}
|
||||
<div className="my-1 border-t border-border" />
|
||||
<PopoverClose className="flex w-full rounded-md px-3 py-2 text-left text-small text-error hover:bg-error/5">
|
||||
Delete
|
||||
</PopoverClose>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
),
|
||||
}
|
||||
|
||||
// --- Placements ---
|
||||
|
||||
export const BottomStart: Story = {
|
||||
render: () => (
|
||||
<Popover placement="bottom-start">
|
||||
<PopoverTrigger>
|
||||
<Button variant="secondary" intent="neutral">Bottom start</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<p className="text-small text-text">Aligned to the start of the trigger.</p>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
),
|
||||
}
|
||||
|
||||
export const TopEnd: Story = {
|
||||
render: () => (
|
||||
<Popover placement="top-end">
|
||||
<PopoverTrigger>
|
||||
<Button variant="secondary" intent="neutral">Top end</Button>
|
||||
</PopoverTrigger>
|
||||
<PopoverContent>
|
||||
<p className="text-small text-text">Aligned to the end of the trigger, above.</p>
|
||||
</PopoverContent>
|
||||
</Popover>
|
||||
),
|
||||
}
|
||||
Reference in New Issue
Block a user