feat: add infrastructure for borrowing hints toggle
Add new showBorrowingHints toggle to guide students through borrowing: - Add showBorrowingHints field to V4 manual config schema - Add toggle to ConfigPanel UI (shows for subtraction/mixed only) - Wire through validation, auto-save, preview, and example route - Update typstGenerator and typstHelpers to accept parameter - Default to false for backward compatibility This commit adds the plumbing/infrastructure. The actual Typst rendering logic for arrows and calculations will be implemented next. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -32,6 +32,7 @@ interface ExampleRequest {
|
||||
showTenFrames?: boolean
|
||||
showTenFramesForAll?: boolean
|
||||
showBorrowNotation?: boolean
|
||||
showBorrowingHints?: boolean
|
||||
fontSize?: number
|
||||
operator?: WorksheetOperator
|
||||
// For addition
|
||||
@@ -59,6 +60,7 @@ function generateExampleTypst(config: ExampleRequest): string {
|
||||
const showTenFrames = config.showTenFrames ?? false
|
||||
const showTenFramesForAll = config.showTenFramesForAll ?? false
|
||||
const showBorrowNotation = config.showBorrowNotation ?? true
|
||||
const showBorrowingHints = config.showBorrowingHints ?? false
|
||||
|
||||
if (operator === 'addition') {
|
||||
// Use custom addends if provided, otherwise generate a problem
|
||||
@@ -128,6 +130,7 @@ ${generateProblemStackFunction(cellSize, 3)}
|
||||
#let show-ten-frames = ${showTenFrames ? 'true' : 'false'}
|
||||
#let show-ten-frames-for-all = ${showTenFramesForAll ? 'true' : 'false'}
|
||||
#let show-borrow-notation = ${showBorrowNotation ? 'true' : 'false'}
|
||||
#let show-borrowing-hints = ${showBorrowingHints ? 'true' : 'false'}
|
||||
|
||||
${generateTypstHelpers(cellSize)}
|
||||
|
||||
@@ -137,7 +140,7 @@ ${generateSubtractionProblemStackFunction(cellSize, 3)}
|
||||
#let subtrahend = ${subtrahend}
|
||||
|
||||
#align(center + horizon)[
|
||||
#subtraction-problem-stack(minuend, subtrahend, if show-numbers { 0 } else { none }, show-borrows, show-answers, show-colors, show-ten-frames, show-numbers, show-borrow-notation)
|
||||
#subtraction-problem-stack(minuend, subtrahend, if show-numbers { 0 } else { none }, show-borrows, show-answers, show-colors, show-ten-frames, show-numbers, show-borrow-notation, show-borrowing-hints)
|
||||
]
|
||||
`
|
||||
}
|
||||
|
||||
@@ -2372,6 +2372,15 @@ export function ConfigPanel({ formState, onChange }: ConfigPanelProps) {
|
||||
/>
|
||||
)}
|
||||
|
||||
{(formState.operator === 'subtraction' || formState.operator === 'mixed') && (
|
||||
<ToggleOption
|
||||
checked={formState.showBorrowingHints ?? false}
|
||||
onChange={(checked) => onChange({ showBorrowingHints: checked })}
|
||||
label="Borrowing Hints"
|
||||
description="Show arrows and calculations guiding the borrowing process"
|
||||
/>
|
||||
)}
|
||||
|
||||
<ToggleOption
|
||||
checked={formState.showTenFrames ?? false}
|
||||
onChange={(checked) => {
|
||||
|
||||
@@ -180,6 +180,7 @@ export function DisplayOptionsPreview({ formState }: DisplayOptionsPreviewProps)
|
||||
showTenFrames: formState.showTenFrames ?? false,
|
||||
showTenFramesForAll: formState.showTenFramesForAll ?? false,
|
||||
showBorrowNotation: formState.showBorrowNotation ?? true,
|
||||
showBorrowingHints: formState.showBorrowingHints ?? false,
|
||||
operator,
|
||||
}
|
||||
|
||||
@@ -217,6 +218,7 @@ export function DisplayOptionsPreview({ formState }: DisplayOptionsPreviewProps)
|
||||
formState.showTenFrames,
|
||||
formState.showTenFramesForAll,
|
||||
formState.showBorrowNotation,
|
||||
formState.showBorrowingHints,
|
||||
formState.operator,
|
||||
operands,
|
||||
])
|
||||
|
||||
@@ -64,6 +64,7 @@ export function useWorksheetAutoSave(
|
||||
showTenFrames,
|
||||
showTenFramesForAll,
|
||||
showBorrowNotation,
|
||||
showBorrowingHints,
|
||||
fontSize,
|
||||
mode,
|
||||
difficultyProfile,
|
||||
@@ -95,6 +96,7 @@ export function useWorksheetAutoSave(
|
||||
showTenFrames,
|
||||
showTenFramesForAll,
|
||||
showBorrowNotation,
|
||||
showBorrowingHints,
|
||||
fontSize,
|
||||
mode,
|
||||
difficultyProfile,
|
||||
|
||||
@@ -85,6 +85,7 @@ function generatePageTypst(
|
||||
...p,
|
||||
...displayOptions,
|
||||
showBorrowNotation: false, // Smart mode doesn't have borrow notation (yet)
|
||||
showBorrowingHints: false, // Smart mode doesn't have borrowing hints (yet)
|
||||
}
|
||||
} else {
|
||||
// Manual mode: Uniform display across all problems
|
||||
@@ -110,6 +111,7 @@ function generatePageTypst(
|
||||
showProblemNumbers: config.showProblemNumbers,
|
||||
showCellBorder: config.showCellBorder,
|
||||
showBorrowNotation: 'showBorrowNotation' in config ? config.showBorrowNotation : true,
|
||||
showBorrowingHints: 'showBorrowingHints' in config ? config.showBorrowingHints : false,
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -118,9 +120,9 @@ function generatePageTypst(
|
||||
const problemsTypst = enrichedProblems
|
||||
.map((p) => {
|
||||
if (p.operator === '+') {
|
||||
return ` (operator: "+", a: ${p.a}, b: ${p.b}, showCarryBoxes: ${p.showCarryBoxes}, showAnswerBoxes: ${p.showAnswerBoxes}, showPlaceValueColors: ${p.showPlaceValueColors}, showTenFrames: ${p.showTenFrames}, showProblemNumbers: ${p.showProblemNumbers}, showCellBorder: ${p.showCellBorder}, showBorrowNotation: ${p.showBorrowNotation}),`
|
||||
return ` (operator: "+", a: ${p.a}, b: ${p.b}, showCarryBoxes: ${p.showCarryBoxes}, showAnswerBoxes: ${p.showAnswerBoxes}, showPlaceValueColors: ${p.showPlaceValueColors}, showTenFrames: ${p.showTenFrames}, showProblemNumbers: ${p.showProblemNumbers}, showCellBorder: ${p.showCellBorder}, showBorrowNotation: ${p.showBorrowNotation}, showBorrowingHints: ${p.showBorrowingHints}),`
|
||||
} else {
|
||||
return ` (operator: "−", minuend: ${p.minuend}, subtrahend: ${p.subtrahend}, showCarryBoxes: ${p.showCarryBoxes}, showAnswerBoxes: ${p.showAnswerBoxes}, showPlaceValueColors: ${p.showPlaceValueColors}, showTenFrames: ${p.showTenFrames}, showProblemNumbers: ${p.showProblemNumbers}, showCellBorder: ${p.showCellBorder}, showBorrowNotation: ${p.showBorrowNotation}),`
|
||||
return ` (operator: "−", minuend: ${p.minuend}, subtrahend: ${p.subtrahend}, showCarryBoxes: ${p.showCarryBoxes}, showAnswerBoxes: ${p.showAnswerBoxes}, showPlaceValueColors: ${p.showPlaceValueColors}, showTenFrames: ${p.showTenFrames}, showProblemNumbers: ${p.showProblemNumbers}, showCellBorder: ${p.showCellBorder}, showBorrowNotation: ${p.showBorrowNotation}, showBorrowingHints: ${p.showBorrowingHints}),`
|
||||
}
|
||||
})
|
||||
.join('\n')
|
||||
@@ -217,7 +219,8 @@ ${generateSubtractionProblemStackFunction(cellSize, maxDigits)}
|
||||
problem.showPlaceValueColors,
|
||||
problem.showTenFrames,
|
||||
problem.showProblemNumbers,
|
||||
problem.showBorrowNotation
|
||||
problem.showBorrowNotation,
|
||||
problem.showBorrowingHints
|
||||
)
|
||||
}
|
||||
]
|
||||
|
||||
@@ -355,8 +355,8 @@ export function generateSubtractionProblemStackFunction(
|
||||
return String.raw`
|
||||
// Subtraction problem rendering function (supports 1-${maxDigits} digit problems)
|
||||
// Returns the stack/grid structure for rendering a single subtraction problem
|
||||
// Per-problem display flags: show-borrows, show-answers, show-colors, show-ten-frames, show-numbers, show-borrow-notation
|
||||
#let subtraction-problem-stack(minuend, subtrahend, index-or-none, show-borrows, show-answers, show-colors, show-ten-frames, show-numbers, show-borrow-notation) = {
|
||||
// Per-problem display flags: show-borrows, show-answers, show-colors, show-ten-frames, show-numbers, show-borrow-notation, show-borrowing-hints
|
||||
#let subtraction-problem-stack(minuend, subtrahend, index-or-none, show-borrows, show-answers, show-colors, show-ten-frames, show-numbers, show-borrow-notation, show-borrowing-hints) = {
|
||||
// Place value colors array for dynamic lookup
|
||||
let place-colors = (${placeColors.join(', ')})
|
||||
|
||||
|
||||
@@ -169,6 +169,7 @@ export function validateWorksheetConfig(formState: WorksheetFormState): Validati
|
||||
showCellBorder: formState.showCellBorder ?? true,
|
||||
showTenFramesForAll: formState.showTenFramesForAll ?? false,
|
||||
showBorrowNotation: formState.showBorrowNotation ?? true,
|
||||
showBorrowingHints: formState.showBorrowingHints ?? false,
|
||||
manualPreset: formState.manualPreset,
|
||||
...sharedFields,
|
||||
}
|
||||
|
||||
@@ -330,6 +330,7 @@ const additionConfigV4ManualSchema = additionConfigV4BaseSchema.extend({
|
||||
showCellBorder: z.boolean(),
|
||||
showTenFramesForAll: z.boolean(),
|
||||
showBorrowNotation: z.boolean(), // Scratch boxes for borrowing work
|
||||
showBorrowingHints: z.boolean(), // Visual hints showing what to write when borrowing
|
||||
|
||||
// Optional: Which manual preset is selected
|
||||
manualPreset: z.string().optional(),
|
||||
@@ -507,6 +508,7 @@ function migrateAdditionV3toV4(v3: AdditionConfigV3): AdditionConfigV4 {
|
||||
showCellBorder: v3.showCellBorder,
|
||||
showTenFramesForAll: v3.showTenFramesForAll,
|
||||
showBorrowNotation: true, // V4: Default to true for backward compatibility
|
||||
showBorrowingHints: false, // V4: Default to false for backward compatibility
|
||||
manualPreset: v3.manualPreset,
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user