Making the style guide a feature to turn on and off.

This commit is contained in:
sean-eskerium
2025-09-22 12:51:44 -04:00
parent f188d3a27a
commit 2150076f14
43 changed files with 2466 additions and 282 deletions

View File

@@ -0,0 +1,351 @@
# PRP: Complete Style Guide Implementation
## Feature Goal
Complete the Archon style guide implementation with fully functional glassmorphism components, properly styled Radix UI toggles with size variants, example components replicating RAG settings, and improved layout patterns with proper sidebar switching behavior.
## Deliverable
A comprehensive style guide page at `/style-guide` route with:
- Fully styled Radix UI Switch components (small, medium, large sizes with icon support)
- Checkbox and Select components with neon glow effects matching RAG settings
- Working layout switcher for sidebar patterns (1/4 sidebar, 3/4 content)
- Complete page examples replacing "coming soon" placeholders
- Consistent application of glassmorphism styles across all components
## Success Definition
- [ ] All Radix UI primitives properly styled with glassmorphism effects
- [ ] Switch component has small, medium, large variants with optional icons
- [ ] RAG-style settings examples fully functional with checkboxes and selects
- [ ] Layout switcher properly adjusts content area proportions
- [ ] No "coming soon" sections - all examples implemented
- [ ] Consistent neon glow effects across all interactive elements
- [ ] All generated code includes proper AI context comments
## Context
```yaml
existing_files:
style_implementation:
- path: archon-ui-main/src/pages/StyleGuidePage.tsx
purpose: Main style guide page entry point
- path: archon-ui-main/src/components/style-guide/StyleGuideView.tsx
purpose: Style guide view component with navigation
- path: archon-ui-main/src/features/ui/primitives/styles.ts
purpose: Glassmorphism styles and utilities
existing_components:
- path: archon-ui-main/src/components/ui/Toggle.tsx
purpose: Current toggle implementation to replace
- path: archon-ui-main/src/styles/toggle.css
purpose: CSS-based toggle styles to migrate
- path: archon-ui-main/src/components/settings/FeaturesSection.tsx
purpose: Feature toggles using current Toggle component
- path: archon-ui-main/src/components/settings/RAGSettings.tsx
purpose: RAG settings with checkboxes and selects to replicate
layout_patterns:
- path: archon-ui-main/src/components/style-guide/patterns/LayoutsPattern.tsx
purpose: Layout patterns including sidebar switcher
issue: Sidebar should be 1/4 width, main content 3/4 when in sidebar mode
placeholder_sections:
- path: archon-ui-main/src/components/style-guide/examples/PagesExample.tsx
purpose: Currently shows "coming soon" - needs implementation
- path: archon-ui-main/src/components/style-guide/examples/CompositionsExample.tsx
purpose: Has examples but could be expanded
key_requirements:
switch_component:
- Create new Radix UI Switch primitive at /features/ui/primitives/switch.tsx
- Small size: 16px height, no icons
- Medium size: 24px height, smaller icons
- Large size: 32px height, full icons (like current feature toggles)
- Support neon glow effects while maintaining accessibility
- Icons should be inside the thumb element
checkbox_component:
- Create Radix UI Checkbox primitive at /features/ui/primitives/checkbox.tsx
- Style with neon colors matching priority colors in styles.ts
- Include check animation and glow effects
- Support indeterminate state
select_component:
- Ensure Select primitive has glassmorphism styling
- Add neon border highlights on focus
- Dropdown should have glass effect backdrop
rag_settings_example:
- Replicate the model selection dropdown
- Replicate the styled checkboxes with labels
- Use new primitives not old components
- Include neon glow effects on all interactive elements
layout_improvements:
- Fix sidebar layout to use proper proportions (1/4 sidebar, 3/4 content)
- Ensure smooth transitions when switching positions
- Top position should show cards in grid
- Left position should show list with proper width constraints
technical_details:
radix_packages_needed:
- "@radix-ui/react-switch" (for Switch primitive)
- "@radix-ui/react-checkbox" (for Checkbox primitive)
- "@radix-ui/react-select" (already installed)
- "@radix-ui/react-label" (for form labels)
style_patterns:
- Use data-[state=checked] for checked states
- Use data-[state=unchecked] for unchecked states
- Use data-[highlighted] for hover states
- Apply transitions with duration-300 for smooth animations
- Use shadow-[0_0_Xpx_rgba()] for glow effects
icon_integration:
- Small switch: No icons
- Medium switch: Icons at 12x12px (h-3 w-3)
- Large switch: Icons at 20x20px (h-5 w-5)
- Use Lucide React icons consistently
gotchas:
- Current Toggle component uses CSS file - need to migrate to Tailwind
- Feature toggles in settings must continue working after migration
- Radix Switch thumb translation must match container width
- Checkbox indicator needs proper centering
- Select dropdown positioning can be tricky with glass effects
- Layout proportions must be exact (25% / 75% split)
```
## Implementation Tasks
### Phase 1: Create Missing Radix Primitives
1. **Create Switch Primitive** `/features/ui/primitives/switch.tsx`
- Import and wrap Radix UI Switch components
- Implement size variants (sm, md, lg) with proper dimensions
- Add icon support for md and lg sizes
- Apply glassmorphism styles and neon glow effects
- Support all accent colors from styles.ts
2. **Create Checkbox Primitive** `/features/ui/primitives/checkbox.tsx`
- Import and wrap Radix UI Checkbox components
- Style indicator with check icon and animations
- Add neon glow effects matching color variants
- Support checked, unchecked, and indeterminate states
3. **Create Label Primitive** `/features/ui/primitives/label.tsx`
- Import and wrap Radix UI Label
- Apply consistent text styling
- Support disabled states
### Phase 2: Update Existing Components
4. **Enhance Select Primitive** `/features/ui/primitives/select.tsx`
- Add glassmorphism to dropdown content
- Apply neon border effects on focus
- Ensure proper backdrop blur on dropdown
5. **Update Card Primitive** (if needed)
- Ensure size props work correctly
- Verify edge glow positions
- Check all color variants
### Phase 3: Create Style Guide Components
6. **Create Switch Configurator** `/components/style-guide/configurators/SwitchConfigurator.tsx`
- Configuration for all three sizes
- Icon selection (on/off icons)
- Color variant selection
- Glow effect toggle
- Generate code with AI context comments
7. **Create Checkbox Configurator** `/components/style-guide/configurators/CheckboxConfigurator.tsx`
- Color variant selection
- State configuration (checked/indeterminate/unchecked)
- Label positioning options
- Generate appropriate code
8. **Create RAG Settings Example** `/components/style-guide/examples/RAGSettingsExample.tsx`
- Model selection dropdown with glass effect
- Styled checkboxes for feature toggles
- Number inputs with glass styling
- Replicate layout from actual RAG settings
### Phase 4: Fix Layout Patterns
9. **Update Sidebar Layout** in `/components/style-guide/patterns/LayoutsPattern.tsx`
- Fix proportions: sidebar 1/4 (w-1/4), content 3/4 (w-3/4)
- Ensure proper responsive behavior
- Add smooth transitions between positions
- Update code generation to reflect correct proportions
### Phase 5: Complete Page Examples
10. **Implement Landing Page Example** in `/components/style-guide/examples/PagesExample.tsx`
- Hero section with glass effects
- Feature cards with neon glows
- Call-to-action buttons
- Proper responsive layout
11. **Implement Dashboard Page Example**
- Navigation with glass effect
- Stats cards with different glow colors
- Data visualization placeholders
- Sidebar navigation pattern
12. **Implement Settings Page Example**
- Form layout with new primitives
- Grouped settings sections
- Toggle switches for features
- Save/cancel actions
### Phase 6: Migration and Integration
13. **Migrate Feature Toggles** in `/components/settings/FeaturesSection.tsx`
- Replace Toggle component with new Switch primitive
- Maintain all existing functionality
- Update icon placement and sizing
- Test all color variants
14. **Update Imports** across codebase
- Find all Toggle imports and replace with Switch
- Update any component using old checkbox styles
- Ensure consistent primitive usage
15. **Remove Legacy Code**
- Delete old `/components/ui/Toggle.tsx`
- Remove `/styles/toggle.css`
- Clean up any unused style utilities
## Validation Gates
```bash
# TypeScript compilation
cd archon-ui-main
npx tsc --noEmit
# Linting
npm run lint
npm run biome:fix
# Development server
npm run dev
# Navigate to http://localhost:3737/style-guide
# Manual testing checklist:
# - [ ] All switch sizes render correctly
# - [ ] Icons appear in medium and large switches
# - [ ] Checkboxes have neon glow on check
# - [ ] Select dropdowns have glass effect
# - [ ] RAG settings example matches original
# - [ ] Sidebar layout uses 1/4 - 3/4 proportions
# - [ ] Page examples are fully implemented
# - [ ] Code generation includes AI comments
# - [ ] All color variants work
# - [ ] Feature toggles in settings still work
```
## Dependencies
### NPM Packages (verify installation)
```json
{
"@radix-ui/react-switch": "^1.0.3",
"@radix-ui/react-checkbox": "^1.0.4",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-select": "^2.0.0"
}
```
### External Documentation
- Radix UI Switch: https://www.radix-ui.com/primitives/docs/components/switch
- Radix UI Checkbox: https://www.radix-ui.com/primitives/docs/components/checkbox
- Radix UI Select: https://www.radix-ui.com/primitives/docs/components/select
- Radix UI Styling Guide: https://www.radix-ui.com/primitives/docs/guides/styling
- Tailwind CSS Radix Plugin: https://github.com/ecklf/tailwindcss-radix
## Code Patterns to Follow
### Switch Implementation Pattern
```typescript
// Size variants object
const switchVariants = {
size: {
sm: { root: "h-4 w-8", thumb: "h-3 w-3 data-[state=checked]:translate-x-4" },
md: { root: "h-6 w-11", thumb: "h-5 w-5 data-[state=checked]:translate-x-5" },
lg: { root: "h-8 w-14", thumb: "h-7 w-7 data-[state=checked]:translate-x-6" }
}
};
// Glow effects using shadow
"data-[state=checked]:shadow-[0_0_20px_rgba(34,211,238,0.5)]"
```
### Checkbox Pattern
```typescript
// Checkbox with indicator
<Checkbox.Root className="glassmorphism">
<Checkbox.Indicator>
<Check className="h-4 w-4" />
</Checkbox.Indicator>
</Checkbox.Root>
```
### Layout Proportions
```typescript
// Correct sidebar layout
<div className="flex">
<div className="w-1/4">Sidebar</div>
<div className="w-3/4">Main Content</div>
</div>
```
## Success Criteria
- **Component Completeness**: All primitives created and working
- **Style Consistency**: Glassmorphism applied uniformly
- **Size Variants**: Switch has functional sm/md/lg sizes
- **Icon Support**: Icons render correctly in switches
- **Glow Effects**: Neon glows on all interactive elements
- **Layout Accuracy**: Sidebar uses exact 25%/75% split
- **Example Quality**: RAG settings replicated accurately
- **Page Examples**: No "coming soon" placeholders remain
- **Code Generation**: All configurators generate working code
- **AI Comments**: Generated code includes decision trees
- **Migration Success**: Feature toggles work with new Switch
- **Performance**: Smooth animations and transitions
- **Accessibility**: Focus states and keyboard navigation work
## Reference Implementation Locations
- Glass styles: `/archon-ui-main/src/features/ui/primitives/styles.ts`
- Current Toggle: `/archon-ui-main/src/components/ui/Toggle.tsx`
- RAG Settings: `/archon-ui-main/src/components/settings/RAGSettings.tsx:lines 400-500`
- Feature Toggles: `/archon-ui-main/src/components/settings/FeaturesSection.tsx:lines 200-316`
- Layout Pattern: `/archon-ui-main/src/components/style-guide/patterns/LayoutsPattern.tsx:lines 95-194`
## Testing Focus Areas
1. **Switch Component**
- Size transitions are smooth
- Icons scale appropriately
- Glow effects visible in dark mode
- Keyboard navigation works
2. **Checkbox Component**
- Check animation is smooth
- Indeterminate state renders
- Click target is adequate
3. **Select Component**
- Dropdown positioning correct
- Glass effect on dropdown
- Keyboard navigation works
4. **Layout Switcher**
- Proportions are exactly 25%/75%
- Transition animations smooth
- Content reflows properly
5. **Migration**
- All feature toggles functional
- No console errors
- Performance not degraded

