Refactor atomic showcase tabs

This commit is contained in:
2026-01-18 00:32:03 +00:00
parent 9cb7297f5b
commit 4c5bd04970
9 changed files with 676 additions and 498 deletions

View File

@@ -1,53 +1,17 @@
import { useState } from 'react'
import { Heart, Share, User, Envelope, Lock, Gear, House, Trash, Pencil, Check } from '@phosphor-icons/react'
import {
Heading,
Text,
Link,
ActionButton,
IconButton,
StatusBadge,
Chip,
Dot,
Avatar,
Code,
Kbd,
Alert,
Spinner,
ProgressBar,
Skeleton,
Label,
HelperText,
Container,
Section,
Stack,
Spacer,
Divider,
Timestamp,
Tag,
BreadcrumbNav,
IconText,
TextArea,
Input,
Toggle,
RadioGroup,
Checkbox,
Slider,
ColorSwatch,
Stepper,
Rating,
Timeline,
FileUpload,
Tabs,
Accordion,
Card,
Notification,
CopyButton,
PasswordInput,
BasicSearchInput,
Select,
Table,
} from '@/components/atoms'
import { House, Pencil, User } from '@phosphor-icons/react'
import showcaseCopy from '@/data/atomic-showcase/showcase.json'
import tabsCopy from '@/data/atomic-showcase/tabs.json'
import { FormsTab } from '@/components/atomic-showcase/FormsTab'
import { DisplayTab } from '@/components/atomic-showcase/DisplayTab'
import { TypographyTab } from '@/components/atomic-showcase/TypographyTab'
import { Container, Heading, Section, Stack, Tabs, Text } from '@/components/atoms'
const tabIcons = {
house: <House />,
pencil: <Pencil />,
user: <User />,
}
export function AtomicComponentShowcase() {
const [toggleValue, setToggleValue] = useState(false)
@@ -63,469 +27,53 @@ export function AtomicComponentShowcase() {
const [activeTab, setActiveTab] = useState('typography')
const [selectedColor, setSelectedColor] = useState('#8b5cf6')
const tableData = [
{ id: 1, name: 'John Doe', email: 'john@example.com', status: 'active' },
{ id: 2, name: 'Jane Smith', email: 'jane@example.com', status: 'inactive' },
{ id: 3, name: 'Bob Johnson', email: 'bob@example.com', status: 'active' },
]
const tabs = [
{ id: 'typography', label: 'Typography', icon: <House /> },
{ id: 'forms', label: 'Forms', icon: <Pencil /> },
{ id: 'display', label: 'Display', icon: <User /> },
]
const tabs = tabsCopy.map((tab) => ({
...tab,
icon: tabIcons[tab.icon as keyof typeof tabIcons],
}))
return (
<Container size="xl" className="py-8">
<Stack spacing="xl">
<Section>
<Heading level={1}>Atomic Component Library</Heading>
<Text variant="muted">
A comprehensive showcase of all available atomic components
</Text>
<Heading level={1}>{showcaseCopy.title}</Heading>
<Text variant="muted">{showcaseCopy.description}</Text>
</Section>
<Tabs tabs={tabs} activeTab={activeTab} onChange={setActiveTab} variant="pills" />
{activeTab === 'typography' && (
<Stack spacing="lg">
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Typography Components</Heading>
<Divider />
<Stack spacing="sm">
<Heading level={3}>Headings</Heading>
<Heading level={1}>Heading Level 1</Heading>
<Heading level={2}>Heading Level 2</Heading>
<Heading level={3}>Heading Level 3</Heading>
</Stack>
<Divider />
<Stack spacing="sm">
<Heading level={3}>Text Variants</Heading>
<Text variant="body">Body text with default styling</Text>
<Text variant="muted">Muted text for less emphasis</Text>
<Text variant="caption">Caption text for descriptions</Text>
<Text variant="small">Small text for fine print</Text>
</Stack>
<Divider />
<Stack spacing="sm">
<Heading level={3}>Links & Code</Heading>
<Link href="#" variant="default">Default Link</Link>
<Link href="#" variant="accent">Accent Link</Link>
<Code inline>npm install react</Code>
<div>Press <Kbd>Ctrl</Kbd> + <Kbd>K</Kbd> to search</div>
</Stack>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Badges & Indicators</Heading>
<Divider />
<Stack spacing="sm">
<Heading level={3}>Status Badges</Heading>
<Stack direction="horizontal" spacing="sm" wrap>
<StatusBadge status="active" />
<StatusBadge status="inactive" />
<StatusBadge status="pending" />
<StatusBadge status="error" />
<StatusBadge status="success" />
<StatusBadge status="warning" />
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>Tags</Heading>
<Stack direction="horizontal" spacing="sm" wrap>
<Tag variant="default">Default</Tag>
<Tag variant="primary">Primary</Tag>
<Tag variant="secondary">Secondary</Tag>
<Tag variant="accent">Accent</Tag>
<Tag variant="destructive">Destructive</Tag>
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>Dots</Heading>
<Stack direction="horizontal" spacing="sm" align="center">
<Dot variant="default" />
<Dot variant="primary" />
<Dot variant="accent" pulse />
<Dot variant="success" />
<Dot variant="warning" pulse />
<Dot variant="error" />
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>Chips</Heading>
<Stack direction="horizontal" spacing="sm" wrap>
<Chip variant="default">React</Chip>
<Chip variant="primary">TypeScript</Chip>
<Chip variant="accent">Tailwind</Chip>
</Stack>
</Stack>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Feedback Components</Heading>
<Divider />
<Alert variant="info" title="Information">
This is an informational message
</Alert>
<Alert variant="success" title="Success">
Operation completed successfully
</Alert>
<Alert variant="warning" title="Warning">
Please review this warning
</Alert>
<Alert variant="error" title="Error">
Something went wrong
</Alert>
<Notification
type="success"
title="Notification"
message="This is a notification with a close button"
onClose={() => {}}
/>
<Stack spacing="sm">
<Heading level={3}>Loading States</Heading>
<Stack direction="horizontal" spacing="md" align="center">
<Spinner size={16} />
<Spinner size={24} />
<Spinner size={32} />
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>Progress Bar</Heading>
<ProgressBar value={35} showLabel />
<ProgressBar value={65} variant="accent" />
<ProgressBar value={85} variant="destructive" />
</Stack>
<Stack spacing="sm">
<Heading level={3}>Skeleton Loaders</Heading>
<Skeleton variant="text" width="100%" />
<Skeleton variant="rounded" width="100%" height={100} />
<Stack direction="horizontal" spacing="sm">
<Skeleton variant="circular" width={40} height={40} />
<Stack spacing="xs" className="flex-1">
<Skeleton variant="text" width="70%" />
<Skeleton variant="text" width="40%" />
</Stack>
</Stack>
</Stack>
</Stack>
</Card>
</Stack>
)}
{activeTab === 'typography' && <TypographyTab />}
{activeTab === 'forms' && (
<Stack spacing="lg">
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Form Components</Heading>
<Divider />
<Input
label="Email"
placeholder="you@example.com"
value={inputValue}
onChange={(e) => setInputValue(e.target.value)}
leftIcon={<Envelope size={18} />}
helperText="Enter your email address"
/>
<PasswordInput
label="Password"
value={passwordValue}
onChange={setPasswordValue}
helperText="Must be at least 8 characters"
/>
<BasicSearchInput
value={searchValue}
onChange={setSearchValue}
placeholder="Search components..."
/>
<TextArea
label="Description"
placeholder="Enter a description..."
value={textAreaValue}
onChange={(e) => setTextAreaValue(e.target.value)}
helperText="Optional field"
/>
<Select
label="Framework"
value={selectValue}
onChange={setSelectValue}
options={[
{ value: 'react', label: 'React' },
{ value: 'vue', label: 'Vue' },
{ value: 'angular', label: 'Angular' },
]}
placeholder="Select a framework"
/>
<Divider />
<Toggle
checked={toggleValue}
onChange={setToggleValue}
label="Enable notifications"
/>
<Checkbox
checked={checkboxValue}
onChange={setCheckboxValue}
label="I agree to the terms and conditions"
/>
<RadioGroup
name="size"
value={radioValue}
onChange={setRadioValue}
options={[
{ value: 'sm', label: 'Small' },
{ value: 'md', label: 'Medium' },
{ value: 'lg', label: 'Large' },
]}
orientation="horizontal"
/>
<Slider
label="Volume"
value={sliderValue}
onChange={setSliderValue}
min={0}
max={100}
showValue
/>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Button Components</Heading>
<Divider />
<Stack direction="horizontal" spacing="sm" wrap>
<ActionButton label="Default" onClick={() => {}} />
<ActionButton label="Primary" variant="default" onClick={() => {}} />
<ActionButton label="Outline" variant="outline" onClick={() => {}} />
<ActionButton label="Ghost" variant="ghost" onClick={() => {}} />
<ActionButton label="Destructive" variant="destructive" onClick={() => {}} />
</Stack>
<Stack direction="horizontal" spacing="sm">
<ActionButton label="Like" icon={<Heart />} onClick={() => {}} />
<ActionButton label="Share" icon={<Share />} variant="outline" onClick={() => {}} />
</Stack>
<Stack direction="horizontal" spacing="sm">
<IconButton icon={<Heart />} onClick={() => {}} />
<IconButton icon={<Share />} variant="outline" onClick={() => {}} />
<IconButton icon={<Trash />} variant="destructive" onClick={() => {}} />
</Stack>
<CopyButton text="Copy this text" size="md" />
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>File Upload</Heading>
<Divider />
<FileUpload
accept="image/*"
multiple
onFilesSelected={(files) => console.log(files)}
/>
</Stack>
</Card>
</Stack>
<FormsTab
checkboxValue={checkboxValue}
inputValue={inputValue}
passwordValue={passwordValue}
radioValue={radioValue}
searchValue={searchValue}
selectValue={selectValue}
sliderValue={sliderValue}
textAreaValue={textAreaValue}
toggleValue={toggleValue}
onCheckboxChange={setCheckboxValue}
onInputChange={setInputValue}
onPasswordChange={setPasswordValue}
onRadioChange={setRadioValue}
onSearchChange={setSearchValue}
onSelectChange={setSelectValue}
onSliderChange={setSliderValue}
onTextAreaChange={setTextAreaValue}
onToggleChange={setToggleValue}
/>
)}
{activeTab === 'display' && (
<Stack spacing="lg">
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Display Components</Heading>
<Divider />
<Stack spacing="sm">
<Heading level={3}>Avatar</Heading>
<Stack direction="horizontal" spacing="sm" align="center">
<Avatar fallback="JD" size="xs" />
<Avatar fallback="JD" size="sm" />
<Avatar fallback="JD" size="md" />
<Avatar fallback="JD" size="lg" />
<Avatar fallback="JD" size="xl" />
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>Rating</Heading>
<Rating value={ratingValue} onChange={setRatingValue} max={5} showValue />
</Stack>
<Stack spacing="sm">
<Heading level={3}>Color Swatches</Heading>
<Stack direction="horizontal" spacing="sm">
<ColorSwatch
color="#8b5cf6"
selected={selectedColor === '#8b5cf6'}
onClick={() => setSelectedColor('#8b5cf6')}
label="Primary"
/>
<ColorSwatch
color="#06b6d4"
selected={selectedColor === '#06b6d4'}
onClick={() => setSelectedColor('#06b6d4')}
label="Accent"
/>
<ColorSwatch
color="#ef4444"
selected={selectedColor === '#ef4444'}
onClick={() => setSelectedColor('#ef4444')}
label="Error"
/>
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>Timestamp</Heading>
<Timestamp date={new Date()} />
<Timestamp date={new Date(Date.now() - 3600000)} relative />
</Stack>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Stepper</Heading>
<Divider />
<Stepper
steps={[
{ label: 'Account', description: 'Create your account' },
{ label: 'Profile', description: 'Add personal details' },
{ label: 'Complete', description: 'Finish setup' },
]}
currentStep={1}
/>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Timeline</Heading>
<Divider />
<Timeline
items={[
{
title: 'Project Created',
description: 'Initial setup completed',
timestamp: '2 hours ago',
status: 'completed',
},
{
title: 'Development',
description: 'Currently building features',
timestamp: 'now',
status: 'current',
},
{
title: 'Testing',
description: 'QA phase',
status: 'pending',
},
]}
/>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Table</Heading>
<Divider />
<Table
data={tableData}
columns={[
{ key: 'name', header: 'Name' },
{ key: 'email', header: 'Email' },
{
key: 'status',
header: 'Status',
render: (item) => <StatusBadge status={item.status as any} />,
},
]}
striped
hoverable
/>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Accordion</Heading>
<Divider />
<Accordion
items={[
{
id: '1',
title: 'What is an atomic component?',
content: (
<Text variant="body">
Atomic components are the smallest building blocks in a design system,
representing basic UI elements that cannot be broken down further.
</Text>
),
},
{
id: '2',
title: 'How do I use these components?',
content: (
<Text variant="body">
Import the components from the atoms folder and use them in your React
components with full TypeScript support.
</Text>
),
},
]}
type="single"
defaultOpen={['1']}
/>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>Navigation</Heading>
<Divider />
<BreadcrumbNav
items={[
{ label: 'Home', onClick: () => {} },
{ label: 'Components', onClick: () => {} },
{ label: 'Showcase' },
]}
/>
</Stack>
</Card>
</Stack>
<DisplayTab
ratingValue={ratingValue}
selectedColor={selectedColor}
onRatingChange={setRatingValue}
onColorChange={setSelectedColor}
/>
)}
</Stack>
</Container>

View File

@@ -0,0 +1,125 @@
import displayCopy from '@/data/atomic-showcase/display.json'
import {
Accordion,
Avatar,
BreadcrumbNav,
Card,
ColorSwatch,
Divider,
Heading,
Rating,
Stack,
StatusBadge,
Stepper,
Table,
Text,
Timeline,
Timestamp,
} from '@/components/atoms'
type DisplayTabProps = {
ratingValue: number
selectedColor: string
onRatingChange: (value: number) => void
onColorChange: (value: string) => void
}
export function DisplayTab({ ratingValue, selectedColor, onRatingChange, onColorChange }: DisplayTabProps) {
const tableColumns = displayCopy.tableColumns.map((column) =>
column.key === 'status'
? { ...column, render: (item: { status: string }) => <StatusBadge status={item.status as any} /> }
: column
)
return (
<Stack spacing="lg">
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{displayCopy.displayTitle}</Heading>
<Divider />
<Stack spacing="sm">
<Heading level={3}>{displayCopy.avatarTitle}</Heading>
<Stack direction="horizontal" spacing="sm" align="center">
<Avatar fallback={displayCopy.avatarFallback} size="xs" />
<Avatar fallback={displayCopy.avatarFallback} size="sm" />
<Avatar fallback={displayCopy.avatarFallback} size="md" />
<Avatar fallback={displayCopy.avatarFallback} size="lg" />
<Avatar fallback={displayCopy.avatarFallback} size="xl" />
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>{displayCopy.ratingTitle}</Heading>
<Rating value={ratingValue} onChange={onRatingChange} max={5} showValue />
</Stack>
<Stack spacing="sm">
<Heading level={3}>{displayCopy.colorSwatchesTitle}</Heading>
<Stack direction="horizontal" spacing="sm">
{displayCopy.colorSwatches.map((swatch) => (
<ColorSwatch
key={swatch.color}
color={swatch.color}
selected={selectedColor === swatch.color}
onClick={() => onColorChange(swatch.color)}
label={swatch.label}
/>
))}
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>{displayCopy.timestampTitle}</Heading>
<Timestamp date={new Date()} />
<Timestamp date={new Date(Date.now() - 3600000)} relative />
</Stack>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{displayCopy.stepperTitle}</Heading>
<Divider />
<Stepper steps={displayCopy.stepperSteps} currentStep={1} />
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{displayCopy.timelineTitle}</Heading>
<Divider />
<Timeline items={displayCopy.timelineItems} />
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{displayCopy.tableTitle}</Heading>
<Divider />
<Table data={displayCopy.tableData} columns={tableColumns} striped hoverable />
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{displayCopy.accordionTitle}</Heading>
<Divider />
<Accordion
items={displayCopy.accordionItems.map((item) => ({
id: item.id,
title: item.title,
content: <Text variant="body">{item.content}</Text>,
}))}
type="single"
defaultOpen={[displayCopy.accordionItems[0]?.id ?? '1']}
/>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{displayCopy.navigationTitle}</Heading>
<Divider />
<BreadcrumbNav
items={displayCopy.breadcrumbs.map((item, index) => ({
label: item.label,
onClick: index < displayCopy.breadcrumbs.length - 1 ? () => {} : undefined,
}))}
/>
</Stack>
</Card>
</Stack>
)
}

View File

@@ -0,0 +1,137 @@
import { Envelope, Heart, Share, Trash } from '@phosphor-icons/react'
import formsCopy from '@/data/atomic-showcase/forms.json'
import {
ActionButton,
BasicSearchInput,
Card,
Checkbox,
CopyButton,
Divider,
FileUpload,
Heading,
IconButton,
Input,
PasswordInput,
RadioGroup,
Select,
Slider,
Stack,
TextArea,
Toggle,
} from '@/components/atoms'
type FormsTabProps = {
checkboxValue: boolean
inputValue: string
passwordValue: string
radioValue: string
searchValue: string
selectValue: string
sliderValue: number
textAreaValue: string
toggleValue: boolean
onCheckboxChange: (value: boolean) => void
onInputChange: (value: string) => void
onPasswordChange: (value: string) => void
onRadioChange: (value: string) => void
onSearchChange: (value: string) => void
onSelectChange: (value: string) => void
onSliderChange: (value: number) => void
onTextAreaChange: (value: string) => void
onToggleChange: (value: boolean) => void
}
const actionIcons = [<Heart key="heart" />, <Share key="share" />]
const iconButtons = [<Heart key="heart" />, <Share key="share" />, <Trash key="trash" />]
export function FormsTab(props: FormsTabProps) {
const {
checkboxValue,
inputValue,
passwordValue,
radioValue,
searchValue,
selectValue,
sliderValue,
textAreaValue,
toggleValue,
onCheckboxChange,
onInputChange,
onPasswordChange,
onRadioChange,
onSearchChange,
onSelectChange,
onSliderChange,
onTextAreaChange,
onToggleChange,
} = props
return (
<Stack spacing="lg">
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{formsCopy.formTitle}</Heading>
<Divider />
<Input
label={formsCopy.email.label}
placeholder={formsCopy.email.placeholder}
value={inputValue}
onChange={(event) => onInputChange(event.target.value)}
leftIcon={<Envelope size={18} />}
helperText={formsCopy.email.helperText}
/>
<PasswordInput label={formsCopy.password.label} value={passwordValue} onChange={onPasswordChange} helperText={formsCopy.password.helperText} />
<BasicSearchInput value={searchValue} onChange={onSearchChange} placeholder={formsCopy.search.placeholder} />
<TextArea
label={formsCopy.textArea.label}
placeholder={formsCopy.textArea.placeholder}
value={textAreaValue}
onChange={(event) => onTextAreaChange(event.target.value)}
helperText={formsCopy.textArea.helperText}
/>
<Select
label={formsCopy.select.label}
value={selectValue}
onChange={onSelectChange}
options={formsCopy.select.options}
placeholder={formsCopy.select.placeholder}
/>
<Divider />
<Toggle checked={toggleValue} onChange={onToggleChange} label={formsCopy.toggle.label} />
<Checkbox checked={checkboxValue} onChange={onCheckboxChange} label={formsCopy.checkbox.label} />
<RadioGroup name={formsCopy.radio.name} value={radioValue} onChange={onRadioChange} options={formsCopy.radio.options} orientation="horizontal" />
<Slider label={formsCopy.slider.label} value={sliderValue} onChange={onSliderChange} min={formsCopy.slider.min} max={formsCopy.slider.max} showValue />
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{formsCopy.buttonTitle}</Heading>
<Divider />
<Stack direction="horizontal" spacing="sm" wrap>
{formsCopy.buttons.map((button) => (
<ActionButton key={button.label} label={button.label} variant={button.variant as any} onClick={() => {}} />
))}
</Stack>
<Stack direction="horizontal" spacing="sm">
{formsCopy.iconActions.map((action, index) => (
<ActionButton key={action.label} label={action.label} icon={actionIcons[index]} variant={action.variant as any} onClick={() => {}} />
))}
</Stack>
<Stack direction="horizontal" spacing="sm">
{formsCopy.iconButtons.map((button, index) => (
<IconButton key={`${button.variant}-${index}`} icon={iconButtons[index]} variant={button.variant as any} onClick={() => {}} />
))}
</Stack>
<CopyButton text={formsCopy.copyButtonText} size="md" />
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{formsCopy.fileUploadTitle}</Heading>
<Divider />
<FileUpload accept={formsCopy.fileUploadAccept} multiple onFilesSelected={(files) => console.log(files)} />
</Stack>
</Card>
</Stack>
)
}

View File

@@ -0,0 +1,149 @@
import typographyCopy from '@/data/atomic-showcase/typography.json'
import {
Alert,
Card,
Chip,
Code,
Divider,
Dot,
Heading,
Kbd,
Link,
Notification,
ProgressBar,
Skeleton,
Spinner,
Stack,
StatusBadge,
Tag,
Text,
} from '@/components/atoms'
export function TypographyTab() {
return (
<Stack spacing="lg">
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{typographyCopy.sectionTitle}</Heading>
<Divider />
<Stack spacing="sm">
<Heading level={3}>{typographyCopy.headingsTitle}</Heading>
{typographyCopy.headingSamples.map((sample) => (
<Heading key={sample.text} level={sample.level}>
{sample.text}
</Heading>
))}
</Stack>
<Divider />
<Stack spacing="sm">
<Heading level={3}>{typographyCopy.textVariantsTitle}</Heading>
{typographyCopy.textVariants.map((variant) => (
<Text key={variant.text} variant={variant.variant as any}>
{variant.text}
</Text>
))}
</Stack>
<Divider />
<Stack spacing="sm">
<Heading level={3}>{typographyCopy.linksCodeTitle}</Heading>
{typographyCopy.links.map((link) => (
<Link key={link.label} href="#" variant={link.variant as any}>
{link.label}
</Link>
))}
<Code inline>{typographyCopy.codeSample}</Code>
<div>
{typographyCopy.kbd.prefix} <Kbd>{typographyCopy.kbd.keys[0]}</Kbd> +{' '}
<Kbd>{typographyCopy.kbd.keys[1]}</Kbd> {typographyCopy.kbd.suffix}
</div>
</Stack>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{typographyCopy.badgesTitle}</Heading>
<Divider />
<Stack spacing="sm">
<Heading level={3}>{typographyCopy.statusBadgesTitle}</Heading>
<Stack direction="horizontal" spacing="sm" wrap>
{typographyCopy.statusBadges.map((status) => (
<StatusBadge key={status} status={status as any} />
))}
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>{typographyCopy.tagsTitle}</Heading>
<Stack direction="horizontal" spacing="sm" wrap>
{typographyCopy.tags.map((tag) => (
<Tag key={tag.label} variant={tag.variant as any}>
{tag.label}
</Tag>
))}
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>{typographyCopy.dotsTitle}</Heading>
<Stack direction="horizontal" spacing="sm" align="center">
{typographyCopy.dots.map((dot) => (
<Dot key={`${dot.variant}-${dot.pulse ?? false}`} variant={dot.variant as any} pulse={dot.pulse} />
))}
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>{typographyCopy.chipsTitle}</Heading>
<Stack direction="horizontal" spacing="sm" wrap>
{typographyCopy.chips.map((chip) => (
<Chip key={chip.label} variant={chip.variant as any}>
{chip.label}
</Chip>
))}
</Stack>
</Stack>
</Stack>
</Card>
<Card variant="bordered" padding="lg">
<Stack spacing="md">
<Heading level={2}>{typographyCopy.feedbackTitle}</Heading>
<Divider />
{typographyCopy.alerts.map((alert) => (
<Alert key={alert.title} variant={alert.variant as any} title={alert.title}>
{alert.message}
</Alert>
))}
<Notification
type={typographyCopy.notification.type as any}
title={typographyCopy.notification.title}
message={typographyCopy.notification.message}
onClose={() => {}}
/>
<Stack spacing="sm">
<Heading level={3}>{typographyCopy.loadingTitle}</Heading>
<Stack direction="horizontal" spacing="md" align="center">
<Spinner size={16} />
<Spinner size={24} />
<Spinner size={32} />
</Stack>
</Stack>
<Stack spacing="sm">
<Heading level={3}>{typographyCopy.progressTitle}</Heading>
{typographyCopy.progressBars.map((bar) => (
<ProgressBar key={`${bar.value}-${bar.variant ?? 'default'}`} value={bar.value} showLabel={bar.showLabel} variant={bar.variant as any} />
))}
</Stack>
<Stack spacing="sm">
<Heading level={3}>{typographyCopy.skeletonTitle}</Heading>
<Skeleton variant="text" width="100%" />
<Skeleton variant="rounded" width="100%" height={100} />
<Stack direction="horizontal" spacing="sm">
<Skeleton variant="circular" width={40} height={40} />
<Stack spacing="xs" className="flex-1">
<Skeleton variant="text" width="70%" />
<Skeleton variant="text" width="40%" />
</Stack>
</Stack>
</Stack>
</Stack>
</Card>
</Stack>
)
}

View File

@@ -0,0 +1,69 @@
{
"displayTitle": "Display Components",
"avatarTitle": "Avatar",
"avatarFallback": "JD",
"ratingTitle": "Rating",
"colorSwatchesTitle": "Color Swatches",
"colorSwatches": [
{ "color": "#8b5cf6", "label": "Primary" },
{ "color": "#06b6d4", "label": "Accent" },
{ "color": "#ef4444", "label": "Error" }
],
"timestampTitle": "Timestamp",
"stepperTitle": "Stepper",
"stepperSteps": [
{ "label": "Account", "description": "Create your account" },
{ "label": "Profile", "description": "Add personal details" },
{ "label": "Complete", "description": "Finish setup" }
],
"timelineTitle": "Timeline",
"timelineItems": [
{
"title": "Project Created",
"description": "Initial setup completed",
"timestamp": "2 hours ago",
"status": "completed"
},
{
"title": "Development",
"description": "Currently building features",
"timestamp": "now",
"status": "current"
},
{
"title": "Testing",
"description": "QA phase",
"status": "pending"
}
],
"tableTitle": "Table",
"tableColumns": [
{ "key": "name", "header": "Name" },
{ "key": "email", "header": "Email" },
{ "key": "status", "header": "Status" }
],
"tableData": [
{ "id": 1, "name": "John Doe", "email": "john@example.com", "status": "active" },
{ "id": 2, "name": "Jane Smith", "email": "jane@example.com", "status": "inactive" },
{ "id": 3, "name": "Bob Johnson", "email": "bob@example.com", "status": "active" }
],
"accordionTitle": "Accordion",
"accordionItems": [
{
"id": "1",
"title": "What is an atomic component?",
"content": "Atomic components are the smallest building blocks in a design system, representing basic UI elements that cannot be broken down further."
},
{
"id": "2",
"title": "How do I use these components?",
"content": "Import the components from the atoms folder and use them in your React components with full TypeScript support."
}
],
"navigationTitle": "Navigation",
"breadcrumbs": [
{ "label": "Home" },
{ "label": "Components" },
{ "label": "Showcase" }
]
}

View File

@@ -0,0 +1,68 @@
{
"formTitle": "Form Components",
"email": {
"label": "Email",
"placeholder": "you@example.com",
"helperText": "Enter your email address"
},
"password": {
"label": "Password",
"helperText": "Must be at least 8 characters"
},
"search": {
"placeholder": "Search components..."
},
"textArea": {
"label": "Description",
"placeholder": "Enter a description...",
"helperText": "Optional field"
},
"select": {
"label": "Framework",
"placeholder": "Select a framework",
"options": [
{ "value": "react", "label": "React" },
{ "value": "vue", "label": "Vue" },
{ "value": "angular", "label": "Angular" }
]
},
"toggle": {
"label": "Enable notifications"
},
"checkbox": {
"label": "I agree to the terms and conditions"
},
"radio": {
"name": "size",
"options": [
{ "value": "sm", "label": "Small" },
{ "value": "md", "label": "Medium" },
{ "value": "lg", "label": "Large" }
]
},
"slider": {
"label": "Volume",
"min": 0,
"max": 100
},
"buttonTitle": "Button Components",
"buttons": [
{ "label": "Default" },
{ "label": "Primary", "variant": "default" },
{ "label": "Outline", "variant": "outline" },
{ "label": "Ghost", "variant": "ghost" },
{ "label": "Destructive", "variant": "destructive" }
],
"iconButtons": [
{ "variant": "default" },
{ "variant": "outline" },
{ "variant": "destructive" }
],
"iconActions": [
{ "label": "Like", "variant": "default" },
{ "label": "Share", "variant": "outline" }
],
"copyButtonText": "Copy this text",
"fileUploadTitle": "File Upload",
"fileUploadAccept": "image/*"
}

View File

@@ -0,0 +1,4 @@
{
"title": "Atomic Component Library",
"description": "A comprehensive showcase of all available atomic components"
}

View File

@@ -0,0 +1,5 @@
[
{ "id": "typography", "label": "Typography", "icon": "house" },
{ "id": "forms", "label": "Forms", "icon": "pencil" },
{ "id": "display", "label": "Display", "icon": "user" }
]

View File

@@ -0,0 +1,73 @@
{
"sectionTitle": "Typography Components",
"headingsTitle": "Headings",
"headingSamples": [
{ "level": 1, "text": "Heading Level 1" },
{ "level": 2, "text": "Heading Level 2" },
{ "level": 3, "text": "Heading Level 3" }
],
"textVariantsTitle": "Text Variants",
"textVariants": [
{ "variant": "body", "text": "Body text with default styling" },
{ "variant": "muted", "text": "Muted text for less emphasis" },
{ "variant": "caption", "text": "Caption text for descriptions" },
{ "variant": "small", "text": "Small text for fine print" }
],
"linksCodeTitle": "Links & Code",
"links": [
{ "variant": "default", "label": "Default Link" },
{ "variant": "accent", "label": "Accent Link" }
],
"codeSample": "npm install react",
"kbd": {
"prefix": "Press",
"keys": ["Ctrl", "K"],
"suffix": "to search"
},
"badgesTitle": "Badges & Indicators",
"statusBadgesTitle": "Status Badges",
"statusBadges": ["active", "inactive", "pending", "error", "success", "warning"],
"tagsTitle": "Tags",
"tags": [
{ "variant": "default", "label": "Default" },
{ "variant": "primary", "label": "Primary" },
{ "variant": "secondary", "label": "Secondary" },
{ "variant": "accent", "label": "Accent" },
{ "variant": "destructive", "label": "Destructive" }
],
"dotsTitle": "Dots",
"dots": [
{ "variant": "default" },
{ "variant": "primary" },
{ "variant": "accent", "pulse": true },
{ "variant": "success" },
{ "variant": "warning", "pulse": true },
{ "variant": "error" }
],
"chipsTitle": "Chips",
"chips": [
{ "variant": "default", "label": "React" },
{ "variant": "primary", "label": "TypeScript" },
{ "variant": "accent", "label": "Tailwind" }
],
"feedbackTitle": "Feedback Components",
"alerts": [
{ "variant": "info", "title": "Information", "message": "This is an informational message" },
{ "variant": "success", "title": "Success", "message": "Operation completed successfully" },
{ "variant": "warning", "title": "Warning", "message": "Please review this warning" },
{ "variant": "error", "title": "Error", "message": "Something went wrong" }
],
"notification": {
"type": "success",
"title": "Notification",
"message": "This is a notification with a close button"
},
"loadingTitle": "Loading States",
"progressTitle": "Progress Bar",
"progressBars": [
{ "value": 35, "showLabel": true },
{ "value": 65, "variant": "accent" },
{ "value": 85, "variant": "destructive" }
],
"skeletonTitle": "Skeleton Loaders"
}