Remove dead code

This commit is contained in:
sean-eskerium
2025-10-09 12:14:36 -04:00
parent 5c7924f43d
commit db538a5f46
22 changed files with 3 additions and 4606 deletions

View File

@@ -1,20 +1,16 @@
import { useState } from "react"; import { useState } from "react";
import { Palette, Layout, Settings } from "lucide-react"; import { Palette, Layout } from "lucide-react";
import { PillNavigation, type PillNavigationItem } from "../shared/PillNavigation"; import { PillNavigation, type PillNavigationItem } from "../shared/PillNavigation";
import { StyleGuideTab } from "../tabs/StyleGuideTab"; import { StyleGuideTab } from "../tabs/StyleGuideTab";
import { LayoutsTab } from "../tabs/LayoutsTab"; import { LayoutsTab } from "../tabs/LayoutsTab";
import { ConfiguratorsTab } from "../tabs/ConfiguratorsTab";
import { ThemeToggle } from "../../../components/ui/ThemeToggle"; import { ThemeToggle } from "../../../components/ui/ThemeToggle";
export const StyleGuideView = () => { export const StyleGuideView = () => {
const [activeTab, setActiveTab] = useState<"style-guide" | "layouts" | "configurators">( const [activeTab, setActiveTab] = useState<"style-guide" | "layouts">("style-guide");
"style-guide",
);
const navigationItems: PillNavigationItem[] = [ const navigationItems: PillNavigationItem[] = [
{ id: "style-guide", label: "Style Guide", icon: <Palette className="w-4 h-4" /> }, { id: "style-guide", label: "Style Guide", icon: <Palette className="w-4 h-4" /> },
{ id: "layouts", label: "Layouts", icon: <Layout className="w-4 h-4" /> }, { id: "layouts", label: "Layouts", icon: <Layout className="w-4 h-4" /> },
{ id: "configurators", label: "Configurators", icon: <Settings className="w-4 h-4" /> },
]; ];
return ( return (
@@ -29,7 +25,7 @@ export const StyleGuideView = () => {
Archon UI Style Guide Archon UI Style Guide
</h1> </h1>
<p className="text-gray-600 dark:text-gray-400 text-lg max-w-2xl mx-auto"> <p className="text-gray-600 dark:text-gray-400 text-lg max-w-2xl mx-auto">
Design system foundations, layout patterns, and interactive component configurators. Design system foundations and layout patterns for building consistent interfaces.
</p> </p>
</div> </div>
</div> </div>
@@ -51,7 +47,6 @@ export const StyleGuideView = () => {
<div> <div>
{activeTab === "style-guide" && <StyleGuideTab />} {activeTab === "style-guide" && <StyleGuideTab />}
{activeTab === "layouts" && <LayoutsTab />} {activeTab === "layouts" && <LayoutsTab />}
{activeTab === "configurators" && <ConfiguratorsTab />}
</div> </div>
</div> </div>
); );

View File

@@ -1,214 +0,0 @@
import { useState } from 'react';
import { Button } from '@/features/ui/primitives/button';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/features/ui/primitives/select';
import { Switch } from '@/features/ui/primitives/switch';
import { Input } from '@/features/ui/primitives/input';
import { LivePreview } from '../shared/LivePreview';
import { CodeDisplay } from '../shared/CodeDisplay';
import { ConfigPanel } from '../shared/ConfigPanel';
import { ConfigRow } from '../shared/ConfigRow';
import { Loader2, Download, Eye, Code } from 'lucide-react';
import type { ButtonVariant, ButtonSize } from '../types';
interface ButtonConfig {
variant: ButtonVariant;
size: ButtonSize;
loading: boolean;
disabled: boolean;
withIcon: boolean;
text: string;
}
export const ButtonConfigurator = () => {
const [config, setConfig] = useState<ButtonConfig>({
variant: 'default',
size: 'default',
loading: false,
disabled: false,
withIcon: false,
text: 'Click me'
});
const [activeTab, setActiveTab] = useState<'preview' | 'code'>('preview');
const generateCode = (config: ButtonConfig) => {
const imports = [`import { Button } from '@/features/ui/primitives/button';`];
if (config.loading) {
imports.push(`import { Loader2 } from 'lucide-react';`);
}
if (config.withIcon) {
imports.push(`import { Download } from 'lucide-react';`);
}
const aiContext = `/**
* 🤖 AI CONTEXT: Button Component
*
* VARIANT DECISION TREE:
* - default: Primary actions, main CTAs, submit buttons
* - destructive: Delete, remove, cancel dangerous operations
* - outline: Secondary actions, alternative options
* - ghost: Tertiary actions, minimal emphasis
* - link: Navigation, text-only actions
* - cyan: Special emphasis, Tron-themed primary
* - knowledge: Knowledge base specific actions
*
* SIZE GUIDELINES:
* - xs: Inline actions, table cells
* - sm: Dense UI, secondary actions
* - default: Most use cases
* - lg: Primary CTAs, hero sections
* - icon: Icon-only buttons
*/`;
const props: string[] = [];
if (config.variant !== 'default') props.push(`variant="${config.variant}"`);
if (config.size !== 'default') props.push(`size="${config.size}"`);
if (config.loading) props.push(`loading={true}`);
if (config.disabled) props.push(`disabled={true}`);
const content = config.loading
? `<>\n <Loader2 className="mr-2 h-4 w-4 animate-spin" />\n ${config.text}\n </>`
: config.withIcon
? `<>\n <Download className="mr-2 h-4 w-4" />\n ${config.text}\n </>`
: config.text;
const component = `export const MyButton = () => {
return (
<Button${props.length > 0 ? '\n ' + props.join('\n ') : ''}>
${content}
</Button>
);
};`;
return `${imports.join('\n')}\n\n${aiContext}\n\n${component}`;
};
return (
<div className="grid grid-cols-4 gap-6 h-full">
{/* LEFT: Configuration Panel (1/4 width) */}
<div className="col-span-1">
<ConfigPanel title="Button Configuration">
<div className="space-y-3">
<ConfigRow label="Variant">
<Select
value={config.variant}
onValueChange={(value) => setConfig({...config, variant: value as ButtonVariant})}
>
<SelectTrigger className="w-24 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="default">Default</SelectItem>
<SelectItem value="destructive">Destructive</SelectItem>
<SelectItem value="outline">Outline</SelectItem>
<SelectItem value="ghost">Ghost</SelectItem>
<SelectItem value="link">Link</SelectItem>
<SelectItem value="cyan">Cyan</SelectItem>
<SelectItem value="knowledge">Knowledge</SelectItem>
</SelectContent>
</Select>
</ConfigRow>
<ConfigRow label="Size">
<Select
value={config.size}
onValueChange={(value) => setConfig({...config, size: value as ButtonSize})}
>
<SelectTrigger className="w-24 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="xs">XS</SelectItem>
<SelectItem value="sm">SM</SelectItem>
<SelectItem value="default">Default</SelectItem>
<SelectItem value="lg">LG</SelectItem>
<SelectItem value="icon">Icon</SelectItem>
</SelectContent>
</Select>
</ConfigRow>
<ConfigRow label="Loading">
<Switch
checked={config.loading}
onCheckedChange={(loading) => setConfig({...config, loading})}
/>
</ConfigRow>
<ConfigRow label="Disabled">
<Switch
checked={config.disabled}
onCheckedChange={(disabled) => setConfig({...config, disabled})}
/>
</ConfigRow>
<ConfigRow label="With Icon">
<Switch
checked={config.withIcon}
onCheckedChange={(withIcon) => setConfig({...config, withIcon})}
/>
</ConfigRow>
{config.size !== 'icon' && (
<ConfigRow label="Text">
<Input
value={config.text}
onChange={(e) => setConfig({...config, text: e.target.value})}
placeholder="Button text..."
className="w-24 text-xs"
/>
</ConfigRow>
)}
</div>
{/* Preview/Code Tabs INSIDE configurator */}
<div className="mt-6 pt-4 border-t border-gray-200 dark:border-gray-700">
<div className="flex gap-2">
<Button
size="sm"
variant={activeTab === 'preview' ? 'default' : 'outline'}
onClick={() => setActiveTab('preview')}
className="flex items-center gap-2"
>
<Eye className="w-4 h-4" />
Preview
</Button>
<Button
size="sm"
variant={activeTab === 'code' ? 'default' : 'outline'}
onClick={() => setActiveTab('code')}
className="flex items-center gap-2"
>
<Code className="w-4 h-4" />
Code
</Button>
</div>
</div>
</ConfigPanel>
</div>
{/* RIGHT: Preview or Code Content (3/4 width) */}
<div className="col-span-3">
{activeTab === 'preview' ? (
<LivePreview>
<Button
variant={config.variant}
size={config.size}
loading={config.loading}
disabled={config.disabled}
>
{config.loading && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
{!config.loading && config.withIcon && <Download className="mr-2 h-4 w-4" />}
{config.size !== 'icon' && config.text}
{config.size === 'icon' && !config.loading && <Download className="h-4 w-4" />}
</Button>
</LivePreview>
) : (
<CodeDisplay
code={generateCode(config)}
showLineNumbers
/>
)}
</div>
</div>
);
};

View File

@@ -1,315 +0,0 @@
import React, { useState } from "react";
import { Checkbox, type CheckboxColor } from "../../../features/ui/primitives/checkbox";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue
} from "../../../features/ui/primitives/select";
import { ConfiguratorCard } from "../shared/ConfiguratorCard";
import { Label } from "../../../features/ui/primitives/label";
const colorOptions = [
{ value: "purple", label: "Purple" },
{ value: "blue", label: "Blue" },
{ value: "green", label: "Green" },
{ value: "pink", label: "Pink" },
{ value: "orange", label: "Orange" },
{ value: "cyan", label: "Cyan" },
];
const stateOptions = [
{ value: "unchecked", label: "Unchecked" },
{ value: "checked", label: "Checked" },
{ value: "indeterminate", label: "Indeterminate" },
];
/**
* 🤖 AI CONTEXT: Checkbox Configurator
*
* CONFIGURATION OPTIONS:
* 1. COLOR - Six accent colors with neon glow
* - Each color has associated glow effects
* - Glow intensity increases on check
*
* 2. STATE - Three checkbox states
* - Unchecked: Empty glass box
* - Checked: Check icon with glow
* - Indeterminate: Minus icon (partial selection)
*
* 3. LABEL - Optional label positioning
* - Can be placed left or right
* - Click target includes label
*
* 4. DISABLED - Interactive state control
*/
export function CheckboxConfigurator() {
const [color, setColor] = useState<CheckboxColor>("cyan");
const [state, setState] = useState<"unchecked" | "checked" | "indeterminate">("checked");
const [disabled, setDisabled] = useState(false);
const [showLabel, setShowLabel] = useState(true);
const getCheckedState = () => {
if (state === "indeterminate") return "indeterminate";
return state === "checked";
};
const generateCode = () => {
const props: string[] = [];
if (color !== "cyan") props.push(`color="${color}"`);
if (state === "indeterminate") {
props.push(`indeterminate`);
props.push(`checked="indeterminate"`);
} else if (state === "checked") {
props.push(`checked={true}`);
} else {
props.push(`checked={false}`);
}
if (disabled) props.push(`disabled`);
props.push(`onCheckedChange={(checked) => console.log(checked)}`);
const checkboxCode = `<Checkbox
${props.join("\n ")}
/>`;
if (showLabel) {
return `import { Checkbox } from "@/features/ui/primitives/checkbox";
import { Label } from "@/features/ui/primitives/label";
/**
* 🤖 AI CONTEXT: Checkbox with Label
*
* STATE: ${state}
* COLOR: ${color} - Neon glow effect
*
* GLASS PROPERTIES:
* - Transparency: bg-white/10 backdrop-blur
* - Glow: ${color} shadow on checked state
* - Animation: Zoom in/out on check
* ${state === "indeterminate" ? "* Indeterminate: Partial selection state" : ""}
*/
<div className="flex items-center space-x-2">
<Checkbox
id="terms"
${props.join("\n ")}
/>
<Label
htmlFor="terms"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Accept terms and conditions
</Label>
</div>`;
}
return `import { Checkbox } from "@/features/ui/primitives/checkbox";
/**
* 🤖 AI CONTEXT: Standalone Checkbox
*
* STATE: ${state}
* COLOR: ${color} - Neon glow effect
*
* GLASS PROPERTIES:
* - Transparency: bg-white/10 backdrop-blur
* - Glow: ${color} shadow on checked state
* - Animation: Zoom in/out on check
* ${state === "indeterminate" ? "* Indeterminate: Partial selection state" : ""}
*/
${checkboxCode}`;
};
return (
<ConfiguratorCard
title="Checkbox"
description="Checkboxes with neon glow effects and indeterminate state support"
code={generateCode()}
>
<div className="space-y-6">
{/* Preview */}
<div className="flex items-center justify-center p-8 rounded-lg bg-black/5 dark:bg-white/5">
{showLabel ? (
<div className="flex items-center space-x-2">
<Checkbox
id="preview"
color={color}
checked={getCheckedState()}
indeterminate={state === "indeterminate"}
disabled={disabled}
onCheckedChange={() => {
// Cycle through states
if (state === "unchecked") setState("checked");
else if (state === "checked") setState("indeterminate");
else setState("unchecked");
}}
/>
<Label
htmlFor="preview"
className="text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70 cursor-pointer"
>
Accept terms and conditions
</Label>
</div>
) : (
<Checkbox
color={color}
checked={getCheckedState()}
indeterminate={state === "indeterminate"}
disabled={disabled}
onCheckedChange={() => {
// Cycle through states
if (state === "unchecked") setState("checked");
else if (state === "checked") setState("indeterminate");
else setState("unchecked");
}}
/>
)}
</div>
{/* Configuration */}
<div className="grid grid-cols-2 gap-4">
{/* Color */}
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
Color
</label>
<Select value={color} onValueChange={(v) => setColor(v as CheckboxColor)}>
<SelectTrigger color={color}>
<SelectValue />
</SelectTrigger>
<SelectContent color={color}>
{colorOptions.map(option => (
<SelectItem key={option.value} value={option.value} color={color}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* State */}
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
State
</label>
<Select value={state} onValueChange={(v) => setState(v as any)}>
<SelectTrigger color={color}>
<SelectValue />
</SelectTrigger>
<SelectContent color={color}>
{stateOptions.map(option => (
<SelectItem key={option.value} value={option.value} color={color}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* Label */}
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
Label
</label>
<div className="flex gap-4">
<label className="flex items-center gap-2 cursor-pointer">
<Checkbox
color={color}
checked={showLabel}
onCheckedChange={setShowLabel}
/>
<span className="text-sm text-gray-600 dark:text-gray-400">Show Label</span>
</label>
</div>
</div>
{/* Disabled */}
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
State
</label>
<div className="flex gap-4">
<label className="flex items-center gap-2 cursor-pointer">
<Checkbox
color={color}
checked={disabled}
onCheckedChange={setDisabled}
/>
<span className="text-sm text-gray-600 dark:text-gray-400">Disabled</span>
</label>
</div>
</div>
</div>
{/* Examples */}
<div className="space-y-4">
<h4 className="text-sm font-medium text-gray-700 dark:text-gray-300">Examples</h4>
{/* Color Grid */}
<div className="space-y-2">
<p className="text-xs text-gray-500 dark:text-gray-400">All Colors</p>
<div className="flex gap-3">
{colorOptions.map(opt => (
<Checkbox
key={opt.value}
color={opt.value as CheckboxColor}
defaultChecked
/>
))}
</div>
</div>
{/* States */}
<div className="space-y-2">
<p className="text-xs text-gray-500 dark:text-gray-400">States</p>
<div className="flex gap-6">
<div className="flex items-center gap-2">
<Checkbox color={color} checked={false} />
<span className="text-xs text-gray-500">Unchecked</span>
</div>
<div className="flex items-center gap-2">
<Checkbox color={color} checked={true} />
<span className="text-xs text-gray-500">Checked</span>
</div>
<div className="flex items-center gap-2">
<Checkbox color={color} indeterminate />
<span className="text-xs text-gray-500">Indeterminate</span>
</div>
<div className="flex items-center gap-2">
<Checkbox color={color} checked={true} disabled />
<span className="text-xs text-gray-500">Disabled</span>
</div>
</div>
</div>
{/* List Example */}
<div className="space-y-2">
<p className="text-xs text-gray-500 dark:text-gray-400">List Example</p>
<div className="space-y-2 p-4 rounded-lg bg-black/5 dark:bg-white/5">
<div className="flex items-center space-x-2">
<Checkbox id="option1" color={color} defaultChecked />
<Label htmlFor="option1" className="text-sm cursor-pointer">Enable notifications</Label>
</div>
<div className="flex items-center space-x-2">
<Checkbox id="option2" color={color} />
<Label htmlFor="option2" className="text-sm cursor-pointer">Show preview pane</Label>
</div>
<div className="flex items-center space-x-2">
<Checkbox id="option3" color={color} defaultChecked />
<Label htmlFor="option3" className="text-sm cursor-pointer">Auto-save drafts</Label>
</div>
<div className="flex items-center space-x-2">
<Checkbox id="option4" color={color} indeterminate />
<Label htmlFor="option4" className="text-sm cursor-pointer">Sync across devices (partial)</Label>
</div>
</div>
</div>
</div>
</div>
</ConfiguratorCard>
);
}

View File

@@ -1,219 +0,0 @@
import { useState } from 'react';
import { Input } from '@/features/ui/primitives/input';
import { Button } from '@/features/ui/primitives/button';
import { Label } from '@/features/ui/primitives/label';
import { Switch } from '@/features/ui/primitives/switch';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/features/ui/primitives/select';
import { LivePreview } from '../shared/LivePreview';
import { CodeDisplay } from '../shared/CodeDisplay';
import { ConfigPanel } from '../shared/ConfigPanel';
import { Eye, Code } from 'lucide-react';
import type { InputType } from '../types';
interface FormConfig {
error: boolean;
disabled: boolean;
placeholder: string;
inputType: InputType;
}
export const FormConfigurator = () => {
const [config, setConfig] = useState<FormConfig>({
error: false,
disabled: false,
placeholder: 'Enter your text...',
inputType: 'text'
});
const [activeTab, setActiveTab] = useState<'preview' | 'code'>('preview');
const generateCode = (config: FormConfig) => {
const imports = `import { Input } from '@/features/ui/primitives/input';
import { Label } from '@/features/ui/primitives/label';
import { Button } from '@/features/ui/primitives/button';`;
const aiContext = `/**
* 🤖 AI CONTEXT: Form Input Component
*
* PURPOSE: Text input with glass morphism styling and validation states
* WHEN TO USE: Forms, search bars, data entry fields
* WHEN NOT TO USE: Large text content (use textarea), complex selections (use select)
*
* INPUT TYPE GUIDELINES:
* - text: General text input, names, titles
* - email: Email addresses (includes validation)
* - password: Passwords (masks input)
* - number: Numeric values (shows number pad on mobile)
*
* ERROR STATE:
* - Use when validation fails
* - Shows red border and focus ring
* - Pair with error message below input
*
* DISABLED STATE:
* - Use when input is temporarily unavailable
* - Shows reduced opacity and prevents interaction
* - Consider using readonly for permanent restrictions
*/`;
const props: string[] = [];
if (config.inputType !== 'text') props.push(`type="${config.inputType}"`);
if (config.error) props.push(`error={true}`);
if (config.disabled) props.push(`disabled={true}`);
if (config.placeholder) props.push(`placeholder="${config.placeholder}"`);
const component = `export const MyForm = () => {
const [value, setValue] = useState('');
return (
<div className="space-y-4">
<div>
<Label htmlFor="example-input">
${config.inputType === 'email' ? 'Email Address' :
config.inputType === 'password' ? 'Password' :
config.inputType === 'number' ? 'Number' :
'Text Input'}
</Label>
<Input
id="example-input"
value={value}
onChange={(e) => setValue(e.target.value)}${props.length > 0 ? '\n ' + props.join('\n ') : ''}
/>
${config.error ? `<p className="text-sm text-red-600 dark:text-red-400 mt-1">
This field is required
</p>` : ''}
</div>
<Button type="submit">
Submit
</Button>
</div>
);
};`;
return `${imports}\n\n${aiContext}\n\n${component}`;
};
return (
<div className="grid grid-cols-4 gap-6 h-full">
{/* LEFT: Configuration Panel (1/4 width) */}
<div className="col-span-1">
<ConfigPanel title="Form Input Configuration">
<div className="space-y-4">
{/* Input Type */}
<div>
<Label>Input Type</Label>
<Select
value={config.inputType}
onValueChange={(value) => setConfig({...config, inputType: value as InputType})}
>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="text">Text</SelectItem>
<SelectItem value="email">Email</SelectItem>
<SelectItem value="password">Password</SelectItem>
<SelectItem value="number">Number</SelectItem>
</SelectContent>
</Select>
</div>
{/* States */}
<div className="space-y-3">
<div className="flex items-center justify-between">
<Label htmlFor="error-state" className="text-sm">Error State</Label>
<Switch
id="error-state"
checked={config.error}
onCheckedChange={(error) => setConfig({...config, error})}
/>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="disabled-state" className="text-sm">Disabled</Label>
<Switch
id="disabled-state"
checked={config.disabled}
onCheckedChange={(disabled) => setConfig({...config, disabled})}
/>
</div>
</div>
{/* Placeholder */}
<div>
<Label htmlFor="placeholder-text" className="text-sm">Placeholder Text</Label>
<Input
id="placeholder-text"
value={config.placeholder}
onChange={(e) => setConfig({...config, placeholder: e.target.value})}
/>
</div>
</div>
{/* Preview/Code Tabs INSIDE configurator */}
<div className="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700">
<div className="flex gap-2">
<Button
size="sm"
variant={activeTab === 'preview' ? 'default' : 'outline'}
onClick={() => setActiveTab('preview')}
className="flex items-center gap-2"
>
<Eye className="w-4 h-4" />
Preview
</Button>
<Button
size="sm"
variant={activeTab === 'code' ? 'default' : 'outline'}
onClick={() => setActiveTab('code')}
className="flex items-center gap-2"
>
<Code className="w-4 h-4" />
Code
</Button>
</div>
</div>
</ConfigPanel>
</div>
{/* RIGHT: Preview or Code Content (3/4 width) */}
<div className="col-span-3">
{activeTab === 'preview' ? (
<LivePreview>
<div className="space-y-4 w-full max-w-sm">
<div>
<Label htmlFor="preview-input">
{config.inputType === 'email' ? 'Email Address' :
config.inputType === 'password' ? 'Password' :
config.inputType === 'number' ? 'Number' :
'Text Input'}
</Label>
<Input
id="preview-input"
type={config.inputType}
placeholder={config.placeholder}
error={config.error}
disabled={config.disabled}
/>
{config.error && (
<p className="text-sm text-red-600 dark:text-red-400 mt-1">
This field is required
</p>
)}
</div>
<Button type="submit" disabled={config.disabled}>
Submit
</Button>
</div>
</LivePreview>
) : (
<CodeDisplay
code={generateCode(config)}
showLineNumbers
/>
)}
</div>
</div>
);
};

View File

@@ -1,453 +0,0 @@
import { useState } from 'react';
import { Card } from '@/features/ui/primitives/card';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/features/ui/primitives/select';
import { Input } from '@/features/ui/primitives/input';
import { CodeDisplay } from '../shared/CodeDisplay';
import { cn } from '@/features/ui/primitives/styles';
import type { GlowColor, GlowType, EdgePosition, EdgeColor, CardSize, Transparency, BlurLevel, GlassTint } from '../types';
interface GlassCardConfig {
blur: BlurLevel;
transparency: Transparency;
glassTint: GlassTint;
glowColor: GlowColor;
glowType: GlowType;
edgePosition: EdgePosition;
edgeColor: EdgeColor;
size: CardSize;
content: string;
}
// Glass card showcase examples
const GLASS_CARD_EXAMPLES = [
{
name: 'Clear Glass',
transparency: 'light' as const,
glassTint: 'none' as const,
glowColor: 'none' as const,
edgePosition: 'none' as const,
description: 'Pure transparent glass',
usage: 'Default containers, neutral elements'
},
{
name: 'Purple Glass',
transparency: 'medium' as const,
glassTint: 'purple' as const,
glowColor: 'none' as const,
edgePosition: 'none' as const,
description: 'Purple-tinted transparent glass',
usage: 'Primary content areas'
},
{
name: 'Cyan Inner Glow',
transparency: 'light' as const,
glassTint: 'none' as const,
glowColor: 'cyan' as const,
edgePosition: 'none' as const,
description: 'Glass with cyan inner glow',
usage: 'Active/selected states'
},
{
name: 'Purple Outer Glow',
transparency: 'light' as const,
glassTint: 'none' as const,
glowColor: 'purple' as const,
edgePosition: 'none' as const,
description: 'Glass with purple outer glow',
usage: 'Featured content, CTAs'
},
{
name: 'Purple Edge',
transparency: 'light' as const,
glassTint: 'none' as const,
glowColor: 'none' as const,
edgePosition: 'top' as const,
description: 'Glass with purple top edge',
usage: 'Knowledge cards, headers'
},
{
name: 'Blue Left Edge',
transparency: 'light' as const,
glassTint: 'blue' as const,
glowColor: 'none' as const,
edgePosition: 'left' as const,
description: 'Light blue glass with blue left edge',
usage: 'Task cards, side content'
}
];
export const GlassCardConfigurator = () => {
const [activeView, setActiveView] = useState<'showcase' | 'configurator'>('showcase');
const [config, setConfig] = useState<GlassCardConfig>({
blur: 'xl',
transparency: 'light',
glassTint: 'none',
glowColor: 'none',
glowType: 'none',
edgePosition: 'none',
edgeColor: 'cyan',
size: 'lg',
content: 'Your glass card content here'
});
const generateCode = (config: GlassCardConfig) => {
const props: string[] = [];
if (config.blur !== 'xl') props.push(`blur="${config.blur}"`);
if (config.transparency !== 'medium') props.push(`transparency="${config.transparency}"`);
if (config.glassTint !== 'none') props.push(`glassTint="${config.glassTint}"`);
if (config.glowColor !== 'none' && config.glowType === 'inner') props.push(`glowColor="${config.glowColor}"`);
if (config.edgePosition !== 'none') props.push(`edgePosition="${config.edgePosition}"`);
if (config.edgePosition !== 'none' && config.edgeColor !== 'cyan') props.push(`edgeColor="${config.edgeColor}"`);
if (config.size !== 'md') props.push(`size="${config.size}"`);
let additionalClasses = '';
if (config.glowType === 'outer' && config.glowColor !== 'none') {
additionalClasses = `\n className="shadow-[0_0_30px_${config.glowColor}-500/80,_0_0_60px_${config.glowColor}-500/40]"`;
} else if (config.glowType === 'inner' && config.glowColor !== 'none') {
additionalClasses = `\n className="bg-${config.glowColor}-500/40 border border-${config.glowColor}-500 shadow-[inset_0_0_20px_${config.glowColor}-500/60]"`;
}
return `import { Card } from '@/features/ui/primitives/card';
export const MyCard = () => {
return (
<Card${props.length > 0 ? '\n ' + props.join('\n ') : ''}${additionalClasses}>
${config.content}
</Card>
);
};`;
};
return (
<div className="space-y-8">
{/* Small Pill Navigation */}
<div className="flex justify-center">
<div className="backdrop-blur-sm bg-white/40 dark:bg-white/5 border border-white/30 dark:border-white/15 rounded-full p-1 shadow-lg">
<div className="flex gap-1 items-center">
<button
onClick={() => setActiveView('showcase')}
className={cn(
"flex items-center gap-2 px-4 py-2 rounded-full transition-all duration-200",
"text-sm font-medium whitespace-nowrap",
activeView === 'showcase'
? "bg-cyan-500/20 dark:bg-cyan-400/20 text-cyan-700 dark:text-cyan-300 border border-cyan-400/50 shadow-[0_0_10px_rgba(34,211,238,0.5)]"
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5"
)}
>
Showcase
</button>
<button
onClick={() => setActiveView('configurator')}
className={cn(
"flex items-center gap-2 px-4 py-2 rounded-full transition-all duration-200",
"text-sm font-medium whitespace-nowrap",
activeView === 'configurator'
? "bg-cyan-500/20 dark:bg-cyan-400/20 text-cyan-700 dark:text-cyan-300 border border-cyan-400/50 shadow-[0_0_10px_rgba(34,211,238,0.5)]"
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5"
)}
>
Configurator
</button>
</div>
</div>
</div>
{/* Content based on active view */}
{activeView === 'showcase' ? (
<Card className="p-6">
<div className="space-y-6">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">Glass Card Showcase</h3>
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
{GLASS_CARD_EXAMPLES.map((example) => (
<div key={example.name}>
{/* Apply proper effects based on example type */}
{example.name === 'Cyan Inner Glow' ? (
<Card
transparency={example.transparency}
glassTint={example.glassTint}
edgePosition="none"
className={cn(
"hover:scale-105 transition-transform duration-300",
"bg-cyan-500/40 border border-cyan-500 shadow-[inset_0_0_20px_rgba(34,211,238,0.6)]"
)}
>
<h4 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">{example.name}</h4>
<p className="text-gray-700 dark:text-gray-300 text-sm mb-2">{example.description}</p>
<p className="text-gray-600 dark:text-gray-400 text-xs">{example.usage}</p>
</Card>
) : example.name === 'Purple Outer Glow' ? (
<div className="shadow-[0_0_30px_rgba(147,51,234,0.8),_0_0_60px_rgba(147,51,234,0.4)] transition-all duration-200 hover:scale-105 rounded-lg">
<Card
transparency={example.transparency}
glassTint={example.glassTint}
edgePosition="none"
className="transition-transform duration-300"
>
<h4 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">{example.name}</h4>
<p className="text-gray-700 dark:text-gray-300 text-sm mb-2">{example.description}</p>
<p className="text-gray-600 dark:text-gray-400 text-xs">{example.usage}</p>
</Card>
</div>
) : example.name === 'Purple Edge' ? (
<Card
transparency={example.transparency}
glassTint={example.glassTint}
edgePosition={example.edgePosition}
edgeColor="purple"
className="hover:scale-105 transition-transform duration-300"
>
<h4 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">{example.name}</h4>
<p className="text-gray-700 dark:text-gray-300 text-sm mb-2">{example.description}</p>
<p className="text-gray-600 dark:text-gray-400 text-xs">{example.usage}</p>
</Card>
) : example.name === 'Blue Left Edge' ? (
<Card
transparency={example.transparency}
glassTint={example.glassTint}
edgePosition={example.edgePosition}
edgeColor="blue"
className="hover:scale-105 transition-transform duration-300"
>
<h4 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">{example.name}</h4>
<p className="text-gray-700 dark:text-gray-300 text-sm mb-2">{example.description}</p>
<p className="text-gray-600 dark:text-gray-400 text-xs">{example.usage}</p>
</Card>
) : (
<Card
transparency={example.transparency}
glassTint={example.glassTint}
glowColor={example.glowColor}
edgePosition={example.edgePosition}
edgeColor="cyan"
className="hover:scale-105 transition-transform duration-300"
>
<h4 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">{example.name}</h4>
<p className="text-gray-700 dark:text-gray-300 text-sm mb-2">{example.description}</p>
<p className="text-gray-600 dark:text-gray-400 text-xs">{example.usage}</p>
</Card>
)}
</div>
))}
</div>
</div>
</Card>
) : (
<div className="space-y-8">
{/* Configurator with side-by-side layout */}
<Card className="p-6">
<h3 className="text-lg font-semibold text-gray-900 dark:text-white mb-6">Card Configurator</h3>
<div className="grid grid-cols-2 gap-8">
{/* Left: Configuration Controls */}
<div className="space-y-4">
<div className="grid grid-cols-2 gap-3">
<div>
<label className="block text-sm font-medium mb-1">Blur</label>
<Select
value={config.blur}
onValueChange={(value) => setConfig({...config, blur: value as BlurLevel})}
>
<SelectTrigger className="text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="none">None</SelectItem>
<SelectItem value="sm">Minimal</SelectItem>
<SelectItem value="md">Subtle</SelectItem>
<SelectItem value="lg">Light</SelectItem>
<SelectItem value="xl">Standard</SelectItem>
<SelectItem value="2xl">Noticeable</SelectItem>
<SelectItem value="3xl">Maximum</SelectItem>
</SelectContent>
</Select>
</div>
<div>
<label className="block text-sm font-medium mb-1">Transparency</label>
<Select
value={config.transparency}
onValueChange={(value) => setConfig({...config, transparency: value as Transparency})}
>
<SelectTrigger className="text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="clear">Clear</SelectItem>
<SelectItem value="light">Light</SelectItem>
<SelectItem value="medium">Medium</SelectItem>
<SelectItem value="frosted">Frosted</SelectItem>
<SelectItem value="solid">Solid</SelectItem>
</SelectContent>
</Select>
</div>
<div>
<label className="block text-sm font-medium mb-1">Glass Tint</label>
<Select
value={config.glassTint}
onValueChange={(value) => setConfig({...config, glassTint: value as GlassTint})}
>
<SelectTrigger className="text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="none">None</SelectItem>
<SelectItem value="purple">🟣 Purple</SelectItem>
<SelectItem value="blue">🔵 Blue</SelectItem>
<SelectItem value="cyan">🔷 Cyan</SelectItem>
<SelectItem value="green">🟢 Green</SelectItem>
<SelectItem value="orange">🟠 Orange</SelectItem>
<SelectItem value="pink">🩷 Pink</SelectItem>
<SelectItem value="red">🔴 Red</SelectItem>
</SelectContent>
</Select>
</div>
<div>
<label className="block text-sm font-medium mb-1">Glow Type</label>
<Select
value={config.glowType}
onValueChange={(value) => setConfig({...config, glowType: value as GlowType, glowColor: value === 'none' ? 'none' : config.glowColor || 'cyan'})}
disabled={config.edgePosition !== 'none'}
>
<SelectTrigger className="text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="none">None</SelectItem>
<SelectItem value="inner">Inner</SelectItem>
<SelectItem value="outer">Outer</SelectItem>
</SelectContent>
</Select>
</div>
<div>
<label className="block text-sm font-medium mb-1">Glow Color</label>
<Select
value={config.glowColor}
onValueChange={(value) => setConfig({...config, glowColor: value as GlowColor})}
disabled={config.glowType === 'none'}
>
<SelectTrigger className="text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="purple">🟣 Purple</SelectItem>
<SelectItem value="blue">🔵 Blue</SelectItem>
<SelectItem value="cyan">🔷 Cyan</SelectItem>
<SelectItem value="green">🟢 Green</SelectItem>
<SelectItem value="orange">🟠 Orange</SelectItem>
<SelectItem value="pink">🩷 Pink</SelectItem>
<SelectItem value="red">🔴 Red</SelectItem>
</SelectContent>
</Select>
</div>
<div>
<label className="block text-sm font-medium mb-1">Edge Position</label>
<Select
value={config.edgePosition}
onValueChange={(value) => {
setConfig({
...config,
edgePosition: value as EdgePosition,
glowType: value !== 'none' ? 'none' : config.glowType
});
}}
>
<SelectTrigger className="text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="none">None</SelectItem>
<SelectItem value="top"> Top</SelectItem>
<SelectItem value="left"> Left</SelectItem>
<SelectItem value="right"> Right</SelectItem>
<SelectItem value="bottom"> Bottom</SelectItem>
</SelectContent>
</Select>
</div>
<div>
<label className="block text-sm font-medium mb-1">Edge Color</label>
<Select
value={config.edgeColor}
onValueChange={(value) => setConfig({...config, edgeColor: value as EdgeColor})}
disabled={config.edgePosition === 'none'}
>
<SelectTrigger className="text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="purple">🟣 Purple</SelectItem>
<SelectItem value="blue">🔵 Blue</SelectItem>
<SelectItem value="cyan">🔷 Cyan</SelectItem>
<SelectItem value="green">🟢 Green</SelectItem>
<SelectItem value="orange">🟠 Orange</SelectItem>
<SelectItem value="pink">🩷 Pink</SelectItem>
<SelectItem value="red">🔴 Red</SelectItem>
</SelectContent>
</Select>
</div>
<div className="col-span-2">
<label className="block text-sm font-medium mb-1">Content</label>
<Input
value={config.content}
onChange={(e) => setConfig({...config, content: e.target.value})}
placeholder="Card content..."
className="text-xs"
/>
</div>
</div>
</div>
{/* Right: Live Preview on grid background */}
<div className="flex items-center justify-center">
<div
className={cn(
"transition-all duration-200",
// Apply outer glow effect if selected
config.glowType === 'outer' && config.glowColor !== 'none' &&
`shadow-[0_0_30px_${config.glowColor}-500/80,_0_0_60px_${config.glowColor}-500/40]`
)}
>
<Card
blur={config.blur}
transparency={config.transparency}
glassTint={config.glassTint}
glowColor={config.glowType === 'inner' ? config.glowColor : 'none'}
edgePosition={config.edgePosition}
edgeColor={config.edgeColor}
size={config.size}
className={cn(
// Apply inner glow effect with enhanced visibility
config.glowType === 'inner' && config.glowColor !== 'none' && [
`bg-${config.glowColor}-500/40 border border-${config.glowColor}-500`,
`shadow-[inset_0_0_20px_${config.glowColor}-500/60]`
]
)}
>
<h4 className="text-lg font-semibold text-gray-900 dark:text-white mb-2">Glass Card</h4>
<p className="text-gray-700 dark:text-gray-300 text-sm">
{config.content}
</p>
</Card>
</div>
</div>
</div>
</Card>
{/* Generated Code - Full Width Bottom */}
<Card className="p-6">
<h3 className="text-lg font-semibold mb-4">Generated Code</h3>
<CodeDisplay
code={generateCode(config)}
showLineNumbers
/>
</Card>
</div>
)}
</div>
);
};

View File

@@ -1,235 +0,0 @@
import { useState } from 'react';
import { Button } from '@/features/ui/primitives/button';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/features/ui/primitives/select';
import { CodeDisplay } from '../shared/CodeDisplay';
import { ConfigPanel } from '../shared/ConfigPanel';
import { ConfigRow } from '../shared/ConfigRow';
import { MODAL_TYPES } from '../standards/modalStandards';
import { Eye, Code, X } from 'lucide-react';
import type { ModalSize, GlowColor } from '../types';
export const ModalConfigurator = () => {
const [selectedType, setSelectedType] = useState<keyof typeof MODAL_TYPES>('confirmation');
const [activeTab, setActiveTab] = useState<'preview' | 'code'>('preview');
const [customSize, setCustomSize] = useState<ModalSize>('sm');
const [customGlowColor, setCustomGlowColor] = useState<Exclude<GlowColor, 'none' | 'pink'>>('red');
const generateCode = (type: keyof typeof MODAL_TYPES) => {
const imports = `import { AlertDialog, AlertDialogContent, AlertDialogHeader, AlertDialogTitle, AlertDialogDescription, AlertDialogFooter, AlertDialogAction, AlertDialogCancel, AlertDialogTrigger } from '@/features/ui/primitives/alert-dialog';
import { Button } from '@/features/ui/primitives/button';`;
const aiContext = `/**
* 🤖 AI CONTEXT: ${type.charAt(0).toUpperCase() + type.slice(1)} Modal
*
* PURPOSE: ${MODAL_TYPES[type].purpose}
* SIZE: ${customSize.toUpperCase()} - ${customSize === 'sm' ? 'Compact for simple confirmations' :
customSize === 'md' ? 'Standard for forms and content' :
customSize === 'lg' ? 'Large for detailed displays' :
'Extra large for code/data views'}
* GLOW: ${customGlowColor.toUpperCase()} - ${customGlowColor === 'red' ? 'Danger/destructive actions' :
customGlowColor === 'green' ? 'Success/creation actions' :
customGlowColor === 'blue' ? 'Information/editing' :
customGlowColor === 'purple' ? 'Primary/featured content' :
'Special emphasis/code display'}
*
* WHEN TO USE:
* ${type === 'confirmation' ? '- Delete operations\n * - Irreversible actions\n * - Warning confirmations' :
type === 'formCreate' ? '- Creating new resources\n * - Data entry forms\n * - Positive actions' :
type === 'formEdit' ? '- Editing existing data\n * - Update operations\n * - Modification forms' :
type === 'display' ? '- Showing detailed information\n * - Read-only content\n * - Feature showcases' :
type === 'codeViewer' ? '- Code snippets display\n * - JSON/data viewing\n * - Technical content' :
'- Application settings\n * - Configuration panels\n * - User preferences'}
*
* IMPLEMENTATION: Use AlertDialog for modal behavior, wrap trigger in AlertDialogTrigger
*/`;
const component = `export const ${type.charAt(0).toUpperCase() + type.slice(1)}Modal = ({ trigger, onConfirm }) => {
return (
<AlertDialog>
<AlertDialogTrigger asChild>
{trigger}
</AlertDialogTrigger>
<AlertDialogContent className="sm:max-w-${customSize === 'sm' ? 'sm' : customSize === 'md' ? 'md' : customSize === 'lg' ? 'lg' : 'xl'}">
<AlertDialogHeader>
<AlertDialogTitle>${type === 'confirmation' ? 'Confirm Action' :
type === 'formCreate' ? 'Create New Item' :
type === 'formEdit' ? 'Edit Item' :
type === 'display' ? 'Details' :
type === 'codeViewer' ? 'Code Viewer' :
'Settings'}</AlertDialogTitle>
<AlertDialogDescription>
${MODAL_TYPES[type].purpose}
</AlertDialogDescription>
</AlertDialogHeader>
{/* Modal content goes here */}
<AlertDialogFooter>
<AlertDialogCancel>Cancel</AlertDialogCancel>
<AlertDialogAction onClick={onConfirm}>
${type === 'confirmation' ? 'Confirm' :
type === 'formCreate' ? 'Create' :
type === 'formEdit' ? 'Save Changes' :
'Close'}
</AlertDialogAction>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
};`;
return `${imports}\n\n${aiContext}\n\n${component}`;
};
const currentConfig = MODAL_TYPES[selectedType];
return (
<div className="grid grid-cols-4 gap-6 h-full">
{/* LEFT: Configuration Panel (1/4 width) */}
<div className="col-span-1">
<ConfigPanel title="Modal Standards">
<div className="space-y-4">
<ConfigRow label="Modal Type">
<Select
value={selectedType}
onValueChange={(value) => setSelectedType(value as keyof typeof MODAL_TYPES)}
>
<SelectTrigger className="w-32">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="confirmation">Confirmation</SelectItem>
<SelectItem value="formCreate">Form Create</SelectItem>
<SelectItem value="formEdit">Form Edit</SelectItem>
<SelectItem value="display">Display</SelectItem>
<SelectItem value="codeViewer">Code Viewer</SelectItem>
<SelectItem value="settings">Settings</SelectItem>
</SelectContent>
</Select>
</ConfigRow>
<ConfigRow label="Size">
<Select
value={customSize}
onValueChange={(value) => setCustomSize(value as ModalSize)}
>
<SelectTrigger className="w-24 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="sm">SM</SelectItem>
<SelectItem value="md">MD</SelectItem>
<SelectItem value="lg">LG</SelectItem>
<SelectItem value="xl">XL</SelectItem>
</SelectContent>
</Select>
</ConfigRow>
<ConfigRow label="Glow Color">
<Select
value={customGlowColor}
onValueChange={(value) => setCustomGlowColor(value as Exclude<GlowColor, 'none' | 'pink'>)}
>
<SelectTrigger className="w-24 text-xs">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="purple">Purple</SelectItem>
<SelectItem value="blue">Blue</SelectItem>
<SelectItem value="green">Green</SelectItem>
<SelectItem value="red">Red</SelectItem>
<SelectItem value="orange">Orange</SelectItem>
<SelectItem value="cyan">Cyan</SelectItem>
</SelectContent>
</Select>
</ConfigRow>
<ConfigRow label="Purpose">
<div className="text-xs text-gray-600 dark:text-gray-400 w-32 text-right">
{currentConfig.purpose}
</div>
</ConfigRow>
</div>
{/* Preview/Code Tabs INSIDE configurator */}
<div className="mt-6 pt-4 border-t border-gray-200 dark:border-gray-700">
<div className="flex gap-2">
<Button
size="sm"
variant={activeTab === 'preview' ? 'default' : 'outline'}
onClick={() => setActiveTab('preview')}
className="flex items-center gap-2"
>
<Eye className="w-4 h-4" />
Preview
</Button>
<Button
size="sm"
variant={activeTab === 'code' ? 'default' : 'outline'}
onClick={() => setActiveTab('code')}
className="flex items-center gap-2"
>
<Code className="w-4 h-4" />
Code
</Button>
</div>
</div>
</ConfigPanel>
</div>
{/* RIGHT: Preview or Code Content (3/4 width) */}
<div className="col-span-3">
{activeTab === 'preview' ? (
<div className="flex items-center justify-center min-h-[400px]">
{/* Inline Modal Preview - No Button Trigger */}
<div className={`relative max-w-${customSize === 'sm' ? 'sm' : customSize === 'md' ? 'md' : customSize === 'lg' ? 'lg' : 'xl'} w-full mx-auto`}>
<div className="backdrop-blur-md bg-white/95 dark:bg-gray-900/95 border border-gray-200 dark:border-gray-700 rounded-lg shadow-2xl p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-lg font-semibold">
{selectedType === 'confirmation' ? 'Confirm Action' :
selectedType === 'formCreate' ? 'Create New Item' :
selectedType === 'formEdit' ? 'Edit Item' :
selectedType === 'display' ? 'Details' :
selectedType === 'codeViewer' ? 'Code Viewer' :
'Settings'}
</h3>
<Button size="icon" variant="ghost">
<X className="h-4 w-4" />
</Button>
</div>
<div className="mb-4">
<p className="text-sm text-gray-600 dark:text-gray-400">
{currentConfig.purpose} - This is an inline preview of the {selectedType} modal type.
</p>
</div>
<div className="py-4 mb-6">
<p className="text-sm text-gray-600 dark:text-gray-400">
Modal content would go here. This {customSize} sized modal uses {customGlowColor} color theming.
</p>
</div>
<div className="flex justify-end gap-3">
<Button variant="outline">Cancel</Button>
<Button variant={selectedType === 'confirmation' ? 'destructive' : 'default'}>
{selectedType === 'confirmation' ? 'Confirm' :
selectedType === 'formCreate' ? 'Create' :
selectedType === 'formEdit' ? 'Save Changes' :
'Close'}
</Button>
</div>
</div>
</div>
</div>
) : (
<CodeDisplay
code={generateCode(selectedType)}
showLineNumbers
/>
)}
</div>
</div>
);
};

View File

@@ -1,489 +0,0 @@
import React, { useState } from 'react';
import { Card } from '@/features/ui/primitives/card';
import { Checkbox } from '@/features/ui/primitives/checkbox';
import { CodeDisplay } from '../shared/CodeDisplay';
import { cn } from '@/features/ui/primitives/styles';
import {
Home,
FileText,
BarChart,
Settings,
ChevronRight,
Palette,
Component,
Layout,
Code
} from 'lucide-react';
// Pill Navigation Configurator
const PillNavigationConfigurator = () => {
const [activeSection, setActiveSection] = useState('foundations');
const [activeItem, setActiveItem] = useState('Colors');
const [openDropdown, setOpenDropdown] = useState<string | null>('foundations');
// Configuration options
const [colorVariant, setColorVariant] = useState('cyan');
const [size, setSize] = useState('default');
const [showIcons, setShowIcons] = useState(true);
const [showText, setShowText] = useState(true);
const [hasSubmenus, setHasSubmenus] = useState(true);
// Editable navigation items
const [navigationItems, setNavigationItems] = useState([
{
id: 'foundations',
label: 'Foundations',
icon: <Palette className="w-4 h-4" />,
items: ['Colors', 'Typography', 'Spacing', 'Effects']
},
{
id: 'components',
label: 'Components',
icon: <Component className="w-4 h-4" />,
items: ['Cards', 'Buttons', 'Forms', 'Tables']
},
{
id: 'patterns',
label: 'Patterns',
icon: <Layout className="w-4 h-4" />,
items: ['Layouts', 'Navigation', 'Data Display']
},
{
id: 'examples',
label: 'Examples',
icon: <Code className="w-4 h-4" />,
items: ['Compositions', 'Pages', 'Workflows']
}
]);
const handleSectionClick = (sectionId: string) => {
if (activeSection === sectionId && openDropdown === sectionId) {
setOpenDropdown(null);
} else {
setActiveSection(sectionId);
if (hasSubmenus) {
setOpenDropdown(sectionId);
// Set first item as default
const section = navigationItems.find(item => item.id === sectionId);
if (section?.items?.[0]) {
setActiveItem(section.items[0]);
}
}
}
};
const handleItemClick = (item: string) => {
setActiveItem(item);
};
const updateItemLabel = (itemIndex: number, newLabel: string) => {
setNavigationItems(prev =>
prev.map((item, index) =>
index === itemIndex ? { ...item, label: newLabel } : item
)
);
};
const getColorClasses = (variant: string, isSelected: boolean) => {
const colors = {
cyan: isSelected
? "bg-cyan-500/20 dark:bg-cyan-400/20 text-cyan-700 dark:text-cyan-300 border border-cyan-400/50 shadow-[0_0_10px_rgba(34,211,238,0.5)]"
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5",
purple: isSelected
? "bg-purple-500/20 dark:bg-purple-400/20 text-purple-700 dark:text-purple-300 border border-purple-400/50 shadow-[0_0_10px_rgba(147,51,234,0.5)]"
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5",
emerald: isSelected
? "bg-emerald-500/20 dark:bg-emerald-400/20 text-emerald-700 dark:text-emerald-300 border border-emerald-400/50 shadow-[0_0_10px_rgba(16,185,129,0.5)]"
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5",
orange: isSelected
? "bg-orange-500/20 dark:bg-orange-400/20 text-orange-700 dark:text-orange-300 border border-orange-400/50 shadow-[0_0_10px_rgba(251,146,60,0.5)]"
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5"
};
return colors[variant as keyof typeof colors] || colors.cyan;
};
const getSizeClasses = (sizeVariant: string) => {
const sizes = {
small: "px-4 py-2 text-xs",
default: "px-6 py-3 text-sm",
large: "px-8 py-4 text-base"
};
return sizes[sizeVariant as keyof typeof sizes] || sizes.default;
};
const selectedSectionData = navigationItems.find(item => item.id === activeSection);
const renderPillNavigation = () => (
<div className="backdrop-blur-sm bg-white/40 dark:bg-white/5 border border-white/30 dark:border-white/15 rounded-full p-1 shadow-lg transition-all duration-300 ease-in-out">
<div className="flex gap-1 items-center">
{navigationItems.map((item) => {
const isSelected = activeSection === item.id;
const hasDropdown = hasSubmenus && item.items && item.items.length > 0;
const isThisExpanded = openDropdown === item.id && hasDropdown;
return (
<div key={item.id} className="relative">
{/* Extended pill for selected item with dropdown */}
{isSelected && hasDropdown ? (
<div className={cn(
"flex items-center gap-2 rounded-full transition-all duration-200",
"font-medium whitespace-nowrap",
getSizeClasses(size),
getColorClasses(colorVariant, true)
)}>
{showIcons && item.icon}
{showText && item.label}
{/* Dropdown selector inside the pill */}
<div className="flex items-center ml-4 pl-4 border-l border-current/30">
<select
value={activeItem || ''}
onChange={(e) => handleItemClick(e.target.value)}
className="bg-transparent border-none outline-none font-medium cursor-pointer text-inherit"
>
<option value="" disabled>Select...</option>
{item.items?.map((subItem) => (
<option key={subItem} value={subItem} className="bg-gray-800 text-white">
{subItem}
</option>
))}
</select>
</div>
<ChevronRight
className={cn(
"w-4 h-4 transition-transform duration-300 ml-2 cursor-pointer",
isThisExpanded ? "-rotate-90" : "rotate-0"
)}
onClick={() => handleSectionClick(item.id)}
/>
</div>
) : (
/* Regular pill for non-selected items */
<button
onClick={() => handleSectionClick(item.id)}
className={cn(
"flex items-center gap-2 rounded-full transition-all duration-200",
"font-medium whitespace-nowrap",
getSizeClasses(size),
getColorClasses(colorVariant, isSelected)
)}
>
{showIcons && item.icon}
{showText && item.label}
{hasDropdown && (
<ChevronRight
className={cn(
"w-4 h-4 transition-transform duration-300",
isThisExpanded ? "-rotate-90" : "rotate-0"
)}
/>
)}
</button>
)}
</div>
);
})}
</div>
</div>
);
return {
renderPillNavigation,
activeSection,
activeItem,
colorVariant,
setColorVariant,
size,
setSize,
showIcons,
setShowIcons,
showText,
setShowText,
hasSubmenus,
setHasSubmenus,
navigationItems,
updateItemLabel
};
};
const generateCode = (configurator: ReturnType<typeof PillNavigationConfigurator>) => {
const hasSubmenus = configurator.hasSubmenus;
const colorVariant = configurator.colorVariant;
const size = configurator.size;
const showIcons = configurator.showIcons;
const showText = configurator.showText;
const navigationItems = configurator.navigationItems;
const itemsCode = navigationItems.map(item => {
const iconName = item.icon?.type?.displayName || item.icon?.type?.name || 'Icon';
return ` {
id: '${item.id}',
label: '${item.label}',${showIcons ? `
icon: <${iconName} className="w-4 h-4" />,` : ''}${hasSubmenus ? `
items: [${item.items?.map(subItem => `'${subItem}'`).join(', ')}]` : ''}
}`;
}).join(',\n');
return `import { useState } from 'react';
import { cn } from '@/features/ui/primitives/styles';${hasSubmenus ? `
import { ChevronRight } from 'lucide-react';` : ''}${showIcons ? `
import { ${navigationItems.map(item => {
const iconName = item.icon?.type?.displayName || item.icon?.type?.name || 'Icon';
return iconName;
}).filter((name, index, arr) => arr.indexOf(name) === index).join(', ')} } from 'lucide-react';` : ''}
export const PillNavigation = () => {
const [activeSection, setActiveSection] = useState('${configurator.activeSection}');${hasSubmenus ? `
const [activeItem, setActiveItem] = useState('${configurator.activeItem}');
const [openDropdown, setOpenDropdown] = useState<string | null>('${configurator.activeSection}');` : ''}
const navigationItems = [
${itemsCode}
];
const handleSectionClick = (sectionId: string) => {${hasSubmenus ? `
if (activeSection === sectionId && openDropdown === sectionId) {
setOpenDropdown(null);
} else {
setActiveSection(sectionId);
setOpenDropdown(sectionId);
// Set first item as default
const section = navigationItems.find(item => item.id === sectionId);
if (section?.items?.[0]) {
setActiveItem(section.items[0]);
}
}` : `
setActiveSection(sectionId);`}
};${hasSubmenus ? `
const handleItemClick = (item: string) => {
setActiveItem(item);
};` : ''}
const getColorClasses = (isSelected: boolean) => {
return isSelected
? "bg-${colorVariant}-500/20 dark:bg-${colorVariant}-400/20 text-${colorVariant}-700 dark:text-${colorVariant}-300 border border-${colorVariant}-400/50 shadow-[0_0_10px_rgba(${colorVariant === 'cyan' ? '34,211,238' : colorVariant === 'purple' ? '147,51,234' : colorVariant === 'emerald' ? '16,185,129' : '251,146,60'},0.5)]"
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5";
};${hasSubmenus ? `
const selectedSectionData = navigationItems.find(item => item.id === activeSection);` : ''}
return (
<div className="backdrop-blur-sm bg-white/40 dark:bg-white/5 border border-white/30 dark:border-white/15 rounded-full p-1 shadow-lg transition-all duration-300 ease-in-out">
<div className="flex gap-1 items-center">
{navigationItems.map((item) => {
const isSelected = activeSection === item.id;${hasSubmenus ? `
const hasDropdown = item.items && item.items.length > 0;
const isThisExpanded = openDropdown === item.id && hasDropdown;` : ''}
return (
<div key={item.id} className="relative">${hasSubmenus ? `
{/* Extended pill for selected item with dropdown */}
{isSelected && hasDropdown ? (
<div className={cn(
"flex items-center gap-2 ${size === 'small' ? 'px-4 py-2 text-xs' : size === 'large' ? 'px-8 py-4 text-base' : 'px-6 py-3 text-sm'} rounded-full transition-all duration-200",
"font-medium whitespace-nowrap",
getColorClasses(true)
)}>
${showIcons ? '{item.icon}' : ''}${showText ? `${showIcons ? ' ' : ''}{item.label}` : ''}
{/* Dropdown selector inside the pill */}
<div className="flex items-center ml-4 pl-4 border-l border-current/30">
<select
value={activeItem || ''}
onChange={(e) => handleItemClick(e.target.value)}
className="bg-transparent border-none outline-none font-medium cursor-pointer text-inherit"
>
<option value="" disabled>Select...</option>
{item.items?.map((subItem) => (
<option key={subItem} value={subItem} className="bg-gray-800 text-white">
{subItem}
</option>
))}
</select>
</div>
<ChevronRight
className={cn(
"w-4 h-4 transition-transform duration-300 ml-2 cursor-pointer",
isThisExpanded ? "-rotate-90" : "rotate-0"
)}
onClick={() => handleSectionClick(item.id)}
/>
</div>
) : (
/* Regular pill for non-selected items */` : ''}
<button
onClick={() => handleSectionClick(item.id)}
className={cn(
"flex items-center gap-2 ${size === 'small' ? 'px-4 py-2 text-xs' : size === 'large' ? 'px-8 py-4 text-base' : 'px-6 py-3 text-sm'} rounded-full transition-all duration-200",
"font-medium whitespace-nowrap",
getColorClasses(isSelected)
)}
>
${showIcons ? '{item.icon}' : ''}${showText ? `${showIcons ? ' ' : ''}{item.label}` : ''}${hasSubmenus ? `
{hasDropdown && (
<ChevronRight
className={cn(
"w-4 h-4 transition-transform duration-300",
isThisExpanded ? "-rotate-90" : "rotate-0"
)}
/>
)}` : ''}
</button>${hasSubmenus ? `
)}` : ''}
</div>
);
})}
</div>
</div>
);
};`;
};
export const NavigationPattern = () => {
const configurator = PillNavigationConfigurator();
return (
<div className="space-y-8">
{/* Header Description */}
<div>
<h2 className="text-2xl font-bold mb-4">Pill Navigation</h2>
<p className="text-gray-600 dark:text-gray-400 mb-6">
Modern glassmorphism pill-style navigation with optional sub-menu support. Perfect for primary navigation,
tab switching, and section selection with hierarchical options. Features an extended pill design for selected
items with internal dropdown selectors.
</p>
</div>
{/* Full Width Live Preview */}
<Card className="p-6">
<h3 className="text-lg font-semibold mb-4">Live Preview</h3>
<div className="flex items-center justify-center py-8">
{configurator.renderPillNavigation()}
</div>
{/* Current Selection Display */}
{configurator.hasSubmenus && (
<div className="mt-6 text-center p-4 bg-gray-50 dark:bg-gray-800/30 rounded-lg">
<h4 className="font-medium text-gray-900 dark:text-gray-100">Current Selection</h4>
<p className="text-sm text-gray-600 dark:text-gray-400">
Section: <span className="font-medium">{configurator.activeSection}</span>
{configurator.activeItem && (
<> | Item: <span className="font-medium">{configurator.activeItem}</span></>
)}
</p>
</div>
)}
</Card>
{/* Split Layout: Configurator + Code */}
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
{/* Left Half: Configuration Controls */}
<Card className="p-6">
<h3 className="text-lg font-semibold mb-4">Configuration Options</h3>
<div className="space-y-4">
{/* Color and Size */}
<div className="grid grid-cols-2 gap-4">
<div>
<label className="block text-sm font-medium mb-2">Color Variant</label>
<select
value={configurator.colorVariant}
onChange={(e) => configurator.setColorVariant(e.target.value)}
className="w-full p-2 text-sm border rounded-md bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600"
>
<option value="cyan">Cyan</option>
<option value="purple">Purple</option>
<option value="emerald">Emerald</option>
<option value="orange">Orange</option>
</select>
</div>
<div>
<label className="block text-sm font-medium mb-2">Size</label>
<select
value={configurator.size}
onChange={(e) => configurator.setSize(e.target.value)}
className="w-full p-2 text-sm border rounded-md bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600"
>
<option value="small">Small</option>
<option value="default">Default</option>
<option value="large">Large</option>
</select>
</div>
</div>
{/* Checkboxes */}
<div className="grid grid-cols-2 gap-4">
<div className="flex items-center gap-3">
<Checkbox
id="show-icons"
checked={configurator.showIcons}
onCheckedChange={configurator.setShowIcons}
color="cyan"
/>
<label htmlFor="show-icons" className="text-sm font-medium">
Show Icons
</label>
</div>
<div className="flex items-center gap-3">
<Checkbox
id="show-text"
checked={configurator.showText}
onCheckedChange={configurator.setShowText}
color="cyan"
/>
<label htmlFor="show-text" className="text-sm font-medium">
Show Text
</label>
</div>
</div>
{/* Submenu toggle */}
<div className="flex items-center gap-3">
<Checkbox
id="has-submenus"
checked={configurator.hasSubmenus}
onCheckedChange={configurator.setHasSubmenus}
color="cyan"
/>
<label htmlFor="has-submenus" className="text-sm font-medium">
Enable Sub-menus
</label>
</div>
{/* Editable Navigation Items */}
<div>
<label className="block text-sm font-medium mb-2">Navigation Items</label>
<div className="space-y-2">
{configurator.navigationItems.map((item, index) => (
<input
key={item.id}
type="text"
value={item.label}
onChange={(e) => configurator.updateItemLabel(index, e.target.value)}
className="w-full p-2 text-sm border rounded-md bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600"
placeholder={`Item ${index + 1} label`}
/>
))}
</div>
</div>
</div>
</Card>
{/* Right Half: Generated Code */}
<Card className="p-6">
<h3 className="text-lg font-semibold mb-4">Generated Code</h3>
<CodeDisplay
code={generateCode(configurator)}
showLineNumbers
/>
</Card>
</div>
</div>
);
};

View File

@@ -1,319 +0,0 @@
import { useState } from "react";
import {
Moon, Sun, Power, Wifi, WifiOff,
Volume2, VolumeX, Bell, BellOff,
Eye, EyeOff, Lock, Unlock
} from "lucide-react";
import { Switch, type SwitchSize, type SwitchColor } from "../../../features/ui/primitives/switch";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue
} from "../../../features/ui/primitives/select";
import { ConfiguratorCard } from "../shared/ConfiguratorCard";
const sizeOptions = [
{ value: "sm", label: "Small (16px)" },
{ value: "md", label: "Medium (24px)" },
{ value: "lg", label: "Large (32px)" },
];
const colorOptions = [
{ value: "purple", label: "Purple" },
{ value: "blue", label: "Blue" },
{ value: "green", label: "Green" },
{ value: "pink", label: "Pink" },
{ value: "orange", label: "Orange" },
{ value: "cyan", label: "Cyan" },
];
const iconOptions = [
{ value: "none", label: "No Icon", iconOn: null, iconOff: null },
{ value: "theme", label: "Theme", iconOn: <Moon className="w-full h-full" />, iconOff: <Sun className="w-full h-full" /> },
{ value: "power", label: "Power", iconOn: <Power className="w-full h-full" />, iconOff: <Power className="w-full h-full" /> },
{ value: "wifi", label: "WiFi", iconOn: <Wifi className="w-full h-full" />, iconOff: <WifiOff className="w-full h-full" /> },
{ value: "sound", label: "Sound", iconOn: <Volume2 className="w-full h-full" />, iconOff: <VolumeX className="w-full h-full" /> },
{ value: "notifications", label: "Notifications", iconOn: <Bell className="w-full h-full" />, iconOff: <BellOff className="w-full h-full" /> },
{ value: "visibility", label: "Visibility", iconOn: <Eye className="w-full h-full" />, iconOff: <EyeOff className="w-full h-full" /> },
{ value: "lock", label: "Lock", iconOn: <Lock className="w-full h-full" />, iconOff: <Unlock className="w-full h-full" /> },
];
/**
* 🤖 AI CONTEXT: Switch Configurator
*
* CONFIGURATION OPTIONS:
* 1. SIZE - Three variants for different use cases
* - Small: Clean minimal switches for dense UIs
* - Medium: Standard switches with optional icons
* - Large: Feature toggles with prominent icons
*
* 2. COLOR - Six accent colors matching the design system
* - Each color has associated glow effects
*
* 3. ICONS - Dynamic icon switching
* - Different icons for on/off states
* - Icons scale based on size variant
*
* 4. STATE - Interactive toggle preview
* - Live preview updates as configuration changes
*/
export function SwitchConfigurator() {
const [checked, setChecked] = useState(false);
const [size, setSize] = useState<SwitchSize>("lg");
const [color, setColor] = useState<SwitchColor>("cyan");
const [iconOption, setIconOption] = useState("theme");
const [disabled, setDisabled] = useState(false);
const [transparency, setTransparency] = useState("medium");
const [glowIntensity, setGlowIntensity] = useState("normal");
const [iconColorSync, setIconColorSync] = useState(true);
const selectedIcon = iconOptions.find(opt => opt.value === iconOption);
const generateCode = () => {
const imports = ["Switch"];
const props: string[] = [];
if (size !== "md") props.push(`size="${size}"`);
if (color !== "cyan") props.push(`color="${color}"`);
if (selectedIcon?.iconOn && selectedIcon?.iconOff) {
if (selectedIcon.value === "theme") {
imports.push("Moon", "Sun");
props.push(`iconOn={<Moon className="w-full h-full" />}`);
props.push(`iconOff={<Sun className="w-full h-full" />}`);
} else if (selectedIcon.value === "power") {
imports.push("Power");
props.push(`icon={<Power className="w-full h-full" />}`);
} else if (selectedIcon.value === "wifi") {
imports.push("Wifi", "WifiOff");
props.push(`iconOn={<Wifi className="w-full h-full" />}`);
props.push(`iconOff={<WifiOff className="w-full h-full" />}`);
}
// Add other icon cases as needed
}
if (disabled) props.push(`disabled`);
props.push(`checked={checked}`);
props.push(`onCheckedChange={setChecked}`);
const iconImports = imports.filter(i => i !== "Switch").length > 0
? `import { ${imports.filter(i => i !== "Switch").join(", ")} } from "lucide-react";\n`
: "";
return `${iconImports}import { Switch } from "@/features/ui/primitives/switch";
/**
* 🤖 AI CONTEXT: Switch Component
*
* SIZE: ${size} - ${sizeOptions.find(s => s.value === size)?.label}
* COLOR: ${color} - Neon glow effect
* ICONS: ${iconOption === "none" ? "No icons" : `${selectedIcon?.label} icons`}
* ${size === "sm" ? "* Note: Small switches don't display icons" : ""}
*
* GLASS PROPERTIES:
* - Transparency: bg-white/10 backdrop-blur
* - Glow: ${color} shadow on checked state
* - Transition: 500ms cubic-bezier animation
*/
<Switch
${props.join("\n ")}
/>`;
};
return (
<ConfiguratorCard
title="Switch"
description="Toggle switches with size variants, icons, and neon glow effects"
code={generateCode()}
>
<div className="space-y-6">
{/* Preview */}
<div className="flex items-center justify-center p-8 rounded-lg bg-black/5 dark:bg-white/5">
<Switch
size={size}
color={color}
iconOn={selectedIcon?.iconOn}
iconOff={selectedIcon?.iconOff}
checked={checked}
onCheckedChange={setChecked}
disabled={disabled}
/>
</div>
{/* Configuration */}
<div className="grid grid-cols-2 gap-4">
{/* Size */}
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
Size
</label>
<Select value={size} onValueChange={(v) => setSize(v as SwitchSize)}>
<SelectTrigger color={color}>
<SelectValue />
</SelectTrigger>
<SelectContent color={color}>
{sizeOptions.map(option => (
<SelectItem key={option.value} value={option.value} color={color}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* Color */}
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
Color
</label>
<Select value={color} onValueChange={(v) => setColor(v as SwitchColor)}>
<SelectTrigger color={color}>
<SelectValue />
</SelectTrigger>
<SelectContent color={color}>
{colorOptions.map(option => (
<SelectItem key={option.value} value={option.value} color={color}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* Icon */}
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
Icon {size === "sm" && "(Not shown for small)"}
</label>
<Select value={iconOption} onValueChange={setIconOption}>
<SelectTrigger color={color}>
<SelectValue />
</SelectTrigger>
<SelectContent color={color}>
{iconOptions.map(option => (
<SelectItem key={option.value} value={option.value} color={color}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* Transparency */}
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
Transparency
</label>
<Select value={transparency} onValueChange={setTransparency}>
<SelectTrigger color={color}>
<SelectValue />
</SelectTrigger>
<SelectContent color={color}>
<SelectItem value="low" color={color}>Low (More opaque)</SelectItem>
<SelectItem value="medium" color={color}>Medium</SelectItem>
<SelectItem value="high" color={color}>High (More transparent)</SelectItem>
</SelectContent>
</Select>
</div>
{/* Glow Intensity */}
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
Glow Intensity
</label>
<Select value={glowIntensity} onValueChange={setGlowIntensity}>
<SelectTrigger color={color}>
<SelectValue />
</SelectTrigger>
<SelectContent color={color}>
<SelectItem value="none" color={color}>None</SelectItem>
<SelectItem value="subtle" color={color}>Subtle</SelectItem>
<SelectItem value="normal" color={color}>Normal</SelectItem>
<SelectItem value="intense" color={color}>Intense</SelectItem>
</SelectContent>
</Select>
</div>
{/* State & Icon Color */}
<div>
<label className="text-sm font-medium text-gray-700 dark:text-gray-300 mb-2 block">
Options
</label>
<div className="flex flex-col gap-2">
<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
checked={disabled}
onChange={(e) => setDisabled(e.target.checked)}
className="sr-only"
/>
<Switch
size="sm"
color={color}
checked={disabled}
onCheckedChange={setDisabled}
/>
<span className="text-sm text-gray-600 dark:text-gray-400">Disabled</span>
</label>
<label className="flex items-center gap-2 cursor-pointer">
<input
type="checkbox"
checked={iconColorSync}
onChange={(e) => setIconColorSync(e.target.checked)}
className="sr-only"
/>
<Switch
size="sm"
color={color}
checked={iconColorSync}
onCheckedChange={setIconColorSync}
/>
<span className="text-sm text-gray-600 dark:text-gray-400">Icon color syncs</span>
</label>
</div>
</div>
</div>
{/* Examples */}
<div className="space-y-4">
<h4 className="text-sm font-medium text-gray-700 dark:text-gray-300">Examples</h4>
<div className="grid grid-cols-3 gap-4">
<div className="space-y-2">
<p className="text-xs text-gray-500 dark:text-gray-400">Small</p>
<div className="flex gap-2">
{colorOptions.slice(0, 3).map(opt => (
<Switch
key={opt.value}
size="sm"
color={opt.value as SwitchColor}
defaultChecked
/>
))}
</div>
</div>
<div className="space-y-2">
<p className="text-xs text-gray-500 dark:text-gray-400">Medium with Icons</p>
<div className="flex gap-2">
<Switch size="md" color="purple" iconOn={<Moon />} iconOff={<Sun />} defaultChecked />
<Switch size="md" color="green" icon={<Wifi />} />
</div>
</div>
<div className="space-y-2">
<p className="text-xs text-gray-500 dark:text-gray-400">Large Feature</p>
<div className="flex gap-2">
<Switch
size="lg"
color="blue"
iconOn={<Power />}
iconOff={<Power />}
defaultChecked
/>
</div>
</div>
</div>
</div>
</div>
</ConfiguratorCard>
);
}

View File

@@ -1,196 +0,0 @@
import { useState } from 'react';
import { Button } from '@/features/ui/primitives/button';
import { Switch } from '@/features/ui/primitives/switch';
import { Label } from '@/features/ui/primitives/label';
import { LivePreview } from '../shared/LivePreview';
import { CodeDisplay } from '../shared/CodeDisplay';
import { ConfigPanel } from '../shared/ConfigPanel';
import { Edit, Trash2, Eye, Code } from 'lucide-react';
interface TableConfig {
glassMorphism: boolean;
actions: boolean;
headers: boolean;
striped: boolean;
}
const sampleData = [
{ 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' },
];
export const TableConfigurator = () => {
const [config, setConfig] = useState<TableConfig>({
glassMorphism: true,
actions: true,
headers: true,
striped: true
});
const [activeTab, setActiveTab] = useState<'preview' | 'code'>('preview');
const generateCode = (_config: TableConfig) => {
const imports = `import { Button } from '@/features/ui/primitives/button';
import { Edit, Trash2, Eye } from 'lucide-react';`;
const aiContext = `/**
* 🤖 AI CONTEXT: Glass Morphism Table
*
* PURPOSE: Data display with glass morphism styling and interactive elements
* WHEN TO USE: Data grids, lists with actions, dashboard tables
* WHEN NOT TO USE: Simple lists (use basic ul/li), massive datasets (use virtualization)
*/`;
return `${imports}\n\n${aiContext}\n\n// Table component code here...`;
};
return (
<div className="grid grid-cols-4 gap-6 h-full">
{/* LEFT: Configuration Panel (1/4 width) */}
<div className="col-span-1">
<ConfigPanel title="Table Configuration">
<div className="space-y-4">
<div className="flex items-center justify-between">
<Label htmlFor="glass-morphism" className="text-sm">Glass Morphism</Label>
<Switch
id="glass-morphism"
checked={config.glassMorphism}
onCheckedChange={(glassMorphism) => setConfig({...config, glassMorphism})}
/>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="show-actions" className="text-sm">Show Actions</Label>
<Switch
id="show-actions"
checked={config.actions}
onCheckedChange={(actions) => setConfig({...config, actions})}
/>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="show-headers" className="text-sm">Show Headers</Label>
<Switch
id="show-headers"
checked={config.headers}
onCheckedChange={(headers) => setConfig({...config, headers})}
/>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="striped-rows" className="text-sm">Striped Rows</Label>
<Switch
id="striped-rows"
checked={config.striped}
onCheckedChange={(striped) => setConfig({...config, striped})}
/>
</div>
</div>
{/* Preview/Code Tabs INSIDE configurator */}
<div className="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700">
<div className="flex gap-2">
<Button
size="sm"
variant={activeTab === 'preview' ? 'default' : 'outline'}
onClick={() => setActiveTab('preview')}
className="flex items-center gap-2"
>
<Eye className="w-4 h-4" />
Preview
</Button>
<Button
size="sm"
variant={activeTab === 'code' ? 'default' : 'outline'}
onClick={() => setActiveTab('code')}
className="flex items-center gap-2"
>
<Code className="w-4 h-4" />
Code
</Button>
</div>
</div>
</ConfigPanel>
</div>
{/* RIGHT: Preview or Code Content (3/4 width) */}
<div className="col-span-3">
{activeTab === 'preview' ? (
<LivePreview>
<div className={`w-full ${config.glassMorphism
? 'backdrop-blur-md bg-white/80 dark:bg-black/30 border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden shadow-lg'
: 'bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden'
}`}>
<table className="w-full">
{config.headers && (
<thead className="bg-gray-50/80 dark:bg-gray-800/80 border-b border-gray-200 dark:border-gray-700">
<tr>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
Name
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
Email
</th>
<th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
Status
</th>
{config.actions && (
<th className="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">
Actions
</th>
)}
</tr>
</thead>
)}
<tbody className="divide-y divide-gray-200 dark:divide-gray-700">
{sampleData.map((item, index) => (
<tr
key={item.id}
className={`${config.striped && index % 2 === 1 ? 'bg-gray-50/50 dark:bg-gray-800/50' : ''} hover:bg-gray-50/70 dark:hover:bg-gray-800/70 transition-colors`}
>
<td className="px-6 py-4 whitespace-nowrap text-sm font-medium text-gray-900 dark:text-white">
{item.name}
</td>
<td className="px-6 py-4 whitespace-nowrap text-sm text-gray-500 dark:text-gray-400">
{item.email}
</td>
<td className="px-6 py-4 whitespace-nowrap">
<span className={`inline-flex px-2 py-1 text-xs font-semibold rounded-full ${
item.status === 'Active'
? 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400'
: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400'
}`}>
{item.status}
</span>
</td>
{config.actions && (
<td className="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
<div className="flex justify-end gap-2">
<Button size="icon" variant="ghost">
<Eye className="h-4 w-4" />
</Button>
<Button size="icon" variant="ghost">
<Edit className="h-4 w-4" />
</Button>
<Button size="icon" variant="ghost">
<Trash2 className="h-4 w-4" />
</Button>
</div>
</td>
)}
</tr>
))}
</tbody>
</table>
</div>
</LivePreview>
) : (
<CodeDisplay
code={generateCode(config)}
showLineNumbers
/>
)}
</div>
</div>
);
};

View File

@@ -1,219 +0,0 @@
import { useState } from 'react';
import { Switch } from '@/features/ui/primitives/switch';
import { Button } from '@/features/ui/primitives/button';
import { Label } from '@/features/ui/primitives/label';
import { RadioGroup, RadioGroupItem } from '@/features/ui/primitives/radio-group';
import { LivePreview } from '../shared/LivePreview';
import { CodeDisplay } from '../shared/CodeDisplay';
import { ConfigPanel } from '../shared/ConfigPanel';
import { Eye, Code, Moon, Sun, Volume2, VolumeX, Wifi, WifiOff } from 'lucide-react';
import type { LabelPosition } from '../types';
interface ToggleConfig {
disabled: boolean;
size: 'sm' | 'default' | 'lg';
labelPosition: LabelPosition;
labelText: string;
}
export const ToggleConfigurator = () => {
const [config, setConfig] = useState<ToggleConfig>({
disabled: false,
size: 'default',
labelPosition: 'right',
labelText: 'Enable notifications'
});
const [activeTab, setActiveTab] = useState<'preview' | 'code'>('preview');
const [toggleState, setToggleState] = useState(false);
const generateCode = (_config: ToggleConfig) => {
const imports = `import { Switch } from '@/features/ui/primitives/switch';
import { Label } from '@/features/ui/primitives/label';`;
const aiContext = `/**
* 🤖 AI CONTEXT: Switch Toggle Component
*
* PURPOSE: Binary on/off controls with accessible labeling
* WHEN TO USE: Settings, preferences, feature toggles, boolean states
* WHEN NOT TO USE: Multiple options (use RadioGroup), momentary actions (use Button)
*/`;
return `${imports}\n\n${aiContext}\n\n// Toggle component code here...`;
};
const layoutClasses = {
left: 'flex-row-reverse',
right: 'flex-row',
top: 'flex-col',
bottom: 'flex-col-reverse'
};
const gapClasses = {
left: 'gap-3',
right: 'gap-3',
top: 'gap-2',
bottom: 'gap-2'
};
return (
<div className="grid grid-cols-4 gap-6 h-full">
{/* LEFT: Configuration Panel (1/4 width) */}
<div className="col-span-1">
<ConfigPanel title="Switch Toggle Configuration">
<div className="space-y-4">
{/* Label Position */}
<div>
<Label className="text-sm">Label Position</Label>
<RadioGroup
value={config.labelPosition}
onValueChange={(value) => setConfig({...config, labelPosition: value as LabelPosition})}
>
<div className="grid grid-cols-2 gap-2">
{['left', 'right', 'top', 'bottom'].map(position => (
<div key={position} className="flex items-center space-x-2">
<RadioGroupItem value={position} id={`position-${position}`} />
<Label htmlFor={`position-${position}`} className="capitalize text-xs">
{position}
</Label>
</div>
))}
</div>
</RadioGroup>
</div>
{/* States */}
<div className="flex items-center justify-between">
<Label htmlFor="disabled-toggle" className="text-sm">Disabled State</Label>
<Switch
id="disabled-toggle"
checked={config.disabled}
onCheckedChange={(disabled) => setConfig({...config, disabled})}
/>
</div>
{/* Label Text */}
<div>
<Label htmlFor="label-text" className="text-sm">Label Text</Label>
<input
id="label-text"
type="text"
value={config.labelText}
onChange={(e) => setConfig({...config, labelText: e.target.value})}
className="w-full mt-1 px-3 py-2 border rounded-md dark:bg-gray-800 text-sm"
/>
</div>
</div>
{/* Preview/Code Tabs INSIDE configurator */}
<div className="mt-4 pt-4 border-t border-gray-200 dark:border-gray-700">
<div className="flex gap-2">
<Button
size="sm"
variant={activeTab === 'preview' ? 'default' : 'outline'}
onClick={() => setActiveTab('preview')}
className="flex items-center gap-2"
>
<Eye className="w-4 h-4" />
Preview
</Button>
<Button
size="sm"
variant={activeTab === 'code' ? 'default' : 'outline'}
onClick={() => setActiveTab('code')}
className="flex items-center gap-2"
>
<Code className="w-4 h-4" />
Code
</Button>
</div>
</div>
</ConfigPanel>
</div>
{/* RIGHT: Preview or Code Content (3/4 width) */}
<div className="col-span-3 space-y-6">
{activeTab === 'preview' ? (
<>
<LivePreview>
<div className={`flex ${layoutClasses[config.labelPosition]} ${gapClasses[config.labelPosition]} items-center`}>
{(config.labelPosition === 'top' || config.labelPosition === 'left') ? (
<>
<Label htmlFor="preview-toggle">
{config.labelText}
</Label>
<Switch
id="preview-toggle"
checked={toggleState}
onCheckedChange={setToggleState}
disabled={config.disabled}
/>
</>
) : (
<>
<Switch
id="preview-toggle"
checked={toggleState}
onCheckedChange={setToggleState}
disabled={config.disabled}
/>
<Label htmlFor="preview-toggle">
{config.labelText}
</Label>
</>
)}
</div>
</LivePreview>
{/* Icon Switch Examples */}
<div className="space-y-4">
<h4 className="text-sm font-semibold text-gray-900 dark:text-white">Switches with Icons</h4>
<LivePreview>
<div className="space-y-6">
{/* Dark Mode Toggle */}
<div className="flex items-center gap-3">
<Label>Dark Mode</Label>
<Switch
size="lg"
color="purple"
iconOn={<Sun className="w-5 h-5" />}
iconOff={<Moon className="w-5 h-5" />}
defaultChecked
/>
</div>
{/* Volume Toggle */}
<div className="flex items-center gap-3">
<Label>Audio</Label>
<Switch
size="md"
color="blue"
iconOn={<Volume2 className="w-3 h-3" />}
iconOff={<VolumeX className="w-3 h-3" />}
/>
</div>
{/* WiFi Toggle */}
<div className="flex items-center gap-3">
<Label>WiFi</Label>
<Switch
size="md"
color="cyan"
iconOn={<Wifi className="w-3 h-3" />}
iconOff={<WifiOff className="w-3 h-3" />}
defaultChecked
/>
</div>
</div>
</LivePreview>
</div>
</>
) : (
<CodeDisplay
code={generateCode(config)}
showLineNumbers
/>
)}
</div>
</div>
);
};

View File

@@ -1,368 +0,0 @@
import { Card } from '@/features/ui/primitives/card';
import { useState } from 'react';
import { Copy, Check } from 'lucide-react';
// Core color palette with neon variations
const CORE_COLORS = [
{
name: 'Cyan',
base: '#06b6d4',
variants: {
50: '#ecfeff',
100: '#cffafe',
200: '#a5f3fc',
300: '#67e8f9',
400: '#22d3ee',
500: '#06b6d4',
600: '#0891b2',
700: '#0e7490',
800: '#155e75',
900: '#164e63'
},
usage: 'Primary brand, active states, focus indicators'
},
{
name: 'Blue',
base: '#3b82f6',
variants: {
50: '#eff6ff',
100: '#dbeafe',
200: '#bfdbfe',
300: '#93c5fd',
400: '#60a5fa',
500: '#3b82f6',
600: '#2563eb',
700: '#1d4ed8',
800: '#1e40af',
900: '#1e3a8a'
},
usage: 'Information, links, secondary actions'
},
{
name: 'Purple',
base: '#a855f7',
variants: {
50: '#faf5ff',
100: '#f3e8ff',
200: '#e9d5ff',
300: '#d8b4fe',
400: '#c084fc',
500: '#a855f7',
600: '#9333ea',
700: '#7c3aed',
800: '#6b21a8',
900: '#581c87'
},
usage: 'Secondary actions, creative elements, highlights'
},
{
name: 'Emerald',
base: '#10b981',
variants: {
50: '#ecfdf5',
100: '#d1fae5',
200: '#a7f3d0',
300: '#6ee7b7',
400: '#34d399',
500: '#10b981',
600: '#059669',
700: '#047857',
800: '#065f46',
900: '#064e3b'
},
usage: 'Success states, positive feedback, growth indicators'
},
{
name: 'Orange',
base: '#f97316',
variants: {
50: '#fff7ed',
100: '#ffedd5',
200: '#fed7aa',
300: '#fdba74',
400: '#fb923c',
500: '#f97316',
600: '#ea580c',
700: '#c2410c',
800: '#9a3412',
900: '#7c2d12'
},
usage: 'Warnings, notifications, energy elements'
},
{
name: 'Pink',
base: '#ec4899',
variants: {
50: '#fdf2f8',
100: '#fce7f3',
200: '#fbcfe8',
300: '#f9a8d4',
400: '#f472b6',
500: '#ec4899',
600: '#db2777',
700: '#be185d',
800: '#9d174d',
900: '#831843'
},
usage: 'Special features, premium content, creativity'
},
{
name: 'Red',
base: '#ef4444',
variants: {
50: '#fef2f2',
100: '#fee2e2',
200: '#fecaca',
300: '#fca5a5',
400: '#f87171',
500: '#ef4444',
600: '#dc2626',
700: '#b91c1c',
800: '#991b1b',
900: '#7f1d1d'
},
usage: 'Errors, dangerous actions, critical alerts'
}
];
// Effect types for demonstration
const EFFECT_TYPES = [
{ name: 'Solid', key: 'solid' },
{ name: 'Border', key: 'border' },
{ name: 'Inner Glow', key: 'inner-glow' },
{ name: 'Outer Glow', key: 'outer-glow' },
{ name: 'Text', key: 'text' }
];
// Interactive Color Swatch with Selector and Slider
const InteractiveColorSwatch = ({ color }: { color: any }) => {
const [selectedVariant, setSelectedVariant] = useState(500);
const [copied, setCopied] = useState(false);
const currentColor = color.variants[selectedVariant as keyof typeof color.variants];
const handleCopy = () => {
navigator.clipboard.writeText(currentColor);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
return (
<div className="space-y-4">
<div className="flex items-center justify-between">
<h3 className="text-xl font-semibold text-gray-900 dark:text-white">{color.name}</h3>
<div
className="w-8 h-8 rounded-full border-2 border-gray-300 dark:border-gray-600 cursor-pointer transition-transform hover:scale-110"
style={{ backgroundColor: currentColor }}
onClick={handleCopy}
/>
</div>
<p className="text-gray-600 dark:text-gray-400 text-sm">{color.usage}</p>
{/* Color Selector with Current Swatch */}
<div
className="group relative rounded-lg overflow-hidden cursor-pointer transition-transform hover:scale-105 border border-gray-200 dark:border-gray-700"
onClick={handleCopy}
>
<div
className="h-20 w-full transition-all duration-200"
style={{ backgroundColor: currentColor }}
/>
<div className="p-3 bg-white dark:bg-gray-800">
<div className="flex items-center justify-between">
<div>
<p className="text-sm font-medium text-gray-900 dark:text-white">{color.name}-{selectedVariant}</p>
<p className="text-xs text-gray-600 dark:text-gray-400 font-mono">{currentColor}</p>
</div>
<div className="opacity-60 group-hover:opacity-100 transition-opacity">
{copied ? (
<Check className="w-4 h-4 text-green-500" />
) : (
<Copy className="w-4 h-4 text-gray-400" />
)}
</div>
</div>
</div>
</div>
{/* Variant Slider */}
<div>
<label className="block text-sm font-medium mb-2">Color Weight: {selectedVariant}</label>
<input
type="range"
min="100"
max="900"
step="100"
value={selectedVariant}
onChange={(e) => setSelectedVariant(Number(e.target.value))}
className="w-full h-2 bg-gray-200 dark:bg-gray-700 rounded-lg appearance-none cursor-pointer"
style={{
background: `linear-gradient(to right,
${color.variants[100]},
${color.variants[200]},
${color.variants[300]},
${color.variants[400]},
${color.variants[500]},
${color.variants[600]},
${color.variants[700]},
${color.variants[800]},
${color.variants[900]})`
}}
/>
<div className="flex justify-between text-xs text-gray-500 dark:text-gray-400 mt-1">
<span>100</span>
<span>500</span>
<span>900</span>
</div>
</div>
</div>
);
};
// Enhanced Effect demonstration component with improved glow
const EffectDemo = ({ color, effectType }: { color: any, effectType: string }) => {
const getEffectStyles = () => {
switch (effectType) {
case 'solid':
return {
backgroundColor: color.base,
color: 'white'
};
case 'border':
return {
border: `2px solid ${color.base}`,
backgroundColor: 'transparent',
color: color.base
};
case 'inner-glow':
return {
backgroundColor: `${color.base}40`, // More opaque for visibility
border: `1px solid ${color.base}`,
boxShadow: `inset 0 0 20px ${color.base}60`,
color: color.base
};
case 'outer-glow':
return {
backgroundColor: `${color.base}20`,
border: `1px solid ${color.base}`,
boxShadow: `0 0 30px ${color.base}80, 0 0 60px ${color.base}40`,
color: color.base
};
case 'text':
return {
color: color.base,
backgroundColor: 'transparent'
};
default:
return {};
}
};
const getEffectName = () => {
switch (effectType) {
case 'solid': return 'Solid';
case 'border': return 'Border';
case 'inner-glow': return 'Inner Glow';
case 'outer-glow': return 'Outer Glow';
case 'text': return 'Text';
default: return effectType;
}
};
return (
<div
className="p-4 rounded-lg text-center transition-all duration-200 hover:scale-105"
style={getEffectStyles()}
>
<p className="text-sm font-medium">{getEffectName()}</p>
</div>
);
};
export const ColorsFoundation = () => {
const [copiedColor, setCopiedColor] = useState<string | null>(null);
const handleColorCopy = (color: string) => {
navigator.clipboard.writeText(color);
setCopiedColor(color);
setTimeout(() => setCopiedColor(null), 2000);
};
return (
<div className="space-y-12">
{/* Header */}
<div className="text-center">
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-4">Color System</h2>
<p className="text-gray-600 dark:text-gray-400 text-lg max-w-3xl mx-auto">
Neon-inspired color palette with solid fills, borders, glows, and text treatments for Tron-style interfaces.
</p>
</div>
{/* Semantic Colors Overview */}
<div className="grid grid-cols-2 md:grid-cols-3 lg:grid-cols-6 gap-4 mb-12">
<div className="text-center">
<div className="w-16 h-16 mx-auto bg-gray-900 dark:bg-gray-100 rounded-lg mb-2"></div>
<h3 className="text-sm font-semibold text-gray-900 dark:text-gray-100">Primary</h3>
<p className="text-xs text-gray-600 dark:text-gray-400">#111827</p>
</div>
<div className="text-center">
<div className="w-16 h-16 mx-auto bg-gray-700 dark:bg-gray-300 rounded-lg mb-2"></div>
<h3 className="text-sm font-semibold text-gray-900 dark:text-gray-100">Secondary</h3>
<p className="text-xs text-gray-600 dark:text-gray-400">#374151</p>
</div>
<div className="text-center">
<div className="w-16 h-16 mx-auto bg-blue-500 rounded-lg mb-2 shadow-[0_0_20px_rgba(59,130,246,0.4)]"></div>
<h3 className="text-sm font-semibold text-gray-900 dark:text-gray-100">Accent</h3>
<p className="text-xs text-gray-600 dark:text-gray-400">#3b82f6</p>
</div>
<div className="text-center">
<div className="w-16 h-16 mx-auto bg-emerald-500 rounded-lg mb-2 shadow-[0_0_20px_rgba(16,185,129,0.4)]"></div>
<h3 className="text-sm font-semibold text-gray-900 dark:text-gray-100">Success</h3>
<p className="text-xs text-gray-600 dark:text-gray-400">#10b981</p>
</div>
<div className="text-center">
<div className="w-16 h-16 mx-auto bg-orange-500 rounded-lg mb-2 shadow-[0_0_20px_rgba(249,115,22,0.4)]"></div>
<h3 className="text-sm font-semibold text-gray-900 dark:text-gray-100">Warning</h3>
<p className="text-xs text-gray-600 dark:text-gray-400">#f97316</p>
</div>
<div className="text-center">
<div className="w-16 h-16 mx-auto bg-red-500 rounded-lg mb-2 shadow-[0_0_20px_rgba(239,68,68,0.4)]"></div>
<h3 className="text-sm font-semibold text-gray-900 dark:text-gray-100">Error</h3>
<p className="text-xs text-gray-600 dark:text-gray-400">#ef4444</p>
</div>
</div>
{/* Interactive Color Palette */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
{CORE_COLORS.map((color) => (
<Card key={color.name} className="p-6">
<InteractiveColorSwatch color={color} />
{/* Effect Demonstrations */}
<div className="mt-6 space-y-3">
<h4 className="text-sm font-medium text-gray-900 dark:text-white">Effects</h4>
<div className="grid grid-cols-1 gap-3">
{EFFECT_TYPES.map((effect) => (
<EffectDemo
key={effect.key}
color={color}
effectType={effect.key}
/>
))}
</div>
</div>
</Card>
))}
</div>
{/* Copy Notification */}
{copiedColor && (
<div className="fixed bottom-4 right-4 bg-green-500 text-white px-4 py-2 rounded-lg shadow-lg">
Copied {copiedColor} to clipboard!
</div>
)}
</div>
);
};

View File

@@ -1,645 +0,0 @@
import { useState, useEffect } from 'react';
import { Card } from '@/features/ui/primitives/card';
import { Button } from '@/features/ui/primitives/button';
import { CodeDisplay } from '../shared/CodeDisplay';
import { cn } from '@/features/ui/primitives/styles';
import { Loader2, Zap, Sparkles, MousePointer } from 'lucide-react';
// Add Tron animations to the page
const addTronAnimations = () => {
const style = document.createElement('style');
style.textContent = `
@keyframes dataStream {
0%, 100% { transform: translateY(-100%); }
50% { transform: translateY(100%); }
}
@keyframes progressSweep {
0%, 100% { background: linear-gradient(to right, #3b82f6, #ef4444, #3b82f6); }
50% { background: linear-gradient(to right, #ef4444, #3b82f6, #ef4444); }
}
@keyframes lightTrail {
0% { transform: translateX(-100%); }
100% { transform: translateX(400%); }
}
@keyframes energyCascade {
0% { transform: translateX(-100%) skewX(12deg); }
100% { transform: translateX(200%) skewX(12deg); }
}
@keyframes recognitionScan {
0%, 100% { height: 0.5rem; opacity: 0.3; }
50% { height: 2rem; opacity: 1; }
}
@keyframes spectrumWave {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
@keyframes sparkRace {
0% {
top: 0;
left: 0;
transform: translateX(0);
}
25% {
top: 0;
left: 100%;
transform: translateX(-100%);
}
25.01% {
top: 0;
left: 100%;
transform: translateY(0);
}
50% {
top: 100%;
left: 100%;
transform: translateY(-100%);
}
50.01% {
top: 100%;
left: 100%;
transform: translateX(0);
}
75% {
top: 100%;
left: 0;
transform: translateX(0);
}
75.01% {
top: 100%;
left: 0;
transform: translateY(0);
}
100% {
top: 0;
left: 0;
transform: translateY(0);
}
}
.animate-spin-reverse {
animation: spin 1s linear infinite reverse;
}
.animate-dataStream {
animation: dataStream 1.5s ease-in-out infinite;
}
.animate-progressSweep {
animation: progressSweep 3s ease-in-out infinite;
}
.animate-lightTrail {
animation: lightTrail 2s ease-in-out infinite;
}
.animate-energyCascade {
animation: energyCascade 2s linear infinite;
}
.animate-recognitionScan {
animation: recognitionScan 2s ease-in-out infinite;
}
.animate-spectrumWave {
animation: spectrumWave 4s ease-in-out infinite;
}
.animate-borderRace {
animation: borderRace 2s linear infinite;
}
`;
document.head.appendChild(style);
return () => style.remove();
};
const EFFECT_OPTIONS = [
'Interaction',
'Loading',
'Neon',
'Animation'
];
export const EffectsFoundation = () => {
const [activeOption, setActiveOption] = useState('Interaction');
const [selectedEffect, setSelectedEffect] = useState('hover-glow');
// Add custom animations when component mounts
useEffect(() => {
const cleanup = addTronAnimations();
return cleanup;
}, []);
// Option 1: Hover & Interaction Effects
const renderOption1 = () => (
<div className="space-y-8">
<h3 className="text-lg font-semibold flex items-center gap-2">
<MousePointer className="w-5 h-5" />
Hover & Interaction Effects
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Racing Border Effect */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Racing Border</h4>
<div className="w-20 h-12 mx-auto bg-black border border-gray-600 rounded-lg cursor-pointer group relative flex items-center justify-center text-xs text-gray-300">
<span className="relative z-10">Hover Me</span>
{/* Racing spark */}
<div className="absolute w-2 h-0.5 bg-blue-400 shadow-[0_0_8px_rgba(59,130,246,1)] opacity-0 group-hover:opacity-100 group-hover:animate-[sparkRace_2s_linear_infinite] rounded-full"></div>
</div>
</Card>
{/* Blue Glass Button */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Blue Glass</h4>
<button className="backdrop-blur-sm bg-blue-500/20 border border-blue-500/50 hover:bg-blue-500/30 hover:border-blue-500 hover:shadow-[0_0_25px_rgba(59,130,246,0.8)] transition-all duration-300 text-blue-300 hover:text-blue-200 px-4 py-2 rounded-full text-sm font-medium">
Glass Button
</button>
</Card>
{/* Red Alert Hover */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Red Alert</h4>
<div className="w-16 h-16 mx-auto bg-red-500/20 border border-red-500 rounded-lg cursor-pointer hover:scale-110 hover:shadow-[0_0_30px_rgba(239,68,68,0.8)] transition-all duration-200 flex items-center justify-center text-red-300 text-xs">Alert</div>
</Card>
{/* Neon Text Glow */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Neon Text</h4>
<div className="text-blue-400 cursor-pointer hover:drop-shadow-[0_0_12px_rgba(59,130,246,1)] transition-all duration-300 font-bold text-lg">
BLUE NEON
</div>
</Card>
{/* Program Recognition */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Program ID</h4>
<div className="w-20 h-12 mx-auto bg-black border border-blue-500/50 rounded-lg cursor-pointer hover:border-red-500 hover:shadow-[0_0_20px_rgba(239,68,68,0.6)] transition-all duration-500 flex items-center justify-center text-xs text-gray-300">
ID: 7364
</div>
</Card>
{/* Pulse Activation */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Pulse Hover</h4>
<div className="w-20 h-12 mx-auto bg-purple-500/20 border border-purple-500 rounded-lg cursor-pointer hover:animate-pulse hover:shadow-[0_0_30px_rgba(168,85,247,0.8)] transition-all duration-300 flex items-center justify-center text-purple-300 text-xs font-medium">
Pulse Me
</div>
</Card>
</div>
</div>
);
// Option 2: Loading & Skeleton Effects
const renderOption2 = () => (
<div className="space-y-8">
<h3 className="text-lg font-semibold flex items-center gap-2">
<Loader2 className="w-5 h-5" />
Loading & Skeleton Effects
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Light Cycle Circuit */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Light Cycle Circuit</h4>
<div className="w-16 h-16 mx-auto relative">
<div className="absolute inset-0 border-2 border-transparent border-t-blue-400 border-r-red-500 rounded-full animate-spin shadow-[0_0_20px_rgba(59,130,246,0.8)]"></div>
<div className="absolute inset-2 border-2 border-transparent border-b-red-500 border-l-blue-400 rounded-full animate-spin-reverse shadow-[0_0_20px_rgba(239,68,68,0.8)]"></div>
</div>
</Card>
{/* Data Stream */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Data Stream</h4>
<div className="w-16 h-16 mx-auto relative overflow-hidden rounded-lg border border-blue-500/30">
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-blue-500/40 to-transparent animate-dataStream"></div>
<div className="absolute inset-0 bg-gradient-to-b from-transparent via-red-500/40 to-transparent animate-dataStream" style={{animationDelay: '0.75s'}}></div>
</div>
</Card>
{/* Tron Grid Progress */}
<Card className="p-4 bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Grid Progress</h4>
<div className="w-full bg-black border border-blue-500/30 h-4 rounded relative overflow-hidden"
style={{
backgroundImage: `
linear-gradient(rgba(59, 130, 246, 0.1) 1px, transparent 1px),
linear-gradient(90deg, rgba(59, 130, 246, 0.1) 1px, transparent 1px)
`,
backgroundSize: '4px 4px'
}}>
<div className="h-full rounded shadow-[0_0_15px_rgba(59,130,246,0.8)] animate-progressSweep"
style={{width: '60%'}}></div>
</div>
</Card>
{/* Light Trail Skeleton */}
<Card className="p-4 bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Light Trails</h4>
<div className="space-y-3">
<div className="h-3 bg-black border border-blue-500/50 rounded relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-blue-400 to-transparent w-1/3 animate-lightTrail shadow-[0_0_10px_rgba(59,130,246,0.8)]"></div>
</div>
<div className="h-3 bg-black border border-red-500/50 rounded w-3/4 relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-red-500 to-transparent w-1/3 animate-lightTrail shadow-[0_0_10px_rgba(239,68,68,0.8)]" style={{animationDelay: '0.5s'}}></div>
</div>
<div className="h-3 bg-black border border-blue-500/50 rounded w-1/2 relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-blue-400 to-transparent w-1/3 animate-lightTrail shadow-[0_0_10px_rgba(59,130,246,0.8)]" style={{animationDelay: '1s'}}></div>
</div>
</div>
</Card>
{/* Energy Cascade */}
<Card className="p-4 bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Energy Cascade</h4>
<div className="w-full h-16 bg-black border border-blue-500/30 rounded-lg relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-blue-400/60 to-transparent animate-energyCascade shadow-[0_0_20px_rgba(59,130,246,0.6)]"></div>
<div className="absolute inset-0 bg-gradient-to-r from-transparent via-red-500/40 to-transparent animate-energyCascade shadow-[0_0_20px_rgba(239,68,68,0.4)]" style={{animationDelay: '1s'}}></div>
</div>
</Card>
{/* Recognition Pattern */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Recognition Pattern</h4>
<div className="flex gap-1 justify-center">
{[0, 1, 2, 3, 4].map(i => (
<div
key={i}
className={cn(
"w-2 rounded-sm animate-recognitionScan",
i % 2 === 0 ? "bg-blue-400 shadow-[0_0_8px_rgba(59,130,246,0.8)]" : "bg-red-500 shadow-[0_0_8px_rgba(239,68,68,0.8)]"
)}
style={{ animationDelay: `${i * 0.1}s` }}
></div>
))}
</div>
</Card>
</div>
{/* Custom Tron Animations CSS */}
<Card className="p-4 bg-black border border-cyan-500/30">
<h4 className="text-sm font-medium text-gray-100 mb-3">Tron Animation Keyframes (Add to CSS)</h4>
<CodeDisplay
code={`@keyframes dataStream {
0%, 100% { transform: translateY(-100%); }
50% { transform: translateY(100%); }
}
@keyframes progressSweep {
0%, 100% { background: linear-gradient(to right, #3b82f6, #ef4444, #3b82f6); }
50% { background: linear-gradient(to right, #ef4444, #3b82f6, #ef4444); }
}
@keyframes lightTrail {
0% { transform: translateX(-100%); }
100% { transform: translateX(400%); }
}
@keyframes energyCascade {
0% { transform: translateX(-100%) skewX(12deg); }
100% { transform: translateX(200%) skewX(12deg); }
}
@keyframes recognitionScan {
0%, 100% { height: 0.5rem; opacity: 0.3; }
50% { height: 2rem; opacity: 1; }
}`}
showLineNumbers={false}
/>
</Card>
</div>
);
// Option 3: Gradient & Neon Effects
const renderOption3 = () => (
<div className="space-y-8">
<h3 className="text-lg font-semibold flex items-center gap-2">
<Zap className="w-5 h-5" />
Gradient & Neon Effects
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Multi-Color Neon Text */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Neon Typography</h4>
<div className="space-y-2">
<div className="text-blue-400 text-lg font-bold drop-shadow-[0_0_10px_rgba(59,130,246,0.8)]">BLUE NEON</div>
<div className="text-pink-400 text-lg font-bold drop-shadow-[0_0_10px_rgba(244,114,182,0.8)]">PINK NEON</div>
<div className="text-emerald-400 text-lg font-bold drop-shadow-[0_0_10px_rgba(52,211,153,0.8)]">GREEN NEON</div>
</div>
</Card>
{/* Neon Orb Constellation */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Neon Orbs</h4>
<div className="flex gap-2 justify-center items-center">
<div className="w-8 h-8 bg-purple-500 rounded-full shadow-[0_0_20px_rgba(168,85,247,0.8)] animate-pulse"></div>
<div className="w-6 h-6 bg-blue-500 rounded-full shadow-[0_0_15px_rgba(59,130,246,0.8)] animate-pulse" style={{animationDelay: '0.5s'}}></div>
<div className="w-10 h-10 bg-pink-500 rounded-full shadow-[0_0_25px_rgba(244,114,182,0.8)] animate-pulse" style={{animationDelay: '1s'}}></div>
<div className="w-7 h-7 bg-emerald-500 rounded-full shadow-[0_0_18px_rgba(52,211,153,0.8)] animate-pulse" style={{animationDelay: '1.5s'}}></div>
</div>
</Card>
{/* Rainbow Laser Grid */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Laser Grid</h4>
<div className="w-full h-16 relative overflow-hidden rounded-lg border border-purple-500/30">
<div className="absolute top-2 left-0 right-0 h-0.5 bg-gradient-to-r from-transparent via-blue-400 to-transparent shadow-[0_0_8px_rgba(59,130,246,0.8)]"></div>
<div className="absolute top-6 left-0 right-0 h-0.5 bg-gradient-to-r from-transparent via-pink-400 to-transparent shadow-[0_0_8px_rgba(244,114,182,0.8)]"></div>
<div className="absolute top-10 left-0 right-0 h-0.5 bg-gradient-to-r from-transparent via-emerald-400 to-transparent shadow-[0_0_8px_rgba(52,211,153,0.8)]"></div>
<div className="absolute top-14 left-0 right-0 h-0.5 bg-gradient-to-r from-transparent via-purple-400 to-transparent shadow-[0_0_8px_rgba(168,85,247,0.8)]"></div>
</div>
</Card>
{/* Gradient Borders */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Neon Borders</h4>
<div className="space-y-3">
<div className="w-20 h-8 mx-auto bg-gradient-to-r from-purple-500 via-pink-500 to-purple-500 p-[2px] rounded-lg">
<div className="w-full h-full bg-black rounded-md flex items-center justify-center text-xs text-gray-300">Purple</div>
</div>
<div className="w-20 h-8 mx-auto bg-gradient-to-r from-blue-500 via-emerald-500 to-blue-500 p-[2px] rounded-lg">
<div className="w-full h-full bg-black rounded-md flex items-center justify-center text-xs text-gray-300">Blue</div>
</div>
</div>
</Card>
{/* Spectrum Wave */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Spectrum Wave</h4>
<div className="w-full h-12 rounded-lg relative overflow-hidden">
<div className="absolute inset-0 bg-gradient-to-r from-purple-500 via-blue-500 via-emerald-500 via-pink-500 to-purple-500 animate-[spectrumWave_4s_ease-in-out_infinite] bg-[length:200%_100%]"></div>
</div>
</Card>
{/* Pulsing Circuit */}
<Card className="p-4 text-center bg-black">
<h4 className="text-sm font-medium text-gray-100 mb-3">Pulsing Circuit</h4>
<div className="w-16 h-16 mx-auto relative">
<div className="absolute inset-0 border-2 border-blue-500 rounded-lg animate-pulse shadow-[0_0_20px_rgba(59,130,246,0.6)]"></div>
<div className="absolute inset-2 border-2 border-pink-500 rounded-lg animate-pulse shadow-[0_0_15px_rgba(244,114,182,0.6)]" style={{animationDelay: '0.5s'}}></div>
<div className="absolute inset-4 border-2 border-emerald-500 rounded-lg animate-pulse shadow-[0_0_10px_rgba(52,211,153,0.6)]" style={{animationDelay: '1s'}}></div>
</div>
</Card>
</div>
{/* Neon Animation Keyframes */}
<Card className="p-4 bg-black border border-pink-500/30">
<h4 className="text-sm font-medium text-gray-100 mb-3">Neon Animation Keyframes (Add to CSS)</h4>
<CodeDisplay
code={`@keyframes spectrumWave {
0%, 100% { background-position: 0% 50%; }
50% { background-position: 100% 50%; }
}
@keyframes neonPulse {
0%, 100% {
box-shadow: 0 0 5px currentColor, 0 0 10px currentColor, 0 0 20px currentColor;
}
50% {
box-shadow: 0 0 10px currentColor, 0 0 20px currentColor, 0 0 40px currentColor;
}
}
@keyframes colorShift {
0% { filter: hue-rotate(0deg); }
25% { filter: hue-rotate(90deg); }
50% { filter: hue-rotate(180deg); }
75% { filter: hue-rotate(270deg); }
100% { filter: hue-rotate(360deg); }
}`}
showLineNumbers={false}
/>
</Card>
</div>
);
// Option 4: Motion & Animation Effects
const renderOption4 = () => (
<div className="space-y-8">
<h3 className="text-lg font-semibold flex items-center gap-2">
<Sparkles className="w-5 h-5" />
Motion & Animation Effects
</h3>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{/* Fade In */}
<Card className="p-4 text-center">
<h4 className="text-sm font-medium text-gray-900 dark:text-gray-100 mb-3">Fade In</h4>
<div className="w-16 h-16 mx-auto bg-gradient-to-br from-purple-500 to-emerald-500 rounded-lg animate-[fadeIn_2s_ease-in-out_infinite] shadow-[0_0_15px_rgba(168,85,247,0.4)]"></div>
</Card>
{/* Slide Up */}
<Card className="p-4 text-center">
<h4 className="text-sm font-medium text-gray-900 dark:text-gray-100 mb-3">Slide Up</h4>
<div className="w-16 h-16 mx-auto bg-gradient-to-br from-cyan-500 to-emerald-500 rounded-lg animate-[slideUp_2s_ease-in-out_infinite] shadow-[0_0_15px_rgba(34,211,238,0.4)]"></div>
</Card>
{/* Bounce */}
<Card className="p-4 text-center">
<h4 className="text-sm font-medium text-gray-900 dark:text-gray-100 mb-3">Bounce</h4>
<div className="w-16 h-16 mx-auto bg-emerald-500 rounded-lg animate-bounce shadow-[0_0_15px_rgba(16,185,129,0.6)]"></div>
</Card>
{/* Wiggle */}
<Card className="p-4 text-center">
<h4 className="text-sm font-medium text-gray-900 dark:text-gray-100 mb-3">Wiggle</h4>
<div className="w-16 h-16 mx-auto bg-orange-500 rounded-lg animate-[wiggle_1s_ease-in-out_infinite] shadow-[0_0_15px_rgba(249,115,22,0.4)]"></div>
</Card>
{/* Float */}
<Card className="p-4 text-center">
<h4 className="text-sm font-medium text-gray-900 dark:text-gray-100 mb-3">Float</h4>
<div className="w-16 h-16 mx-auto bg-pink-500 rounded-lg animate-[float_3s_ease-in-out_infinite] shadow-[0_0_15px_rgba(236,72,153,0.4)]"></div>
</Card>
{/* Rotate */}
<Card className="p-4 text-center">
<h4 className="text-sm font-medium text-gray-900 dark:text-gray-100 mb-3">Rotate</h4>
<div className="w-16 h-16 mx-auto bg-red-500 rounded-lg animate-spin shadow-[0_0_15px_rgba(239,68,68,0.4)]"></div>
</Card>
</div>
{/* Custom Animations CSS */}
<Card className="p-4">
<h4 className="text-sm font-medium mb-3">Custom Animations (Add to CSS)</h4>
<CodeDisplay
code={`@keyframes fadeIn {
0% { opacity: 0; transform: translateY(10px); }
100% { opacity: 1; transform: translateY(0); }
}
@keyframes slideUp {
0%, 100% { transform: translateY(20px); }
50% { transform: translateY(0); }
}
@keyframes wiggle {
0%, 100% { transform: rotate(-3deg); }
50% { transform: rotate(3deg); }
}
@keyframes float {
0%, 100% { transform: translateY(0px); }
50% { transform: translateY(-10px); }
}
@keyframes shimmer {
0% { transform: translateX(-100%); }
100% { transform: translateX(100%); }
}`}
showLineNumbers={false}
/>
</Card>
</div>
);
const renderContent = () => {
switch (activeOption) {
case 'Interaction':
return renderOption1();
case 'Loading':
return renderOption2();
case 'Neon':
return renderOption3();
case 'Animation':
return renderOption4();
default:
return renderOption1();
}
};
const generateCode = () => {
switch (activeOption) {
case 'Interaction':
return `// Hover & Interaction Effects
<button className="hover:shadow-[0_0_20px_rgba(34,211,238,0.6)] transition-all duration-300">
Glow Hover
</button>
<div className="hover:scale-110 transition-transform duration-200">
Scale Hover
</div>
<div className="hover:border-cyan-500 hover:shadow-[0_0_15px_rgba(34,211,238,0.5)] transition-all duration-300">
Neon Border Hover
</div>
<div className="text-cyan-500 hover:drop-shadow-[0_0_8px_rgba(34,211,238,0.8)] transition-all duration-300">
Glowing Text
</div>`;
case 'Loading':
return `// Tron-style Loading Effects
<div className="w-12 h-12 border-2 border-transparent border-t-cyan-500 border-r-cyan-500 rounded-full animate-spin shadow-[0_0_15px_rgba(34,211,238,0.5)]"></div>
<div className="w-full bg-gray-800 border border-gray-600 rounded-full h-3 shadow-inner">
<div className="bg-gradient-to-r from-cyan-500 to-emerald-500 h-full rounded-full shadow-[0_0_10px_rgba(34,211,238,0.6)] animate-pulse" style="width: 60%"></div>
</div>
<div className="space-y-2">
<div className="h-4 bg-gradient-to-r from-gray-700 to-gray-600 rounded animate-pulse shadow-[0_0_5px_rgba(34,211,238,0.3)]"></div>
<div className="h-3 bg-gradient-to-r from-gray-700 to-gray-600 rounded w-3/4 animate-pulse shadow-[0_0_5px_rgba(34,211,238,0.3)]"></div>
</div>`;
case 'Neon':
return `// Gradient & Neon Effects
<div className="bg-gradient-to-r from-purple-500 via-cyan-500 to-emerald-500 p-[2px] rounded-lg">
<div className="bg-gray-900 rounded-md p-4">Gradient Border</div>
</div>
<span className="text-cyan-400 drop-shadow-[0_0_10px_rgba(34,211,238,0.8)] font-bold">
NEON TEXT
</span>
<div className="w-12 h-12 bg-cyan-500 rounded-full shadow-[0_0_30px_rgba(34,211,238,0.8),_0_0_60px_rgba(34,211,238,0.4)] animate-pulse">
</div>
<div
className="w-full h-16 rounded-lg border border-cyan-500/50"
style={{
backgroundImage: \`
linear-gradient(rgba(34, 211, 238, 0.1) 1px, transparent 1px),
linear-gradient(90deg, rgba(34, 211, 238, 0.1) 1px, transparent 1px)
\`,
backgroundSize: '10px 10px'
}}
></div>`;
case 'Animation':
return `// Motion & Animation Effects
<div className="bg-gradient-to-br from-purple-500 to-emerald-500 rounded-lg animate-[fadeIn_2s_ease-in-out_infinite] shadow-[0_0_15px_rgba(168,85,247,0.4)]">
Fade In
</div>
<div className="bg-gradient-to-br from-cyan-500 to-emerald-500 rounded-lg animate-[slideUp_2s_ease-in-out_infinite] shadow-[0_0_15px_rgba(34,211,238,0.4)]">
Slide Up
</div>
<div className="bg-emerald-500 rounded-lg animate-bounce shadow-[0_0_15px_rgba(16,185,129,0.6)]">
Bounce
</div>
<div className="bg-pink-500 rounded-lg animate-[float_3s_ease-in-out_infinite] shadow-[0_0_15px_rgba(236,72,153,0.4)]">
Float
</div>`;
default:
return '';
}
};
return (
<div className="space-y-8">
{/* Header */}
<div className="text-center">
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-4">Effects System</h2>
<p className="text-gray-600 dark:text-gray-400 text-lg">
Animation, interaction, and visual effects library
</p>
</div>
{/* Option Tabs */}
<div className="flex justify-center">
<div className="backdrop-blur-sm bg-white/40 dark:bg-white/5 border border-white/30 dark:border-white/15 rounded-full p-1 shadow-lg">
<div className="flex gap-1 items-center">
{EFFECT_OPTIONS.map((option) => (
<button
key={option}
onClick={() => setActiveOption(option)}
className={cn(
"flex items-center gap-2 px-4 py-2 rounded-full transition-all duration-200",
"text-sm font-medium whitespace-nowrap",
activeOption === option
? "bg-cyan-500/20 dark:bg-cyan-400/20 text-cyan-700 dark:text-cyan-300 border border-cyan-400/50 shadow-[0_0_10px_rgba(34,211,238,0.5)]"
: "text-gray-700 dark:text-gray-300 hover:bg-white/10 dark:hover:bg-white/5"
)}
>
{option}
</button>
))}
</div>
</div>
</div>
{/* Content */}
<Card className="p-8">
{renderContent()}
{/* Generated Code */}
<div className="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
<h4 className="text-sm font-medium text-gray-900 dark:text-white mb-3">Generated Code</h4>
<CodeDisplay
code={generateCode()}
showLineNumbers={false}
/>
</div>
</Card>
</div>
);
};

View File

@@ -1,233 +0,0 @@
import { useState } from 'react';
import { Card } from '@/features/ui/primitives/card';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/features/ui/primitives/select';
import { CodeDisplay } from '../shared/CodeDisplay';
import { cn } from '@/features/ui/primitives/styles';
// Simplified spacing scale
const SPACING_VALUES = [
{ name: '1', pixels: '4px', value: '0.25rem' },
{ name: '2', pixels: '8px', value: '0.5rem' },
{ name: '3', pixels: '12px', value: '0.75rem' },
{ name: '4', pixels: '16px', value: '1rem' },
{ name: '6', pixels: '24px', value: '1.5rem' },
{ name: '8', pixels: '32px', value: '2rem' },
{ name: '12', pixels: '48px', value: '3rem' },
{ name: '16', pixels: '64px', value: '4rem' },
{ name: '20', pixels: '80px', value: '5rem' },
{ name: '24', pixels: '96px', value: '6rem' }
];
const SPACING_TYPES = [
{ name: 'Padding', prefix: 'p' },
{ name: 'Margin', prefix: 'm' },
{ name: 'Gap', prefix: 'gap' },
{ name: 'Space Y', prefix: 'space-y' },
{ name: 'Space X', prefix: 'space-x' }
];
export const SpacingFoundation = () => {
const [selectedValue, setSelectedValue] = useState('4');
const [selectedType, setSelectedType] = useState('Padding');
const currentSpacing = SPACING_VALUES.find(s => s.name === selectedValue);
const currentType = SPACING_TYPES.find(t => t.name === selectedType);
const generateCode = () => {
if (!currentSpacing || !currentType) return '';
const className = `${currentType.prefix}-${selectedValue}`;
const pixelValue = currentSpacing.pixels;
const remValue = currentSpacing.value;
return `// ${selectedType} with ${pixelValue} spacing
<div className="${className}">
Content with ${selectedType.toLowerCase()} of ${pixelValue}
</div>
// Values:
// ${className} = ${remValue} (${pixelValue})`;
};
const renderDemo = () => {
if (!currentSpacing || !currentType) return null;
const className = `${currentType.prefix}-${selectedValue}`;
switch (selectedType) {
case 'Padding':
return (
<div className="border-2 border-dashed border-gray-300 dark:border-gray-600">
<div className={cn(className, 'bg-cyan-100 dark:bg-cyan-900/30')}>
<div className="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded text-center py-4">
Content with {currentSpacing.pixels} padding
</div>
</div>
</div>
);
case 'Margin':
return (
<div className="border-2 border-dashed border-gray-300 dark:border-gray-600 p-4">
<div className={cn(className, 'bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded text-center py-4 bg-cyan-100 dark:bg-cyan-900/30')}>
Content with {currentSpacing.pixels} margin
</div>
</div>
);
case 'Gap':
return (
<div className={cn('flex', className)}>
{[1, 2, 3].map((i) => (
<div
key={i}
className="w-20 h-16 bg-cyan-100 dark:bg-cyan-900/30 border border-gray-200 dark:border-gray-700 rounded flex items-center justify-center text-sm"
>
Item {i}
</div>
))}
</div>
);
case 'Space Y':
return (
<div className={cn('space-y-' + selectedValue)}>
{[1, 2, 3].map((i) => (
<div
key={i}
className="w-full h-12 bg-cyan-100 dark:bg-cyan-900/30 border border-gray-200 dark:border-gray-700 rounded flex items-center justify-center text-sm"
>
Item {i}
</div>
))}
</div>
);
case 'Space X':
return (
<div className={cn('flex space-x-' + selectedValue)}>
{[1, 2, 3].map((i) => (
<div
key={i}
className="w-20 h-16 bg-cyan-100 dark:bg-cyan-900/30 border border-gray-200 dark:border-gray-700 rounded flex items-center justify-center text-sm"
>
Item {i}
</div>
))}
</div>
);
default:
return null;
}
};
return (
<div className="space-y-8">
{/* Header */}
<div className="text-center">
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-4">Spacing System</h2>
<p className="text-gray-600 dark:text-gray-400 text-lg">
Interactive spacing scale explorer
</p>
</div>
{/* Spacing Explorer - Above the Fold */}
<Card className="p-8">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Left: Controls */}
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">Spacing Type</label>
<Select value={selectedType} onValueChange={setSelectedType}>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
{SPACING_TYPES.map((type) => (
<SelectItem key={type.name} value={type.name}>
{type.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div>
<label className="block text-sm font-medium mb-2">Spacing Value</label>
<Select value={selectedValue} onValueChange={setSelectedValue}>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
{SPACING_VALUES.map((spacing) => (
<SelectItem key={spacing.name} value={spacing.name}>
{spacing.name} ({spacing.pixels})
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* Current Selection Info */}
<div className="p-3 bg-gray-50 dark:bg-gray-800/50 rounded-lg text-sm">
<div className="font-medium text-gray-900 dark:text-white">
{currentType?.prefix}-{selectedValue}
</div>
<div className="text-gray-600 dark:text-gray-400">
{currentSpacing?.pixels} {currentSpacing?.value}
</div>
</div>
</div>
{/* Center: Live Demo */}
<div className="flex items-center justify-center">
<div className="w-full max-w-xs">
{renderDemo()}
</div>
</div>
{/* Right: Spacing Scale */}
<div className="space-y-3">
<h4 className="text-sm font-medium text-gray-900 dark:text-white">Spacing Scale</h4>
<div className="space-y-2">
{SPACING_VALUES.map((spacing) => (
<div
key={spacing.name}
className={cn(
"flex items-center justify-between p-2 rounded cursor-pointer transition-colors",
selectedValue === spacing.name
? "bg-cyan-500/20 border border-cyan-500"
: "hover:bg-gray-100 dark:hover:bg-gray-800"
)}
onClick={() => setSelectedValue(spacing.name)}
>
<div className="flex items-center gap-2">
<div
className="bg-cyan-500 rounded"
style={{
width: Math.min(parseInt(spacing.pixels), 24) + 'px',
height: '12px'
}}
/>
<span className="text-sm font-mono">{spacing.name}</span>
</div>
<span className="text-xs text-gray-500">{spacing.pixels}</span>
</div>
))}
</div>
</div>
</div>
{/* Generated Code */}
<div className="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
<h4 className="text-sm font-medium text-gray-900 dark:text-white mb-3">Generated Code</h4>
<CodeDisplay
code={generateCode()}
showLineNumbers={false}
/>
</div>
</Card>
</div>
);
};

View File

@@ -1,169 +0,0 @@
import { useState } from 'react';
import { Card } from '@/features/ui/primitives/card';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/features/ui/primitives/select';
import { CodeDisplay } from '../shared/CodeDisplay';
import { cn } from '@/features/ui/primitives/styles';
// Typography scale
const TYPOGRAPHY_SCALE = [
{ name: 'Display', className: 'text-4xl md:text-5xl font-bold', example: 'Hero Title' },
{ name: 'H1', className: 'text-3xl font-bold', example: 'Page Title' },
{ name: 'H2', className: 'text-2xl font-bold', example: 'Section Title' },
{ name: 'H3', className: 'text-xl font-semibold', example: 'Subsection Title' },
{ name: 'H4', className: 'text-lg font-semibold', example: 'Component Header' },
{ name: 'Body Large', className: 'text-lg font-normal', example: 'Large body text for important content' },
{ name: 'Body', className: 'text-base font-normal', example: 'Standard body text for regular content' },
{ name: 'Body Small', className: 'text-sm font-normal', example: 'Small text for descriptions' },
{ name: 'Caption', className: 'text-xs font-normal', example: 'Caption and metadata text' },
{ name: 'Button', className: 'text-sm font-medium', example: 'Button Label' },
{ name: 'Code', className: 'text-sm font-mono', example: 'const variable = value;' }
];
// Color variations
const TEXT_COLORS = [
{ name: 'Primary', className: 'text-gray-900 dark:text-gray-100' },
{ name: 'Secondary', className: 'text-gray-700 dark:text-gray-300' },
{ name: 'Muted', className: 'text-gray-500 dark:text-gray-400' },
{ name: 'Accent', className: 'text-cyan-500' },
{ name: 'Success', className: 'text-emerald-500' },
{ name: 'Warning', className: 'text-orange-500' },
{ name: 'Error', className: 'text-red-500' }
];
export const TypographyFoundation = () => {
const [selectedColor, setSelectedColor] = useState('Primary');
const [selectedType, setSelectedType] = useState('H1');
const currentColorClass = TEXT_COLORS.find(color => color.name === selectedColor)?.className || 'text-gray-900 dark:text-gray-100';
const generateCode = () => {
const selectedTypeData = TYPOGRAPHY_SCALE.find(type => type.name === selectedType);
const selectedColorData = TEXT_COLORS.find(color => color.name === selectedColor);
if (!selectedTypeData || !selectedColorData) return '';
const className = selectedColorData.name === 'Primary'
? selectedTypeData.className
: `${selectedTypeData.className} ${selectedColorData.className}`;
return `// ${selectedTypeData.name} with ${selectedColorData.name} color
<${selectedType.toLowerCase().startsWith('h') ? selectedType.toLowerCase() : 'p'} className="${className}">
${selectedTypeData.example}
</${selectedType.toLowerCase().startsWith('h') ? selectedType.toLowerCase() : 'p'}>`;
};
return (
<div className="space-y-8">
{/* Header */}
<div className="text-center">
<h2 className="text-3xl font-bold text-gray-900 dark:text-white mb-4">Typography System</h2>
<p className="text-gray-600 dark:text-gray-400 text-lg">
Interactive typography configurator with live examples
</p>
</div>
{/* Typography Configurator */}
<Card className="p-8">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
{/* Left: Controls */}
<div className="space-y-4">
<h3 className="text-lg font-semibold">Typography Configurator</h3>
<div className="space-y-4">
<div>
<label className="block text-sm font-medium mb-2">Typography Style</label>
<Select value={selectedType} onValueChange={setSelectedType}>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
{TYPOGRAPHY_SCALE.map((type) => (
<SelectItem key={type.name} value={type.name}>
{type.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div>
<label className="block text-sm font-medium mb-2">Text Color</label>
<Select value={selectedColor} onValueChange={setSelectedColor}>
<SelectTrigger>
<SelectValue />
</SelectTrigger>
<SelectContent>
{TEXT_COLORS.map((color) => (
<SelectItem key={color.name} value={color.name}>
{color.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
{/* Current Selection */}
<div className="p-3 bg-gray-50 dark:bg-gray-800/50 rounded-lg">
<div className="font-medium text-sm">Current Selection</div>
<div className="text-xs text-gray-600 dark:text-gray-400 mt-1">
{selectedType} {selectedColor}
</div>
<div className="text-xs font-mono text-gray-500 mt-1">
{TYPOGRAPHY_SCALE.find(t => t.name === selectedType)?.className} {selectedColor !== 'Primary' ? TEXT_COLORS.find(c => c.name === selectedColor)?.className : ''}
</div>
</div>
</div>
</div>
{/* Right: Live Examples */}
<div className="space-y-6">
<h3 className="text-lg font-semibold">Live Examples</h3>
{/* Card Example */}
<Card className="p-4">
<div className={cn(TYPOGRAPHY_SCALE.find(t => t.name === selectedType)?.className, currentColorClass)}>
Sample {selectedType} Text
</div>
<div className="text-sm text-gray-600 dark:text-gray-400 mt-2">
This is how your typography appears in a card component
</div>
</Card>
{/* Code Example */}
<Card className="p-4 bg-gray-900 dark:bg-gray-950">
<div className="text-green-400 text-xs font-mono mb-1">// Code example</div>
<div className={cn(TYPOGRAPHY_SCALE.find(t => t.name === selectedType)?.className, currentColorClass, 'font-mono')}>
function example() {'{'}
</div>
<div className="text-gray-400 text-sm font-mono ml-4">
console.log('Typography in code context');
</div>
<div className={cn(TYPOGRAPHY_SCALE.find(t => t.name === selectedType)?.className, currentColorClass, 'font-mono')}>
{'}'}
</div>
</Card>
{/* Section Example */}
<div className="space-y-2">
<div className={cn(TYPOGRAPHY_SCALE.find(t => t.name === selectedType)?.className, currentColorClass)}>
Section Header Example
</div>
<div className="text-sm text-gray-600 dark:text-gray-400">
This demonstrates how the typography works as section headers with descriptions below.
</div>
</div>
</div>
</div>
{/* Generated Code */}
<div className="mt-8 pt-6 border-t border-gray-200 dark:border-gray-700">
<h4 className="text-sm font-medium text-gray-900 dark:text-white mb-3">Generated Code</h4>
<CodeDisplay
code={generateCode()}
showLineNumbers={false}
/>
</div>
</Card>
</div>
);
};

View File

@@ -3,4 +3,3 @@ export { PillNavigation } from "./shared/PillNavigation";
export { SideNavigation } from "./shared/SideNavigation"; export { SideNavigation } from "./shared/SideNavigation";
export { StyleGuideTab } from "./tabs/StyleGuideTab"; export { StyleGuideTab } from "./tabs/StyleGuideTab";
export { LayoutsTab } from "./tabs/LayoutsTab"; export { LayoutsTab } from "./tabs/LayoutsTab";
export { ConfiguratorsTab } from "./tabs/ConfiguratorsTab";

View File

@@ -1,106 +0,0 @@
import { useState } from 'react';
import { Check, Copy } from 'lucide-react';
import { Button } from '@/features/ui/primitives/button';
import { cn } from '@/features/ui/primitives/styles';
interface CodeDisplayProps {
code: string;
showLineNumbers?: boolean;
className?: string;
}
export const CodeDisplay = ({
code,
showLineNumbers = false,
className
}: CodeDisplayProps) => {
const [copied, setCopied] = useState(false);
const handleCopy = async () => {
await navigator.clipboard.writeText(code);
setCopied(true);
setTimeout(() => setCopied(false), 2000);
};
const lines = code.split('\n');
// Basic syntax highlighting with regex
const highlightCode = (line: string) => {
// Escape HTML
line = line.replace(/&/g, '&amp;').replace(/</g, '&lt;').replace(/>/g, '&gt;');
// Keywords
line = line.replace(
/\b(import|export|from|const|let|var|function|return|if|else|interface|type|class|extends|implements)\b/g,
'<span class="text-purple-400">$1</span>'
);
// Strings
line = line.replace(
/(["'`])([^"'`]*)\1/g,
'<span class="text-green-400">$1$2$1</span>'
);
// Comments
line = line.replace(
/(\/\/.*$|\/\*.*\*\/)/g,
'<span class="text-gray-500">$1</span>'
);
// JSX tags
line = line.replace(
/&lt;([A-Z][A-Za-z0-9]*)(\s|&gt;|\/&gt;)/g,
'&lt;<span class="text-cyan-400">$1</span>$2'
);
// Props
line = line.replace(
/(\w+)=/g,
'<span class="text-orange-400">$1</span>='
);
return line;
};
return (
<div className={cn(
"relative rounded-lg overflow-hidden",
"bg-gray-900 border border-gray-800",
className
)}>
{/* Copy Button */}
<Button
size="icon"
variant="ghost"
onClick={handleCopy}
className="absolute top-2 right-2 z-10 text-gray-400 hover:text-white"
>
{copied ? (
<Check className="w-4 h-4 text-green-400" />
) : (
<Copy className="w-4 h-4" />
)}
</Button>
{/* Code Content */}
<pre className="p-4 overflow-x-auto">
<code className="text-sm font-mono">
{lines.map((line, index) => (
<div key={index} className="flex">
{showLineNumbers && (
<span className="text-gray-500 mr-4 select-none w-8 text-right">
{index + 1}
</span>
)}
<span
dangerouslySetInnerHTML={{
__html: highlightCode(line) || '&nbsp;'
}}
/>
</div>
))}
</code>
</pre>
</div>
);
};

View File

@@ -1,15 +0,0 @@
import { Card } from '@/features/ui/primitives/card';
import { cn } from '@/features/ui/primitives/styles';
interface ConfigPanelProps {
title?: string;
children: React.ReactNode;
className?: string;
}
export const ConfigPanel = ({ title, children, className }: ConfigPanelProps) => (
<Card blur="lg" className={cn("space-y-4", className)}>
{title && <h3 className="font-semibold text-lg mb-2 text-gray-900 dark:text-white">{title}</h3>}
{children}
</Card>
);

View File

@@ -1,17 +0,0 @@
import { Label } from '@/features/ui/primitives/label';
import { cn } from '@/features/ui/primitives/styles';
interface ConfigRowProps {
label: string;
children: React.ReactNode;
className?: string;
}
export const ConfigRow = ({ label, children, className }: ConfigRowProps) => (
<div className={cn("flex items-center justify-between", className)}>
<Label className="text-sm font-medium text-gray-700 dark:text-gray-300">{label}</Label>
<div className="flex-shrink-0">
{children}
</div>
</div>
);

View File

@@ -1,58 +0,0 @@
import React, { useState } from 'react';
import { Card } from '@/features/ui/primitives/card';
import { Button } from '@/features/ui/primitives/button';
import { Eye, Code } from 'lucide-react';
interface ConfiguratorCardProps {
title: string;
description?: string;
code: string;
children: React.ReactNode;
}
export function ConfiguratorCard({ title, description, code, children }: ConfiguratorCardProps) {
const [showCode, setShowCode] = useState(false);
return (
<Card className="p-6" glassTint="none" glowColor="none">
<div className="space-y-4">
<div className="flex items-center justify-between">
<div>
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">{title}</h3>
{description && (
<p className="text-sm text-gray-600 dark:text-gray-400 mt-1">{description}</p>
)}
</div>
<div className="flex gap-2">
<Button
variant={!showCode ? 'default' : 'outline'}
size="sm"
onClick={() => setShowCode(false)}
>
<Eye className="w-4 h-4 mr-2" />
Preview
</Button>
<Button
variant={showCode ? 'default' : 'outline'}
size="sm"
onClick={() => setShowCode(true)}
>
<Code className="w-4 h-4 mr-2" />
Code
</Button>
</div>
</div>
{showCode ? (
<div className="rounded-lg bg-gray-900 p-4 overflow-x-auto">
<pre className="text-xs text-gray-100">
<code>{code}</code>
</pre>
</div>
) : (
<div>{children}</div>
)}
</div>
</Card>
);
}

View File

@@ -1,64 +0,0 @@
import { useState } from 'react';
import { ZoomIn, ZoomOut, RotateCcw } from 'lucide-react';
import { Button } from '@/features/ui/primitives/button';
import { cn } from '@/features/ui/primitives/styles';
interface LivePreviewProps {
children: React.ReactNode;
className?: string;
minHeight?: string;
}
export const LivePreview = ({ children, className, minHeight = "400px" }: LivePreviewProps) => {
const [zoom, setZoom] = useState(100);
return (
<div className="relative rounded-lg overflow-hidden">
{/* Zoom Controls */}
<div className="absolute top-2 right-2 z-10 flex gap-1">
<Button
size="icon"
variant="outline"
onClick={() => setZoom(prev => Math.max(50, prev - 25))}
>
<ZoomOut className="w-4 h-4" />
</Button>
<Button
size="icon"
variant="outline"
onClick={() => setZoom(100)}
>
<RotateCcw className="w-4 h-4" />
</Button>
<Button
size="icon"
variant="outline"
onClick={() => setZoom(prev => Math.min(150, prev + 25))}
>
<ZoomIn className="w-4 h-4" />
</Button>
</div>
{/* Grid Background */}
<div
className={cn(
"bg-gray-50 dark:bg-gray-900/50",
"bg-[linear-gradient(to_right,#8882_1px,transparent_1px),linear-gradient(to_bottom,#8882_1px,transparent_1px)]",
"bg-[size:20px_20px]",
"p-8 flex items-center justify-center",
className
)}
style={{ minHeight }}
>
<div
style={{
transform: `scale(${zoom / 100})`,
transformOrigin: 'center'
}}
>
{children}
</div>
</div>
</div>
);
};

View File

@@ -1,91 +0,0 @@
import { useState } from 'react';
import { ChevronRight, ChevronDown } from 'lucide-react';
import { cn } from '@/features/ui/primitives/styles';
interface NavigationSection {
label: string;
items: string[];
}
interface NavigationSidebarProps {
sections: NavigationSection[];
selectedItem: string;
onItemSelect: (item: string) => void;
}
// Default navigation structure for style guide
// This can be used when creating a NavigationSidebar instanc
export const NavigationSidebar: React.FC<NavigationSidebarProps> = ({
sections,
selectedItem,
onItemSelect
}) => {
const [expandedSections, setExpandedSections] = useState<string[]>(
sections.map(s => s.label)
);
const toggleSection = (label: string) => {
setExpandedSections(prev =>
prev.includes(label)
? prev.filter(l => l !== label)
: [...prev, label]
);
};
return (
<aside className="w-64 p-4">
<div className="space-y-2">
{sections.map((section) => {
const isExpanded = expandedSections.includes(section.label);
return (
<div key={section.label}>
<button
onClick={() => toggleSection(section.label)}
className={cn(
"flex items-center justify-between w-full px-3 py-2 text-left",
"rounded-md hover:bg-white/10 dark:hover:bg-white/5",
"text-sm font-medium text-gray-700 dark:text-gray-300",
"transition-colors"
)}
>
{section.label}
{isExpanded ? (
<ChevronDown className="w-4 h-4" />
) : (
<ChevronRight className="w-4 h-4" />
)}
</button>
{isExpanded && (
<div className="ml-2 mt-1 space-y-1">
{section.items.map((item) => {
const isSelected = selectedItem === item;
return (
<button
key={item}
onClick={() => onItemSelect(item)}
className={cn(
"block w-full px-3 py-1.5 text-left rounded-md",
"text-sm text-gray-600 dark:text-gray-400",
"transition-colors",
isSelected
? "bg-cyan-500/20 text-cyan-700 dark:text-cyan-300"
: "hover:bg-white/10 dark:hover:bg-white/5"
)}
>
{item}
</button>
);
})}
</div>
)}
</div>
);
})}
</div>
</aside>
);
};

View File

@@ -1,172 +0,0 @@
import { useState } from "react";
import {
Type,
Sparkles,
CreditCard,
MousePointer,
Navigation as NavIcon,
Square,
FormInput,
Table as TableIcon,
ToggleLeft,
Power,
CheckSquare,
} from "lucide-react";
import { SideNavigation, type SideNavigationSection } from "../shared/SideNavigation";
import { TypographyFoundation } from "../foundations/TypographyFoundation";
import { EffectsFoundation } from "../foundations/EffectsFoundation";
import { GlassCardConfigurator } from "../configurators/GlassCardConfigurator";
import { ButtonConfigurator } from "../configurators/ButtonConfigurator";
import { NavigationPattern } from "../configurators/NavigationConfigurator";
import { ModalConfigurator } from "../configurators/ModalConfigurator";
import { FormConfigurator } from "../configurators/FormConfigurator";
import { TableConfigurator } from "../configurators/TableConfigurator";
import { ToggleConfigurator } from "../configurators/ToggleConfigurator";
import { SwitchConfigurator } from "../configurators/SwitchConfigurator";
import { CheckboxConfigurator } from "../configurators/CheckboxConfigurator";
export const ConfiguratorsTab = () => {
const [activeSection, setActiveSection] = useState("typography");
const sections: SideNavigationSection[] = [
{ id: "typography", label: "Typography", icon: <Type className="w-3 h-3" /> },
{ id: "effects", label: "Effects", icon: <Sparkles className="w-3 h-3" /> },
{ id: "glass-card", label: "Glass Card", icon: <CreditCard className="w-3 h-3" /> },
{ id: "button", label: "Button", icon: <MousePointer className="w-3 h-3" /> },
{ id: "navigation", label: "Navigation", icon: <NavIcon className="w-3 h-3" /> },
{ id: "modal", label: "Modal", icon: <Square className="w-3 h-3" /> },
{ id: "form", label: "Form", icon: <FormInput className="w-3 h-3" /> },
{ id: "table", label: "Table", icon: <TableIcon className="w-3 h-3" /> },
{ id: "toggle", label: "Toggle", icon: <ToggleLeft className="w-3 h-3" /> },
{ id: "switch", label: "Switch", icon: <Power className="w-3 h-3" /> },
{ id: "checkbox", label: "Checkbox", icon: <CheckSquare className="w-3 h-3" /> },
];
// Render content based on active section
const renderContent = () => {
switch (activeSection) {
case "typography":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Typography Configurator
</h2>
<TypographyFoundation />
</div>
);
case "effects":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Effects Configurator
</h2>
<EffectsFoundation />
</div>
);
case "glass-card":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Glass Card Configurator
</h2>
<GlassCardConfigurator />
</div>
);
case "button":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Button Configurator
</h2>
<ButtonConfigurator />
</div>
);
case "navigation":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Navigation Configurator
</h2>
<NavigationPattern />
</div>
);
case "modal":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Modal Configurator
</h2>
<ModalConfigurator />
</div>
);
case "form":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Form Configurator
</h2>
<FormConfigurator />
</div>
);
case "table":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Table Configurator
</h2>
<TableConfigurator />
</div>
);
case "toggle":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Toggle Configurator
</h2>
<ToggleConfigurator />
</div>
);
case "switch":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Switch Configurator
</h2>
<SwitchConfigurator />
</div>
);
case "checkbox":
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Checkbox Configurator
</h2>
<CheckboxConfigurator />
</div>
);
default:
return (
<div>
<h2 className="text-2xl font-bold mb-4 text-gray-900 dark:text-white">
Glass Card Configurator
</h2>
<GlassCardConfigurator />
</div>
);
}
};
return (
<div className="flex gap-6">
{/* Side Navigation */}
<SideNavigation
sections={sections}
activeSection={activeSection}
onSectionClick={setActiveSection}
/>
{/* Main Content */}
<div className="flex-1 max-w-5xl">{renderContent()}</div>
</div>
);
};