fix: add mode descriptions and remove double borders
Address two issues with the tab-style mode selector: 1. Add back helpful description text - Each mode now shows its description below the tabs - Description updates based on active tab - Preserves the helpful context from the old button layout 2. Remove double borders - Remove wrapper div that added extra background/padding - Let mode-specific controls use their own styling - Eliminates visual layering conflicts - Creates cleaner, more native tab-to-content flow Mode descriptions: - 🎯 Smart: "Research-backed progressive difficulty with adaptive scaffolding per problem" - 🎛️ Manual: "Full control over display options with uniform scaffolding across all problems" - 🎓 Mastery: "Skill-based progression with automatic review mixing for pedagogical practice" 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
8910f6a197
commit
6f2f6d444c
|
|
@ -105,39 +105,28 @@ export function ConfigPanel({ formState, onChange, isDark = false }: ConfigPanel
|
|||
isDark={isDark}
|
||||
/>
|
||||
|
||||
{/* Mode Selector Tabs */}
|
||||
{/* Mode Selector Tabs with description */}
|
||||
<ModeSelector
|
||||
currentMode={formState.mode ?? 'smart'}
|
||||
onChange={handleModeChange}
|
||||
isDark={isDark}
|
||||
/>
|
||||
|
||||
{/* Mode-specific controls as tab content */}
|
||||
<div
|
||||
data-element="mode-content"
|
||||
className={stack({
|
||||
gap: '3',
|
||||
padding: '1.5rem',
|
||||
backgroundColor: isDark ? 'gray.700' : 'gray.50',
|
||||
borderRadius: '0 0 8px 8px',
|
||||
marginTop: '-1.5rem', // Connect visually to tabs
|
||||
})}
|
||||
>
|
||||
{/* Smart Mode Controls */}
|
||||
{(!formState.mode || formState.mode === 'smart') && (
|
||||
<SmartModeControls formState={formState} onChange={onChange} isDark={isDark} />
|
||||
)}
|
||||
{/* Mode-specific controls - no wrapper, let controls style themselves */}
|
||||
{/* Smart Mode Controls */}
|
||||
{(!formState.mode || formState.mode === 'smart') && (
|
||||
<SmartModeControls formState={formState} onChange={onChange} isDark={isDark} />
|
||||
)}
|
||||
|
||||
{/* Manual Mode Controls */}
|
||||
{formState.mode === 'manual' && (
|
||||
<ManualModeControls formState={formState} onChange={onChange} isDark={isDark} />
|
||||
)}
|
||||
{/* Manual Mode Controls */}
|
||||
{formState.mode === 'manual' && (
|
||||
<ManualModeControls formState={formState} onChange={onChange} isDark={isDark} />
|
||||
)}
|
||||
|
||||
{/* Mastery Mode Controls */}
|
||||
{formState.mode === 'mastery' && (
|
||||
<MasteryModePanel formState={formState} onChange={onChange} isDark={isDark} />
|
||||
)}
|
||||
</div>
|
||||
{/* Mastery Mode Controls */}
|
||||
{formState.mode === 'mastery' && (
|
||||
<MasteryModePanel formState={formState} onChange={onChange} isDark={isDark} />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -18,93 +18,115 @@ export function ModeSelector({ currentMode, onChange, isDark = false }: ModeSele
|
|||
id: 'smart' as const,
|
||||
emoji: '🎯',
|
||||
label: 'Smart Difficulty',
|
||||
description: 'Research-backed progressive difficulty with adaptive scaffolding per problem',
|
||||
},
|
||||
{
|
||||
id: 'manual' as const,
|
||||
emoji: '🎛️',
|
||||
label: 'Manual Control',
|
||||
description: 'Full control over display options with uniform scaffolding across all problems',
|
||||
},
|
||||
{
|
||||
id: 'mastery' as const,
|
||||
emoji: '🎓',
|
||||
label: 'Mastery Progression',
|
||||
description: 'Skill-based progression with automatic review mixing for pedagogical practice',
|
||||
},
|
||||
]
|
||||
|
||||
const currentModeData = modes.find((m) => m.id === currentMode)
|
||||
|
||||
return (
|
||||
<div
|
||||
data-component="mode-selector-tabs"
|
||||
className={css({
|
||||
display: 'flex',
|
||||
gap: '0.5rem',
|
||||
borderBottom: '2px solid',
|
||||
borderColor: isDark ? 'gray.600' : 'gray.200',
|
||||
marginBottom: '1.5rem',
|
||||
})}
|
||||
>
|
||||
{modes.map((mode) => {
|
||||
const isActive = currentMode === mode.id
|
||||
return (
|
||||
<button
|
||||
key={mode.id}
|
||||
type="button"
|
||||
data-action={`select-${mode.id}-mode`}
|
||||
data-selected={isActive}
|
||||
onClick={() => onChange(mode.id)}
|
||||
className={css({
|
||||
flex: 1,
|
||||
padding: '1rem 1.5rem',
|
||||
border: 'none',
|
||||
borderBottom: '3px solid',
|
||||
borderBottomColor: isActive ? 'blue.500' : 'transparent',
|
||||
backgroundColor: isActive
|
||||
? isDark
|
||||
? 'gray.700'
|
||||
: 'white'
|
||||
: isDark
|
||||
? 'gray.800'
|
||||
: 'gray.50',
|
||||
color: isActive
|
||||
? isDark
|
||||
? 'blue.300'
|
||||
: 'blue.600'
|
||||
: isDark
|
||||
? 'gray.400'
|
||||
: 'gray.600',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.2s',
|
||||
fontSize: '0.95rem',
|
||||
fontWeight: isActive ? '700' : '500',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: '0.5rem',
|
||||
borderTopLeftRadius: '8px',
|
||||
borderTopRightRadius: '8px',
|
||||
_hover: {
|
||||
<div data-component="mode-selector-tabs">
|
||||
{/* Tab buttons */}
|
||||
<div
|
||||
className={css({
|
||||
display: 'flex',
|
||||
gap: '0.5rem',
|
||||
borderBottom: '2px solid',
|
||||
borderColor: isDark ? 'gray.600' : 'gray.200',
|
||||
})}
|
||||
>
|
||||
{modes.map((mode) => {
|
||||
const isActive = currentMode === mode.id
|
||||
return (
|
||||
<button
|
||||
key={mode.id}
|
||||
type="button"
|
||||
data-action={`select-${mode.id}-mode`}
|
||||
data-selected={isActive}
|
||||
onClick={() => onChange(mode.id)}
|
||||
className={css({
|
||||
flex: 1,
|
||||
padding: '1rem 1.5rem',
|
||||
border: 'none',
|
||||
borderBottom: '3px solid',
|
||||
borderBottomColor: isActive ? 'blue.500' : 'transparent',
|
||||
backgroundColor: isActive
|
||||
? isDark
|
||||
? 'gray.700'
|
||||
: 'white'
|
||||
: isDark
|
||||
? 'gray.700'
|
||||
: 'gray.100',
|
||||
borderBottomColor: isActive ? 'blue.500' : isDark ? 'gray.500' : 'gray.400',
|
||||
? 'gray.800'
|
||||
: 'gray.50',
|
||||
color: isActive
|
||||
? isDark
|
||||
? 'blue.300'
|
||||
: 'blue.600'
|
||||
: isDark
|
||||
? 'gray.300'
|
||||
: 'gray.700',
|
||||
},
|
||||
})}
|
||||
>
|
||||
<span className={css({ fontSize: '1.25rem' })}>{mode.emoji}</span>
|
||||
<span>{mode.label}</span>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
? 'gray.400'
|
||||
: 'gray.600',
|
||||
cursor: 'pointer',
|
||||
transition: 'all 0.2s',
|
||||
fontSize: '0.95rem',
|
||||
fontWeight: isActive ? '700' : '500',
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
gap: '0.5rem',
|
||||
borderTopLeftRadius: '8px',
|
||||
borderTopRightRadius: '8px',
|
||||
_hover: {
|
||||
backgroundColor: isActive
|
||||
? isDark
|
||||
? 'gray.700'
|
||||
: 'white'
|
||||
: isDark
|
||||
? 'gray.700'
|
||||
: 'gray.100',
|
||||
borderBottomColor: isActive ? 'blue.500' : isDark ? 'gray.500' : 'gray.400',
|
||||
color: isActive
|
||||
? isDark
|
||||
? 'blue.300'
|
||||
: 'blue.600'
|
||||
: isDark
|
||||
? 'gray.300'
|
||||
: 'gray.700',
|
||||
},
|
||||
})}
|
||||
>
|
||||
<span className={css({ fontSize: '1.25rem' })}>{mode.emoji}</span>
|
||||
<span>{mode.label}</span>
|
||||
</button>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Description of active mode */}
|
||||
{currentModeData && (
|
||||
<p
|
||||
className={css({
|
||||
fontSize: 'sm',
|
||||
color: isDark ? 'gray.400' : 'gray.600',
|
||||
mt: '3',
|
||||
mb: '3',
|
||||
px: '2',
|
||||
lineHeight: '1.5',
|
||||
})}
|
||||
>
|
||||
{currentModeData.description}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue