Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
2b0f4ca
feat(quiz): redesign attempt timer and progress header
b-l-i-n-d Feb 18, 2026
d1af906
fix: reduce quiz component vertical padding in the learning area quiz…
b-l-i-n-d Feb 18, 2026
0627f24
refactor: Conditionally render quiz timer frame based on time limit a…
b-l-i-n-d Feb 18, 2026
a7b7da1
feat: Introduce quiz question and attempt progress indicators and upd…
b-l-i-n-d Feb 18, 2026
1c99346
feat: Display current question number and quiz attempt progress in th…
b-l-i-n-d Feb 18, 2026
9f054a3
feat(quiz): refine v4 single-question footer actions
b-l-i-n-d Feb 18, 2026
dd65f71
feat(quiz): add reveal-mode footer feedback states
b-l-i-n-d Feb 18, 2026
a13678b
chore: Update indentation
b-l-i-n-d Feb 19, 2026
4c20c64
refactor(quiz): centralize required-answer context in question template
b-l-i-n-d Feb 19, 2026
ba60928
feat(quiz): align linear footer action layout
b-l-i-n-d Feb 19, 2026
5336f4a
refactor(quiz): remove unused footer position state
b-l-i-n-d Feb 19, 2026
14723a5
feat(quiz): add directional question view transitions
b-l-i-n-d Feb 19, 2026
a05d142
Merge branch 'v4-quiz' into v4-quiz-layout-single
b-l-i-n-d Feb 20, 2026
45aac9a
Merge branch 'v4-quiz' into v4-quiz-layout-single
b-l-i-n-d Feb 20, 2026
1a1b401
Merge branch 'v4-quiz' into v4-quiz-layout-single
b-l-i-n-d Feb 20, 2026
dc7ad1d
feat(quiz): enhance linear pagination states and styles
b-l-i-n-d Feb 23, 2026
b1bccf3
feat(tokens): add brand secondary icon color token
b-l-i-n-d Feb 23, 2026
7350943
fix(quiz): restore reveal feedback on revisit and remove transitions
b-l-i-n-d Feb 23, 2026
c8d3fa2
feat(quiz): update progress header layout and timer title alignment
b-l-i-n-d Feb 23, 2026
339435c
fix(quiz): remove unload beacon and keep leave warning flow
b-l-i-n-d Feb 23, 2026
8bd4ee5
Merge branch 'v4-quiz' into v4-quiz-layout-single
b-l-i-n-d Feb 23, 2026
c3dc82b
fix(quiz): add matching dropzone snap animation
b-l-i-n-d Feb 23, 2026
af6d832
Merge branch 'v4-quiz' into v4-quiz-layout-single
b-l-i-n-d Feb 24, 2026
da4834a
Merge branch 'v4-quiz' into v4-quiz-layout-single
b-l-i-n-d Feb 24, 2026
bb44794
Merge branch 'v4-quiz' into v4-quiz-layout-single
b-l-i-n-d Mar 2, 2026
4a2ea2f
Merge branch 'v4-quiz' into v4-quiz-layout-single
b-l-i-n-d Mar 5, 2026
da3410a
Merge branch 'v4-quiz' into v4-quiz-layout-single
b-l-i-n-d Mar 9, 2026
27c3d39
refactor(quiz): extract basic inline kses tags
b-l-i-n-d Mar 9, 2026
f846a4a
feat: Refactor pagination layout logic
b-l-i-n-d Mar 9, 2026
3fa914a
refactor: Remove unused variables
b-l-i-n-d Mar 10, 2026
c815caf
Merge branch 'v4-quiz' into v4-quiz-layout-single
b-l-i-n-d Mar 10, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions assets/core/scss/themes/_dark.scss
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@
--tutor-icon-disabled: #{$tutor-gray-600};
--tutor-icon-brand: #{$tutor-brand-600};
--tutor-icon-brand-hover: #{$tutor-brand-700};
--tutor-icon-brand-secondary: #{$tutor-brand-300};
--tutor-icon-exception1: #{$tutor-exception-1};
--tutor-icon-exception2: #{$tutor-exception-2};
--tutor-icon-success-primary: #{$tutor-success-600};
Expand Down
1 change: 1 addition & 0 deletions assets/core/scss/themes/_light.scss
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
--tutor-icon-disabled: #{$tutor-gray-300};
--tutor-icon-brand: #{$tutor-brand-600};
--tutor-icon-brand-hover: #{$tutor-brand-700};
--tutor-icon-brand-secondary: #{$tutor-brand-300};
--tutor-icon-exception1: #{$tutor-exception-1};
--tutor-icon-exception2: #{$tutor-exception-2};
--tutor-icon-success-primary: #{$tutor-success-700};
Expand Down
4 changes: 3 additions & 1 deletion assets/core/scss/tokens/_icons.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ $tutor-icon-secondary: var(--tutor-icon-secondary);
$tutor-icon-subdued: var(--tutor-icon-subdued);
$tutor-icon-brand: var(--tutor-icon-brand);
$tutor-icon-brand-hover: var(--tutor-icon-brand-hover);
$tutor-icon-brand-secondary: var(--tutor-icon-brand-secondary);
$tutor-icon-success-primary: var(--tutor-icon-success-primary);
$tutor-icon-critical: var(--tutor-icon-critical);
$tutor-icon-critical-hover: var(--tutor-icon-critical-hover);
Expand All @@ -35,6 +36,7 @@ $tutor-icons: (
subdued: $tutor-icon-subdued,
brand: $tutor-icon-brand,
brand-hover: $tutor-icon-brand-hover,
brand-secondary: $tutor-icon-brand-secondary,
success-primary: $tutor-icon-success-primary,
critical: $tutor-icon-critical,
critical-hover: $tutor-icon-critical-hover,
Expand All @@ -44,4 +46,4 @@ $tutor-icons: (
exception2: $tutor-icon-exception2,
exception4: $tutor-icon-exception4,
disabled: $tutor-icon-disabled,
);
);
5 changes: 5 additions & 0 deletions assets/icons/clock-frame.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 1 addition & 8 deletions assets/src/js/frontend/learning-area/quiz/constants.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export type QuizFooterPosition = 'only' | 'first' | 'middle' | 'last';
export type RevealQuestionType = (typeof QUIZ_REVEAL_CONFIG.SUPPORTED_TYPES)[number];

