feat(worksheets): display scaffolding attributes on separate lines with fixed button height
Changes: - Each attribute (regrouping %, always items, conditional items) now on its own line - Added minH: '20' to dropdown button to prevent height changes as slider moves - Updated getScaffoldingSummary() to return multi-line JSX instead of single string - Consistent formatting across dropdown trigger and menu items Before: 25% regrouping • Always: carry boxes, answer boxes • When needed: ten-frames After (multi-line): 25% regrouping Always: carry boxes, answer boxes When needed: ten-frames This improves readability and prevents the button from resizing vertically as the user moves the difficulty slider (scrubber). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -36,9 +36,9 @@ interface ConfigPanelProps {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Generate a human-readable summary of enabled scaffolding aids
|
* Generate a human-readable summary of enabled scaffolding aids
|
||||||
* Groups by frequency: "Always: x, y • When needed: z"
|
* Returns JSX with each frequency group on its own line
|
||||||
*/
|
*/
|
||||||
function getScaffoldingSummary(displayRules: any): string {
|
function getScaffoldingSummary(displayRules: any): React.ReactNode {
|
||||||
console.log('[getScaffoldingSummary] displayRules:', displayRules)
|
console.log('[getScaffoldingSummary] displayRules:', displayRules)
|
||||||
|
|
||||||
const alwaysItems: string[] = []
|
const alwaysItems: string[] = []
|
||||||
@@ -68,20 +68,19 @@ function getScaffoldingSummary(displayRules: any): string {
|
|||||||
conditionalItems.push('ten-frames')
|
conditionalItems.push('ten-frames')
|
||||||
}
|
}
|
||||||
|
|
||||||
const parts: string[] = []
|
if (alwaysItems.length === 0 && conditionalItems.length === 0) {
|
||||||
|
console.log('[getScaffoldingSummary] Final summary: no scaffolding')
|
||||||
if (alwaysItems.length > 0) {
|
return <span className={css({ color: 'gray.500', fontStyle: 'italic' })}>no scaffolding</span>
|
||||||
parts.push(`Always: ${alwaysItems.join(', ')}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (conditionalItems.length > 0) {
|
console.log('[getScaffoldingSummary] Final summary:', { alwaysItems, conditionalItems })
|
||||||
parts.push(`When needed: ${conditionalItems.join(', ')}`)
|
|
||||||
}
|
|
||||||
|
|
||||||
const summary = parts.length > 0 ? parts.join(' • ') : 'no scaffolding'
|
return (
|
||||||
console.log('[getScaffoldingSummary] Final summary:', summary)
|
<div className={css({ display: 'flex', flexDirection: 'column', gap: '0.5' })}>
|
||||||
|
{alwaysItems.length > 0 && <div>Always: {alwaysItems.join(', ')}</div>}
|
||||||
return summary
|
{conditionalItems.length > 0 && <div>When needed: {conditionalItems.join(', ')}</div>}
|
||||||
|
</div>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ToggleOptionProps {
|
interface ToggleOptionProps {
|
||||||
@@ -422,7 +421,7 @@ export function ConfigPanel({ formState, onChange }: ConfigPanelProps) {
|
|||||||
// Find nearest presets for custom configurations
|
// Find nearest presets for custom configurations
|
||||||
let nearestEasier: DifficultyLevel | null = null
|
let nearestEasier: DifficultyLevel | null = null
|
||||||
let nearestHarder: DifficultyLevel | null = null
|
let nearestHarder: DifficultyLevel | null = null
|
||||||
let customDescription = ''
|
let customDescription: React.ReactNode = ''
|
||||||
|
|
||||||
if (isCustom) {
|
if (isCustom) {
|
||||||
const currentRegrouping = calculateRegroupingIntensity(pAnyStart, pAllStart)
|
const currentRegrouping = calculateRegroupingIntensity(pAnyStart, pAllStart)
|
||||||
@@ -477,7 +476,12 @@ export function ConfigPanel({ formState, onChange }: ConfigPanelProps) {
|
|||||||
// Generate custom description
|
// Generate custom description
|
||||||
const regroupingPercent = Math.round(currentRegrouping * 10)
|
const regroupingPercent = Math.round(currentRegrouping * 10)
|
||||||
const scaffoldingSummary = getScaffoldingSummary(displayRules)
|
const scaffoldingSummary = getScaffoldingSummary(displayRules)
|
||||||
customDescription = `${regroupingPercent}% regrouping • ${scaffoldingSummary}`
|
customDescription = (
|
||||||
|
<>
|
||||||
|
<div>{regroupingPercent}% regrouping</div>
|
||||||
|
{scaffoldingSummary}
|
||||||
|
</>
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculate current difficulty position
|
// Calculate current difficulty position
|
||||||
@@ -580,6 +584,7 @@ export function ConfigPanel({ formState, onChange }: ConfigPanelProps) {
|
|||||||
data-action="open-preset-dropdown"
|
data-action="open-preset-dropdown"
|
||||||
className={css({
|
className={css({
|
||||||
w: 'full',
|
w: 'full',
|
||||||
|
minH: '20',
|
||||||
px: '3',
|
px: '3',
|
||||||
py: '2.5',
|
py: '2.5',
|
||||||
border: '2px solid',
|
border: '2px solid',
|
||||||
@@ -636,23 +641,36 @@ export function ConfigPanel({ formState, onChange }: ConfigPanelProps) {
|
|||||||
lineHeight: '1.3',
|
lineHeight: '1.3',
|
||||||
})}
|
})}
|
||||||
>
|
>
|
||||||
{isCustom
|
{isCustom ? (
|
||||||
? customDescription
|
customDescription
|
||||||
: currentProfile
|
) : currentProfile ? (
|
||||||
? (() => {
|
(() => {
|
||||||
const preset = DIFFICULTY_PROFILES[currentProfile]
|
const preset = DIFFICULTY_PROFILES[currentProfile]
|
||||||
const regroupingPercent = Math.round(
|
const regroupingPercent = Math.round(
|
||||||
calculateRegroupingIntensity(
|
calculateRegroupingIntensity(
|
||||||
preset.regrouping.pAnyStart,
|
preset.regrouping.pAnyStart,
|
||||||
preset.regrouping.pAllStart
|
preset.regrouping.pAllStart
|
||||||
) * 10
|
) * 10
|
||||||
)
|
)
|
||||||
const scaffoldingSummary = getScaffoldingSummary(
|
const scaffoldingSummary = getScaffoldingSummary(
|
||||||
preset.displayRules
|
preset.displayRules
|
||||||
)
|
)
|
||||||
return `${regroupingPercent}% regrouping • ${scaffoldingSummary}`
|
return (
|
||||||
})()
|
<>
|
||||||
: '25% regrouping • Always: carry boxes, answer boxes, place value colors, ten-frames'}
|
<div>{regroupingPercent}% regrouping</div>
|
||||||
|
{scaffoldingSummary}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
})()
|
||||||
|
) : (
|
||||||
|
<>
|
||||||
|
<div>25% regrouping</div>
|
||||||
|
<div>
|
||||||
|
Always: carry boxes, answer boxes, place value colors,
|
||||||
|
ten-frames
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
@@ -691,7 +709,12 @@ export function ConfigPanel({ formState, onChange }: ConfigPanelProps) {
|
|||||||
) * 10
|
) * 10
|
||||||
)
|
)
|
||||||
const scaffoldingSummary = getScaffoldingSummary(preset.displayRules)
|
const scaffoldingSummary = getScaffoldingSummary(preset.displayRules)
|
||||||
const presetDescription = `${regroupingPercent}% regrouping • ${scaffoldingSummary}`
|
const presetDescription = (
|
||||||
|
<>
|
||||||
|
<div>{regroupingPercent}% regrouping</div>
|
||||||
|
{scaffoldingSummary}
|
||||||
|
</>
|
||||||
|
)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
|
|||||||
Reference in New Issue
Block a user