feat: move difficulty parameters into Smart mode

Group difficulty configuration parameters inside Smart Difficulty mode:
- Digit Range moved from always-visible to Smart mode
- Regrouping Frequency moved from always-visible to Smart mode
- These are difficulty tuning parameters, not general settings

Changes:
- Add DigitRangeSection to top of SmartModeControls
- Add RegroupingFrequencyPanel to bottom of SmartModeControls
- Extract RegroupingFrequencyPanel as standalone component
- Remove both from ConfigPanel's always-visible section

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock 2025-11-10 18:12:23 -06:00
parent 804fb1a2f6
commit 4b667587f8
2 changed files with 184 additions and 12 deletions

View File

@ -0,0 +1,168 @@
'use client'
import * as Slider from '@radix-ui/react-slider'
import { css } from '../../../../../../../styled-system/css'
import { stack } from '../../../../../../../styled-system/patterns'
import type { WorksheetFormState } from '../../types'
export interface RegroupingFrequencyPanelProps {
formState: WorksheetFormState
onChange: (updates: Partial<WorksheetFormState>) => void
isDark?: boolean
}
export function RegroupingFrequencyPanel({
formState,
onChange,
isDark = false,
}: RegroupingFrequencyPanelProps) {
return (
<div
data-section="regrouping"
className={css({
bg: isDark ? 'gray.800' : 'gray.50',
border: '1px solid',
borderColor: isDark ? 'gray.600' : 'gray.200',
rounded: 'xl',
p: '3',
})}
>
<div className={stack({ gap: '2.5' })}>
<div
className={css({
fontSize: 'xs',
fontWeight: 'semibold',
color: isDark ? 'gray.400' : 'gray.500',
textTransform: 'uppercase',
letterSpacing: 'wider',
})}
>
Regrouping Frequency
</div>
{/* Current values display */}
<div
className={css({
display: 'flex',
justifyContent: 'space-between',
fontSize: 'xs',
color: isDark ? 'gray.400' : 'gray.600',
})}
>
<div>
Both:{' '}
<span
className={css({
color: 'brand.600',
fontWeight: 'semibold',
})}
>
{Math.round((formState.pAllStart || 0) * 100)}%
</span>
</div>
<div>
Any:{' '}
<span
className={css({
color: 'brand.600',
fontWeight: 'semibold',
})}
>
{Math.round((formState.pAnyStart || 0.25) * 100)}%
</span>
</div>
</div>
{/* Double-thumbed range slider */}
<Slider.Root
className={css({
position: 'relative',
display: 'flex',
alignItems: 'center',
userSelect: 'none',
touchAction: 'none',
width: 'full',
height: '6',
})}
value={[(formState.pAllStart || 0) * 100, (formState.pAnyStart || 0.25) * 100]}
onValueChange={(values) => {
onChange({
pAllStart: values[0] / 100,
pAnyStart: values[1] / 100,
})
}}
min={0}
max={100}
step={5}
minStepsBetweenThumbs={0}
>
<Slider.Track
className={css({
position: 'relative',
flexGrow: 1,
bg: 'gray.200',
rounded: 'full',
height: '1.5',
})}
>
<Slider.Range
className={css({
position: 'absolute',
bg: 'brand.500',
rounded: 'full',
height: 'full',
})}
/>
</Slider.Track>
<Slider.Thumb
className={css({
display: 'block',
width: '3.5',
height: '3.5',
bg: 'white',
boxShadow: '0 2px 4px rgba(0,0,0,0.15)',
rounded: 'full',
border: '2px solid',
borderColor: 'brand.500',
cursor: 'pointer',
_hover: { transform: 'scale(1.1)' },
_focus: {
outline: 'none',
boxShadow: '0 0 0 3px rgba(59, 130, 246, 0.3)',
},
})}
/>
<Slider.Thumb
className={css({
display: 'block',
width: '3.5',
height: '3.5',
bg: 'white',
boxShadow: '0 2px 4px rgba(0,0,0,0.15)',
rounded: 'full',
border: '2px solid',
borderColor: 'brand.600',
cursor: 'pointer',
_hover: { transform: 'scale(1.1)' },
_focus: {
outline: 'none',
boxShadow: '0 0 0 3px rgba(59, 130, 246, 0.3)',
},
})}
/>
</Slider.Root>
<div
className={css({
fontSize: '2xs',
color: isDark ? 'gray.400' : 'gray.500',
lineHeight: '1.3',
})}
>
Regrouping difficulty at worksheet start (Both = all columns regroup, Any = at least one
column regroups)
</div>
</div>
</div>
)
}

View File

@ -25,6 +25,8 @@ import {
} from '../../difficultyProfiles'
import type { DisplayRules } from '../../displayRules'
import { getScaffoldingSummary } from './utils'
import { RegroupingFrequencyPanel } from './RegroupingFrequencyPanel'
import { DigitRangeSection } from './DigitRangeSection'
export interface SmartModeControlsProps {
formState: WorksheetFormState
@ -74,22 +76,21 @@ export function SmartModeControls({ formState, onChange, isDark = false }: Smart
}
return (
<div
data-section="difficulty"
className={css({
bg: 'gray.50',
border: '1px solid',
borderColor: 'gray.200',
rounded: 'xl',
p: '3',
})}
>
<div className={stack({ gap: '2.5' })}>
<div data-section="smart-mode" className={stack({ gap: '3' })}>
{/* Digit Range */}
<DigitRangeSection
digitRange={formState.digitRange}
onChange={(digitRange) => onChange({ digitRange })}
isDark={isDark}
/>
{/* Difficulty Level */}
<div data-section="difficulty" className={stack({ gap: '2.5' })}>
<div
className={css({
fontSize: 'xs',
fontWeight: 'semibold',
color: 'gray.500',
color: isDark ? 'gray.400' : 'gray.500',
textTransform: 'uppercase',
letterSpacing: 'wider',
})}
@ -1478,6 +1479,9 @@ export function SmartModeControls({ formState, onChange, isDark = false }: Smart
)
})()}
</div>
{/* Regrouping Frequency */}
<RegroupingFrequencyPanel formState={formState} onChange={onChange} isDark={isDark} />
</div>
)
}