mirror of
https://github.com/johndoe6345789/low-code-react-app-b.git
synced 2026-04-24 13:44:54 +00:00
Merge pull request #41 from johndoe6345789/codex/refactor-atomiccomponentshowcase-to-reduce-loc
Refactor atomic component showcase tabs into modules and externalize demo data
This commit is contained in:
@@ -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>
|
||||
|
||||
125
src/components/atomic-showcase/DisplayTab.tsx
Normal file
125
src/components/atomic-showcase/DisplayTab.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
137
src/components/atomic-showcase/FormsTab.tsx
Normal file
137
src/components/atomic-showcase/FormsTab.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
149
src/components/atomic-showcase/TypographyTab.tsx
Normal file
149
src/components/atomic-showcase/TypographyTab.tsx
Normal 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>
|
||||
)
|
||||
}
|
||||
69
src/data/atomic-showcase/display.json
Normal file
69
src/data/atomic-showcase/display.json
Normal 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" }
|
||||
]
|
||||
}
|
||||
68
src/data/atomic-showcase/forms.json
Normal file
68
src/data/atomic-showcase/forms.json
Normal 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/*"
|
||||
}
|
||||
4
src/data/atomic-showcase/showcase.json
Normal file
4
src/data/atomic-showcase/showcase.json
Normal file
@@ -0,0 +1,4 @@
|
||||
{
|
||||
"title": "Atomic Component Library",
|
||||
"description": "A comprehensive showcase of all available atomic components"
|
||||
}
|
||||
5
src/data/atomic-showcase/tabs.json
Normal file
5
src/data/atomic-showcase/tabs.json
Normal file
@@ -0,0 +1,5 @@
|
||||
[
|
||||
{ "id": "typography", "label": "Typography", "icon": "house" },
|
||||
{ "id": "forms", "label": "Forms", "icon": "pencil" },
|
||||
{ "id": "display", "label": "Display", "icon": "user" }
|
||||
]
|
||||
73
src/data/atomic-showcase/typography.json
Normal file
73
src/data/atomic-showcase/typography.json
Normal 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"
|
||||
}
|
||||
Reference in New Issue
Block a user