@pocketprep/ui-kit 3.4.52 → 3.4.53

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,131 @@
1
+ <script setup lang="ts">
2
+ import RadioButton from '../../Forms/RadioButton.vue'
3
+ import { dark as vDark } from '../../../directives'
4
+
5
+ interface Props {
6
+ isDarkMode: boolean
7
+ choices: string[]
8
+ labels: string[]
9
+ showAnswers: boolean
10
+ disabled: boolean
11
+ }
12
+
13
+ const props = withDefaults(defineProps<Props>(), {
14
+ isDarkMode: false,
15
+ showAnswers: false,
16
+ disabled: false,
17
+ })
18
+
19
+ const selectedChoice = defineModel<string>()
20
+
21
+ const selectChoice = (choiceKey: string) => {
22
+ selectedChoice.value = choiceKey
23
+ }
24
+
25
+ const radioButtonColor = (choice: string) => {
26
+ if (props.showAnswers) {
27
+ if (choice === selectedChoice.value && selectedChoice.value?.startsWith('a')) {
28
+ return 'green'
29
+ }
30
+
31
+ if (choice === selectedChoice.value && selectedChoice.value?.startsWith('d')) {
32
+ return 'gray'
33
+ }
34
+
35
+ if (choice.startsWith('a')) {
36
+ return 'green'
37
+ }
38
+ }
39
+
40
+ return 'blue'
41
+ }
42
+
43
+ const stripText = (string?: string) => {
44
+ return string?.replace(/<[^\s>]+[^>]*>/gi, ' ').trim()
45
+ }
46
+ </script>
47
+
48
+ <template>
49
+ <ul
50
+ v-if="choices.length"
51
+ class="uikit-mobile-matrix-radio-group"
52
+ v-dark="isDarkMode"
53
+ role="radiogroup"
54
+ >
55
+ <li
56
+ class="uikit-mobile-matrix-radio-group__option"
57
+ v-dark="isDarkMode"
58
+ role="radio"
59
+ v-for="(choice, index) in choices"
60
+ :key="choice"
61
+ >
62
+ <RadioButton
63
+ class="uikit-mobile-matrix-radio-group__radio-btn"
64
+ :selected="(choice === selectedChoice) || (showAnswers && choice.startsWith('a'))"
65
+ :disabled="disabled"
66
+ :isDarkMode="isDarkMode"
67
+ :color="radioButtonColor(choice)"
68
+ @click="!disabled && !showAnswers && selectChoice(choice)"
69
+ />
70
+ <div
71
+ v-if="labels"
72
+ v-dark="props.isDarkMode"
73
+ class="uikit-mobile-matrix-radio-group__label"
74
+ :class="{
75
+ 'uikit-mobile-matrix-radio-group__label--distractor':
76
+ showAnswers && choice?.startsWith('d')
77
+ }"
78
+ @click="!disabled && !showAnswers && selectChoice(choice)"
79
+ >
80
+ {{ stripText(labels[index]) }}
81
+ </div>
82
+ </li>
83
+ </ul>
84
+ </template>
85
+
86
+ <style lang="scss" scoped>
87
+ @import '../../../styles/breakpoints';
88
+ @import '../../../styles/colors';
89
+
90
+ .uikit-mobile-matrix-radio-group {
91
+ list-style: none;
92
+ margin: 0;
93
+ padding: 0;
94
+ display: block;
95
+ background: $white;
96
+ border-radius: 0px 0px 5px 5px;
97
+
98
+ &--dark {
99
+ background: $brand-black;
100
+ }
101
+
102
+ &__option {
103
+ display: flex;
104
+ align-items: center;
105
+ padding-left: 15px;
106
+ height: 47px;
107
+ max-width: 325px;
108
+ border: 0.5px solid rgba($pewter, 0.85);
109
+ border-top: none;
110
+ }
111
+
112
+
113
+ &__label {
114
+ display: block;
115
+ margin-left: 12px;
116
+ color: $brand-black;
117
+ font-size: 16px;
118
+ font-weight: 500;
119
+ line-height: 23px;
120
+ letter-spacing: -0.1px;
121
+
122
+ &--dark {
123
+ color: $barely-background;
124
+ }
125
+
126
+ &--distractor {
127
+ text-decoration: line-through;
128
+ }
129
+ }
130
+ }
131
+ </style>
@@ -4,17 +4,23 @@
4
4
  class="uikit-question-stats-summary"
