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:
@@ -105,39 +105,28 @@ export function ConfigPanel({ formState, onChange, isDark = false }: ConfigPanel
|
|||||||
isDark={isDark}
|
isDark={isDark}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Mode Selector Tabs */}
|
{/* Mode Selector Tabs with description */}
|
||||||
<ModeSelector
|
<ModeSelector
|
||||||
currentMode={formState.mode ?? 'smart'}
|
currentMode={formState.mode ?? 'smart'}
|
||||||
onChange={handleModeChange}
|
onChange={handleModeChange}
|
||||||
isDark={isDark}
|
isDark={isDark}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* Mode-specific controls as tab content */}
|
{/* Mode-specific controls - no wrapper, let controls style themselves */}
|
||||||
<div
|
{/* Smart Mode Controls */}
|
||||||
data-element="mode-content"
|
{(!formState.mode || formState.mode === 'smart') && (
|
||||||
className={stack({
|
<SmartModeControls formState={formState} onChange={onChange} isDark={isDark} />
|
||||||
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} />
|
|
||||||
)}
|
|
||||||
|
|
||||||
{/* Manual Mode Controls */}
|
{/* Manual Mode Controls */}
|
||||||
{formState.mode === 'manual' && (
|
{formState.mode === 'manual' && (
|
||||||
<ManualModeControls formState={formState} onChange={onChange} isDark={isDark} />
|
<ManualModeControls formState={formState} onChange={onChange} isDark={isDark} />
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Mastery Mode Controls */}
|
{/* Mastery Mode Controls */}
|
||||||
{formState.mode === 'mastery' && (
|
{formState.mode === 'mastery' && (
|
||||||
<MasteryModePanel formState={formState} onChange={onChange} isDark={isDark} />
|
<MasteryModePanel formState={formState} onChange={onChange} isDark={isDark} />
|
||||||
)}
|
)}
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,93 +18,115 @@ export function ModeSelector({ currentMode, onChange, isDark = false }: ModeSele
|
|||||||
id: 'smart' as const,
|
id: 'smart' as const,
|
||||||
emoji: '🎯',
|
emoji: '🎯',
|
||||||
label: 'Smart Difficulty',
|
label: 'Smart Difficulty',
|
||||||
|
description: 'Research-backed progressive difficulty with adaptive scaffolding per problem',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'manual' as const,
|
id: 'manual' as const,
|
||||||
emoji: '🎛️',
|
emoji: '🎛️',
|
||||||
label: 'Manual Control',
|
label: 'Manual Control',
|
||||||
|
description: 'Full control over display options with uniform scaffolding across all problems',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
id: 'mastery' as const,
|
id: 'mastery' as const,
|
||||||
emoji: '🎓',
|
emoji: '🎓',
|
||||||
label: 'Mastery Progression',
|
label: 'Mastery Progression',
|
||||||
|
description: 'Skill-based progression with automatic review mixing for pedagogical practice',
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
|
|
||||||
|
const currentModeData = modes.find((m) => m.id === currentMode)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div data-component="mode-selector-tabs">
|
||||||
data-component="mode-selector-tabs"
|
{/* Tab buttons */}
|
||||||
className={css({
|
<div
|
||||||
display: 'flex',
|
className={css({
|
||||||
gap: '0.5rem',
|
display: 'flex',
|
||||||
borderBottom: '2px solid',
|
gap: '0.5rem',
|
||||||
borderColor: isDark ? 'gray.600' : 'gray.200',
|
borderBottom: '2px solid',
|
||||||
marginBottom: '1.5rem',
|
borderColor: isDark ? 'gray.600' : 'gray.200',
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{modes.map((mode) => {
|
{modes.map((mode) => {
|
||||||
const isActive = currentMode === mode.id
|
const isActive = currentMode === mode.id
|
||||||
return (
|
return (
|
||||||
<button
|
<button
|
||||||
key={mode.id}
|
key={mode.id}
|
||||||
type="button"
|
type="button"
|
||||||
data-action={`select-${mode.id}-mode`}
|
data-action={`select-${mode.id}-mode`}
|
||||||
data-selected={isActive}
|
data-selected={isActive}
|
||||||
onClick={() => onChange(mode.id)}
|
onClick={() => onChange(mode.id)}
|
||||||
className={css({
|
className={css({
|
||||||
flex: 1,
|
flex: 1,
|
||||||
padding: '1rem 1.5rem',
|
padding: '1rem 1.5rem',
|
||||||
border: 'none',
|
border: 'none',
|
||||||
borderBottom: '3px solid',
|
borderBottom: '3px solid',
|
||||||
borderBottomColor: isActive ? 'blue.500' : 'transparent',
|
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: {
|
|
||||||
backgroundColor: isActive
|
backgroundColor: isActive
|
||||||
? isDark
|
? isDark
|
||||||
? 'gray.700'
|
? 'gray.700'
|
||||||
: 'white'
|
: 'white'
|
||||||
: isDark
|
: isDark
|
||||||
? 'gray.700'
|
? 'gray.800'
|
||||||
: 'gray.100',
|
: 'gray.50',
|
||||||
borderBottomColor: isActive ? 'blue.500' : isDark ? 'gray.500' : 'gray.400',
|
|
||||||
color: isActive
|
color: isActive
|
||||||
? isDark
|
? isDark
|
||||||
? 'blue.300'
|
? 'blue.300'
|
||||||
: 'blue.600'
|
: 'blue.600'
|
||||||
: isDark
|
: isDark
|
||||||
? 'gray.300'
|
? 'gray.400'
|
||||||
: 'gray.700',
|
: 'gray.600',
|
||||||
},
|
cursor: 'pointer',
|
||||||
})}
|
transition: 'all 0.2s',
|
||||||
>
|
fontSize: '0.95rem',
|
||||||
<span className={css({ fontSize: '1.25rem' })}>{mode.emoji}</span>
|
fontWeight: isActive ? '700' : '500',
|
||||||
<span>{mode.label}</span>
|
display: 'flex',
|
||||||
</button>
|
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>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user