mirror of
https://github.com/coleam00/Archon.git
synced 2025-12-24 02:39:17 -05:00
command for UI review, and settings to use primitives.
This commit is contained in:
314
.claude/commands/archon/archon-ui-consistency-review.md
Normal file
314
.claude/commands/archon/archon-ui-consistency-review.md
Normal file
@@ -0,0 +1,314 @@
|
||||
---
|
||||
description: Analyze UI components for reusability, Radix usage, primitives, and styling consistency
|
||||
argument-hint: <feature path, component path, or directory>
|
||||
allowed-tools: Read, Grep, Glob, Write
|
||||
thinking: auto
|
||||
---
|
||||
|
||||
# UI Consistency Review for Archon
|
||||
|
||||
**Review scope**: $ARGUMENTS
|
||||
|
||||
I'll analyze the UI components and generate a detailed report on consistency, reusability, and adherence to the Archon design system.
|
||||
|
||||
## Analysis Framework
|
||||
|
||||
### Design System Standards
|
||||
|
||||
**Archon uses:**
|
||||
- **Primitives**: `/src/features/ui/primitives/` - Reusable Radix components with glassmorphism styling
|
||||
- **Card Variants**:
|
||||
- Base glass card
|
||||
- Edge-lit cards: `<Card edgePosition="top" edgeColor="cyan|pink|blue|...">`
|
||||
- Outer glow cards
|
||||
- Inner glow cards
|
||||
- **Navigation**: PillNavigation component for all pill-style navigation
|
||||
- **Glassmorphism**: `backdrop-blur-sm` (minimal), frosted glass backgrounds
|
||||
- **Colors**: Semantic colors (Primary blue #3b82f6, Success, Warning, Error) + accents
|
||||
|
||||
### Scoring Criteria
|
||||
|
||||
**1. Reusability (1-10)**
|
||||
- 10: Uses shared primitives, no hardcoded styles
|
||||
- 7-9: Mostly reusable, minor hardcoding
|
||||
- 4-6: Mix of primitives and custom code
|
||||
- 1-3: Completely custom, duplicates existing patterns
|
||||
|
||||
**2. Radix Component Usage (1-10)**
|
||||
- 10: Uses Radix primitives for ALL interactive elements (Select, Checkbox, Switch, Tabs, Dialog, etc.)
|
||||
- 7-9: Mostly Radix, few native HTML elements
|
||||
- 4-6: Mix of Radix and native elements
|
||||
- 1-3: Primarily native HTML elements
|
||||
|
||||
**3. Primitives Usage (1-10)**
|
||||
- 10: Uses Card, Button, Input primitives with proper props
|
||||
- 7-9: Uses most primitives, some custom styling
|
||||
- 4-6: Mix of primitives and manual styling
|
||||
- 1-3: Hardcoded styling, doesn't use primitives
|
||||
|
||||
**4. Styling Consistency (1-10)**
|
||||
- 10: Matches design system exactly (colors, blur, edge-lit patterns)
|
||||
- 7-9: Close match, minor deviations
|
||||
- 4-6: Significant inconsistencies
|
||||
- 1-3: Completely different styling approach
|
||||
|
||||
## Review Process
|
||||
|
||||
### Step 1: Identify Components
|
||||
|
||||
Scan the provided path for:
|
||||
- React components (`.tsx` files)
|
||||
- Component usage patterns
|
||||
- Imports from primitives vs manual styling
|
||||
|
||||
### Step 2: Analyze Each Component
|
||||
|
||||
For each component, check:
|
||||
|
||||
**Primitives Usage:**
|
||||
```tsx
|
||||
// GOOD - Uses Card primitive with props
|
||||
<Card edgePosition="top" edgeColor="cyan">...</Card>
|
||||
|
||||
// BAD - Hardcoded edge glow
|
||||
<div className="relative overflow-hidden rounded-xl">
|
||||
<div className="absolute inset-x-0 top-0 h-[2px] bg-cyan-500..." />
|
||||
<div className="absolute inset-x-0 top-0 h-8 bg-gradient-to-b..." />
|
||||
...
|
||||
</div>
|
||||
```
|
||||
|
||||
**Radix Usage:**
|
||||
```tsx
|
||||
// GOOD - Radix Select primitive
|
||||
import { Select, SelectTrigger, SelectContent, SelectItem } from '@/features/ui/primitives/select';
|
||||
|
||||
// BAD - Native HTML
|
||||
<select><option>...</option></select>
|
||||
```
|
||||
|
||||
**Reusable Patterns:**
|
||||
```tsx
|
||||
// GOOD - Shared PillNavigation component
|
||||
<PillNavigation items={...} colorVariant="orange" />
|
||||
|
||||
// BAD - Custom hardcoded pill navigation
|
||||
<div className="backdrop-blur-sm bg-white/40...">
|
||||
{items.map(item => <button className="px-6 py-3...">...)}
|
||||
</div>
|
||||
```
|
||||
|
||||
### Step 3: Generate Scores
|
||||
|
||||
Calculate scores for each component based on:
|
||||
- Count of primitive vs hardcoded elements
|
||||
- Radix usage vs native HTML
|
||||
- Styling duplication vs reuse
|
||||
- Pattern consistency
|
||||
|
||||
### Step 4: Identify Issues
|
||||
|
||||
Common anti-patterns to flag:
|
||||
|
||||
**Hardcoded Edge-Lit Cards:**
|
||||
```tsx
|
||||
// BAD - Manual implementation (like KnowledgeCard currently)
|
||||
<div className="pointer-events-none absolute inset-x-0 top-0">
|
||||
<div className="h-[2px] bg-cyan-500..." />
|
||||
<div className="h-8 bg-gradient-to-b..." />
|
||||
</div>
|
||||
|
||||
// GOOD - Use Card primitive
|
||||
<Card edgePosition="top" edgeColor="cyan">
|
||||
```
|
||||
|
||||
**Native HTML Form Elements:**
|
||||
```tsx
|
||||
// BAD
|
||||
<select>, <input type="checkbox">, <input type="radio">
|
||||
|
||||
// GOOD
|
||||
<Select />, <Checkbox />, <RadioGroup />
|
||||
```
|
||||
|
||||
**Duplicated Pill Navigation:**
|
||||
```tsx
|
||||
// BAD - Creating custom pill nav each time
|
||||
// GOOD - Use PillNavigation component
|
||||
```
|
||||
|
||||
### Step 5: Write Resolution Steps
|
||||
|
||||
For each issue, provide:
|
||||
- What to change
|
||||
- Why it matters
|
||||
- Specific code example of the fix
|
||||
- Impact on consistency
|
||||
|
||||
## Report Format
|
||||
|
||||
Generate `ui-consistency-review-[feature].md`:
|
||||
|
||||
```markdown
|
||||
# UI Consistency Review
|
||||
|
||||
**Date**: [Today's date]
|
||||
**Scope**: [Path reviewed]
|
||||
**Components Analyzed**: [Count]
|
||||
|
||||
---
|
||||
|
||||
## Overall Scores
|
||||
|
||||
| Category | Score | Assessment |
|
||||
|----------|-------|------------|
|
||||
| Reusability | X/10 | [Good/Needs Work/Poor] |
|
||||
| Radix Usage | X/10 | [Good/Needs Work/Poor] |
|
||||
| Primitives Usage | X/10 | [Good/Needs Work/Poor] |
|
||||
| Styling Consistency | X/10 | [Good/Needs Work/Poor] |
|
||||
|
||||
**Overall Grade**: [A-F] - [Summary]
|
||||
|
||||
---
|
||||
|
||||
## Component-by-Component Analysis
|
||||
|
||||
### [ComponentName.tsx]
|
||||
|
||||
**Scores:**
|
||||
- Reusability: X/10
|
||||
- Radix Usage: X/10
|
||||
- Primitives Usage: X/10
|
||||
- Styling Consistency: X/10
|
||||
|
||||
**Issues Found:**
|
||||
|
||||
1. **[Issue Type]** - [Description]
|
||||
- Location: `[file:line]`
|
||||
- Current: `[code snippet]`
|
||||
- Should be: `[corrected code]`
|
||||
- Impact: [Why this matters]
|
||||
|
||||
**Standalone vs Primitive:**
|
||||
[This component SHOULD/SHOULD NOT be standalone because...]
|
||||
|
||||
---
|
||||
|
||||
## Critical Issues (Must Fix)
|
||||
|
||||
### 1. [Issue Title]
|
||||
- **File**: `[path:line]`
|
||||
- **Problem**: [Description]
|
||||
- **Why**: [Impact on consistency/maintainability]
|
||||
- **Fix**:
|
||||
```tsx
|
||||
// Current
|
||||
[bad code]
|
||||
|
||||
// Should be
|
||||
[good code]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Recommendations
|
||||
|
||||
### Immediate Actions
|
||||
|
||||
1. **[Action]** - [Why]
|
||||
2. **[Action]** - [Why]
|
||||
|
||||
### Pattern Improvements
|
||||
|
||||
1. **[Pattern]** - [Benefit]
|
||||
2. **[Pattern]** - [Benefit]
|
||||
|
||||
### Refactoring Priorities
|
||||
|
||||
1. **High Priority**: [Components that break consistency]
|
||||
2. **Medium Priority**: [Components that could use primitives]
|
||||
3. **Low Priority**: [Minor inconsistencies]
|
||||
|
||||
---
|
||||
|
||||
## Design System Compliance
|
||||
|
||||
**Primitives Used Correctly:**
|
||||
- [List of components using primitives properly]
|
||||
|
||||
**Missing Primitive Usage:**
|
||||
- [List of components that should use primitives]
|
||||
|
||||
**Radix Compliance:**
|
||||
- [List of components using Radix properly]
|
||||
- [List of components using native HTML instead of Radix]
|
||||
|
||||
**Styling Patterns:**
|
||||
- Edge-lit cards: [X using primitive, Y hardcoded]
|
||||
- Pill navigation: [X using component, Y custom]
|
||||
- Glass effects: [X using blur tokens, Y custom values]
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. [Most important fix]
|
||||
2. [Second priority]
|
||||
3. [Third priority]
|
||||
|
||||
**Estimated Effort**: [X hours for full refactor]
|
||||
```
|
||||
|
||||
## What to Scan
|
||||
|
||||
Based on the argument:
|
||||
|
||||
**If directory path** (e.g., `src/features/knowledge`):
|
||||
- Scan all `.tsx` files recursively
|
||||
- Analyze each component
|
||||
- Aggregate scores
|
||||
|
||||
**If single file** (e.g., `KnowledgeCard.tsx`):
|
||||
- Deep analysis of that component
|
||||
- Check all its dependencies
|
||||
- Compare to similar components
|
||||
|
||||
**If feature name** (e.g., `projects`):
|
||||
- Find feature directory
|
||||
- Scan all components
|
||||
- Check consistency within feature
|
||||
|
||||
## Red Flags to Auto-Detect
|
||||
|
||||
Use grep/glob to find:
|
||||
|
||||
```bash
|
||||
# Hardcoded edge-lit implementations
|
||||
grep -r "absolute inset-x-0 top-0" [path]
|
||||
|
||||
# Native HTML form elements
|
||||
grep -r "<select>\|<option>\|<input type=\"checkbox\"" [path]
|
||||
|
||||
# Hardcoded pill navigation
|
||||
grep -r "backdrop-blur-sm bg-white/40.*rounded-full" [path]
|
||||
|
||||
# Manual glassmorphism
|
||||
grep -r "bg-gradient-to-b from-white/\|from-purple-100/" [path]
|
||||
|
||||
# Hardcoded colors instead of semantic tokens
|
||||
grep -r "#[0-9a-fA-F]{6}" [path]
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Key Questions to Answer
|
||||
|
||||
1. **Does this component duplicate existing primitives?**
|
||||
2. **Should this be refactored to use Card with edgePosition/edgeColor?**
|
||||
3. **Are there native HTML elements that should be Radix?**
|
||||
4. **Is the glassmorphism consistent with the design system?**
|
||||
5. **Can multiple components be consolidated into one reusable primitive?**
|
||||
|
||||
---
|
||||
|
||||
Start the review now and save the report to `ui-consistency-review-[feature].md` in the project root.
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Settings, Palette, Key, Database, Code, Globe } from "lucide-react";
|
||||
import { Settings, Palette, Key, Database, Code, Globe, Moon, FileText, Flame, Monitor } from "lucide-react";
|
||||
import { CollapsibleSettingsCard } from "@/components/ui/CollapsibleSettingsCard";
|
||||
import { Card } from "@/features/ui/primitives/card";
|
||||
import { Switch } from "@/features/ui/primitives/switch";
|
||||
import { Input } from "@/features/ui/primitives/input";
|
||||
import { Label } from "@/features/ui/primitives/label";
|
||||
@@ -15,148 +16,218 @@ export const SettingsLayoutExample = () => {
|
||||
|
||||
{/* Bento Grid */}
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-6">
|
||||
{/* Features Section */}
|
||||
<CollapsibleSettingsCard
|
||||
title="Feature Toggles"
|
||||
title="Features"
|
||||
icon={Palette}
|
||||
accentColor="purple"
|
||||
defaultExpanded={true}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="projects-toggle">Enable Projects</Label>
|
||||
<Switch id="projects-toggle" defaultChecked />
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
{/* Dark Mode */}
|
||||
<div className="flex items-center gap-4 p-4 rounded-xl bg-gradient-to-br from-purple-500/10 to-purple-600/5 backdrop-blur-sm border border-purple-500/20 shadow-lg">
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="font-medium text-gray-800 dark:text-white text-sm">Dark Mode</p>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
Switch between themes
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex-shrink-0">
|
||||
<Switch size="lg" defaultChecked color="purple" iconOn={<Moon className="w-5 h-5" />} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="style-toggle">Style Guide</Label>
|
||||
<Switch id="style-toggle" defaultChecked />
|
||||
|
||||
{/* Projects */}
|
||||
<div className="flex items-center gap-4 p-4 rounded-xl bg-gradient-to-br from-blue-500/10 to-blue-600/5 backdrop-blur-sm border border-blue-500/20 shadow-lg">
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="font-medium text-gray-800 dark:text-white text-sm">Projects</p>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
Enable Projects functionality
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex-shrink-0">
|
||||
<Switch size="lg" defaultChecked color="blue" icon={<FileText className="w-5 h-5" />} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="dark-mode">Dark Mode</Label>
|
||||
<Switch id="dark-mode" defaultChecked />
|
||||
|
||||
{/* Style Guide */}
|
||||
<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 text-sm">Style Guide</p>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
Show UI components
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex-shrink-0">
|
||||
<Switch size="lg" defaultChecked color="cyan" icon={<Palette className="w-5 h-5" />} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Pydantic Logfire */}
|
||||
<div className="flex items-center gap-4 p-4 rounded-xl bg-gradient-to-br from-orange-500/10 to-orange-600/5 backdrop-blur-sm border border-orange-500/20 shadow-lg">
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="font-medium text-gray-800 dark:text-white text-sm">Pydantic Logfire</p>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
Logging platform
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex-shrink-0">
|
||||
<Switch size="lg" color="orange" icon={<Flame className="w-5 h-5" />} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* Disconnect Screen */}
|
||||
<div className="flex items-center gap-4 p-4 rounded-xl bg-gradient-to-br from-green-500/10 to-green-600/5 backdrop-blur-sm border border-green-500/20 shadow-lg">
|
||||
<div className="flex-1 min-w-0">
|
||||
<p className="font-medium text-gray-800 dark:text-white text-sm">Disconnect Screen</p>
|
||||
<p className="text-xs text-gray-500 dark:text-gray-400">
|
||||
Show when disconnected
|
||||
</p>
|
||||
</div>
|
||||
<div className="flex-shrink-0">
|
||||
<Switch size="lg" defaultChecked color="green" icon={<Monitor className="w-5 h-5" />} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CollapsibleSettingsCard>
|
||||
|
||||
<CollapsibleSettingsCard title="API Keys" icon={Key} accentColor="cyan" defaultExpanded={true}>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Label htmlFor="openai-key">OpenAI API Key</Label>
|
||||
<Input
|
||||
id="openai-key"
|
||||
type="password"
|
||||
placeholder="sk-..."
|
||||
className="mt-1"
|
||||
defaultValue="sk-example-key-hidden"
|
||||
/>
|
||||
{/* API Keys Section */}
|
||||
<CollapsibleSettingsCard title="API Keys" icon={Key} accentColor="pink" defaultExpanded={true}>
|
||||
<Card edgePosition="top" edgeColor="pink">
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mb-6">
|
||||
Manage your API keys and credentials for various services used by Archon.
|
||||
</p>
|
||||
<div className="space-y-4">
|
||||
<div>
|
||||
<Label htmlFor="openai-key" className="text-xs font-medium text-gray-600 dark:text-gray-400">
|
||||
OPENAI_API_KEY
|
||||
</Label>
|
||||
<Input
|
||||
id="openai-key"
|
||||
type="password"
|
||||
placeholder="Enter new value (encrypted)"
|
||||
className="mt-2"
|
||||
defaultValue="••••••••••••••••••"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="google-key" className="text-xs font-medium text-gray-600 dark:text-gray-400">
|
||||
GOOGLE_API_KEY
|
||||
</Label>
|
||||
<Input
|
||||
id="google-key"
|
||||
type="password"
|
||||
placeholder="Enter new value (encrypted)"
|
||||
className="mt-2"
|
||||
defaultValue="••••••••••••••••"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="anthropic-key">Anthropic API Key</Label>
|
||||
<Input
|
||||
id="anthropic-key"
|
||||
type="password"
|
||||
placeholder="sk-ant-..."
|
||||
className="mt-1"
|
||||
defaultValue="sk-ant-example-key"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</CollapsibleSettingsCard>
|
||||
|
||||
{/* Database Settings */}
|
||||
<CollapsibleSettingsCard
|
||||
title="Database Settings"
|
||||
icon={Database}
|
||||
accentColor="blue"
|
||||
defaultExpanded={false}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<Card edgePosition="top" edgeColor="blue">
|
||||
<div>
|
||||
<Label htmlFor="db-url">Database URL</Label>
|
||||
<Label htmlFor="db-url" className="text-sm font-medium">Database URL</Label>
|
||||
<Input
|
||||
id="db-url"
|
||||
placeholder="postgresql://..."
|
||||
className="mt-1"
|
||||
className="mt-2"
|
||||
defaultValue="postgresql://localhost:5432/archon"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="auto-backup">Auto Backup</Label>
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<Label htmlFor="auto-backup" className="text-sm font-medium">Auto Backup</Label>
|
||||
<Switch id="auto-backup" />
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</CollapsibleSettingsCard>
|
||||
|
||||
{/* Code Extraction */}
|
||||
<CollapsibleSettingsCard
|
||||
title="Code Extraction"
|
||||
icon={Code}
|
||||
accentColor="green"
|
||||
defaultExpanded={false}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="extract-code">Extract Code Examples</Label>
|
||||
<Card edgePosition="top" edgeColor="green">
|
||||
<p className="text-sm text-gray-500 dark:text-gray-400 mb-4">
|
||||
Configure how code blocks are extracted from crawled documents.
|
||||
</p>
|
||||
<div className="flex items-center justify-between mb-4">
|
||||
<Label htmlFor="extract-code" className="text-sm font-medium">Extract Code Examples</Label>
|
||||
<Switch id="extract-code" defaultChecked />
|
||||
</div>
|
||||
<div>
|
||||
<Label htmlFor="max-examples">Max Examples per Source</Label>
|
||||
<Label htmlFor="max-examples" className="text-sm font-medium">Max Examples per Source</Label>
|
||||
<Input
|
||||
id="max-examples"
|
||||
type="number"
|
||||
placeholder="50"
|
||||
className="mt-1"
|
||||
className="mt-2"
|
||||
defaultValue="50"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</CollapsibleSettingsCard>
|
||||
|
||||
{/* RAG Configuration */}
|
||||
<CollapsibleSettingsCard
|
||||
title="RAG Configuration"
|
||||
icon={Settings}
|
||||
accentColor="orange"
|
||||
defaultExpanded={true}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<Card edgePosition="top" edgeColor="orange">
|
||||
<div>
|
||||
<Label htmlFor="match-count">Match Count</Label>
|
||||
<Label htmlFor="match-count" className="text-sm font-medium">Match Count</Label>
|
||||
<Input
|
||||
id="match-count"
|
||||
type="number"
|
||||
placeholder="5"
|
||||
className="mt-1"
|
||||
className="mt-2"
|
||||
defaultValue="5"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="rerank">Enable Reranking</Label>
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<Label htmlFor="rerank" className="text-sm font-medium">Enable Reranking</Label>
|
||||
<Switch id="rerank" defaultChecked />
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</CollapsibleSettingsCard>
|
||||
|
||||
{/* Crawling Settings */}
|
||||
<CollapsibleSettingsCard
|
||||
title="Crawling Settings"
|
||||
icon={Globe}
|
||||
accentColor="pink"
|
||||
defaultExpanded={false}
|
||||
>
|
||||
<div className="space-y-4">
|
||||
<Card edgePosition="top" edgeColor="pink">
|
||||
<div>
|
||||
<Label htmlFor="max-depth">Max Crawl Depth</Label>
|
||||
<Label htmlFor="max-depth" className="text-sm font-medium">Max Crawl Depth</Label>
|
||||
<Input
|
||||
id="max-depth"
|
||||
type="number"
|
||||
placeholder="3"
|
||||
className="mt-1"
|
||||
className="mt-2"
|
||||
defaultValue="3"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex items-center justify-between">
|
||||
<Label htmlFor="follow-links">Follow External Links</Label>
|
||||
<div className="flex items-center justify-between mt-4">
|
||||
<Label htmlFor="follow-links" className="text-sm font-medium">Follow External Links</Label>
|
||||
<Switch id="follow-links" />
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</CollapsibleSettingsCard>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
};
|
||||
|
||||
@@ -21,8 +21,8 @@ interface CardProps extends React.HTMLAttributes<HTMLDivElement> {
|
||||
export const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
||||
({
|
||||
className,
|
||||
blur = 'xl', // Default to standard glass (3px blur - subtle)
|
||||
transparency = 'light', // Default to subtle transparency (3%)
|
||||
blur = 'xl',
|
||||
transparency = 'light',
|
||||
glassTint = 'none',
|
||||
glowColor = 'none',
|
||||
edgePosition = 'none',
|
||||
@@ -33,42 +33,69 @@ export const Card = React.forwardRef<HTMLDivElement, CardProps>(
|
||||
}, ref) => {
|
||||
const glowVariant = glassCard.variants[glowColor] || glassCard.variants.none;
|
||||
const hasEdge = edgePosition !== 'none';
|
||||
const isHorizontalEdge = edgePosition === 'top' || edgePosition === 'bottom';
|
||||
const edgeColorConfig = hasEdge ? glassCard.edgeLit.color[edgeColor] : null;
|
||||
|
||||
// Edge color mappings
|
||||
const edgeColors = {
|
||||
purple: { solid: 'bg-purple-500', gradient: 'from-purple-500/40', border: 'border-purple-500/30' },
|
||||
blue: { solid: 'bg-blue-500', gradient: 'from-blue-500/40', border: 'border-blue-500/30' },
|
||||
cyan: { solid: 'bg-cyan-500', gradient: 'from-cyan-500/40', border: 'border-cyan-500/30' },
|
||||
green: { solid: 'bg-green-500', gradient: 'from-green-500/40', border: 'border-green-500/30' },
|
||||
orange: { solid: 'bg-orange-500', gradient: 'from-orange-500/40', border: 'border-orange-500/30' },
|
||||
pink: { solid: 'bg-pink-500', gradient: 'from-pink-500/40', border: 'border-pink-500/30' },
|
||||
red: { solid: 'bg-red-500', gradient: 'from-red-500/40', border: 'border-red-500/30' },
|
||||
};
|
||||
|
||||
const edgeStyle = edgeColors[edgeColor];
|
||||
|
||||
// Tint backgrounds for edge-lit cards
|
||||
const tintBackgrounds = {
|
||||
purple: 'bg-gradient-to-br from-purple-500/15 to-purple-600/5',
|
||||
blue: 'bg-gradient-to-br from-blue-500/15 to-blue-600/5',
|
||||
cyan: 'bg-gradient-to-br from-cyan-500/15 to-cyan-600/5',
|
||||
green: 'bg-gradient-to-br from-green-500/15 to-green-600/5',
|
||||
orange: 'bg-gradient-to-br from-orange-500/15 to-orange-600/5',
|
||||
pink: 'bg-gradient-to-br from-pink-500/15 to-pink-600/5',
|
||||
red: 'bg-gradient-to-br from-red-500/15 to-red-600/5',
|
||||
};
|
||||
|
||||
if (hasEdge && edgePosition === 'top') {
|
||||
// Edge-lit card with actual div elements (not pseudo-elements)
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"relative rounded-xl overflow-hidden",
|
||||
edgeStyle.border,
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{/* Top edge light bar */}
|
||||
<div className={cn("absolute inset-x-0 top-0 h-[3px] pointer-events-none z-10", edgeStyle.solid)} />
|
||||
{/* Glow bleeding into card */}
|
||||
<div className={cn("absolute inset-x-0 top-0 h-16 bg-gradient-to-b to-transparent blur-lg pointer-events-none z-10", edgeStyle.gradient)} />
|
||||
{/* Content with tinted background */}
|
||||
<div className={cn("backdrop-blur-sm", tintBackgrounds[edgeColor], glassCard.sizes[size])}>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Standard card (no edge-lit)
|
||||
return (
|
||||
<div
|
||||
ref={ref}
|
||||
className={cn(
|
||||
// Base glass effect
|
||||
glassCard.base,
|
||||
|
||||
// Backdrop blur intensity - consistent glass effect
|
||||
glassCard.blur[blur],
|
||||
|
||||
// Apply background with proper transparency
|
||||
glassTint !== 'none'
|
||||
? glassCard.tints[glassTint][transparency]
|
||||
: glassCard.transparency[transparency],
|
||||
|
||||
// Size
|
||||
glassCard.sizes[size],
|
||||
|
||||
// Glow effects (border, shadow, hover) - only if no edge-lit
|
||||
!hasEdge && glowVariant.border,
|
||||
!hasEdge && glowVariant.glow,
|
||||
!hasEdge && glowVariant.hover,
|
||||
|
||||
// Edge-lit effects
|
||||
hasEdge && glassCard.edgeLit.position[edgePosition],
|
||||
hasEdge && edgeColorConfig ? edgeColorConfig.glow : false,
|
||||
hasEdge && edgeColorConfig ? (
|
||||
isHorizontalEdge
|
||||
? edgeColorConfig.gradient.horizontal
|
||||
: edgeColorConfig.gradient.vertical
|
||||
) : false,
|
||||
|
||||
// User overrides
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
|
||||
Reference in New Issue
Block a user