diff --git a/docs/demo/elements.md b/docs/demo/elements.md index 82e6bd5..b743ea2 100644 --- a/docs/demo/elements.md +++ b/docs/demo/elements.md @@ -49,9 +49,14 @@ module enable the creation of quizzes as dynamic page elements. diff --git a/tdoc/common/static/tdoc/quizz.js b/tdoc/common/static/tdoc/quizz.js index c2d7599..c80a604 100644 --- a/tdoc/common/static/tdoc/quizz.js +++ b/tdoc/common/static/tdoc/quizz.js @@ -28,6 +28,7 @@ export function question(node, prompt, check) {
\
\ +
\ `); if (prompt) { if (typeof prompt === 'string') prompt = text(prompt); @@ -35,20 +36,27 @@ export function question(node, prompt, check) { } const input = div.querySelector('input'); const btn = div.querySelector('button'); + const hint = div.querySelector('.hint'); function checkResp(resp) { input.parentNode.classList.remove('good', 'bad'); + hint.classList.add('hide'); const good = check(resp); - input.parentNode.classList.add(good ? 'good' : 'bad'); + input.parentNode.classList.add(good === true ? 'good' : 'bad'); + if (typeof good === 'string') { + hint.replaceChildren(text(good)); + hint.classList.remove('hide'); + } return good; } input.addEventListener('input', () => { input.parentNode.classList.remove('good', 'bad'); + hint.classList.add('hide'); }); input.addEventListener('keydown', (e) => { if (e.altKey || e.ctrlKey || e.metaKey) return; if (e.key === 'Enter') { e.preventDefault(); - if (!checkResp(input.value)) return; + if (checkResp(input.value) !== true) return; find(div, true)?.querySelector?.('input')?.focus?.() } else if (e.key === 'ArrowUp' && !e.shiftKey) { e.preventDefault(); @@ -58,7 +66,11 @@ export function question(node, prompt, check) { find(div, true)?.querySelector?.('input')?.focus?.() } }); - btn.addEventListener('click', () => { checkResp(input.value); }); + input.addEventListener('blur', () => hint.classList.add('hide')); + btn.addEventListener('click', () => checkResp(input.value)); + btn.addEventListener('blur', (e) => { + if (e.relatedTarget !== input) hint.classList.add('hide'); + }); node.after(div); focusIfVisible(input); return div; diff --git a/tdoc/common/static/tdoc/styles.css.jinja b/tdoc/common/static/tdoc/styles.css.jinja index 0722634..aa10b98 100644 --- a/tdoc/common/static/tdoc/styles.css.jinja +++ b/tdoc/common/static/tdoc/styles.css.jinja @@ -156,6 +156,7 @@ div.tdoc-quizz { align-items: baseline; margin: 0.3rem 0; column-gap: 0.3rem; + position: relative; } div.tdoc-quizz > .prompt { flex: 1 1 auto; @@ -191,11 +192,29 @@ div.tdoc-quizz > .input::before { } div.tdoc-quizz > .input.bad::before { content: '\f00d'; - color: red; + color: var(--pst-color-danger); } div.tdoc-quizz > .input.good::before { content: '\f00c'; - color: green; + color: var(--pst-color-success); +} +div.tdoc-quizz > .hint { + position: absolute; + bottom: calc(100% + 0.8rem); + right: 0; + max-width: 60%; + padding: 0.25rem 0.5rem; + border-left: 0.2rem solid var(--pst-color-success); + border-radius: 0.25rem; + background-color: var(--pst-color-success-bg); + box-shadow: 0 0.2rem 0.5rem var(--pst-color-shadow), + 0 0 0.0625rem var(--pst-color-shadow); + z-index: 100; + transition: 0.3s visibility, 0.3s opacity; +} +div.tdoc-quizz > .hint.hide { + visibility: hidden; + opacity: 0; } /* Auto-sizing text area */