From 804fb1a2f65e647919e2c6eb0bd0d83763b65f0e Mon Sep 17 00:00:00 2001 From: Thomas Hallock Date: Mon, 10 Nov 2025 18:12:22 -0600 Subject: [PATCH] feat: make scaffolding and preview collapsible MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make pedagogical scaffolding controls collapsible (power user feature): - Pedagogical Scaffolding section collapsed by default - Live Preview nested inside, also collapsed by default - Use Radix UI Collapsible for smooth accordion behavior Changes: - Add DisplayControlsPanel component with collapsible sections - Pedagogical Scaffolding header with "(Advanced)" label - Live Preview header with "(Optional)" label - Animated arrow indicators for expand/collapse state 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .../components/DisplayControlsPanel.tsx | 307 ++++++++++++++++++ 1 file changed, 307 insertions(+) create mode 100644 apps/web/src/app/create/worksheets/addition/components/DisplayControlsPanel.tsx diff --git a/apps/web/src/app/create/worksheets/addition/components/DisplayControlsPanel.tsx b/apps/web/src/app/create/worksheets/addition/components/DisplayControlsPanel.tsx new file mode 100644 index 00000000..d88e4436 --- /dev/null +++ b/apps/web/src/app/create/worksheets/addition/components/DisplayControlsPanel.tsx @@ -0,0 +1,307 @@ +'use client' + +import { useState } from 'react' +import * as Collapsible from '@radix-ui/react-collapsible' +import { css } from '../../../../../../styled-system/css' +import { stack } from '../../../../../../styled-system/patterns' +import type { WorksheetFormState } from '../types' +import type { DisplayRules } from '../displayRules' +import { defaultAdditionConfig } from '@/app/create/worksheets/config-schemas' +import { RuleThermometer } from './config-panel/RuleThermometer' +import { DisplayOptionsPreview } from './DisplayOptionsPreview' + +export interface DisplayControlsPanelProps { + formState: WorksheetFormState + onChange: (updates: Partial) => void + isDark?: boolean +} + +export function DisplayControlsPanel({ + formState, + onChange, + isDark = false, +}: DisplayControlsPanelProps) { + const [isOpen, setIsOpen] = useState(false) + const [isPreviewOpen, setIsPreviewOpen] = useState(false) + + // Get current displayRules or use defaults + const displayRules: DisplayRules = formState.displayRules ?? defaultAdditionConfig.displayRules + + // Helper to update a single display rule + const updateRule = (key: keyof DisplayRules, value: DisplayRules[keyof DisplayRules]) => { + onChange({ + displayRules: { + ...displayRules, + [key]: value, + }, + }) + } + + return ( + +
+ + + + + +
+
+ + +
+ + {/* Pedagogical scaffolding thermometers */} +
+ updateRule('answerBoxes', value)} + isDark={isDark} + /> + + updateRule('placeValueColors', value)} + isDark={isDark} + /> + + updateRule('carryBoxes', value)} + isDark={isDark} + /> + + {(formState.operator === 'subtraction' || formState.operator === 'mixed') && ( + updateRule('borrowNotation', value)} + isDark={isDark} + /> + )} + + {(formState.operator === 'subtraction' || formState.operator === 'mixed') && ( + updateRule('borrowingHints', value)} + isDark={isDark} + /> + )} + + updateRule('tenFrames', value)} + isDark={isDark} + /> +
+ + {/* Live Preview - Collapsible */} + + + + + + +
+ +
+
+
+
+
+
+
+ ) +}