Claude-skill-registry Implement Multiple Choice Question
Create D3 questions with radio button selections and optional explanations. Students select from options and explain their reasoning.
install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/implement-multiple-choice-question" ~/.claude/skills/majiayu000-claude-skill-registry-implement-multiple-choice-question && rm -rf "$T"
manifest:
skills/data/implement-multiple-choice-question/SKILL.mdsource content
Implement Multiple Choice Question
Use this skill when creating questions where students:
- Select one option from a list of choices
- Choose between equations, statements, or concepts
- Make a selection and explain their reasoning
When to Use This Pattern
Perfect for:
- "Which equation represents the relationship?"
- "Select the correct statement"
- "Choose the graph that matches..."
- Any single-selection question with explanations
Not suitable for:
- Multiple selections (checkboxes) → use standard checkbox pattern
- Drag-and-drop matching → use implement-drag-match-question
- Value entry → use implement-table-question
Components Required
Copy these from
.claude/skills/question-types/snippets/:
Required
→cards/standard-card.jscreateStandardCard()
Optional
→cards/explanation-card.js
- For reasoningcreateExplanationCard()
→cards/video-accordion.js
- For help videoscreateVideoAccordion()
Quick Start
- Review the pattern guide: PATTERN.md (if exists)
- Study working examples:
cat courses/IM-8th-Grade/modules/Unit-3/assignments/Ramp-Up-01/questions/04/attachments/chart.js cat courses/IM-8th-Grade/modules/Unit-3/assignments/Ramp-Up-01/questions/06/attachments/chart.js
Key Implementation Decisions
- Option display - Simple text, equations, or visual cards?
- Selection style - Radio buttons or clickable cards?
- State structure - Store selected option ID
- Explanation requirement - Required or optional?
State Shape
function createDefaultState() { return { selectedOption: null, // ID of selected option explanation: "" }; }
Core Pattern (Clickable Cards)
const OPTIONS = [ { id: "opt1", text: "y = 2x + 3", display: "\\(y = 2x + 3\\)" }, { id: "opt2", text: "y = 3x + 2", display: "\\(y = 3x + 2\\)" }, { id: "opt3", text: "y = x + 5", display: "\\(y = x + 5\\)" }, ]; function renderOptions(container) { const optionsDiv = container.append("div") .style("display", "flex") .style("flex-direction", "column") .style("gap", "12px"); OPTIONS.forEach(option => { const isSelected = chartState.selectedOption === option.id; const optionCard = optionsDiv.append("div") .style("padding", "16px") .style("border", isSelected ? "2px solid #3b82f6" : "1px solid #e5e7eb") .style("border-radius", "12px") .style("background", isSelected ? "#eff6ff" : "#ffffff") .style("cursor", interactivityLocked ? "default" : "pointer") .style("transition", "all 0.2s") .on("click", () => { if (interactivityLocked) return; chartState.selectedOption = option.id; renderOptions(container); // Re-render to show selection sendChartState(); }); optionCard.append("div") .style("font-size", "18px") .html(option.display); }); }
Core Pattern (Radio Buttons)
function renderOptions(container) { const form = container.append("form"); OPTIONS.forEach(option => { const label = form.append("label") .style("display", "block") .style("margin", "12px 0") .style("cursor", "pointer"); label.append("input") .attr("type", "radio") .attr("name", "choice") .attr("value", option.id) .property("checked", chartState.selectedOption === option.id) .property("disabled", interactivityLocked) .on("change", function() { chartState.selectedOption = this.value; sendChartState(); }); label.append("span") .style("margin-left", "8px") .html(option.display); }); }
Working Examples
In codebase:
- IM-8th-Grade Ramp-Up-01 Q04 - Equation selection
- IM-8th-Grade Ramp-Up-01 Q06 - Multiple choice with explanation
Common Variations
With Explanation Card
createExplanationCard(d3, container, { prompt: "Explain why you selected this option.", value: chartState.explanation, onChange: (value) => { chartState.explanation = value; sendChartState(); }, locked: interactivityLocked });
Visual Options (Images/Graphs)
OPTIONS.forEach(option => { const optionCard = optionsDiv.append("div"); // Render graph or image if (option.type === "graph") { renderGraph(optionCard, option.data); } else if (option.type === "image") { optionCard.append("img").attr("src", option.imageUrl); } });
Grid Layout
const optionsGrid = container.append("div") .style("display", "grid") .style("grid-template-columns", "repeat(2, 1fr)") .style("gap", "16px");
Implementation Checklist
- Defined OPTIONS array with unique IDs
- Created
withcreateDefaultState()
fieldselectedOption - Rendered option cards or radio buttons
- Implemented click/change handlers to update state
- Added visual feedback for selected option
- Added explanation card (if needed)
- Implemented
to disable selection when lockedsetInteractivity() - Implemented
to restore selectionapplyInitialState() - Tested selection changes
- Tested state restoration
- Tested locking/unlocking
Tips
- Clear visual feedback - Make selected option obviously different
- Use MathJax/KaTeX - For mathematical expressions in options
- Provide context - Use intro cards to explain what students are selecting
- Test on mobile - Ensure touch targets are large enough (min 44x44px)
- Require explanation - Helps prevent guessing, encourages reasoning
Styling Tips
Hover effects:
.on("mouseover", function() { if (!interactivityLocked) { d3.select(this).style("background", "#f9fafb"); } }) .on("mouseout", function() { const isSelected = /* check selection */; d3.select(this).style("background", isSelected ? "#eff6ff" : "#ffffff"); })
Focus states for accessibility:
optionCard .attr("tabindex", "0") .on("keypress", (event) => { if (event.key === "Enter" && !interactivityLocked) { chartState.selectedOption = option.id; renderOptions(container); sendChartState(); } });
Related Skills
- implement-text-response-question - For selection + explanation focus
- implement-drag-match-question - For matching multiple items
- create-d3-question - Parent workflow skill
Additional Resources
- snippets/form-inputs.js - Form input patterns
- snippets/cards/standard-card.js - Card styling