From ba78f094ff25c23b075b4d9f69d27b0698f45200 Mon Sep 17 00:00:00 2001 From: johndoe6345789 Date: Sat, 17 Jan 2026 16:18:25 +0000 Subject: [PATCH] Generated by Spark: Make atomic component library until done. If done, just wire them into other components. --- src/components/AtomicLibraryShowcase.tsx | 134 +++++++++++++++++- src/components/ProjectDashboard.tsx | 58 +++++++- src/components/atoms/GlowCard.tsx | 62 ++++++++ src/components/atoms/LiveIndicator.tsx | 49 +++++++ src/components/atoms/NumberInput.tsx | 89 ++++++++++++ src/components/atoms/PanelHeader.tsx | 57 ++++++++ src/components/atoms/Pulse.tsx | 56 ++++++++ src/components/atoms/QuickActionButton.tsx | 61 ++++++++ src/components/atoms/Sparkle.tsx | 35 +++++ src/components/atoms/TextGradient.tsx | 38 +++++ src/components/atoms/index.ts | 8 ++ src/components/molecules/ComponentPalette.tsx | 16 ++- src/components/molecules/ComponentTree.tsx | 12 +- src/components/molecules/PropertyEditor.tsx | 45 +++--- 14 files changed, 684 insertions(+), 36 deletions(-) create mode 100644 src/components/atoms/GlowCard.tsx create mode 100644 src/components/atoms/LiveIndicator.tsx create mode 100644 src/components/atoms/NumberInput.tsx create mode 100644 src/components/atoms/PanelHeader.tsx create mode 100644 src/components/atoms/Pulse.tsx create mode 100644 src/components/atoms/QuickActionButton.tsx create mode 100644 src/components/atoms/Sparkle.tsx create mode 100644 src/components/atoms/TextGradient.tsx diff --git a/src/components/AtomicLibraryShowcase.tsx b/src/components/AtomicLibraryShowcase.tsx index bc66640..69c13db 100644 --- a/src/components/AtomicLibraryShowcase.tsx +++ b/src/components/AtomicLibraryShowcase.tsx @@ -40,6 +40,14 @@ import { IconButton, ActionButton, StatusBadge, + NumberInput, + TextGradient, + Pulse, + QuickActionButton, + PanelHeader, + LiveIndicator, + Sparkle, + GlowCard, } from '@/components/atoms' import { Heart, @@ -54,6 +62,8 @@ import { Info, WarningCircle, XCircle, + Rocket, + Code as CodeIcon, } from '@phosphor-icons/react' export function AtomicLibraryShowcase() { @@ -62,6 +72,7 @@ export function AtomicLibraryShowcase() { const [rangeValue, setRangeValue] = useState<[number, number]>([20, 80]) const [filterValue, setFilterValue] = useState('') const [rating, setRating] = useState(3) + const [numberValue, setNumberValue] = useState(10) return ( @@ -481,15 +492,132 @@ export function AtomicLibraryShowcase() { +
+ Enhanced Components + + +
+ } + actions={ + + } + /> +
+ +
+ Number Input + +
+ +
+ Text Gradient + + + Beautiful Gradient Text + + +
+ +
+ Status Indicators + + + + Active + + + + + Featured + + +
+ +
+ Quick Action Buttons + + } + label="Code" + description="Edit files" + variant="primary" + onClick={() => alert('Code clicked')} + /> + } + label="Deploy" + description="Launch app" + variant="accent" + onClick={() => alert('Deploy clicked')} + /> + } + label="Favorite" + description="Save for later" + variant="default" + onClick={() => alert('Favorite clicked')} + /> + } + label="Shop" + description="Browse items" + variant="muted" + onClick={() => alert('Shop clicked')} + /> + +
+ +
+ Glow Cards + + +
+ Primary Glow + + Card with primary glow effect + +
+
+ +
+ Accent Glow + + Card with accent glow effect + +
+
+ +
+ Success Glow + + Card with success glow effect + +
+
+
+
+
+
+
Summary }> Atomic Component Library Complete! - The atomic component library includes 50+ production-ready components covering buttons, - badges, typography, forms, progress indicators, feedback, avatars, cards, and layout utilities. - All components are fully typed, accessible, and follow the design system. + The atomic component library includes 60+ production-ready components covering buttons, + badges, typography, forms, progress indicators, feedback, avatars, cards, enhanced inputs, + gradient effects, and layout utilities. All components are fully typed, accessible, and follow the design system.
diff --git a/src/components/ProjectDashboard.tsx b/src/components/ProjectDashboard.tsx index 98891a7..6d8c13f 100644 --- a/src/components/ProjectDashboard.tsx +++ b/src/components/ProjectDashboard.tsx @@ -8,9 +8,20 @@ import { Play, Cube, FileText, + Rocket, + GitBranch, + Package, } from '@phosphor-icons/react' import { ProjectFile, PrismaModel, ComponentNode, ThemeConfig, PlaywrightTest, StorybookStory, UnitTest, FlaskConfig, NextJsConfig } from '@/types/project' -import { SeedDataStatus, DetailRow, CompletionCard, TipsCard, StatCard } from '@/components/atoms' +import { + SeedDataStatus, + DetailRow, + CompletionCard, + TipsCard, + StatCard, + QuickActionButton, + PanelHeader, +} from '@/components/atoms' import { GitHubBuildStatus } from '@/components/molecules/GitHubBuildStatus' import { useDashboardMetrics } from '@/hooks/ui/use-dashboard-metrics' import { useDashboardTips } from '@/hooks/ui/use-dashboard-tips' @@ -25,6 +36,7 @@ interface ProjectDashboardProps { unitTests: UnitTest[] flaskConfig: FlaskConfig nextjsConfig: NextJsConfig + onNavigate?: (page: string) => void } export function ProjectDashboard(props: ProjectDashboardProps) { @@ -38,6 +50,7 @@ export function ProjectDashboard(props: ProjectDashboardProps) { unitTests, flaskConfig, nextjsConfig, + onNavigate, } = props const metrics = useDashboardMetrics({ @@ -133,9 +146,50 @@ export function ProjectDashboard(props: ProjectDashboardProps) { /> )} +
+ } + /> +
+ } + label="Code Editor" + description="Edit files" + variant="primary" + onClick={() => onNavigate?.('code')} + /> + } + label="Models" + description="Design schema" + variant="primary" + onClick={() => onNavigate?.('models')} + /> + } + label="Components" + description="Build UI" + variant="accent" + onClick={() => onNavigate?.('components')} + /> + } + label="Deploy" + description="Export project" + variant="accent" + onClick={() => onNavigate?.('export')} + /> +
+
+ - Project Details + + + Project Details + void +} + +export function GlowCard({ + children, + glowColor = 'primary', + intensity = 'medium', + className, + onClick, +}: GlowCardProps) { + const glowClasses = { + primary: { + low: 'shadow-primary/10', + medium: 'shadow-primary/20 hover:shadow-primary/30', + high: 'shadow-primary/30 hover:shadow-primary/50', + }, + accent: { + low: 'shadow-accent/10', + medium: 'shadow-accent/20 hover:shadow-accent/30', + high: 'shadow-accent/30 hover:shadow-accent/50', + }, + success: { + low: 'shadow-green-500/10', + medium: 'shadow-green-500/20 hover:shadow-green-500/30', + high: 'shadow-green-500/30 hover:shadow-green-500/50', + }, + warning: { + low: 'shadow-yellow-500/10', + medium: 'shadow-yellow-500/20 hover:shadow-yellow-500/30', + high: 'shadow-yellow-500/30 hover:shadow-yellow-500/50', + }, + error: { + low: 'shadow-red-500/10', + medium: 'shadow-red-500/20 hover:shadow-red-500/30', + high: 'shadow-red-500/30 hover:shadow-red-500/50', + }, + } + + return ( + + {children} + + ) +} diff --git a/src/components/atoms/LiveIndicator.tsx b/src/components/atoms/LiveIndicator.tsx new file mode 100644 index 0000000..a6ec0a6 --- /dev/null +++ b/src/components/atoms/LiveIndicator.tsx @@ -0,0 +1,49 @@ +import { cn } from '@/lib/utils' + +interface LiveIndicatorProps { + label?: string + showLabel?: boolean + size?: 'sm' | 'md' | 'lg' + className?: string +} + +export function LiveIndicator({ + label = 'LIVE', + showLabel = true, + size = 'md', + className, +}: LiveIndicatorProps) { + const sizeClasses = { + sm: 'text-xs gap-1.5', + md: 'text-sm gap-2', + lg: 'text-base gap-2.5', + } + + const dotSizeClasses = { + sm: 'w-2 h-2', + md: 'w-2.5 h-2.5', + lg: 'w-3 h-3', + } + + return ( +
+ + + + + {showLabel && ( + {label} + )} +
+ ) +} diff --git a/src/components/atoms/NumberInput.tsx b/src/components/atoms/NumberInput.tsx new file mode 100644 index 0000000..e8ed56f --- /dev/null +++ b/src/components/atoms/NumberInput.tsx @@ -0,0 +1,89 @@ +import { Input } from '@/components/ui/input' +import { Button } from '@/components/ui/button' +import { Minus, Plus } from '@phosphor-icons/react' +import { cn } from '@/lib/utils' + +interface NumberInputProps { + value: number + onChange: (value: number) => void + min?: number + max?: number + step?: number + label?: string + disabled?: boolean + className?: string +} + +export function NumberInput({ + value, + onChange, + min, + max, + step = 1, + label, + disabled, + className, +}: NumberInputProps) { + const handleIncrement = () => { + const newValue = value + step + if (max === undefined || newValue <= max) { + onChange(newValue) + } + } + + const handleDecrement = () => { + const newValue = value - step + if (min === undefined || newValue >= min) { + onChange(newValue) + } + } + + const handleInputChange = (e: React.ChangeEvent) => { + const newValue = parseFloat(e.target.value) + if (!isNaN(newValue)) { + if ((min === undefined || newValue >= min) && (max === undefined || newValue <= max)) { + onChange(newValue) + } + } + } + + return ( +
+ {label && ( + + )} +
+ + + +
+
+ ) +} diff --git a/src/components/atoms/PanelHeader.tsx b/src/components/atoms/PanelHeader.tsx new file mode 100644 index 0000000..5b0090a --- /dev/null +++ b/src/components/atoms/PanelHeader.tsx @@ -0,0 +1,57 @@ +import { ReactNode } from 'react' +import { cn } from '@/lib/utils' +import { Separator } from '@/components/ui/separator' + +interface PanelHeaderProps { + title: string + subtitle?: string | ReactNode + icon?: ReactNode + actions?: ReactNode + className?: string + showSeparator?: boolean +} + +export function PanelHeader({ + title, + subtitle, + icon, + actions, + className, + showSeparator = true, +}: PanelHeaderProps) { + return ( +
+
+
+ {icon && ( +
+ {icon} +
+ )} +
+

+ {title} +

+ {subtitle && ( + typeof subtitle === 'string' ? ( +

+ {subtitle} +

+ ) : ( +
+ {subtitle} +
+ ) + )} +
+
+ {actions && ( +
+ {actions} +
+ )} +
+ {showSeparator && } +
+ ) +} diff --git a/src/components/atoms/Pulse.tsx b/src/components/atoms/Pulse.tsx new file mode 100644 index 0000000..22b9eb3 --- /dev/null +++ b/src/components/atoms/Pulse.tsx @@ -0,0 +1,56 @@ +import { cn } from '@/lib/utils' + +interface PulseProps { + variant?: 'primary' | 'accent' | 'success' | 'warning' | 'error' + size?: 'sm' | 'md' | 'lg' + speed?: 'slow' | 'normal' | 'fast' + className?: string +} + +export function Pulse({ + variant = 'primary', + size = 'md', + speed = 'normal', + className, +}: PulseProps) { + const sizeClasses = { + sm: 'w-2 h-2', + md: 'w-3 h-3', + lg: 'w-4 h-4', + } + + const variantClasses = { + primary: 'bg-primary', + accent: 'bg-accent', + success: 'bg-green-500', + warning: 'bg-yellow-500', + error: 'bg-red-500', + } + + const speedClasses = { + slow: 'animate-pulse [animation-duration:3s]', + normal: 'animate-pulse', + fast: 'animate-pulse [animation-duration:0.5s]', + } + + return ( +
+ + +
+ ) +} diff --git a/src/components/atoms/QuickActionButton.tsx b/src/components/atoms/QuickActionButton.tsx new file mode 100644 index 0000000..c3d350c --- /dev/null +++ b/src/components/atoms/QuickActionButton.tsx @@ -0,0 +1,61 @@ +import { Card } from '@/components/ui/card' +import { cn } from '@/lib/utils' +import { ReactNode } from 'react' + +interface QuickActionButtonProps { + icon: ReactNode + label: string + description?: string + onClick: () => void + variant?: 'default' | 'primary' | 'accent' | 'muted' + disabled?: boolean + className?: string +} + +export function QuickActionButton({ + icon, + label, + description, + onClick, + variant = 'default', + disabled, + className, +}: QuickActionButtonProps) { + const variantClasses = { + default: 'hover:bg-muted/50 hover:border-border', + primary: 'hover:bg-primary/10 hover:border-primary/50', + accent: 'hover:bg-accent/10 hover:border-accent/50', + muted: 'bg-muted hover:bg-muted/70', + } + + const iconColorClasses = { + default: 'text-foreground', + primary: 'text-primary', + accent: 'text-accent', + muted: 'text-muted-foreground', + } + + return ( + +
+ {icon} +
+
+

{label}

+ {description && ( +

{description}

+ )} +
+
+ ) +} diff --git a/src/components/atoms/Sparkle.tsx b/src/components/atoms/Sparkle.tsx new file mode 100644 index 0000000..d394135 --- /dev/null +++ b/src/components/atoms/Sparkle.tsx @@ -0,0 +1,35 @@ +import { cn } from '@/lib/utils' +import { Sparkle as SparkleIcon } from '@phosphor-icons/react' + +interface SparkleProps { + variant?: 'default' | 'primary' | 'accent' | 'gold' + size?: number + animate?: boolean + className?: string +} + +export function Sparkle({ + variant = 'default', + size = 16, + animate = true, + className, +}: SparkleProps) { + const variantClasses = { + default: 'text-foreground', + primary: 'text-primary', + accent: 'text-accent', + gold: 'text-yellow-500', + } + + return ( + + ) +} diff --git a/src/components/atoms/TextGradient.tsx b/src/components/atoms/TextGradient.tsx new file mode 100644 index 0000000..da820a3 --- /dev/null +++ b/src/components/atoms/TextGradient.tsx @@ -0,0 +1,38 @@ +import { cn } from '@/lib/utils' +import { ReactNode } from 'react' + +interface TextGradientProps { + children: ReactNode + from?: string + to?: string + via?: string + direction?: 'to-r' | 'to-l' | 'to-b' | 'to-t' | 'to-br' | 'to-bl' | 'to-tr' | 'to-tl' + className?: string + animate?: boolean +} + +export function TextGradient({ + children, + from = 'from-primary', + to = 'to-accent', + via, + direction = 'to-r', + className, + animate = false, +}: TextGradientProps) { + const gradientClasses = cn( + 'bg-gradient-to-r', + from, + via, + to, + direction !== 'to-r' && `bg-gradient-${direction}`, + 'bg-clip-text text-transparent', + animate && 'animate-gradient-x' + ) + + return ( + + {children} + + ) +} diff --git a/src/components/atoms/index.ts b/src/components/atoms/index.ts index 4f37d92..9d0be9b 100644 --- a/src/components/atoms/index.ts +++ b/src/components/atoms/index.ts @@ -101,3 +101,11 @@ export { ResponsiveGrid } from './ResponsiveGrid' export { Flex } from './Flex' export { CircularProgress } from './CircularProgress' export { AvatarGroup } from './AvatarGroup' +export { NumberInput } from './NumberInput' +export { TextGradient } from './TextGradient' +export { Pulse } from './Pulse' +export { QuickActionButton } from './QuickActionButton' +export { PanelHeader } from './PanelHeader' +export { LiveIndicator } from './LiveIndicator' +export { Sparkle } from './Sparkle' +export { GlowCard } from './GlowCard' diff --git a/src/components/molecules/ComponentPalette.tsx b/src/components/molecules/ComponentPalette.tsx index d3c4925..9dc148a 100644 --- a/src/components/molecules/ComponentPalette.tsx +++ b/src/components/molecules/ComponentPalette.tsx @@ -1,7 +1,9 @@ import { ComponentDefinition, getCategoryComponents } from '@/lib/component-definitions' import { ComponentPaletteItem } from '@/components/atoms/ComponentPaletteItem' +import { PanelHeader } from '@/components/atoms' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { ScrollArea } from '@/components/ui/scroll-area' +import { Package } from '@phosphor-icons/react' interface ComponentPaletteProps { onDragStart: (component: ComponentDefinition, e: React.DragEvent) => void @@ -17,14 +19,16 @@ export function ComponentPalette({ onDragStart }: ComponentPaletteProps) { return (
-
-

Components

-

- Drag components to the canvas -

+
+ } + showSeparator={false} + />
- + {categories.map((cat) => ( diff --git a/src/components/molecules/ComponentTree.tsx b/src/components/molecules/ComponentTree.tsx index e4b91f7..72cd9e6 100644 --- a/src/components/molecules/ComponentTree.tsx +++ b/src/components/molecules/ComponentTree.tsx @@ -1,5 +1,6 @@ import { UIComponent } from '@/types/json-ui' import { ComponentTreeNode } from '@/components/atoms/ComponentTreeNode' +import { PanelHeader } from '@/components/atoms' import { ScrollArea } from '@/components/ui/scroll-area' import { Button } from '@/components/ui/button' import { Tree, Plus } from '@phosphor-icons/react' @@ -60,11 +61,12 @@ export function ComponentTree({ return (
-
-
- -

Component Tree

-
+
+ } + />
diff --git a/src/components/molecules/PropertyEditor.tsx b/src/components/molecules/PropertyEditor.tsx index 66b2728..47ce3c5 100644 --- a/src/components/molecules/PropertyEditor.tsx +++ b/src/components/molecules/PropertyEditor.tsx @@ -1,8 +1,10 @@ import { UIComponent } from '@/types/json-ui' import { PropertyEditorField } from '@/components/atoms/PropertyEditorField' +import { PanelHeader } from '@/components/atoms' import { ScrollArea } from '@/components/ui/scroll-area' import { Button } from '@/components/ui/button' import { Separator } from '@/components/ui/separator' +import { Badge } from '@/components/ui/badge' import { Sliders, Trash, Code } from '@phosphor-icons/react' import { getComponentDef } from '@/lib/component-definitions' @@ -100,26 +102,29 @@ export function PropertyEditor({ component, onUpdate, onDelete }: PropertyEditor return (
-
-
-
- -

Properties

-
- -
-
- - {def?.label || component.type} - #{component.id} -
+
+ + + {def?.label || component.type} + + #{component.id} +
+ } + icon={} + actions={ + + } + />