export const QUIZ_REVEAL_CONFIG = {
Expand All @@ -13,6 +12,7 @@ export const QUIZ_REVEAL_CONFIG = {
EXPLANATION_CONTENT_DATASET: 'quizExplanationContent',
DATA_OPTION_ATTR: 'data-option',
DATA_REVEALED_ATTR: 'data-revealed',
DATA_RESULT_ATTR: 'data-reveal-result',
DATA_OPTION_CORRECT: 'correct',
DATA_OPTION_INCORRECT: 'incorrect',
} as const;
Expand All @@ -22,13 +22,6 @@ export const QUIZ_ABANDON_CONFIG = {
IGNORE_ANCHOR_PREFIXES: ['#', 'javascript:'],
} as const;

export const QUIZ_FOOTER_POSITIONS = {
ONLY: 'only',
FIRST: 'first',
MIDDLE: 'middle',
LAST: 'last',
} as const;

export const QuestionTimeoutAction = {
AUTO_ABANDON: 'auto_abandon',
AUTO_SUBMIT: 'auto_submit',
Expand Down
22 changes: 22 additions & 0 deletions assets/src/js/frontend/learning-area/quiz/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ export const revealQuestionWithAnswers = (wrapper: HTMLElement, revealAnswerIds:
}

const inputs = Array.from(question.querySelectorAll<HTMLInputElement>('input[type="radio"], input[type="checkbox"]'));
const selectedAnswerIds = new Set<number>();
const correctAnswerIds = new Set<number>();

inputs.forEach((input) => {
const option = input.closest(QUIZ_REVEAL_CONFIG.OPTION_SELECTOR) as HTMLElement | null;
Expand All @@ -59,7 +61,18 @@ export const revealQuestionWithAnswers = (wrapper: HTMLElement, revealAnswerIds:
}

const answerId = Number(input.value);
if (Number.isNaN(answerId)) {
return;
}

if (input.checked) {
selectedAnswerIds.add(answerId);
}

const isCorrect = revealAnswerIds.includes(answerId);
if (isCorrect) {
correctAnswerIds.add(answerId);
}

if (isCorrect) {
option.setAttribute(QUIZ_REVEAL_CONFIG.DATA_OPTION_ATTR, QUIZ_REVEAL_CONFIG.DATA_OPTION_CORRECT);
Expand All @@ -70,5 +83,14 @@ export const revealQuestionWithAnswers = (wrapper: HTMLElement, revealAnswerIds:
input.disabled = true;
});

const hasMatchingSelection =
selectedAnswerIds.size > 0 &&
selectedAnswerIds.size === correctAnswerIds.size &&
Array.from(selectedAnswerIds).every((id) => correctAnswerIds.has(id));

question.setAttribute(
QUIZ_REVEAL_CONFIG.DATA_RESULT_ATTR,
hasMatchingSelection ? QUIZ_REVEAL_CONFIG.DATA_OPTION_CORRECT : QUIZ_REVEAL_CONFIG.DATA_OPTION_INCORRECT,
);
question.setAttribute(QUIZ_REVEAL_CONFIG.DATA_REVEALED_ATTR, '1');
};
Loading
Loading