View File

@@ -10,6 +10,7 @@
"dependencies": {
"@mdxeditor/editor": "^3.42.0",
"@radix-ui/react-alert-dialog": "^1.1.15",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",
@@ -2518,6 +2519,36 @@
}
}
},
"node_modules/@radix-ui/react-checkbox": {
"version": "1.3.3",
"resolved": "https://registry.npmjs.org/@radix-ui/react-checkbox/-/react-checkbox-1.3.3.tgz",
"integrity": "sha512-wBbpv+NQftHDdG86Qc0pIyXk5IR3tM8Vd0nWLKDcX8nNn4nXFOFwsKuqw2okA/1D/mpaAkmuyndrPJTYDNZtFw==",
"license": "MIT",
"dependencies": {
"@radix-ui/primitive": "1.1.3",
"@radix-ui/react-compose-refs": "1.1.2",
"@radix-ui/react-context": "1.1.2",
"@radix-ui/react-presence": "1.1.5",
"@radix-ui/react-primitive": "2.1.3",
"@radix-ui/react-use-controllable-state": "1.2.2",
"@radix-ui/react-use-previous": "1.1.1",
"@radix-ui/react-use-size": "1.1.1"
},
"peerDependencies": {
"@types/react": "*",
"@types/react-dom": "*",
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
},
"peerDependenciesMeta": {
"@types/react": {
"optional": true
},
"@types/react-dom": {
"optional": true
}
}
},
"node_modules/@radix-ui/react-collection": {
"version": "1.1.7",
"resolved": "https://registry.npmjs.org/@radix-ui/react-collection/-/react-collection-1.1.7.tgz",

View File

@@ -30,6 +30,7 @@
"dependencies": {
"@mdxeditor/editor": "^3.42.0",
"@radix-ui/react-alert-dialog": "^1.1.15",
"@radix-ui/react-checkbox": "^1.3.3",
"@radix-ui/react-dialog": "^1.1.15",
"@radix-ui/react-dropdown-menu": "^2.1.16",
"@radix-ui/react-label": "^2.1.7",

View File

@@ -22,15 +22,19 @@ import { useMigrationStatus } from './hooks/useMigrationStatus';
const AppRoutes = () => {
const { projectsEnabled } = useSettings();
const { projectsEnabled, styleGuideEnabled } = useSettings();
return (
<Routes>
<Route path="/" element={<KnowledgeBasePage />} />
<Route path="/onboarding" element={<OnboardingPage />} />
<Route path="/settings" element={<SettingsPage />} />
<Route path="/mcp" element={<MCPPage />} />
<Route path="/style-guide" element={<StyleGuidePage />} />
{styleGuideEnabled ? (
<Route path="/style-guide" element={<StyleGuidePage />} />
) : (
<Route path="/style-guide" element={<Navigate to="/" replace />} />
)}
{projectsEnabled ? (
<>
<Route path="/projects" element={<ProjectPage />} />

View File

@@ -24,7 +24,7 @@ interface NavigationProps {
*/
export function Navigation({ className }: NavigationProps) {
const location = useLocation();
const { projectsEnabled } = useSettings();
const { projectsEnabled, styleGuideEnabled } = useSettings();
// Navigation items configuration
const navigationItems: NavigationItem[] = [
@@ -58,7 +58,7 @@ export function Navigation({ className }: NavigationProps) {
path: "/style-guide",
icon: <Palette className="h-5 w-5" />,
label: "Style Guide",
enabled: true,
enabled: styleGuideEnabled,
},
{
path: "/settings",
@@ -68,6 +68,9 @@ export function Navigation({ className }: NavigationProps) {
},
];
// Filter out disabled navigation items
const enabledNavigationItems = navigationItems.filter(item => item.enabled);
const isProjectsActive = location.pathname.startsWith("/projects");
return (
@@ -131,15 +134,14 @@ export function Navigation({ className }: NavigationProps) {
{/* Navigation Items */}
<nav className="flex flex-col gap-4">
{navigationItems.map((item) => {
{enabledNavigationItems.map((item) => {
const isActive = location.pathname === item.path;
const isEnabled = item.enabled !== false;
return (
<Tooltip key={item.path}>
<TooltipTrigger asChild>
<Link
to={isEnabled ? item.path : "#"}
to={item.path}
className={cn(
"relative p-3 rounded-lg transition-all duration-300",
"flex items-center justify-center",
@@ -154,13 +156,7 @@ export function Navigation({ className }: NavigationProps) {
"hover:text-blue-600 dark:hover:text-blue-400",
"hover:bg-white/10 dark:hover:bg-white/5",
],
!isEnabled && "opacity-50 cursor-not-allowed pointer-events-none",
)}
onClick={(e) => {
if (!isEnabled) {
e.preventDefault();
}
}}
>
{item.icon}
{/* Active state decorations with neon line */}

View File

@@ -1,11 +1,12 @@
import React, { useState, useEffect } from 'react';
import { Moon, Sun, FileText, Layout, Bot, Settings, Palette, Flame, Monitor } from 'lucide-react';
import { Toggle } from '../ui/Toggle';
import { Switch } from '@/features/ui/primitives/switch';
import { Card } from '../ui/Card';
import { useTheme } from '../../contexts/ThemeContext';
import { credentialsService } from '../../services/credentialsService';
import { useToast } from '../../features/ui/hooks/useToast';
import { serverHealthService } from '../../services/serverHealthService';
import { useSettings } from '../../contexts/SettingsContext';
export const FeaturesSection = () => {
const {
@@ -13,24 +14,30 @@ export const FeaturesSection = () => {
setTheme
} = useTheme();
const { showToast } = useToast();
const { styleGuideEnabled, setStyleGuideEnabled: setStyleGuideContext } = useSettings();
const isDarkMode = theme === 'dark';
const [projectsEnabled, setProjectsEnabled] = useState(true);
const [styleGuideEnabledLocal, setStyleGuideEnabledLocal] = useState(styleGuideEnabled);
// Commented out for future release
const [agUILibraryEnabled, setAgUILibraryEnabled] = useState(false);
const [agentsEnabled, setAgentsEnabled] = useState(false);
const [logfireEnabled, setLogfireEnabled] = useState(false);
const [disconnectScreenEnabled, setDisconnectScreenEnabled] = useState(true);
const [loading, setLoading] = useState(true);
const [projectsSchemaValid, setProjectsSchemaValid] = useState(true);
const [projectsSchemaError, setProjectsSchemaError] = useState<string | null>(null);
// Load settings on mount
// Load settings on mount and sync with context
useEffect(() => {
loadSettings();
}, []);
useEffect(() => {
setStyleGuideEnabledLocal(styleGuideEnabled);
}, [styleGuideEnabled]);
const loadSettings = async () => {
try {
setLoading(true);
@@ -174,7 +181,7 @@ export const FeaturesSection = () => {
const handleDisconnectScreenToggle = async (checked: boolean) => {
if (loading) return;
try {
setLoading(true);
setDisconnectScreenEnabled(checked);
@@ -182,7 +189,7 @@ export const FeaturesSection = () => {
await serverHealthService.updateSettings(checked);
showToast(
checked ? 'Disconnect Screen Enabled' : 'Disconnect Screen Disabled',
checked ? 'Disconnect Screen Enabled' : 'Disconnect Screen Disabled',
checked ? 'success' : 'warning'
);
} catch (error) {
@@ -194,6 +201,29 @@ export const FeaturesSection = () => {
}
};
const handleStyleGuideToggle = async (checked: boolean) => {
if (loading) return;
try {
setLoading(true);
setStyleGuideEnabledLocal(checked);
// Update context which will save to backend
await setStyleGuideContext(checked);
showToast(
checked ? 'Style Guide Enabled' : 'Style Guide Disabled',
checked ? 'success' : 'warning'
);
} catch (error) {
console.error('Failed to update style guide setting:', error);
setStyleGuideEnabledLocal(!checked);
showToast('Failed to update style guide setting', 'error');
} finally {
setLoading(false);
}
};
return (
<>
<div className="grid grid-cols-2 gap-4">
@@ -208,7 +238,14 @@ export const FeaturesSection = () => {
</p>
</div>
<div className="flex-shrink-0">
<Toggle checked={isDarkMode} onCheckedChange={handleThemeToggle} accentColor="purple" icon={isDarkMode ? <Moon className="w-5 h-5" /> : <Sun className="w-5 h-5" />} />
<Switch
size="lg"
checked={isDarkMode}
onCheckedChange={handleThemeToggle}
color="purple"
iconOn={<Moon className="w-5 h-5" />}
iconOff={<Sun className="w-5 h-5" />}
/>
</div>
</div>
@@ -228,16 +265,39 @@ export const FeaturesSection = () => {
)}
</div>
<div className="flex-shrink-0">
<Toggle
checked={projectsEnabled}
onCheckedChange={handleProjectsToggle}
accentColor="blue"
<Switch
size="lg"
checked={projectsEnabled}
onCheckedChange={handleProjectsToggle}
color="blue"
icon={<FileText className="w-5 h-5" />}
disabled={loading || !projectsSchemaValid}
/>
</div>
</div>
{/* Style Guide Toggle */}
<div className="flex items-center gap-4 p-4 rounded-xl bg-gradient-to-br from-cyan-500/10 to-cyan-600/5 backdrop-blur-sm border border-cyan-500/20 shadow-lg">
<div className="flex-1 min-w-0">
<p className="font-medium text-gray-800 dark:text-white">
Style Guide
</p>
<p className="text-sm text-gray-500 dark:text-gray-400">
Show UI style guide and components in navigation
</p>
</div>
<div className="flex-shrink-0">
<Switch
size="lg"
checked={styleGuideEnabledLocal}
onCheckedChange={handleStyleGuideToggle}
color="cyan"
icon={<Palette className="w-5 h-5" />}
disabled={loading}
/>
</div>
</div>
{/* COMMENTED OUT FOR FUTURE RELEASE - AG-UI Library Toggle */}
{/*
<div className="flex items-center gap-4 p-4 rounded-xl bg-gradient-to-br from-pink-500/10 to-pink-600/5 backdrop-blur-sm border border-pink-500/20 shadow-lg">
@@ -283,10 +343,11 @@ export const FeaturesSection = () => {
</p>
</div>
<div className="flex-shrink-0">
<Toggle
checked={logfireEnabled}
onCheckedChange={handleLogfireToggle}
accentColor="orange"
<Switch
size="lg"
checked={logfireEnabled}
onCheckedChange={handleLogfireToggle}
color="orange"
icon={<Flame className="w-5 h-5" />}
disabled={loading}
/>
@@ -304,10 +365,11 @@ export const FeaturesSection = () => {
</p>
</div>
<div className="flex-shrink-0">
<Toggle
checked={disconnectScreenEnabled}
onCheckedChange={handleDisconnectScreenToggle}
accentColor="green"
<Switch
size="lg"
checked={disconnectScreenEnabled}
onCheckedChange={handleDisconnectScreenToggle}
color="green"
icon={<Monitor className="w-5 h-5" />}
disabled={loading}
/>

View File

@@ -1,94 +0,0 @@
import { Card } from '@/features/ui/primitives/card';
import { CodeDisplay } from '../shared/CodeDisplay';
export const PagesExample = () => {
const generateCode = () => {
return `/**
* 🤖 AI CONTEXT: Complete Page Examples
*
* PURPOSE: Full page layouts using Archon's design system
* WHEN TO USE: Reference for building new pages with consistent styling
* WHEN NOT TO USE: Component-level implementation
*
* PAGE TYPES:
* - Landing pages with hero sections
* - Dashboard pages with data visualization
* - Settings pages with form layouts
* - Profile pages with user information
* - Error pages with helpful messaging
*
* COMPOSITION PRINCIPLES:
* - Consistent spacing and typography
* - Proper use of glassmorphism effects
* - Responsive grid layouts
* - Accessible navigation patterns
*/
// Example: Landing Page
export const LandingPage = () => {
return (
<div className="min-h-screen bg-gradient-to-br from-gray-900 to-gray-800">
{/* Hero Section */}
<section className="py-20 text-center">
<h1 className="text-4xl md:text-6xl font-bold mb-6">
Welcome to Archon
</h1>
<p className="text-xl text-gray-400 mb-8 max-w-2xl mx-auto">
Build beautiful applications with our glassmorphism design system
</p>
<Button size="lg" glowColor="purple">
Get Started
</Button>
</section>
{/* Features Section */}
<section className="py-20">
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 max-w-6xl mx-auto">
{features.map((feature) => (
<Card key={feature.id} glowColor="cyan" className="p-8 text-center">
<feature.icon className="w-12 h-12 mx-auto mb-4" />
<h3 className="text-xl font-bold mb-4">{feature.title}</h3>
<p className="text-gray-400">{feature.description}</p>
</Card>
))}
</div>
</section>
</div>
);
};`;
};
return (
<div className="space-y-8">
<div>
<h2 className="text-2xl font-bold mb-4">Page Examples</h2>
<p className="text-gray-600 dark:text-gray-400 mb-6">
Complete page layouts demonstrating how to compose components into full user interfaces.
</p>
</div>
<Card className="p-6 max-w-none">
<h3 className="text-lg font-semibold mb-4">Coming Soon</h3>
<p className="text-gray-600 dark:text-gray-400 mb-4">
This section will include complete page examples such as:
</p>
<ul className="list-disc list-inside text-sm text-gray-600 dark:text-gray-400 space-y-1 mb-6">
<li>Landing pages with hero sections and feature grids</li>
<li>Dashboard pages with navigation and data visualization</li>
<li>Settings pages with form layouts and preferences</li>
<li>Profile pages with user information and actions</li>
<li>Error pages with helpful messaging and navigation</li>
</ul>
</Card>
<Card className="p-6 max-w-none">
<h3 className="text-lg font-semibold mb-4">Example Code Structure</h3>
<CodeDisplay
code={generateCode()}
showLineNumbers
/>
</Card>
</div>
);
};

View File

@@ -4,6 +4,8 @@ import { credentialsService } from '../services/credentialsService';
interface SettingsContextType {
projectsEnabled: boolean;
setProjectsEnabled: (enabled: boolean) => void;
styleGuideEnabled: boolean;
setStyleGuideEnabled: (enabled: boolean) => void;
loading: boolean;
refreshSettings: () => Promise<void>;
}
@@ -24,24 +26,35 @@ interface SettingsProviderProps {
export const SettingsProvider: React.FC<SettingsProviderProps> = ({ children }) => {
const [projectsEnabled, setProjectsEnabledState] = useState(true);
const [styleGuideEnabled, setStyleGuideEnabledState] = useState(false);
const [loading, setLoading] = useState(true);
const loadSettings = async () => {
try {
setLoading(true);
// Load Projects setting
const projectsResponse = await credentialsService.getCredential('PROJECTS_ENABLED').catch(() => ({ value: undefined }));
// Load Projects and Style Guide settings
const [projectsResponse, styleGuideResponse] = await Promise.all([
credentialsService.getCredential('PROJECTS_ENABLED').catch(() => ({ value: undefined })),
credentialsService.getCredential('STYLE_GUIDE_ENABLED').catch(() => ({ value: undefined }))
]);
if (projectsResponse.value !== undefined) {
setProjectsEnabledState(projectsResponse.value === 'true');
} else {
setProjectsEnabledState(true); // Default to true
}
if (styleGuideResponse.value !== undefined) {
setStyleGuideEnabledState(styleGuideResponse.value === 'true');
} else {
setStyleGuideEnabledState(false); // Default to false
}
} catch (error) {
console.error('Failed to load settings:', error);
setProjectsEnabledState(true);
setStyleGuideEnabledState(false);
} finally {
setLoading(false);
}
@@ -72,6 +85,27 @@ export const SettingsProvider: React.FC<SettingsProviderProps> = ({ children })
}
};
const setStyleGuideEnabled = async (enabled: boolean) => {
try {
// Update local state immediately
setStyleGuideEnabledState(enabled);
// Save to backend
await credentialsService.createCredential({
key: 'STYLE_GUIDE_ENABLED',
value: enabled.toString(),
is_encrypted: false,
category: 'features',
description: 'Show UI style guide and components in navigation'
});
} catch (error) {
console.error('Failed to update style guide setting:', error);
// Revert on error
setStyleGuideEnabledState(!enabled);
throw error;
}
};
const refreshSettings = async () => {
await loadSettings();
};
@@ -79,6 +113,8 @@ export const SettingsProvider: React.FC<SettingsProviderProps> = ({ children })
const value: SettingsContextType = {
projectsEnabled,
setProjectsEnabled,
styleGuideEnabled,
setStyleGuideEnabled,
loading,
refreshSettings
};

View File

@@ -1,24 +1,27 @@
import { useState } from 'react';
import { Palette, Component, Layout, Code } from 'lucide-react';
import { PillNavigation } from './shared/PillNavigation';
import { ThemeToggle } from '../ui/ThemeToggle';
import { GlassCardConfigurator } from './configurators/GlassCardConfigurator';
import { ButtonConfigurator } from './configurators/ButtonConfigurator';
import { ModalConfigurator } from './configurators/ModalConfigurator';
import { FormConfigurator } from './configurators/FormConfigurator';
import { TableConfigurator } from './configurators/TableConfigurator';
import { ToggleConfigurator } from './configurators/ToggleConfigurator';
import { ColorsFoundation } from './foundations/ColorsFoundation';
import { TypographyFoundation } from './foundations/TypographyFoundation';
import { SpacingFoundation } from './foundations/SpacingFoundation';
import { EffectsFoundation } from './foundations/EffectsFoundation';
import { LayoutsPattern } from './patterns/LayoutsPattern';
import { FeedbackPattern } from './patterns/FeedbackPattern';
import { NavigationPattern } from './patterns/NavigationPattern';
import { DataDisplayPattern } from './patterns/DataDisplayPattern';
import { CompositionsExample } from './examples/CompositionsExample';
import { PagesExample } from './examples/PagesExample';
import { WorkflowsExample } from './examples/WorkflowsExample';
import { PillNavigation } from '../shared/PillNavigation';
import { ThemeToggle } from '../../../components/ui/ThemeToggle';
import { GlassCardConfigurator } from '../configurators/GlassCardConfigurator';
import { ButtonConfigurator } from '../configurators/ButtonConfigurator';
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';
import { ColorsFoundation } from '../foundations/ColorsFoundation';
import { TypographyFoundation } from '../foundations/TypographyFoundation';
import { SpacingFoundation } from '../foundations/SpacingFoundation';
import { EffectsFoundation } from '../foundations/EffectsFoundation';
import { LayoutsPattern } from '../patterns/LayoutsPattern';
import { FeedbackPattern } from '../patterns/FeedbackPattern';
import { NavigationPattern } from '../patterns/NavigationPattern';
import { DataDisplayPattern } from '../patterns/DataDisplayPattern';
import { CompositionsExample } from '../examples/CompositionsExample';
import { PagesExample } from '../examples/PagesExample';
import { WorkflowsExample } from '../examples/WorkflowsExample';
import { RAGSettingsExample } from '../examples/RAGSettingsExample';
const FOUNDATION_TABS = [
{ id: 'Colors', label: 'Colors', component: ColorsFoundation },
@@ -34,6 +37,8 @@ const COMPONENT_TABS = [
{ id: 'Tables', label: 'Tables', component: TableConfigurator },
{ id: 'Modals', label: 'Modals', component: ModalConfigurator },
{ id: 'Toggles', label: 'Toggles', component: ToggleConfigurator },
{ id: 'Switches', label: 'Switches', component: SwitchConfigurator },
{ id: 'Checkboxes', label: 'Checkboxes', component: CheckboxConfigurator },
];
const PATTERN_TABS = [
@@ -47,6 +52,7 @@ const EXAMPLE_TABS = [
{ id: 'Compositions', label: 'Compositions', component: CompositionsExample },
{ id: 'Pages', label: 'Pages', component: PagesExample },
{ id: 'Workflows', label: 'Workflows', component: WorkflowsExample },
{ id: 'RAG Settings', label: 'RAG Settings', component: RAGSettingsExample },
];
export const StyleGuideView = () => {

View File

@@ -0,0 +1,315 @@
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

@@ -0,0 +1,319 @@
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

@@ -0,0 +1,395 @@
import React, { useState } from 'react';
import { Card } from '@/features/ui/primitives/card';
import { Button } from '@/features/ui/primitives/button';
import { Switch } from '@/features/ui/primitives/switch';
import { Input } from '@/features/ui/primitives/input';
import { Label } from '@/features/ui/primitives/label';
import { CodeDisplay } from '../shared/CodeDisplay';
import {
ArrowRight, Zap, Shield, Sparkles,
BarChart, Users, DollarSign, TrendingUp,
User, Bell, Lock, Palette, Globe, Database
} from 'lucide-react';
// Landing Page Example
const LandingPageExample = () => {
return (
<div className="relative overflow-hidden rounded-lg">
<div className="bg-gradient-to-br from-gray-900 via-purple-900/20 to-gray-900 p-8">
{/* Hero Section */}
<section className="text-center py-12">
<h1 className="text-4xl font-bold mb-4 bg-gradient-to-r from-cyan-400 to-purple-400 bg-clip-text text-transparent">
Welcome to Archon
</h1>
<p className="text-gray-400 mb-8 max-w-2xl mx-auto">
Build beautiful applications with our glassmorphism design system
</p>
<div className="flex gap-4 justify-center">
<Button size="lg" className="shadow-[0_0_20px_rgba(168,85,247,0.5)]">
Get Started <ArrowRight className="ml-2 w-4 h-4" />
</Button>
<Button variant="outline" size="lg">
Learn More
</Button>
</div>
</section>
{/* Features Grid */}
<section className="mt-12 grid grid-cols-3 gap-6">
<Card accentColor="purple" className="p-6 text-center hover:scale-105 transition-transform">
<Zap className="w-12 h-12 mx-auto mb-4 text-purple-400" />
<h3 className="font-semibold mb-2">Lightning Fast</h3>
<p className="text-sm text-gray-400">Optimized performance for modern applications</p>
</Card>
<Card accentColor="cyan" className="p-6 text-center hover:scale-105 transition-transform">
<Shield className="w-12 h-12 mx-auto mb-4 text-cyan-400" />
<h3 className="font-semibold mb-2">Secure by Default</h3>
<p className="text-sm text-gray-400">Enterprise-grade security features built-in</p>
</Card>
<Card accentColor="pink" className="p-6 text-center hover:scale-105 transition-transform">
<Sparkles className="w-12 h-12 mx-auto mb-4 text-pink-400" />
<h3 className="font-semibold mb-2">Beautiful UI</h3>
<p className="text-sm text-gray-400">Glassmorphic design that stands out</p>
</Card>
</section>
</div>
</div>
);
};
// Dashboard Page Example
const DashboardPageExample = () => {
return (
<div className="p-6 space-y-6 bg-gray-900/50 rounded-lg">
{/* Header */}
<div className="flex justify-between items-center">
<div>
<h2 className="text-2xl font-bold">Dashboard</h2>
<p className="text-sm text-gray-400">Welcome back, Admin</p>
</div>
<Button>Download Report</Button>
</div>
{/* Stats Cards */}
<div className="grid grid-cols-4 gap-4">
<Card accentColor="green" className="p-4">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-gray-400">Total Revenue</p>
<p className="text-2xl font-bold">$45,231</p>
<p className="text-xs text-green-400">+12.5% from last month</p>
</div>
<DollarSign className="w-8 h-8 text-green-400" />
</div>
</Card>
<Card accentColor="blue" className="p-4">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-gray-400">Active Users</p>
<p className="text-2xl font-bold">2,543</p>
<p className="text-xs text-blue-400">+23 new today</p>
</div>
<Users className="w-8 h-8 text-blue-400" />
</div>
</Card>
<Card accentColor="purple" className="p-4">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-gray-400">Conversion Rate</p>
<p className="text-2xl font-bold">3.2%</p>
<p className="text-xs text-purple-400">+0.5% this week</p>
</div>
<TrendingUp className="w-8 h-8 text-purple-400" />
</div>
</Card>
<Card accentColor="orange" className="p-4">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-gray-400">Active Projects</p>
<p className="text-2xl font-bold">12</p>
<p className="text-xs text-orange-400">3 pending review</p>
</div>
<BarChart className="w-8 h-8 text-orange-400" />
</div>
</Card>
</div>
{/* Main Content Grid */}
<div className="grid grid-cols-3 gap-6">
<Card className="col-span-2 p-6">
<h3 className="font-semibold mb-4">Revenue Chart</h3>
<div className="h-48 bg-gradient-to-t from-cyan-500/10 to-transparent rounded-lg flex items-end justify-around">
{[40, 65, 45, 75, 55, 85, 70].map((height, i) => (
<div
key={i}
className="w-8 bg-cyan-500/50 rounded-t"
style={{ height: `${height}%` }}
/>
))}
</div>
</Card>
<Card className="p-6">
<h3 className="font-semibold mb-4">Recent Activity</h3>
<div className="space-y-3">
<div className="flex items-center gap-3 text-sm">
<div className="w-2 h-2 bg-green-400 rounded-full" />
<span className="text-gray-400">New user registered</span>
</div>
<div className="flex items-center gap-3 text-sm">
<div className="w-2 h-2 bg-blue-400 rounded-full" />
<span className="text-gray-400">Payment received</span>
</div>
<div className="flex items-center gap-3 text-sm">
<div className="w-2 h-2 bg-purple-400 rounded-full" />
<span className="text-gray-400">Project completed</span>
</div>
</div>
</Card>
</div>
</div>
);
};
// Settings Page Example
const SettingsPageExample = () => {
const [notifications, setNotifications] = useState(true);
const [darkMode, setDarkMode] = useState(true);
const [autoSave, setAutoSave] = useState(false);
return (
<div className="max-w-2xl mx-auto p-6 space-y-6">
<h2 className="text-2xl font-bold mb-6">Settings</h2>
{/* Profile Section */}
<Card accentColor="blue" className="p-6">
<div className="flex items-center gap-2 mb-4">
<User className="w-5 h-5 text-blue-400" />
<h3 className="text-lg font-semibold">Profile</h3>
</div>
<div className="space-y-4">
<div>
<Label htmlFor="name">Display Name</Label>
<Input id="name" defaultValue="John Doe" className="mt-1" />
</div>
<div>
<Label htmlFor="email">Email</Label>
<Input id="email" type="email" defaultValue="john@example.com" className="mt-1" />
</div>
</div>
</Card>
{/* Preferences Section */}
<Card accentColor="purple" className="p-6">
<div className="flex items-center gap-2 mb-4">
<Palette className="w-5 h-5 text-purple-400" />
<h3 className="text-lg font-semibold">Preferences</h3>
</div>
<div className="space-y-4">
<div className="flex items-center justify-between">
<div>
<Label htmlFor="dark-mode">Dark Mode</Label>
<p className="text-sm text-gray-400">Use dark theme across the application</p>
</div>
<Switch
id="dark-mode"
size="lg"
color="purple"
checked={darkMode}
onCheckedChange={setDarkMode}
/>
</div>
<div className="flex items-center justify-between">
<div>
<Label htmlFor="notifications">Notifications</Label>
<p className="text-sm text-gray-400">Receive push notifications</p>
</div>
<Switch
id="notifications"
size="lg"
color="purple"
checked={notifications}
onCheckedChange={setNotifications}
iconOn={<Bell className="w-5 h-5" />}
iconOff={<Bell className="w-5 h-5" />}
/>
</div>
<div className="flex items-center justify-between">
<div>
<Label htmlFor="auto-save">Auto Save</Label>
<p className="text-sm text-gray-400">Automatically save changes</p>
</div>
<Switch
id="auto-save"
size="lg"
color="purple"
checked={autoSave}
onCheckedChange={setAutoSave}
/>
</div>
</div>
</Card>
{/* Security Section */}
<Card accentColor="green" className="p-6">
<div className="flex items-center gap-2 mb-4">
<Lock className="w-5 h-5 text-green-400" />
<h3 className="text-lg font-semibold">Security</h3>
</div>
<div className="space-y-4">
<Button variant="outline" className="w-full justify-start">
Change Password
</Button>
<Button variant="outline" className="w-full justify-start">
Two-Factor Authentication
</Button>
<Button variant="outline" className="w-full justify-start text-red-500 hover:text-red-400">
Delete Account
</Button>
</div>
</Card>
</div>
);
};
export const PagesExample = () => {
const [activeExample, setActiveExample] = useState<'landing' | 'dashboard' | 'settings'>('landing');
const generateCode = () => {
if (activeExample === 'dashboard') {
return `// Dashboard Page with Stats Cards
import { Card } from '@/features/ui/primitives/card';
import { DollarSign, Users, TrendingUp, BarChart } from 'lucide-react';
export const Dashboard = () => {
return (
<div className="p-6 space-y-6">
{/* Stats Cards */}
<div className="grid grid-cols-4 gap-4">
<Card accentColor="green" className="p-4">
<div className="flex items-center justify-between">
<div>
<p className="text-sm text-gray-400">Revenue</p>
<p className="text-2xl font-bold">$45,231</p>
</div>
<DollarSign className="w-8 h-8 text-green-400" />
</div>
</Card>
{/* More stat cards... */}
</div>
</div>
);
};`;
} else if (activeExample === 'settings') {
return `// Settings Page with Form Sections
import { Card } from '@/features/ui/primitives/card';
import { Switch } from '@/features/ui/primitives/switch';
import { Input } from '@/features/ui/primitives/input';
export const Settings = () => {
const [darkMode, setDarkMode] = useState(true);
return (
<div className="max-w-2xl mx-auto p-6 space-y-6">
<Card accentColor="purple" className="p-6">
<h3 className="text-lg font-semibold mb-4">Preferences</h3>
<div className="flex items-center justify-between">
<Label htmlFor="dark-mode">Dark Mode</Label>
<Switch
id="dark-mode"
size="lg"
color="purple"
checked={darkMode}
onCheckedChange={setDarkMode}
/>
</div>
</Card>
</div>
);
};`;
}
return `// Landing Page with Hero Section
import { Card } from '@/features/ui/primitives/card';
import { Button } from '@/features/ui/primitives/button';
import { ArrowRight, Zap, Shield, Sparkles } from 'lucide-react';
export const LandingPage = () => {
return (
<div className="bg-gradient-to-br from-gray-900 to-purple-900/20">
{/* Hero Section */}
<section className="text-center py-12">
<h1 className="text-4xl font-bold mb-4 bg-gradient-to-r from-cyan-400 to-purple-400 bg-clip-text text-transparent">
Welcome to Archon
</h1>
<Button size="lg">
Get Started <ArrowRight className="ml-2 w-4 h-4" />
</Button>
</section>
{/* Features Grid */}
<section className="grid grid-cols-3 gap-6">
<Card accentColor="purple" className="p-6 text-center">
<Zap className="w-12 h-12 mx-auto mb-4 text-purple-400" />
<h3 className="font-semibold">Lightning Fast</h3>
</Card>
{/* More feature cards... */}
</section>
</div>
);
};`;
};
return (
<div className="space-y-8">
<div>
<h2 className="text-2xl font-bold mb-4">Page Examples</h2>
<p className="text-gray-600 dark:text-gray-400 mb-6">
Complete page layouts demonstrating how to compose components into full user interfaces.
</p>
</div>
{/* Example Selector */}
<div className="flex gap-2 mb-6">
<Button
variant={activeExample === 'landing' ? 'primary' : 'outline'}
size="sm"
onClick={() => setActiveExample('landing')}
>
Landing Page
</Button>
<Button
variant={activeExample === 'dashboard' ? 'primary' : 'outline'}
size="sm"
onClick={() => setActiveExample('dashboard')}
>
Dashboard
</Button>
<Button
variant={activeExample === 'settings' ? 'primary' : 'outline'}
size="sm"
onClick={() => setActiveExample('settings')}
>
Settings
</Button>
</div>
{/* Live Example */}
<Card className="p-0 overflow-hidden">
<div className="max-h-96 overflow-auto">
{activeExample === 'landing' && <LandingPageExample />}
{activeExample === 'dashboard' && <DashboardPageExample />}
{activeExample === 'settings' && <SettingsPageExample />}
</div>
</Card>
{/* Code Example */}
<Card className="p-6 max-w-none">
<h3 className="text-lg font-semibold mb-4">Implementation Code</h3>
<CodeDisplay
code={generateCode()}
showLineNumbers
/>
</Card>
</div>
);
};

View File

@@ -0,0 +1,369 @@
import { useState } from "react";
import { Card } from "../../../features/ui/primitives/card";
import { Switch } from "../../../features/ui/primitives/switch";
import { Checkbox } from "../../../features/ui/primitives/checkbox";
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue
} from "../../../features/ui/primitives/select";
import { Label } from "../../../features/ui/primitives/label";
import { Input } from "../../../features/ui/primitives/input";
import { Brain, Cpu, Zap, Database, Search, FileText } from "lucide-react";
/**
* 🤖 AI CONTEXT: RAG Settings Example
*
* DESIGN PRINCIPLES:
* 1. GLASSMORPHISM - All components use true glass effect
* 2. NEON ACCENTS - Color-coded sections with glow
* 3. GROUPED LAYOUT - Related settings in glass cards
* 4. ACCESSIBILITY - Proper labels and keyboard navigation
*
* This replicates the actual RAG settings UI with:
* - Model selection dropdowns
* - Feature toggle switches
* - Checkbox options
* - Number inputs with glass styling
*/
export function RAGSettingsExample() {
const [llmProvider, setLlmProvider] = useState("openai");
const [modelChoice, setModelChoice] = useState("gpt-4");
const [embeddingModel, setEmbeddingModel] = useState("text-embedding-3-small");
const [enableRAG, setEnableRAG] = useState(true);
const [enableCache, setEnableCache] = useState(true);
const [enableStreaming, setEnableStreaming] = useState(false);
const [searchOptions, setSearchOptions] = useState({
semantic: true,
keyword: true,
hybrid: false,
});
const [maxTokens, setMaxTokens] = useState("2048");
const [temperature, setTemperature] = useState("0.7");
const [topK, setTopK] = useState("5");
return (
<div className="max-w-4xl mx-auto space-y-6 p-6">
{/* Header */}
<div className="text-center space-y-2">
<h2 className="text-2xl font-bold text-gray-900 dark:text-white">
RAG Settings Example
</h2>
<p className="text-sm text-gray-600 dark:text-gray-400">
Retrieval-Augmented Generation configuration with glassmorphic components
</p>
</div>
{/* LLM Configuration */}
<Card
glassTint="green"
glowColor="green"
transparency="medium"
className="p-6"
>
<div className="flex items-center gap-2 mb-4">
<Brain className="w-5 h-5 text-emerald-400 drop-shadow-[0_0_5px_rgba(16,185,129,0.7)]" />
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
LLM Configuration
</h3>
</div>
<div className="grid grid-cols-2 gap-4">
{/* Provider Selection */}
<div>
<Label htmlFor="provider" className="mb-2 block">
Provider
</Label>
<Select value={llmProvider} onValueChange={setLlmProvider}>
<SelectTrigger id="provider" color="green">
<SelectValue />
</SelectTrigger>
<SelectContent color="green">
<SelectItem value="openai" color="green">OpenAI</SelectItem>
<SelectItem value="anthropic" color="green">Anthropic</SelectItem>
<SelectItem value="google" color="green">Google</SelectItem>
<SelectItem value="ollama" color="green">Ollama (Local)</SelectItem>
</SelectContent>
</Select>
</div>
{/* Model Selection */}
<div>
<Label htmlFor="model" className="mb-2 block">
Model
</Label>
<Select value={modelChoice} onValueChange={setModelChoice}>
<SelectTrigger id="model" color="green">
<SelectValue />
</SelectTrigger>
<SelectContent color="green">
<SelectItem value="gpt-4" color="green">GPT-4</SelectItem>
<SelectItem value="gpt-4-turbo" color="green">GPT-4 Turbo</SelectItem>
<SelectItem value="gpt-3.5-turbo" color="green">GPT-3.5 Turbo</SelectItem>
<SelectItem value="claude-3" color="green">Claude 3</SelectItem>
</SelectContent>
</Select>
</div>
{/* Embedding Model */}
<div>
<Label htmlFor="embedding" className="mb-2 block">
Embedding Model
</Label>
<Select value={embeddingModel} onValueChange={setEmbeddingModel}>
<SelectTrigger id="embedding" color="green">
<SelectValue />
</SelectTrigger>
<SelectContent color="green">
<SelectItem value="text-embedding-3-small" color="green">text-embedding-3-small</SelectItem>
<SelectItem value="text-embedding-3-large" color="green">text-embedding-3-large</SelectItem>
<SelectItem value="text-embedding-ada-002" color="green">text-embedding-ada-002</SelectItem>
</SelectContent>
</Select>
</div>
{/* Max Tokens */}
<div>
<Label htmlFor="max-tokens" className="mb-2 block">
Max Tokens
</Label>
<Input
id="max-tokens"
type="number"
value={maxTokens}
onChange={(e) => setMaxTokens(e.target.value)}
className="backdrop-blur-xl bg-black/10 dark:bg-white/10 border-green-500/30 focus:border-green-500"
/>
</div>
</div>
</Card>
{/* Feature Toggles */}
<Card
glassTint="green"
glowColor="green"
transparency="medium"
className="p-6"
>
<div className="flex items-center gap-2 mb-4">
<Cpu className="w-5 h-5 text-emerald-400 drop-shadow-[0_0_5px_rgba(16,185,129,0.7)]" />
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
Features
</h3>
</div>
<div className="space-y-4">
<div className="flex items-center justify-between p-3 rounded-lg bg-black/5 dark:bg-white/5">
<div className="flex-1">
<Label htmlFor="rag-toggle" className="cursor-pointer">
Enable RAG
</Label>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
Use knowledge base for context enhancement
</p>
</div>
<Switch
id="rag-toggle"
size="lg"
color="green"
checked={enableRAG}
onCheckedChange={setEnableRAG}
icon={<Database className="w-5 h-5" />}
/>
</div>
<div className="flex items-center justify-between p-3 rounded-lg bg-black/5 dark:bg-white/5">
<div className="flex-1">
<Label htmlFor="cache-toggle" className="cursor-pointer">
Response Caching
</Label>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
Cache similar queries for faster responses
</p>
</div>
<Switch
id="cache-toggle"
size="lg"
color="green"
checked={enableCache}
onCheckedChange={setEnableCache}
icon={<Zap className="w-5 h-5" />}
/>
</div>
<div className="flex items-center justify-between p-3 rounded-lg bg-black/5 dark:bg-white/5">
<div className="flex-1">
<Label htmlFor="stream-toggle" className="cursor-pointer">
Stream Responses
</Label>
<p className="text-xs text-gray-500 dark:text-gray-400 mt-1">
Enable real-time streaming of LLM responses
</p>
</div>
<Switch
id="stream-toggle"
size="lg"
color="green"
checked={enableStreaming}
onCheckedChange={setEnableStreaming}
icon={<FileText className="w-5 h-5" />}
/>
</div>
</div>
</Card>
{/* Search Options */}
<Card
glassTint="green"
glowColor="green"
transparency="medium"
className="p-6"
>
<div className="flex items-center gap-2 mb-4">
<Search className="w-5 h-5 text-emerald-400 drop-shadow-[0_0_5px_rgba(16,185,129,0.7)]" />
<h3 className="text-lg font-semibold text-gray-900 dark:text-white">
Search Options
</h3>
</div>
<div className="space-y-3">
<div className="flex items-center space-x-2">
<Checkbox
id="semantic"
color="green"
checked={searchOptions.semantic}
onCheckedChange={(checked) =>
setSearchOptions(prev => ({ ...prev, semantic: checked as boolean }))
}
/>
<Label htmlFor="semantic" className="cursor-pointer">
Semantic Search
<span className="text-xs text-gray-500 dark:text-gray-400 ml-2">
(Vector similarity)
</span>
</Label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="keyword"
color="green"
checked={searchOptions.keyword}
onCheckedChange={(checked) =>
setSearchOptions(prev => ({ ...prev, keyword: checked as boolean }))
}
/>
<Label htmlFor="keyword" className="cursor-pointer">
Keyword Search
<span className="text-xs text-gray-500 dark:text-gray-400 ml-2">
(Full-text matching)
</span>
</Label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="hybrid"
color="green"
checked={searchOptions.hybrid}
onCheckedChange={(checked) =>
setSearchOptions(prev => ({ ...prev, hybrid: checked as boolean }))
}
/>
<Label htmlFor="hybrid" className="cursor-pointer">
Hybrid Search
<span className="text-xs text-gray-500 dark:text-gray-400 ml-2">
(Combined approach)
</span>
</Label>
</div>
</div>
<div className="grid grid-cols-2 gap-4 mt-4">
<div>
<Label htmlFor="temperature" className="mb-2 block">
Temperature ({temperature})
</Label>
<input
id="temperature"
type="range"
min="0"
max="2"
step="0.1"
value={temperature}
onChange={(e) => setTemperature(e.target.value)}
className="w-full accent-emerald-500"
/>
</div>
<div>
<Label htmlFor="top-k" className="mb-2 block">
Top K Results
</Label>
<Input
id="top-k"
type="number"
value={topK}
onChange={(e) => setTopK(e.target.value)}
className="backdrop-blur-xl bg-black/10 dark:bg-white/10 border-emerald-500/30 focus:border-emerald-500"
/>
</div>
</div>
</Card>
{/* Status Summary */}
<Card
glassTint="green"
glowColor="green"
transparency="medium"
className="p-4"
>
<div className="grid grid-cols-3 gap-4 text-sm">
<div className="text-center">
<p className="text-gray-500 dark:text-gray-400">Provider</p>
<p className="font-semibold text-gray-900 dark:text-white">{llmProvider}</p>
</div>
<div className="text-center">
<p className="text-gray-500 dark:text-gray-400">Model</p>
<p className="font-semibold text-gray-900 dark:text-white">{modelChoice}</p>
</div>
<div className="text-center">
<p className="text-gray-500 dark:text-gray-400">RAG Status</p>
<p className={`font-semibold ${enableRAG ? 'text-emerald-400' : 'text-gray-500'}`}>
{enableRAG ? 'Enabled' : 'Disabled'}
</p>
</div>
</div>
</Card>
{/* Code Example */}
<div className="mt-8 p-4 rounded-lg bg-gray-900 text-gray-100 overflow-x-auto">
<pre className="text-xs">
{`// Example configuration object
const ragConfig = {
provider: "${llmProvider}",
model: "${modelChoice}",
embedding: "${embeddingModel}",
features: {
rag: ${enableRAG},
cache: ${enableCache},
streaming: ${enableStreaming}
},
search: {
semantic: ${searchOptions.semantic},
keyword: ${searchOptions.keyword},
hybrid: ${searchOptions.hybrid}
},
parameters: {
maxTokens: ${maxTokens},
temperature: ${temperature},
topK: ${topK}
}
};`}
</pre>
</div>
</div>
);
}

View File

@@ -0,0 +1 @@
export { StyleGuideView } from './components/StyleGuideView';

View File

@@ -131,9 +131,9 @@ const SidebarTemplate = () => {
sidebarPosition === 'top' ? "flex-col" : "flex-row",
"gap-4 p-4"
)}>
{/* Sidebar */}
{/* Sidebar - Using proper 1/4 width proportion */}
<div className={cn(
sidebarPosition === 'left' && !sidebarCollapsed && "w-64",
sidebarPosition === 'left' && !sidebarCollapsed && "w-1/4",
sidebarPosition === 'left' && sidebarCollapsed && "w-16",
sidebarPosition === 'top' && "w-full",
"transition-all duration-300"
@@ -177,14 +177,18 @@ const SidebarTemplate = () => {
)}
</div>
{/* Main Content */}
<div className="flex-1">
{/* Main Content - Using proper 3/4 width proportion */}
<div className={cn(
sidebarPosition === 'left' && !sidebarCollapsed && "w-3/4",
sidebarPosition === 'left' && sidebarCollapsed && "flex-1",
sidebarPosition === 'top' && "w-full"
)}>
<Card className="h-full p-6 border-2 border-dashed border-gray-300 dark:border-gray-600">
<div className="text-center text-gray-500 dark:text-gray-400">
<h3 className="font-medium mb-2">Main Content Area</h3>
<h3 className="font-medium mb-2">Main Content Area (3/4 width)</h3>
<p className="text-sm">Your application content goes here</p>
<p className="text-xs mt-2">
Sidebar: {sidebarPosition === 'top' ? 'Top' : `Left (${sidebarCollapsed ? 'Collapsed' : 'Expanded'})`}
Sidebar: {sidebarPosition === 'top' ? 'Top' : `Left (${sidebarCollapsed ? 'Collapsed' : sidebarCollapsed === false ? '1/4 width' : 'Expanded'})`}
</p>
</div>
</Card>
@@ -464,11 +468,17 @@ import { ChevronLeft, ChevronRight } from 'lucide-react';
* WHEN NOT TO USE: Simple content pages, forms, dashboards
*
* FEATURES:
* - Collapsible sidebar (280px -> 60px)
* - Proportional sidebar (1/4 width -> collapsed 60px)
* - Main content area (3/4 width -> flex-1 when collapsed)
* - Responsive behavior (sidebar -> top nav on mobile)
* - Smooth transitions and state preservation
* - Keyboard navigation support
*
* PROPORTIONS:
* - Sidebar: 25% of container width (w-1/4)
* - Content: 75% of container width (w-3/4)
* - Collapsed: Sidebar 60px (w-16), Content flex-1
*
* ACCESSIBILITY:
* - ARIA labels for collapse state
* - Keyboard shortcuts (Ctrl+\\)
@@ -480,10 +490,10 @@ export const SidebarLayout = () => {
return (
<div className="flex h-full">
{/* Sidebar */}
{/* Sidebar - 1/4 width when expanded */}
<div className={cn(
"transition-all duration-300",
collapsed ? "w-16" : "w-64"
collapsed ? "w-16" : "w-1/4"
)}>
<Card className="h-full p-4 rounded-none border-r">
<Button
@@ -523,8 +533,11 @@ export const SidebarLayout = () => {
</Card>
</div>
{/* Main Content */}
<div className="flex-1 p-6">
{/* Main Content - 3/4 width when sidebar expanded */}
<div className={cn(
"transition-all duration-300 p-6",
collapsed ? "flex-1" : "w-3/4"
)}>
{/* Your main content */}
</div>
</div>

View File

@@ -0,0 +1,58 @@
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

@@ -0,0 +1,125 @@
import * as CheckboxPrimitives from "@radix-ui/react-checkbox";
import { Check, Minus } from "lucide-react";
import * as React from "react";
import { cn, glassmorphism } from "./styles";
export type CheckboxColor = "purple" | "blue" | "green" | "pink" | "orange" | "cyan";
interface CheckboxProps extends React.ComponentPropsWithoutRef<typeof CheckboxPrimitives.Root> {
color?: CheckboxColor;
indeterminate?: boolean;
}
const checkboxVariants = {
purple: {
checked: "data-[state=checked]:bg-purple-500/20 data-[state=checked]:border-purple-500",
glow: "data-[state=checked]:shadow-[0_0_15px_rgba(168,85,247,0.5)]",
indicator: "text-purple-400 drop-shadow-[0_0_3px_rgba(168,85,247,0.7)]",
},
blue: {
checked: "data-[state=checked]:bg-blue-500/20 data-[state=checked]:border-blue-500",
glow: "data-[state=checked]:shadow-[0_0_15px_rgba(59,130,246,0.5)]",
indicator: "text-blue-400 drop-shadow-[0_0_3px_rgba(59,130,246,0.7)]",
},
green: {
checked: "data-[state=checked]:bg-emerald-500/20 data-[state=checked]:border-emerald-500",
glow: "data-[state=checked]:shadow-[0_0_15px_rgba(16,185,129,0.5)]",
indicator: "text-emerald-400 drop-shadow-[0_0_3px_rgba(16,185,129,0.7)]",
},
pink: {
checked: "data-[state=checked]:bg-pink-500/20 data-[state=checked]:border-pink-500",
glow: "data-[state=checked]:shadow-[0_0_15px_rgba(236,72,153,0.5)]",
indicator: "text-pink-400 drop-shadow-[0_0_3px_rgba(236,72,153,0.7)]",
},
orange: {
checked: "data-[state=checked]:bg-orange-500/20 data-[state=checked]:border-orange-500",
glow: "data-[state=checked]:shadow-[0_0_15px_rgba(249,115,22,0.5)]",
indicator: "text-orange-400 drop-shadow-[0_0_3px_rgba(249,115,22,0.7)]",
},
cyan: {
checked: "data-[state=checked]:bg-cyan-500/20 data-[state=checked]:border-cyan-500",
glow: "data-[state=checked]:shadow-[0_0_15px_rgba(34,211,238,0.5)]",
indicator: "text-cyan-400 drop-shadow-[0_0_3px_rgba(34,211,238,0.7)]",
},
};
/**
* 🤖 AI CONTEXT: Glassmorphic Checkbox Component
*
* DESIGN DECISIONS:
* 1. TRANSPARENCY - Glass effect with subtle background
* - Unchecked: Almost invisible (bg-white/10)
* - Checked: Color tinted glass (color-500/20)
*
* 2. NEON GLOW - Tron-style accent on activation
* - Box shadow creates outer glow
* - Drop shadow on check icon for depth
*
* 3. ANIMATION - Smooth state transitions
* - Scale animation on check/uncheck
* - Fade in/out for indicator
* - 300ms transitions for smoothness
*
* 4. STATES - Support for three states
* - Unchecked: Empty box
* - Checked: Check icon with glow
* - Indeterminate: Minus icon (partial selection)
*/
const Checkbox = React.forwardRef<
React.ElementRef<typeof CheckboxPrimitives.Root>,
CheckboxProps
>(({ className, color = "cyan", indeterminate, checked, ...props }, ref) => {
const colorStyles = checkboxVariants[color];
return (
<CheckboxPrimitives.Root
className={cn(
"peer h-5 w-5 shrink-0 rounded-md",
"bg-black/10 dark:bg-white/10 backdrop-blur-xl",
"border-2 border-gray-300/30 dark:border-white/10",
"transition-all duration-300",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
`focus-visible:ring-${color}-500`,
"disabled:cursor-not-allowed disabled:opacity-50",
"hover:border-gray-400/50 dark:hover:border-white/20",
colorStyles.checked,
colorStyles.glow,
"data-[state=indeterminate]:bg-opacity-50",
glassmorphism.interactive.base,
className
)}
checked={indeterminate ? "indeterminate" : checked}
{...props}
ref={ref}
>
<CheckboxPrimitives.Indicator
className={cn(
"flex items-center justify-center",
"data-[state=checked]:animate-in data-[state=checked]:zoom-in-0",
"data-[state=unchecked]:animate-out data-[state=unchecked]:zoom-out-0",
"data-[state=indeterminate]:animate-in data-[state=indeterminate]:zoom-in-0"
)}
>
{indeterminate ? (
<Minus
className={cn(
"h-3.5 w-3.5",
colorStyles.indicator
)}
/>
) : (
<Check
className={cn(
"h-4 w-4",
colorStyles.indicator
)}
/>
)}
</CheckboxPrimitives.Indicator>
</CheckboxPrimitives.Root>
);
});
Checkbox.displayName = CheckboxPrimitives.Root.displayName;
export { Checkbox, checkboxVariants };

View File

@@ -1,82 +1,146 @@
import * as SelectPrimitive from "@radix-ui/react-select";
import { Check, ChevronDown } from "lucide-react";
import React from "react";
import { cn } from "./styles";
import { cn, glassmorphism } from "./styles";
export type SelectColor = "purple" | "blue" | "green" | "pink" | "orange" | "cyan";
// Select Root - just re-export
export const Select = SelectPrimitive.Root;
export const SelectValue = SelectPrimitive.Value;
const selectColorVariants = {
purple: {
trigger: "hover:border-purple-400/50 hover:shadow-[0_0_15px_rgba(168,85,247,0.3)] focus:border-purple-500 focus:shadow-[0_0_20px_rgba(168,85,247,0.4)]",
item: "hover:bg-purple-500/20 dark:hover:bg-purple-400/20 data-[state=checked]:bg-purple-500/30 dark:data-[state=checked]:bg-purple-400/30 data-[state=checked]:text-purple-700 dark:data-[state=checked]:text-purple-300",
},
blue: {
trigger: "hover:border-blue-400/50 hover:shadow-[0_0_15px_rgba(59,130,246,0.3)] focus:border-blue-500 focus:shadow-[0_0_20px_rgba(59,130,246,0.4)]",
item: "hover:bg-blue-500/20 dark:hover:bg-blue-400/20 data-[state=checked]:bg-blue-500/30 dark:data-[state=checked]:bg-blue-400/30 data-[state=checked]:text-blue-700 dark:data-[state=checked]:text-blue-300",
},
green: {
trigger: "hover:border-emerald-400/50 hover:shadow-[0_0_15px_rgba(16,185,129,0.3)] focus:border-emerald-500 focus:shadow-[0_0_20px_rgba(16,185,129,0.4)]",
item: "hover:bg-emerald-500/20 dark:hover:bg-emerald-400/20 data-[state=checked]:bg-emerald-500/30 dark:data-[state=checked]:bg-emerald-400/30 data-[state=checked]:text-emerald-700 dark:data-[state=checked]:text-emerald-300",
},
pink: {
trigger: "hover:border-pink-400/50 hover:shadow-[0_0_15px_rgba(236,72,153,0.3)] focus:border-pink-500 focus:shadow-[0_0_20px_rgba(236,72,153,0.4)]",
item: "hover:bg-pink-500/20 dark:hover:bg-pink-400/20 data-[state=checked]:bg-pink-500/30 dark:data-[state=checked]:bg-pink-400/30 data-[state=checked]:text-pink-700 dark:data-[state=checked]:text-pink-300",
},
orange: {
trigger: "hover:border-orange-400/50 hover:shadow-[0_0_15px_rgba(249,115,22,0.3)] focus:border-orange-500 focus:shadow-[0_0_20px_rgba(249,115,22,0.4)]",
item: "hover:bg-orange-500/20 dark:hover:bg-orange-400/20 data-[state=checked]:bg-orange-500/30 dark:data-[state=checked]:bg-orange-400/30 data-[state=checked]:text-orange-700 dark:data-[state=checked]:text-orange-300",
},
cyan: {
trigger: "hover:border-cyan-400/50 hover:shadow-[0_0_15px_rgba(34,211,238,0.3)] focus:border-cyan-500 focus:shadow-[0_0_20px_rgba(34,211,238,0.4)]",
item: "hover:bg-cyan-500/20 dark:hover:bg-cyan-400/20 data-[state=checked]:bg-cyan-500/30 dark:data-[state=checked]:bg-cyan-400/30 data-[state=checked]:text-cyan-700 dark:data-[state=checked]:text-cyan-300",
},
};
/**
* 🤖 AI CONTEXT: Enhanced Select Trigger
*
* GLASSMORPHISM ENHANCEMENTS:
* 1. TRANSPARENCY - True glass effect with backdrop blur
* 2. NEON BORDERS - Color-coded focus states
* 3. GLOW EFFECTS - Box shadows for depth
* 4. COLOR VARIANTS - Support for theme colors
*/
// Select Trigger with glassmorphism styling
export const SelectTrigger = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Trigger>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Trigger> & {
showChevron?: boolean;
color?: SelectColor;
}
>(({ className = "", children, showChevron = true, ...props }, ref) => (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex items-center justify-between gap-2 px-3 py-2 rounded-lg",
"backdrop-blur-md bg-gradient-to-b from-white/80 to-white/60",
"dark:from-white/10 dark:to-black/30",
"border border-gray-200 dark:border-gray-700",
"transition-all duration-200",
"hover:border-cyan-400/50 hover:shadow-[0_0_10px_rgba(34,211,238,0.2)]",
"focus:outline-none focus:border-cyan-500 focus:shadow-[0_0_15px_rgba(34,211,238,0.3)]",
"disabled:opacity-50 disabled:cursor-not-allowed",
"data-[placeholder]:text-gray-500 dark:data-[placeholder]:text-gray-400",
className,
)}
{...props}
>
{children}
{showChevron && (
<SelectPrimitive.Icon className="ml-auto">
<ChevronDown className="w-3 h-3 opacity-60" />
</SelectPrimitive.Icon>
)}
</SelectPrimitive.Trigger>
));
>(({ className = "", children, showChevron = true, color = "cyan", ...props }, ref) => {
const colorStyles = selectColorVariants[color];
return (
<SelectPrimitive.Trigger
ref={ref}
className={cn(
"flex items-center justify-between gap-2 px-3 py-2 rounded-lg",
"backdrop-blur-xl bg-black/10 dark:bg-white/10",
"border border-gray-300/30 dark:border-white/10",
"transition-all duration-300",
colorStyles.trigger,
"disabled:opacity-50 disabled:cursor-not-allowed",
"data-[placeholder]:text-gray-500 dark:data-[placeholder]:text-gray-400",
glassmorphism.interactive.base,
className,
)}
{...props}
>
{children}
{showChevron && (
<SelectPrimitive.Icon className="ml-auto">
<ChevronDown className="w-3 h-3 opacity-60 transition-transform duration-300 data-[state=open]:rotate-180" />
</SelectPrimitive.Icon>
)}
</SelectPrimitive.Trigger>
);
});
SelectTrigger.displayName = SelectPrimitive.Trigger.displayName;
/**
* 🤖 AI CONTEXT: Enhanced Select Content
*
* GLASS DROPDOWN DESIGN:
* 1. TRANSPARENCY - Full glass effect on dropdown
* 2. BACKDROP BLUR - Heavy blur for content behind
* 3. NEON GLOW - Subtle color-matched glow
* 4. PORTAL - Ensures z-index above all content
*/
// Select Content with glassmorphism and Portal for z-index solution
export const SelectContent = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content>
>(({ className = "", children, position = "popper", ...props }, ref) => (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-[10000] min-w-[8rem] overflow-hidden rounded-lg",
// Matching our card glassmorphism
"backdrop-blur-md bg-gradient-to-b from-white/80 to-white/60",
"dark:from-white/10 dark:to-black/30",
"border border-gray-200 dark:border-zinc-800/50",
// Tron shadow with subtle cyan glow
"shadow-[0_10px_30px_-15px_rgba(0,0,0,0.1)] dark:shadow-[0_10px_30px_-15px_rgba(0,0,0,0.7)]",
"shadow-cyan-500/5 dark:shadow-cyan-500/10",
// Text colors matching rest of app
"text-gray-900 dark:text-gray-100",
// Animation
"data-[state=open]:animate-in data-[state=closed]:animate-out",
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
"data-[side=bottom]:slide-in-from-top-2",
"data-[side=left]:slide-in-from-right-2",
"data-[side=right]:slide-in-from-left-2",
"data-[side=top]:slide-in-from-bottom-2",
className,
)}
position={position}
sideOffset={5}
{...props}
>
<SelectPrimitive.Viewport className="p-1">{children}</SelectPrimitive.Viewport>
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
));
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Content> & {
color?: SelectColor;
}
>(({ className = "", children, position = "popper", color = "cyan", ...props }, ref) => {
const glowColor = {
purple: "shadow-purple-500/20 dark:shadow-purple-500/30",
blue: "shadow-blue-500/20 dark:shadow-blue-500/30",
green: "shadow-emerald-500/20 dark:shadow-emerald-500/30",
pink: "shadow-pink-500/20 dark:shadow-pink-500/30",
orange: "shadow-orange-500/20 dark:shadow-orange-500/30",
cyan: "shadow-cyan-500/20 dark:shadow-cyan-500/30",
}[color];
return (
<SelectPrimitive.Portal>
<SelectPrimitive.Content
ref={ref}
className={cn(
"relative z-[10000] min-w-[8rem] overflow-hidden rounded-lg",
// True glassmorphism
"backdrop-blur-xl bg-black/20 dark:bg-white/10",
"border border-gray-300/30 dark:border-white/10",
// Neon shadow with color glow
"shadow-[0_10px_30px_-15px_rgba(0,0,0,0.3)] dark:shadow-[0_10px_30px_-15px_rgba(0,0,0,0.7)]",
glowColor,
// Text colors
"text-gray-900 dark:text-gray-100",
// Animation
"data-[state=open]:animate-in data-[state=closed]:animate-out",
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
"data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
"data-[side=bottom]:slide-in-from-top-2",
"data-[side=left]:slide-in-from-right-2",
"data-[side=right]:slide-in-from-left-2",
"data-[side=top]:slide-in-from-bottom-2",
glassmorphism.animation.fadeIn,
className,
)}
position={position}
sideOffset={5}
{...props}
>
<SelectPrimitive.Viewport className="p-1">{children}</SelectPrimitive.Viewport>
</SelectPrimitive.Content>
</SelectPrimitive.Portal>
);
});
SelectContent.displayName = SelectPrimitive.Content.displayName;
// Select Item with hover effects
@@ -84,41 +148,43 @@ export const SelectItem = React.forwardRef<
React.ElementRef<typeof SelectPrimitive.Item>,
React.ComponentPropsWithoutRef<typeof SelectPrimitive.Item> & {
icon?: React.ReactNode;
color?: SelectColor;
}
>(({ className = "", children, icon, ...props }, ref) => (
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex items-center text-sm outline-none",
"transition-all duration-150 cursor-pointer rounded-md",
"pl-8 pr-3 py-2", // Added left padding for checkmark space
// Text colors
"text-gray-700 dark:text-gray-200",
// Hover state with subtle cyan tint
"hover:bg-cyan-500/20 dark:hover:bg-cyan-400/20",
"hover:text-gray-900 dark:hover:text-white",
// Focus state
"focus:bg-cyan-500/20 dark:focus:bg-cyan-400/20",
"focus:text-gray-900 dark:focus:text-white",
// Disabled state
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
// Selected/checked state with stronger cyan
"data-[state=checked]:bg-cyan-500/30 dark:data-[state=checked]:bg-cyan-400/30",
"data-[state=checked]:text-cyan-700 dark:data-[state=checked]:text-cyan-300",
"data-[state=checked]:font-medium",
className,
)}
{...props}
>
<SelectPrimitive.ItemIndicator className="absolute left-2 flex h-4 w-4 items-center justify-center">
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
<SelectPrimitive.ItemText className="flex items-center gap-2">
{icon && <span className="flex-shrink-0">{icon}</span>}
{children}
</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
));
>(({ className = "", children, icon, color = "cyan", ...props }, ref) => {
const colorStyles = selectColorVariants[color];
return (
<SelectPrimitive.Item
ref={ref}
className={cn(
"relative flex items-center text-sm outline-none",
"transition-all duration-150 cursor-pointer rounded-md",
"pl-8 pr-3 py-2", // Added left padding for checkmark space
// Text colors
"text-gray-700 dark:text-gray-200",
// Hover and focus states with color tint
"hover:text-gray-900 dark:hover:text-white",
"focus:text-gray-900 dark:focus:text-white",
// Disabled state
"data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
// Selected/checked state with stronger color
"data-[state=checked]:font-medium",
colorStyles.item,
glassmorphism.interactive.base,
className,
)}
{...props}
>
<SelectPrimitive.ItemIndicator className="absolute left-2 flex h-4 w-4 items-center justify-center">
<Check className="h-4 w-4" />
</SelectPrimitive.ItemIndicator>
<SelectPrimitive.ItemText className="flex items-center gap-2">
{icon && <span className="flex-shrink-0">{icon}</span>}
{children}
</SelectPrimitive.ItemText>
</SelectPrimitive.Item>
);
});
SelectItem.displayName = SelectPrimitive.Item.displayName;
// Export group and label for completeness

View File

@@ -2,34 +2,164 @@ import * as SwitchPrimitives from "@radix-ui/react-switch";
import * as React from "react";
import { cn, glassmorphism } from "./styles";
export type SwitchSize = "sm" | "md" | "lg";
export type SwitchColor = "purple" | "blue" | "green" | "pink" | "orange" | "cyan";
interface SwitchProps extends React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root> {
size?: SwitchSize;
color?: SwitchColor;
icon?: React.ReactNode;
iconOn?: React.ReactNode;
iconOff?: React.ReactNode;
}
const switchVariants = {
size: {
sm: {
root: "h-4 w-8",
thumb: "h-3 w-3 data-[state=checked]:translate-x-4",
icon: "",
},
md: {
root: "h-6 w-11",
thumb: "h-5 w-5 data-[state=checked]:translate-x-5",
icon: "h-3 w-3",
},
lg: {
root: "h-8 w-14",
thumb: "h-7 w-7 data-[state=checked]:translate-x-6",
icon: "h-5 w-5",
},
},
color: {
purple: {
checked: "data-[state=checked]:bg-purple-500/20 data-[state=checked]:border-purple-500/50",
glow: "data-[state=checked]:shadow-[0_0_20px_rgba(168,85,247,0.5)]",
thumb: "data-[state=checked]:border-purple-400 data-[state=checked]:shadow-[0_0_10px_rgba(168,85,247,0.5)]",
icon: "text-gray-500 dark:text-gray-400 data-[state=checked]:text-purple-400 data-[state=checked]:drop-shadow-[0_0_5px_rgba(168,85,247,0.7)]"
},
blue: {
checked: "data-[state=checked]:bg-blue-500/20 data-[state=checked]:border-blue-500/50",
glow: "data-[state=checked]:shadow-[0_0_20px_rgba(59,130,246,0.5)]",
thumb: "data-[state=checked]:border-blue-400 data-[state=checked]:shadow-[0_0_10px_rgba(59,130,246,0.5)]",
icon: "text-gray-500 dark:text-gray-400 data-[state=checked]:text-blue-400 data-[state=checked]:drop-shadow-[0_0_5px_rgba(59,130,246,0.7)]"
},
green: {
checked: "data-[state=checked]:bg-emerald-500/20 data-[state=checked]:border-emerald-500/50",
glow: "data-[state=checked]:shadow-[0_0_20px_rgba(16,185,129,0.5)]",
thumb: "data-[state=checked]:border-emerald-400 data-[state=checked]:shadow-[0_0_10px_rgba(16,185,129,0.5)]",
icon: "text-gray-500 dark:text-gray-400 data-[state=checked]:text-emerald-400 data-[state=checked]:drop-shadow-[0_0_5px_rgba(16,185,129,0.7)]"
},
pink: {
checked: "data-[state=checked]:bg-pink-500/20 data-[state=checked]:border-pink-500/50",
glow: "data-[state=checked]:shadow-[0_0_20px_rgba(236,72,153,0.5)]",
thumb: "data-[state=checked]:border-pink-400 data-[state=checked]:shadow-[0_0_10px_rgba(236,72,153,0.5)]",
icon: "text-gray-500 dark:text-gray-400 data-[state=checked]:text-pink-400 data-[state=checked]:drop-shadow-[0_0_5px_rgba(236,72,153,0.7)]"
},
orange: {
checked: "data-[state=checked]:bg-orange-500/20 data-[state=checked]:border-orange-500/50",
glow: "data-[state=checked]:shadow-[0_0_20px_rgba(249,115,22,0.5)]",
thumb: "data-[state=checked]:border-orange-400 data-[state=checked]:shadow-[0_0_10px_rgba(249,115,22,0.5)]",
icon: "text-gray-500 dark:text-gray-400 data-[state=checked]:text-orange-400 data-[state=checked]:drop-shadow-[0_0_5px_rgba(249,115,22,0.7)]"
},
cyan: {
checked: "data-[state=checked]:bg-cyan-500/20 data-[state=checked]:border-cyan-500/50",
glow: "data-[state=checked]:shadow-[0_0_20px_rgba(34,211,238,0.5)]",
thumb: "data-[state=checked]:border-cyan-400 data-[state=checked]:shadow-[0_0_10px_rgba(34,211,238,0.5)]",
icon: "text-gray-500 dark:text-gray-400 data-[state=checked]:text-cyan-400 data-[state=checked]:drop-shadow-[0_0_5px_rgba(34,211,238,0.7)]"
}
}
};
/**
* 🤖 AI CONTEXT: Enhanced Switch Component
*
* GLASS PROPERTIES for true glassmorphism:
* 1. TRANSPARENCY - Subtle background opacity
* - unchecked: Almost invisible (bg-white/10)
* - checked: Color tinted glass (color-500/20)
*
* 2. SIZE VARIANTS - Three sizes for different use cases
* - sm: 16px height, no icons
* - md: 24px height, smaller icons (12x12px)
* - lg: 32px height, full icons (20x20px)
*
* 3. GLOW EFFECTS - Neon accents that animate
* - Box shadow for outer glow
* - Drop shadow for icon glow
* - Transition animations for smooth state changes
*
* 4. ICON SUPPORT - Dynamic icon switching
* - iconOn: Displayed when checked
* - iconOff: Displayed when unchecked
* - icon: Same icon for both states
*/
const Switch = React.forwardRef<
React.ElementRef<typeof SwitchPrimitives.Root>,
React.ComponentPropsWithoutRef<typeof SwitchPrimitives.Root>
>(({ className, ...props }, ref) => (
<SwitchPrimitives.Root
className={cn(
"peer inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full",
"transition-colors focus-visible:outline-none focus-visible:ring-2",
"focus-visible:ring-cyan-500 focus-visible:ring-offset-2",
"disabled:cursor-not-allowed disabled:opacity-50",
"data-[state=checked]:bg-cyan-500",
"data-[state=unchecked]:bg-gray-200 dark:data-[state=unchecked]:bg-gray-700",
glassmorphism.interactive.base,
className
)}
{...props}
ref={ref}
>
<SwitchPrimitives.Thumb
SwitchProps
>(({ className, size = "md", color = "cyan", icon, iconOn, iconOff, checked, ...props }, ref) => {
const sizeStyles = switchVariants.size[size];
const colorStyles = switchVariants.color[color];
const displayIcon = React.useMemo(() => {
if (size === "sm") return null;
if (checked !== undefined) {
return checked ? (iconOn || icon) : (iconOff || icon);
}
return icon;
}, [size, checked, icon, iconOn, iconOff]);
return (
<SwitchPrimitives.Root
className={cn(
"pointer-events-none block h-4 w-4 rounded-full",
"bg-white shadow-lg ring-0 transition-transform",
"data-[state=checked]:translate-x-4",
"data-[state=unchecked]:translate-x-0"
"relative inline-flex shrink-0 cursor-pointer items-center rounded-full",
"bg-black/10 dark:bg-white/10 backdrop-blur-xl",
"border border-gray-300/30 dark:border-white/10",
"transition-all duration-500 ease-in-out",
"focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2",
`focus-visible:ring-${color}-500`,
"disabled:cursor-not-allowed disabled:opacity-50",
colorStyles.checked,
colorStyles.glow,
sizeStyles.root,
glassmorphism.interactive.base,
className
)}
/>
</SwitchPrimitives.Root>
));
checked={checked}
{...props}
ref={ref}
>
<SwitchPrimitives.Thumb
className={cn(
"pointer-events-none relative flex items-center justify-center rounded-full",
// Glass effect for thumb with proper fill
"bg-gradient-to-br from-gray-100/80 to-white/60 dark:from-gray-700/80 dark:to-gray-800/60",
"backdrop-blur-sm border-2",
"border-gray-400/50 dark:border-white/30",
"shadow-lg ring-0 transition-all duration-500 cubic-bezier(0.23, 1, 0.32, 1)",
"data-[state=unchecked]:translate-x-0",
// Checked state gets color tinted glass
"data-[state=checked]:from-white/90 data-[state=checked]:to-white/70 dark:data-[state=checked]:from-gray-100/20 dark:data-[state=checked]:to-gray-200/10",
colorStyles.thumb,
sizeStyles.thumb
)}
>
{displayIcon && (
<div className={cn(
"flex items-center justify-center transition-all duration-500",
// Icons have color in both states with different opacity
colorStyles.icon,
sizeStyles.icon
)}>
{displayIcon}
</div>
)}
</SwitchPrimitives.Thumb>
</SwitchPrimitives.Root>
);
});
Switch.displayName = SwitchPrimitives.Root.displayName;
export { Switch };
export { Switch, switchVariants };

View File

@@ -1,5 +1,5 @@
import React from 'react';
import { StyleGuideView } from '@/components/style-guide/StyleGuideView';
import { StyleGuideView } from '@/features/style-guide';
const StyleGuidePage: React.FC = () => {
return <StyleGuideView />;