mirror of
https://github.com/coleam00/Archon.git
synced 2025-12-24 02:39:17 -05:00
Making the style guide a feature to turn on and off.
This commit is contained in:
351
PRPs/complete-style-guide.md
Normal file
351
PRPs/complete-style-guide.md
Normal 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
|
||||
31
archon-ui-main/package-lock.json
generated
31
archon-ui-main/package-lock.json
generated
@@ -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",
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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 />} />
|
||||
|
||||
@@ -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 */}
|
||||
|
||||
@@ -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}
|
||||
/>
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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
|
||||
};
|
||||
|
||||
@@ -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 = () => {
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
1
archon-ui-main/src/features/style-guide/index.ts
Normal file
1
archon-ui-main/src/features/style-guide/index.ts
Normal file
@@ -0,0 +1 @@
|
||||
export { StyleGuideView } from './components/StyleGuideView';
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
);
|
||||
}
|
||||
125
archon-ui-main/src/features/ui/primitives/checkbox.tsx
Normal file
125
archon-ui-main/src/features/ui/primitives/checkbox.tsx
Normal 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 };
|
||||
@@ -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
|
||||
|
||||
@@ -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 };
|
||||
@@ -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 />;
|
||||
|
||||
Reference in New Issue
Block a user