class QuestionBox extends HTMLElement {
connectedCallback() {
const question = this.getAttribute('question') || 'Sample question';
const options = JSON.parse(this.getAttribute('options') || '[]');
const hint = this.getAttribute('hint') || '';
const example = this.getAttribute('example') || '';
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
${question}
${options.map((opt, i) => `
${opt}
`).join('')}
`;
this.shadowRoot.getElementById('hint-btn').addEventListener('click', () => {
this.provideHint();
});
this.shadowRoot.querySelectorAll('.option').forEach(opt => {
opt.addEventListener('click', () => {
this.checkAnswer(opt.dataset.index);
});
});
}
provideHint() {
const question = this.getAttribute('question');
const hint = this.getAttribute('hint') || "Try breaking the problem down into smaller steps.";
const example = this.getAttribute('example') || this.generateExample();
// Dispatch event to parent
this.dispatchEvent(new CustomEvent('show-hint', {
bubbles: true,
composed: true,
detail: { hint, example }
}));
}
generateExample() {
const question = this.getAttribute('question');
return "Here's a similar problem: " +
question.replace(/\d+/g, function(match) {
return Math.floor(Math.random() * 10) + 1;
});
}
checkAnswer(selectedIndex) {
const correctIndex = this.getAttribute('correct') || '0';
const isCorrect = selectedIndex === correctIndex;
this.dispatchEvent(new CustomEvent('answer-checked', {
bubbles: true,
composed: true,
detail: { isCorrect, selectedIndex, correctIndex }
}));
}
}
customElements.define('question-box', QuestionBox);