5
5
  >
6
6
  <div v-dark="isDarkMode" class="uikit-question-stats-summary__stats-summary-total">
7
- <div class="uikit-question-stats-summary__stats-summary-value">
7
+ <div v-if="!isMatrixQuestion" class="uikit-question-stats-summary__stats-summary-value">
8
8
  {{ choiceScores.totalAnswered }}
9
9
  </div>
10
+ <div v-else class="uikit-question-stats-summary__stats-summary-value">
11
+ {{ matrixChoiceScores.totalAnswered }}
12
+ </div>
10
13
  <div v-dark="isDarkMode" class="uikit-question-stats-summary__stats-summary-label">
11
14
  Studiers Answered
12
15
  </div>
13
16
  </div>
14
17
  <div v-dark="isDarkMode" class="uikit-question-stats-summary__stats-summary-correct">
15
- <div class="uikit-question-stats-summary__stats-summary-value">
18
+ <div v-if="!isMatrixQuestion" class="uikit-question-stats-summary__stats-summary-value">
16
19
  {{ Math.round((choiceScores.answeredCorrectly / choiceScores.totalAnswered) * 100) }}%
17
20
  </div>
21
+ <div v-else class="uikit-question-stats-summary__stats-summary-value">
22
+ {{ Math.round((matrixChoiceScores.answeredCorrectly / matrixChoiceScores.totalAnswered) * 100) }}%
23
+ </div>
18
24
  <div v-dark="isDarkMode" class="uikit-question-stats-summary__stats-summary-label">
19
25
  Answered Correctly
20
26
  </div>
@@ -26,7 +32,7 @@
26
32
  import { Component, Vue, Prop } from 'vue-facing-decorator'
27
33
  import type { Study } from '@pocketprep/types'
28
34
  import { dark, breakpoint } from '../../../directives'
29
- import type { TChoiceScores } from './../question'
35
+ import type { TChoiceScores, TMatrixChoiceScores } from './../question'
30
36
 
31
37
 
32
38
  @Component({
@@ -39,6 +45,8 @@ export default class StatsSummary extends Vue {
39
45
  @Prop({ default: null }) globalMetrics!: Study.Class.GlobalQuestionMetricJSON | null
40
46
  @Prop() choiceScores!: TChoiceScores
41
47
  @Prop({ default: false }) isDarkMode!: boolean
48
+ @Prop({ default: false }) isMatrixQuestion!: boolean
49
+ @Prop() matrixChoiceScores!: TMatrixChoiceScores
42
50
  }
43
51
 
44
52
  </script>
@@ -6,7 +6,7 @@
6
6
  class="uikit-question-summary"
7
7
  >
8
8
  <div class="uikit-question-summary__summary-title">
9
- {{ isCorrect ? 'Correct': isUnanswered ? 'Unanswered' : 'Incorrect' }}
9
+ {{ isQuestionCorrect ? 'Correct': isUnanswered ? 'Unanswered' : 'Incorrect' }}
10
10
  </div>
11
11
  <PocketButton
12
12
  v-breakpoint:questionEl="breakpoints"
@@ -97,7 +97,7 @@
97
97
  </div>
98
98
  </div>
99
99
  <Icon
100
- v-if="isCorrect"
100
+ v-if="isQuestionCorrect"
101
101
  v-dark="isDarkMode"
102
102
  type="correct"
103
103
  class="uikit-question-summary__summary-correct-icon"
@@ -139,9 +139,11 @@ export default class Summary extends Vue {
139
139
  @Prop({ default: undefined }) reference!: string | undefined
140
140
  @Prop({ default: false }) hideReferences!: boolean
141
141
  @Prop({ default: false }) isCorrect!: boolean
142
+ @Prop({ default: false }) isMatrixQuestionCorrect!: boolean
142
143
  @Prop({ default: false }) isUnanswered!: boolean
143
144
  @Prop({ default: false }) reviewMode!: boolean
144
145
  @Prop({ default: false }) isDarkMode!: boolean
146
+ @Prop({ default: false }) isMatrixQuestion!: boolean
145
147
  @Prop({ default: null }) questionEl!: Element | null
146
148
  @Prop({ default: {
147
149
  'mobile': 767,
@@ -149,6 +151,10 @@ export default class Summary extends Vue {
149
151
  'tablet-landscape': 1439,
150
152
  } }) breakpoints!: TBreakPointsObject
151
153
 
154
+ get isQuestionCorrect () {
155
+ return (!this.isMatrixQuestion && this.isCorrect) || (this.isMatrixQuestion && this.isMatrixQuestionCorrect)
156
+ }
157
+
152
158
  @Emit('toggleSummaryExplanation')
153
159
  toggleSummaryExplanation () {
154
160
  return
@@ -186,6 +192,7 @@ export default class Summary extends Vue {
186
192
  display: inline-block;
187
193
  }
188
194
 
195
+
189
196
  &__summary-title {
190
197
  font-weight: 600;
191
198
  font-size: 15.5px;
@@ -123,7 +123,7 @@
123
123
  showAnswers && (isMCR || isUnanswered) && !isCorrect && !isTeachReview,
124
124
  'uikit-question__choices--unanswered': showAnswers && !isMCR && isUnanswered && !isCorrect,
125
125
  'uikit-question__choices--show-stats': globalMetrics,
126
- 'uikit-question__choices--no-actions': !(isMCR || isUnanswered)
126
+ 'uikit-question__choices--no-actions': !(isMCR || isUnanswered || isMatrixQuestion)
127
127
  && !globalMetrics
128
128
  && (
129
129
  reviewMode
@@ -152,6 +152,7 @@
152
152
  />
153
153
  </div>
154
154
  <ChoicesContainer
155
+ v-if="question.type !== 'Matrix Checkbox' && question.type !== 'Matrix Radio Button'"
155
156
  ref="uikit-question__choices-container"
156
157
  :question="question"
157
158
  :choices="choices"
@@ -216,10 +217,88 @@
216
217
  />
217
218
  </template>
218
219
  </ChoicesContainer>
220
+ <MatrixChoicesContainer
221
+ v-if="question.type === 'Matrix Checkbox' || question.type === 'Matrix Radio Button'"
222
+ class="uikit-question__matrix-choices-container"
223
+ ref="uikit-question__matrix-choices-container"
224
+ v-breakpoint:questionEl="breakpoints"
225
+ :question="question"
226
+ :matrix-choice-layout="question.matrixChoiceLayout"
227
+ :is-matrix-question-correct="isMatrixQuestionCorrect"
228
+ :matrix-answer-keys="matrixAnswerKeys"
229
+ :matrix-distractor-keys="matrixDistractorKeys"
230
+ :selected-matrix-choices="selectedMatrixChoices"
231
+ :show-matrix-answers="showMatrixAnswers"
232
+ :review-mode="reviewMode"
233
+ :matrix-choice-scores="matrixChoiceScores"
234
+ :global-metrics="globalMetrics"
235
+ :is-dark-mode="isDarkMode"
236
+ :question-el="questionEl"
237
+ :breakpoints="breakpoints"
238
+ @emitSelectedMatrixChoice="selectMatrixChoice"
239
+ @emitAnsweredMatrixRowIndex="answeredMatrixRowIndex"
240
+ >
241
+ <template #motivationalMoment="{
242
+ isCorrect,
243
+ choiceKey,
244
+ showAnswers,
245
+ answerKeys,
246
+ }">
247
+ <slot
248
+ name="motivationalMoment"
249
+ :showAnswers="showAnswers"
250
+ :answerKeys="answerKeys"
251
+ :choiceKey="choiceKey"
252
+ :isCorrect="isCorrect"
253
+ />
254
+ </template>
255
+ <template #showNamesTable="{
256
+ choiceKey,
257
+ }" >
258
+ <slot
259
+ name="showNamesTable"
260
+ :choiceKey="choiceKey"
261
+ />
262
+ </template>
263
+ </MatrixChoicesContainer>
264
+ <MobileMatrixChoicesContainer
265
+ v-if="question.type === 'Matrix Checkbox' || question.type === 'Matrix Radio Button'"
266
+ class="uikit-question__mobile-matrix-choices-container"
267
+ v-breakpoint:questionEl="breakpoints"
268
+ :question="question"
269
+ :matrix-choice-layout="question.matrixChoiceLayout"
270
+ :is-matrix-question-correct="isMatrixQuestionCorrect"
271
+ :matrix-answer-keys="matrixAnswerKeys"
272
+ :matrix-distractor-keys="matrixDistractorKeys"
273
+ :selected-matrix-choices="selectedMatrixChoices"
274
+ :show-matrix-answers="showMatrixAnswers"
275
+ :review-mode="reviewMode"
276
+ :global-metrics="globalMetrics"
277
+ :is-dark-mode="isDarkMode"
278
+ :question-el="questionEl"
279
+ :breakpoints="breakpoints"
280
+ @emitSelectedMatrixChoice="selectMatrixChoice"
281
+ @emitAnsweredMatrixRowIndex="answeredMatrixRowIndex"
282
+ >
283
+ <template #motivationalMoment="{
284
+ isCorrect,
285
+ choiceKey,
286
+ showAnswers,
287
+ answerKeys,
288
+ }">
289
+ <slot
290
+ name="motivationalMoment"
291
+ :showAnswers="showAnswers"
292
+ :answerKeys="answerKeys"
293
+ :choiceKey="choiceKey"
294
+ :isCorrect="isCorrect"
295
+ />
296
+ </template>
297
+ </MobileMatrixChoicesContainer>
219
298
  <slot name="unansweredFlaggedNamesTable" />
220
299
  </div>
221
300
  <Summary
222
- v-if="isMCR && showAnswers && !showPaywall"
301
+ v-if="((isMCR && showAnswers) || (isMatrixQuestion && showMatrixAnswers)) && !showPaywall"
223
302
  ref="uikit-question__summary"
224
303
  class="uikit-question__summary"
225
304
  :question="question"
@@ -231,6 +310,8 @@
231
310
  :reference="reference"
232
311
  :hide-references="hideReferences"
233
312
  :is-correct="isCorrect"
313
+ :is-matrix-question-correct="isMatrixQuestionCorrect"
314
+ :is-matrix-question="isMatrixQuestion"
234
315
  :is-unanswered="isUnanswered"
235
316
  :review-mode="reviewMode"
236
317
  :is-dark-mode="isDarkMode"
@@ -245,6 +326,8 @@
245
326
  class="uikit-question__stats-summary"
246
327
  :global-metrics="globalMetrics"
247
328
  :choice-scores="choiceScores"
329
+ :matrix-choice-scores="matrixChoiceScores"
330
+ :is-matrix-question="isMatrixQuestion"
248
331
  :is-dark-mode="isDarkMode"
249
332
  />
250
333
  </slot>
@@ -277,13 +360,21 @@
277
360
  >
278
361
  <slot name="action">
279
362
  <PocketButton
280
- v-if="!showAnswers && !hideAnswer && (showCheckAnswer || isMCR)"
363
+ v-if="!showAnswers && !hideAnswer && (showCheckAnswer || isMCR) && !isMatrixQuestion"
281
364
  :disabled="!selectedChoices.length"
282
365
  :is-dark-mode="isDarkMode"
283
366
  @click="clickCheckAnswer"
284
367
  >
285
368
  Check Answer
286
369
  </PocketButton>
370
+ <PocketButton
371
+ v-if="!showMatrixAnswers && !hideAnswer && isMatrixQuestion && allMatrixRowsAreAnswered"
372
+ :disabled="!selectedMatrixChoices.length"
373
+ :is-dark-mode="isDarkMode"
374
+ @click="clickCheckMatrixAnswer"
375
+ >
376
+ Check Answer
377
+ </PocketButton>
287
378
  <PocketButton
288
379
  v-else-if="(showAnswers || hideAnswer) && (questionNumber >= quizLength)"
289
380
  :is-dark-mode="isDarkMode"
@@ -376,10 +467,22 @@ import ChoicesContainer from '../Quiz/Question/ChoicesContainer.vue'
376
467
  import StatsSummary from '../Quiz/Question/StatsSummary.vue'
377
468
  import Explanation from '../Quiz/Question/Explanation.vue'
378
469
  import PassageAndImage from '../Quiz/Question/PassageAndImage.vue'
470
+ import MatrixChoicesContainer from '../Quiz/Question/MatrixChoicesContainer.vue'
471
+ import MobileMatrixChoicesContainer from '../Quiz/Question/MobileMatrixChoicesContainer.vue'
379
472
  import type { Study } from '@pocketprep/types'
380
473
  import { breakpoint, dark } from '../../directives'
381
474
  import { highlightKeywordsInText, studyModes } from '../../utils'
382
- import type { Ref, TQuizMode, TChoiceKey, TChoice, TChoiceScores, TNamesRow, TViewNames } from './question'
475
+ import type {
476
+ Ref,
477
+ TQuizMode,
478
+ TChoiceKey,
479
+ TMatrixChoiceKey,
480
+ TChoice,
481
+ TChoiceScores,
482
+ TMatrixChoiceScores,
483
+ TNamesRow,
484
+ TViewNames,
485
+ } from './question'
383
486
 
384
487
  @Component({
385
488
  components: {
@@ -396,6 +499,8 @@ import type { Ref, TQuizMode, TChoiceKey, TChoice, TChoiceScores, TNamesRow, TVi
396
499
  StatsSummary,
397
500
  Explanation,
398
501
  PassageAndImage,
502
+ MatrixChoicesContainer,
503
+ MobileMatrixChoicesContainer,
399
504
  },
400
505
  directives: {
401
506
  breakpoint,
@@ -414,6 +519,7 @@ export default class Question extends Vue {
414
519
  @Prop({ default: true }) showNextQuestion!: boolean
415
520
  @Prop({ default: false }) reviewMode!: boolean
416
521
  @Prop({ default: null }) previousChoices!: TChoiceKey[] | null
522
+ @Prop({ default: null }) previousMatrixChoices!: TMatrixChoiceKey[] | null
417
523
  @Prop({ default: null }) globalMetrics!: Study.Class.GlobalQuestionMetricJSON | null
418
524
  @Prop({ default: null }) showNames!: TViewNames | null
419
525
  @Prop({ default: true }) allowKeyboardShortcuts!: boolean
@@ -432,7 +538,11 @@ export default class Question extends Vue {
432
538
  focusChoiceKey: TChoiceKey | null = null
433
539
  choiceStrikes: TChoiceKey[] = []
434
540
  selectedChoices: TChoiceKey[] = []
541
+ selectedMatrixChoices: TMatrixChoiceKey[] = []
542
+ answeredMatrixRowIndexes: number[] = []
543
+ allMatrixRowsAreAnswered = false
435
544
  showAnswers = false
545
+ showMatrixAnswers = false
436
546
  showExplanation = false
437
547
  showPassageImageLongAlt = false
438
548
  showExplanationImageDropdown = false
@@ -488,6 +598,10 @@ export default class Question extends Vue {
488
598
  return this.question.type === 'Multiple Correct Response'
489
599
  }
490
600
 
601
+ get isMatrixQuestion () {
602
+ return this.question.type === 'Matrix Checkbox' || this.question.type === 'Matrix Radio Button'
603
+ }
604
+
491
605
  get passageImageUrl () {
492
606
  const imageUrl = this.question.passageImage?.url
493
607
 
@@ -522,11 +636,13 @@ export default class Question extends Vue {
522
636
 
523
637
  get passageAndImageTitle () {
524
638
  if (this.question.passage && this.passageImageUrl) {
525
- return 'Passage + Image'
639
+ return this.question.passageLabel ? `${this.question.passageLabel} + Image` :
640
+ 'Passage + Image'
526
641
  } else if (!this.question.passage && this.passageImageUrl) {
527
642
  return 'Image'
528
643
  } else {
529
- return 'Passage'
644
+ return this.question.passageLabel ? `${this.question.passageLabel}` :
645
+ 'Passage'
530
646
  }
531
647
  }
532
648
 
@@ -547,6 +663,20 @@ export default class Question extends Vue {
547
663
  return this.answers.map(choice => choice.key)
548
664
  }
549
665
 
666
+ get matrixAnswerKeys () {
667
+ if (this.question?.matrixChoiceLayout) {
668
+ return this.question?.matrixChoiceLayout.flat().filter(choice => choice.startsWith('a'))
669
+ }
670
+ return []
671
+ }
672
+
673
+ get matrixDistractorKeys () {
674
+ if (this.question?.matrixChoiceLayout) {
675
+ return this.question?.matrixChoiceLayout.flat().filter(choice => choice.startsWith('d'))
676
+ }
677
+ return []
678
+ }
679
+
550
680
  get distractors (): TChoice[] {
551
681
  const distractors = this.question.choices.filter(choice => !choice.isCorrect).map((choice, index) => ({
552
682
  text: choice.text,
@@ -574,6 +704,12 @@ export default class Question extends Vue {
574
704
  && !this.selectedChoices.join(' ').includes('d')
575
705
  }
576
706
 
707
+ get isMatrixQuestionCorrect () {
708
+ return this.showMatrixAnswers
709
+ && this.selectedMatrixChoices.length === this.matrixAnswerKeys.length
710
+ && !this.selectedMatrixChoices.join(' ').includes('d')
711
+ }
712
+
577
713
  get choiceScores (): TChoiceScores {
578
714
  const globalMetrics = this.globalMetrics
579
715
 
@@ -608,8 +744,32 @@ export default class Question extends Vue {
608
744
  return scores
609
745
  }
610
746
 
747
+ get matrixChoiceScores (): TMatrixChoiceScores {
748
+ const globalMetrics = this.globalMetrics
749
+
750
+ const scores: TMatrixChoiceScores = {
751
+ totalAnswered: this.selectedMatrixChoices.length &&
752
+ this.showMatrixAnswers && !this.reviewMode ? 1 : 0,
753
+ answeredCorrectly: this.isCorrect && !this.reviewMode ? 1 : 0,
754
+ }
755
+
756
+ if (!globalMetrics) {
757
+ return scores
758
+ }
759
+
760
+ scores.totalAnswered += (
761
+ (globalMetrics.answeredCorrectlyCount || 0)
762
+ + (globalMetrics.answeredIncorrectlyCount || 0)
763
+ )
764
+ scores.answeredCorrectly += (globalMetrics.answeredCorrectlyCount || 0)
765
+ return scores
766
+ }
767
+
611
768
  get isUnanswered () {
612
- return this.selectedChoices.length === 0
769
+ if (!this.isMatrixQuestion) {
770
+ return this.selectedChoices.length === 0
771
+ }
772
+ return this.selectedMatrixChoices.length === 0
613
773
  }
614
774
 
615
775
  get prompt () {
@@ -626,12 +786,17 @@ export default class Question extends Vue {
626
786
  this.startReviewMode()
627
787
  }
628
788
 
629
- if (this.previousChoices) {
789
+ if (!this.isMatrixQuestion && this.previousChoices) {
630
790
  this.updateSelectedChoices(this.previousChoices)
631
791
  }
632
792
 
793
+ if (this.isMatrixQuestion && this.previousMatrixChoices) {
794
+ this.updateSelectedMatrixChoices(this.previousMatrixChoices)
795
+ }
796
+
633
797
  if (this.initialShowAnswers) {
634
798
  this.showAnswers = this.initialShowAnswers
799
+ this.showMatrixAnswers = this.initialShowAnswers
635
800
  }
636
801
 
637
802
  if (this.allowKeyboardShortcuts) {
@@ -750,21 +915,33 @@ export default class Question extends Vue {
750
915
  }
751
916
 
752
917
  startReviewMode () {
753
- this.showAnswers = true
754
- this.showExplanation = this.defaultShowExplanation === null ? true : this.defaultShowExplanation
755
- this.selectedChoices = this.answerKeys
918
+ if (!this.isMatrixQuestion) {
919
+ this.showAnswers = true
920
+ this.showExplanation = this.defaultShowExplanation === null ? true : this.defaultShowExplanation
921
+ this.selectedChoices = this.answerKeys
922
+ } else {
923
+ this.showMatrixAnswers = true
924
+ this.showExplanation = this.defaultShowExplanation === null ? true : this.defaultShowExplanation
925
+ this.selectedMatrixChoices = this.matrixAnswerKeys as TMatrixChoiceKey[]
926
+ }
756
927
  }
757
928
 
758
929
  stopReviewMode () {
759
930
  this.showAnswers = false
931
+ this.showMatrixAnswers = false
760
932
  this.showExplanation = false
761
933
  this.selectedChoices = []
934
+ this.selectedMatrixChoices = []
762
935
  }
763
936
 
764
937
  updateSelectedChoices (choices: TChoiceKey[]) {
765
938
  this.selectedChoices = [ ...choices ]
766
939
  }
767
940
 
941
+ updateSelectedMatrixChoices (matrixChoices: TMatrixChoiceKey[]) {
942
+ this.selectedMatrixChoices = [ ...matrixChoices ]
943
+ }
944
+
768
945
  // deterministic shuffling of choices so they don't change order everytime you reload the component
769
946
  shuffleChoices (choices: TChoice[]): TChoice[] {
770
947
  const sortedChoices = choices.sort((a, b) => {
@@ -936,6 +1113,21 @@ export default class Question extends Vue {
936
1113
  }
937
1114
  }
938
1115
 
1116
+ selectMatrixChoice (matrixChoiceKeys: TMatrixChoiceKey[]) {
1117
+ if (this.showMatrixAnswers) {
1118
+ return
1119
+ }
1120
+ this.selectedMatrixChoices = matrixChoiceKeys
1121
+ }
1122
+
1123
+ answeredMatrixRowIndex (answeredRowIndexes: number[]) {
1124
+ if (this.showMatrixAnswers) {
1125
+ return
1126
+ }
1127
+ this.answeredMatrixRowIndexes = answeredRowIndexes
1128
+ this.allMatrixRowsAreAnswered = this.answeredMatrixRowIndexes.length === this.question.matrixLabels?.rows.length
1129
+ }
1130
+
939
1131
  togglePassageImageLongAlt () {
940
1132
  this.showPassageImageLongAlt = !this.showPassageImageLongAlt
941
1133
 
@@ -1080,6 +1272,29 @@ export default class Question extends Vue {
1080
1272
  }
1081
1273
  }
1082
1274
 
1275
+ clickCheckMatrixAnswer () {
1276
+ if (!this.hideAnswer) {
1277
+ this.showMatrixAnswers = true
1278
+
1279
+ this.emitCheckAnswer({
1280
+ isCorrect: this.isMatrixQuestionCorrect,
1281
+ selectedChoices: this.selectedMatrixChoices,
1282
+ questionSerial: this.question.serial,
1283
+ })
1284
+
1285
+ setTimeout(() => {
1286
+ const summaryMatrixComp =
1287
+ this.$refs['uikit-question__summary'] as ComponentPublicInstance | undefined
1288
+ const summaryMatrixExplanation =
1289
+ // eslint-disable-next-line max-len
1290
+ summaryMatrixComp?.$refs['uikit-question-summary__summary-toggle-explanation-text'] as HTMLElement | undefined
1291
+ if (summaryMatrixExplanation) {
1292
+ summaryMatrixExplanation?.focus()
1293
+ }
1294
+ }, 500)
1295
+ }
1296
+ }
1297
+
1083
1298
  mappedNameRows (choiceKey: string) {
1084
1299
  /*
1085
1300
  There is a specific order in which we have to fill the rows in the table for visible names.
@@ -1140,6 +1355,11 @@ export default class Question extends Vue {
1140
1355
  this.updateSelectedChoices(choices)
1141
1356
  }
1142
1357
 
1358
+ @Watch('previousMatrixChoices', { deep: true })
1359
+ previousMatrixChoicesChanged (matrixChoice: TMatrixChoiceKey[]) {
1360
+ this.updateSelectedMatrixChoices(matrixChoice)
1361
+ }
1362
+
1143
1363
  @Emit('selectedChoices')
1144
1364
  emitSelectedChoices (selectedChoices: Study.Cloud.IQuizAnswer) {
1145
1365
  return selectedChoices
@@ -1155,6 +1375,16 @@ export default class Question extends Vue {
1155
1375
  } as Study.Cloud.IQuizAnswer)
1156
1376
  }
1157
1377
 
1378
+ @Watch('selectedMatrixChoices', { deep: true })
1379
+ selectedMatrixChoicesChanged () {
1380
+ this.emitSelectedChoices({
1381
+ isCorrect: this.selectedMatrixChoices.length === this.matrixAnswerKeys.length
1382
+ && !this.selectedMatrixChoices.join(' ').includes('d'),
1383
+ selectedChoices: this.selectedMatrixChoices,
1384
+ questionSerial: this.question.serial,
1385
+ } as Study.Cloud.IQuizAnswer)
1386
+ }
1387
+
1158
1388
  @Watch('showExplanation')
1159
1389
  showExplanationChanged () {
1160
1390
  this.emitUpdateShowExplanation()
@@ -1637,5 +1867,16 @@ export default class Question extends Vue {
1637
1867
  margin-top: 24px;
1638
1868
  }
1639
1869
  }
1870
+
1871
+ &__matrix-choices-container {
1872
+ display: block;
1873
+ @include breakpoint(black-bear) {
1874
+ display: none;
1875
+ }
1876
+ }
1877
+
1878
+ &__mobile-matrix-choices-container {
1879
+ display: block;
1880
+ }
1640
1881
  }
1641
1882
  </style>