@pocketprep/ui-kit 3.4.90 → 3.5.1

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.
Files changed (88) hide show
  1. package/README.md +2 -2
  2. package/dist/@pocketprep/ui-kit.css +1 -0
  3. package/dist/@pocketprep/ui-kit.js +16490 -18228
  4. package/dist/@pocketprep/ui-kit.js.map +1 -1
  5. package/dist/@pocketprep/ui-kit.umd.cjs +11 -11
  6. package/dist/@pocketprep/ui-kit.umd.cjs.map +1 -1
  7. package/eslint.config.ts +111 -0
  8. package/lib/components/Banners/Banner.vue +2 -2
  9. package/lib/components/Bundles/BundleList.vue +1 -1
  10. package/lib/components/Bundles/BundleSearch.vue +43 -12
  11. package/lib/components/Bundles/PremiumPill.vue +2 -2
  12. package/lib/components/Buttons/Button.vue +19 -18
  13. package/lib/components/Buttons/Link.vue +9 -8
  14. package/lib/components/Buttons/Tab.vue +4 -3
  15. package/lib/components/Calendar/Calendar.vue +14 -2
  16. package/lib/components/Charts/Bar.vue +3 -3
  17. package/lib/components/Charts/Pie.vue +4 -4
  18. package/lib/components/Controls/SegmentControl.vue +8 -7
  19. package/lib/components/Controls/Slider.vue +2 -3
  20. package/lib/components/Controls/ToggleSwitch.vue +3 -2
  21. package/lib/components/EmptyStates/EmptyState.vue +3 -2
  22. package/lib/components/Exams/ExamCard.vue +3 -3
  23. package/lib/components/Exams/ExamMenuCard.vue +2 -2
  24. package/lib/components/Filters/FilterDropdown.vue +2 -2
  25. package/lib/components/Filters/FilterOptions.vue +2 -2
  26. package/lib/components/Forms/Checkbox.vue +2 -2
  27. package/lib/components/Forms/CheckboxOption.vue +2 -2
  28. package/lib/components/Forms/Errors.vue +2 -2
  29. package/lib/components/Forms/Input.vue +2 -2
  30. package/lib/components/Forms/Radio.vue +37 -39
  31. package/lib/components/Forms/RadioButton.vue +1 -1
  32. package/lib/components/Forms/Select.vue +7 -6
  33. package/lib/components/Forms/Textarea.vue +2 -2
  34. package/lib/components/Icons/Icon.vue +1 -0
  35. package/lib/components/Icons/IconEdit.vue +4 -2
  36. package/lib/components/Icons/IconFullViewActive.vue +1 -1
  37. package/lib/components/Icons/IconLoading2.vue +1 -3
  38. package/lib/components/Loaders/SkeletonLoader.vue +2 -2
  39. package/lib/components/Messaging/InfoMessage.vue +2 -2
  40. package/lib/components/Modal/Modal.vue +2 -2
  41. package/lib/components/Modal/ModalContainer.vue +2 -2
  42. package/lib/components/Onboarding/EmailAuth.vue +5 -5
  43. package/lib/components/Onboarding/MagicCodeEntry.vue +3 -4
  44. package/lib/components/Pagination/QuestionReviewPagination.vue +23 -21
  45. package/lib/components/Pagination/TablePagination.vue +2 -2
  46. package/lib/components/Quiz/FlagToggle.vue +2 -2
  47. package/lib/components/Quiz/GlobalMetricsToggle.vue +3 -2
  48. package/lib/components/Quiz/KeyboardShortcutsButton.vue +1 -1
  49. package/lib/components/Quiz/KeyboardShortcutsModal.vue +1 -1
  50. package/lib/components/Quiz/Question/ChoicesContainer.vue +99 -132
  51. package/lib/components/Quiz/Question/DropdownExplanation.vue +41 -55
  52. package/lib/components/Quiz/Question/Explanation.vue +49 -59
  53. package/lib/components/Quiz/Question/MatrixChoicesContainer.vue +208 -226
  54. package/lib/components/Quiz/Question/MatrixRadioGroup.vue +7 -6
  55. package/lib/components/Quiz/Question/MobileMatrixChoicesContainer.vue +315 -320
  56. package/lib/components/Quiz/Question/MobileMatrixRadioGroup.vue +14 -11
  57. package/lib/components/Quiz/Question/PassageAndImage.vue +34 -45
  58. package/lib/components/Quiz/Question/PassageAndImageDropdown.vue +39 -49
  59. package/lib/components/Quiz/Question/Paywall.vue +30 -41
  60. package/lib/components/Quiz/Question/QuestionContext.vue +24 -33
  61. package/lib/components/Quiz/Question/StatsSummary.vue +12 -22
  62. package/lib/components/Quiz/Question/Summary.vue +56 -66
  63. package/lib/components/Quiz/Question/composables.ts +71 -0
  64. package/lib/components/Quiz/Question/injectionSymbols.ts +69 -0
  65. package/lib/components/Quiz/Question.vue +810 -1009
  66. package/lib/components/Quiz/QuizContainer.vue +63 -67
  67. package/lib/components/Quiz/QuizProgress.vue +73 -77
  68. package/lib/components/Quiz/QuizProgressBar.vue +3 -2
  69. package/lib/components/Quiz/question.d.ts +4 -4
  70. package/lib/components/Search/Pill.vue +2 -2
  71. package/lib/components/Search/Search.vue +2 -2
  72. package/lib/components/SidePanels/SidePanel.vue +8 -3
  73. package/lib/components/Tables/Table.vue +4 -3
  74. package/lib/components/Tables/TableActions.vue +3 -3
  75. package/lib/components/Tags/Tag.vue +2 -2
  76. package/lib/components/Toasts/Toast.vue +5 -3
  77. package/lib/components/Tooltips/OverflowTooltip.vue +2 -2
  78. package/lib/components/Tooltips/Tooltip.vue +2 -2
  79. package/lib/directives.ts +28 -23
  80. package/lib/pocketprep-export.module.scss +3 -2
  81. package/lib/pocketprep.scss +2 -2
  82. package/lib/styles/_breakpoints.scss +12 -24
  83. package/lib/styles/_colors.scss +0 -1
  84. package/package.json +38 -29
  85. package/stylelint.config.js +38 -0
  86. package/.eslintrc.cjs +0 -74
  87. package/dist/style.css +0 -1
  88. package/stylelint.config.cjs +0 -22
@@ -6,12 +6,12 @@
6
6
  >
7
7
  <div
8
8
  v-dark="isDarkMode"
9
- v-breakpoint:questionEl="breakpoints"
9
+ v-breakpoint="breakpointsWithEl"
10
10
  class="uikit-question-matrix-choices-container__columns"
11
11
  >
12
12
  <div
13
13
  v-dark="isDarkMode"
14
- v-breakpoint:questionEl="breakpoints"
14
+ v-breakpoint="breakpointsWithEl"
15
15
  class="uikit-question-matrix-choices-container__column-row-header"
16
16
  :class="{
17
17
  'uikit-question-matrix-choices-container__column-row-header--two-columns':
@@ -34,7 +34,7 @@
34
34
  v-for="(columnLabel, index) in matrixColumnLabels"
35
35
  :key="index"
36
36
  v-dark="isDarkMode"
37
- v-breakpoint:questionEl="breakpoints"
37
+ v-breakpoint="breakpointsWithEl"
38
38
  v-html="columnLabel"
39
39
  />
40
40
  </div>
@@ -50,7 +50,7 @@
50
50
  (showMatrixAnswers || reviewMode) && isTeachGroupReview,
51
51
  }"
52
52
  v-dark="isDarkMode"
53
- v-breakpoint:questionEl="breakpoints"
53
+ v-breakpoint="breakpointsWithEl"
54
54
  >
55
55
  <div
56
56
  class="uikit-question-matrix-choices-container__choices"
@@ -61,7 +61,7 @@
61
61
  numberOfMatrixColumnLabels === 2,
62
62
  }"
63
63
  v-dark="isDarkMode"
64
- v-breakpoint:questionEl="breakpoints"
64
+ v-breakpoint="breakpointsWithEl"
65
65
  v-for="(rowLabel, rowIndex) in matrixRowLabels"
66
66
  :key="rowIndex"
67
67
  >
@@ -76,7 +76,7 @@
76
76
  question.type === 'Matrix Radio Button' && numberOfMatrixColumnLabels === 2,
77
77
  }"
78
78
  v-dark="isDarkMode"
79
- v-breakpoint:questionEl="breakpoints"
79
+ v-breakpoint="breakpointsWithEl"
80
80
  v-html="rowLabel"
81
81
  />
82
82
  <template
@@ -103,7 +103,7 @@
103
103
  v-for="(columnLabel, columnIndex) in matrixColumnLabels"
104
104
  :key="columnIndex"
105
105
  v-dark="isDarkMode"
106
- v-breakpoint:questionEl="breakpoints"
106
+ v-breakpoint="breakpointsWithEl"
107
107
  >
108
108
  <Checkbox
109
109
  v-if="(showMatrixAnswers || reviewMode) &&
@@ -115,7 +115,7 @@
115
115
  :checkbox-styles="checkboxContainerStyling(rowIndex, columnIndex)"
116
116
  />
117
117
  <div
118
- v-else
118
+ v-else
119
119
  class="uikit-question-matrix-choices-container__clickable-checkbox"
120
120
  :class="{
121
121
  'uikit-question-matrix-choices-container__clickable-checkbox--review':
@@ -126,7 +126,7 @@
126
126
  checkboxClicked(rowIndex, columnIndex)"
127
127
  >
128
128
  <Checkbox
129
- :model-value="matrixCheckboxGrid[rowIndex][columnIndex]"
129
+ :model-value="matrixCheckboxGrid[rowIndex]?.[columnIndex] || false"
130
130
  :is-dark-mode="isDarkMode"
131
131
  :disabled="showMatrixAnswers || reviewMode"
132
132
  :checkbox-styles="checkboxContainerStyling(rowIndex, columnIndex)"
@@ -163,7 +163,6 @@
163
163
  :is-dark-mode="isDarkMode"
164
164
  :disabled="false"
165
165
  :question-el="questionEl"
166
- :breakpoints="breakpoints"
167
166
  @update:modelValue="updateRadioRowSelection(rowIndex, $event)"
168
167
  >
169
168
  <template #optionIcon="{ optionIcon }">
@@ -189,278 +188,261 @@
189
188
  </div>
190
189
  </template>
191
190
 
192
- <script lang="ts">
193
- import { Component, Vue, Prop, Emit, Watch } from 'vue-facing-decorator'
191
+ <script setup lang="ts">
194
192
  import Icon from '../../Icons/Icon.vue'
195
- import PocketButton from '../../Buttons/Button.vue'
196
193
  import Checkbox from '../../Forms/Checkbox.vue'
197
194
  import MatrixRadioGroup from './MatrixRadioGroup.vue'
198
- import { dark, breakpoint } from '../../../directives'
199
- import type { TBreakPointsObject, IRadioOptions, TMatrixChoiceKey } from './../question'
200
- import type { Study } from '@pocketprep/types'
195
+ import { dark as vDark, breakpoint as vBreakpoint } from '../../../directives'
196
+ import { useQuestionContext } from './composables'
197
+ import type { IRadioOptions, TMatrixChoiceKey } from './../question'
201
198
  import BrandColors from '../../../pocketprep-export.module.scss'
199
+ import { ref, computed, onMounted, watch } from 'vue'
200
+
201
+ const emit = defineEmits<{
202
+ 'emitSelectedMatrixChoice': [matrixChoiceKeys: TMatrixChoiceKey[]]
203
+ }>()
204
+
205
+ const {
206
+ // questionEl is used by the breakpoint directive
207
+ questionEl,
208
+ question,
209
+ isMatrixQuestionCorrect,
210
+ reviewMode,
211
+ isDarkMode,
212
+ breakpointsWithEl,
213
+ showMatrixAnswers,
214
+ matrixAnswerKeys,
215
+ selectedMatrixChoices,
216
+ isTeachGroupReview,
217
+ } = useQuestionContext()
218
+
219
+ const matrixCheckboxGrid = ref<boolean[][] | undefined>(undefined)
220
+ const matrixRadioGrid = ref<IRadioOptions[] | undefined>(undefined)
221
+ const brandColors = BrandColors
222
+
223
+ const defaultCheckboxGrid = computed(() => {
224
+ return matrixChoiceLayout.value?.map(row => {
225
+ const choiceRow = row.map(() => false)
226
+ return choiceRow
227
+ })
228
+ })
202
229
 
203
- @Component({
204
- components: {
205
- Icon,
206
- Checkbox,
207
- MatrixRadioGroup,
208
- PocketButton,
209
- },
210
- directives: {
211
- dark,
212
- breakpoint,
213
- },
230
+ const defaultRadioButtonGrid = computed(() => {
231
+ return matrixChoiceLayout.value?.map(row => {
232
+ return {
233
+ choices: row as TMatrixChoiceKey[],
234
+ value: null as TMatrixChoiceKey | null,
235
+ }
236
+ })
214
237
  })
215
- export default class MatrixChoicesContainer extends Vue {
216
- @Prop({ default: false }) reviewMode!: boolean
217
- @Prop({ default: false }) isDarkMode!: boolean
218
- @Prop({ default: null }) questionEl!: Element | null
219
- @Prop({ default: {
220
- 'mobile': 767,
221
- 'tablet-portrait': 1023,
222
- 'tablet-landscape': 1439,
223
- } }) breakpoints!: TBreakPointsObject
224
- @Prop() question!: Study.Class.QuestionJSON
225
- @Prop() matrixChoiceLayout!: string[][]
226
- @Prop({ default: false }) showMatrixAnswers!: boolean
227
- @Prop({ default: false }) isUnanswered!: boolean
228
- @Prop({ default: false }) isMatrixQuestionCorrect!: boolean
229
- @Prop() matrixAnswerKeys!: TMatrixChoiceKey[]
230
- @Prop() matrixDistractorKeys!: TMatrixChoiceKey[]
231
- @Prop() selectedMatrixChoices!: TMatrixChoiceKey[]
232
- @Prop({ default: false }) isTeachGroupReview!: boolean
233
-
234
- matrixCheckboxGrid: boolean[][] | undefined = undefined
235
- matrixRadioGrid: IRadioOptions[] | undefined = undefined
236
- columnIndex = 0
237
- rowIndex = 0
238
- brandColors = BrandColors
239
-
240
- get defaultCheckboxGrid () {
241
- return this.matrixChoiceLayout?.map(row => {
242
- const choiceRow = row.map(() => false)
243
- return choiceRow
244
- })
245
- }
246
238
 
247
- get defaultRadioButtonGrid () {
248
- return this.matrixChoiceLayout?.map(row => {
249
- return {
250
- choices: row as TMatrixChoiceKey[],
251
- value: null as TMatrixChoiceKey | null,
252
- }
253
- })
254
- }
239
+ const matrixChoiceLayout = computed(() => {
240
+ return question.value.matrixChoiceLayout
241
+ })
255
242
 
256
- get matrixRowLabels () {
257
- return this.question.matrixLabels?.rows
258
- }
243
+ const matrixRowLabels = computed(() => {
244
+ return question.value.matrixLabels?.rows
245
+ })
259
246
 
260
- get matrixColumnLabels () {
261
- return this.question.matrixLabels?.columns
262
- }
247
+ const matrixColumnLabels = computed(() => {
248
+ return question.value.matrixLabels?.columns
249
+ })
263
250
 
264
- get numberOfMatrixColumnLabels () {
265
- return this.question.matrixLabels?.columns.length || 0
266
- }
251
+ const numberOfMatrixColumnLabels = computed(() => {
252
+ return question.value.matrixLabels?.columns.length || 0
253
+ })
267
254
 
268
- get matrixColumnLabelsForRows () {
269
- return this.question.matrixLabels?.columnLabelForRows
255
+ const matrixColumnLabelsForRows = computed(() => {
256
+ return question.value.matrixLabels?.columnLabelForRows
257
+ })
258
+
259
+ onMounted(() => {
260
+ if (question.value.type === 'Matrix Checkbox') {
261
+ matrixCheckboxGrid.value = convertSelectedMatrixChoiceToCheckboxGrid()
270
262
  }
263
+
264
+ if (question.value.type === 'Matrix Radio Button') {
265
+ matrixRadioGrid.value = convertSelectedMatrixChoiceToRadioBtnGrid()
266
+ }
267
+ })
271
268
 
272
- mounted () {
273
- if (this.question.type === 'Matrix Checkbox') {
274
- this.matrixCheckboxGrid = this.convertSelectedMatrixChoiceToCheckboxGrid()
269
+ const convertSelectedMatrixChoiceToCheckboxGrid = () => {
270
+ const checkboxGrid = defaultCheckboxGrid.value
271
+ selectedMatrixChoices.value.forEach(choice => {
272
+ const rowIndex = Number(choice.substring(1, choice.indexOf('_'))) - 1
273
+ const colIndex = Number(choice.split('_').pop()) - 1
274
+ const row = checkboxGrid?.[rowIndex]
275
+ if (row) {
276
+ row[colIndex] = true
275
277
  }
276
-
277
- if (this.question.type === 'Matrix Radio Button') {
278
- this.matrixRadioGrid = this.convertSelectedMatrixChoiceToRadioBtnGrid()
278
+ })
279
+ return checkboxGrid
280
+ }
281
+
282
+ const convertSelectedMatrixChoiceToRadioBtnGrid = () => {
283
+ const radioBtnGrid = defaultRadioButtonGrid.value
284
+ selectedMatrixChoices.value.forEach(choice => {
285
+ const rowIndex = Number(choice.substring(1, choice.indexOf('_'))) - 1
286
+ const row = radioBtnGrid?.[rowIndex]
287
+ if (row) {
288
+ row.value = choice
279
289
  }
280
- }
290
+ })
291
+ return radioBtnGrid
292
+ }
281
293
 
282
- convertSelectedMatrixChoiceToCheckboxGrid () {
283
- const checkboxGrid = this.defaultCheckboxGrid
284
- this.selectedMatrixChoices.forEach(choice => {
285
- const rowIndex = Number(choice.substring(1, choice.indexOf('_'))) - 1
286
- const colIndex = Number(choice.split('_').pop()) - 1
287
- if (checkboxGrid && checkboxGrid[rowIndex]) {
288
- checkboxGrid[rowIndex][colIndex] = true
289
- }
290
- })
291
- return checkboxGrid
292
- }
294
+ const getRadioRowSelection = (rowIndex: number) => {
295
+ return matrixRadioGrid.value?.[rowIndex]?.value
296
+ }
293
297
 
294
- convertSelectedMatrixChoiceToRadioBtnGrid () {
295
- const radioBtnGrid = this.defaultRadioButtonGrid
296
- this.selectedMatrixChoices.forEach(choice => {
297
- const rowIndex = Number(choice.substring(1, choice.indexOf('_'))) - 1
298
- if (radioBtnGrid && radioBtnGrid[rowIndex]) {
299
- radioBtnGrid[rowIndex].value = choice
300
- }
301
- })
302
- return radioBtnGrid
303
- }
298
+ const getRadioRowChoices = (rowIndex: number) => {
299
+ const choices = matrixRadioGrid.value?.[rowIndex]?.choices
300
+ return choices
301
+ }
304
302
 
305
- getRadioRowSelection (rowIndex: number) {
306
- return this.matrixRadioGrid?.[rowIndex]?.value
303
+ const updateRadioRowSelection = (rowIndex: number, choiceKey: TMatrixChoiceKey | null) => {
304
+ const row = matrixRadioGrid.value?.[rowIndex]
305
+ if (row) {
306
+ row.value = choiceKey
307
307
  }
308
+ }
308
309
 
309
- getRadioRowChoices (rowIndex: number) {
310
- const choices = this.matrixRadioGrid?.[rowIndex]?.choices
311
- return choices
310
+ const selectedChoiceKey = (rowIndex: number, colIndex: number) => {
311
+ const row = rowIndex += 1
312
+ const column = colIndex += 1
313
+ if (selectedMatrixChoices && matrixAnswerKeys) {
314
+ const matrixSelectedChoiceKey = selectedMatrixChoices.value.find((choice) => {
315
+ const substring = choice.substring(1)
316
+ return substring === `${row}_${column}`
317
+ })
318
+ return matrixSelectedChoiceKey
312
319
  }
320
+ return undefined
321
+ }
313
322
 
314
- updateRadioRowSelection (rowIndex: number, choiceKey: TMatrixChoiceKey) {
315
- const row = this.matrixRadioGrid?.[rowIndex]
316
- if (row) {
317
- row.value = choiceKey
323
+ const correctlySelectedChoice = (rowIndex: number, colIndex: number) => {
324
+ if (selectedMatrixChoices.value && matrixAnswerKeys.value) {
325
+ const selectedChoice = selectedChoiceKey(rowIndex, colIndex)
326
+ if (selectedChoice && selectedChoice.startsWith('a') && matrixAnswerKeys.value.includes(selectedChoice)) {
327
+ return true
318
328
  }
319
329
  }
330
+ return false
331
+ }
320
332
 
321
- selectedChoiceKey (rowIndex: number, colIndex: number) {
322
- const row = rowIndex += 1
323
- const column = colIndex += 1
324
- if (this.selectedMatrixChoices && this.matrixAnswerKeys) {
325
- const matrixSelectedChoiceKey = this.selectedMatrixChoices.find((choice) => {
326
- const substring = choice.substring(1)
327
- return substring === `${row}_${column}`
328
- })
329
- return matrixSelectedChoiceKey
333
+ const incorrectlySelectedChoice = (rowIndex: number, colIndex: number) => {
334
+ if (selectedMatrixChoices.value && matrixAnswerKeys.value) {
335
+ const selectedChoice = selectedChoiceKey(rowIndex, colIndex)
336
+ if (selectedChoice?.startsWith('d')) {
337
+ return true
330
338
  }
331
- return undefined
332
339
  }
340
+ return false
341
+ }
342
+
343
+ const correctAnswerButNotSelected = (rowIndex: number, colIndex: number) => {
344
+ const selectedChoice = selectedChoiceKey(rowIndex, colIndex)
345
+ const answerKey = matrixAnswerKeys.value.find(choice => choice === `a${rowIndex + 1}_${colIndex + 1}`)
346
+ return answerKey && !selectedChoice
347
+ }
333
348
 
334
- correctlySelectedChoice (rowIndex: number, colIndex: number) {
335
- if (this.selectedMatrixChoices && this.matrixAnswerKeys) {
336
- const selectedChoice = this.selectedChoiceKey(rowIndex, colIndex)
337
- if (selectedChoice && selectedChoice.startsWith('a') && this.matrixAnswerKeys.includes(selectedChoice)) {
338
- return true
339
- }
340
- }
341
- return false
342
- }
349
+ const checkboxContainerStyling = (rowIndex: number, columnIndex: number) => {
350
+ const isReviewMode = showMatrixAnswers.value || reviewMode.value
343
351
 
344
- incorrectlySelectedChoice (rowIndex: number, colIndex: number) {
345
- if (this.selectedMatrixChoices && this.matrixAnswerKeys) {
346
- const selectedChoice = this.selectedChoiceKey(rowIndex, colIndex)
347
- if (selectedChoice && selectedChoice.startsWith('d')) {
348
- return true
349
- }
352
+ // check box is correctlySelected
353
+ if (isReviewMode && correctlySelectedChoice(rowIndex, columnIndex)) {
354
+ const borderColor = isDarkMode.value ? brandColors.jungleGreen : brandColors.cadaverous
355
+ return {
356
+ borderColor: `${borderColor} !important`,
357
+ background: `${borderColor} !important`,
350
358
  }
351
- return false
352
359
  }
353
-
354
- correctAnswerButNotSelected (rowIndex: number, colIndex: number) {
355
- const selectedChoice = this.selectedChoiceKey(rowIndex, colIndex)
356
- const answerKey = this.matrixAnswerKeys.find(choice => choice === `a${rowIndex + 1}_${colIndex + 1}`)
357
- return answerKey && !selectedChoice
358
- }
359
-
360
- checkboxContainerStyling (rowIndex: number, columnIndex: number) {
361
- const isReviewMode = this.showMatrixAnswers || this.reviewMode
362
- const incorrectlySelectedChoice = this.incorrectlySelectedChoice(rowIndex, columnIndex)
363
-
364
- // check box is correctlySelected
365
- if (isReviewMode && this.correctlySelectedChoice(rowIndex, columnIndex)) {
366
- const borderColor = this.isDarkMode ? this.brandColors.jungleGreen : this.brandColors.cadaverous
367
- return {
368
- borderColor: `${borderColor} !important`,
369
- background: `${borderColor} !important`,
370
- }
371
- }
372
360
 
373
- if (isReviewMode && incorrectlySelectedChoice) {
374
- return {
375
- background: `${this.brandColors.steel} !important`,
376
- border: `1px solid ${this.brandColors.steel} !important`,
377
- }
378
- }
379
-
380
- if (isReviewMode && this.correctAnswerButNotSelected(rowIndex, columnIndex)) {
381
- return {
382
- background: 'transparent !important',
383
- border: `1px solid ${this.brandColors.slate} !important`,
384
- }
361
+ if (isReviewMode && incorrectlySelectedChoice(rowIndex, columnIndex)) {
362
+ return {
363
+ background: `${brandColors.steel} !important`,
364
+ border: `1px solid ${brandColors.steel} !important`,
385
365
  }
386
366
  }
387
367
 
388
- checkboxCheckStyling (rowIndex: number, columnIndex: number) {
389
- const isReviewMode = this.showMatrixAnswers || this.reviewMode
390
- if (isReviewMode && this.correctAnswerButNotSelected(rowIndex, columnIndex)) {
391
- const color = this.isDarkMode ? this.brandColors.jungleGreen : this.brandColors.cadaverous
392
- return {
393
- color: `${color} !important`,
394
- }
368
+ if (isReviewMode && correctAnswerButNotSelected(rowIndex, columnIndex)) {
369
+ return {
370
+ background: 'transparent !important',
371
+ border: `1px solid ${brandColors.slate} !important`,
395
372
  }
396
373
  }
374
+ }
397
375
 
398
- checkboxClicked (rowIndex: number, columnIndex: number) {
399
- if (this.matrixCheckboxGrid && this.matrixCheckboxGrid[rowIndex]) {
400
- this.matrixCheckboxGrid[rowIndex][columnIndex] = !this.matrixCheckboxGrid[rowIndex][columnIndex]
376
+ const checkboxCheckStyling = (rowIndex: number, columnIndex: number) => {
377
+ const isReviewMode = showMatrixAnswers.value || reviewMode.value
378
+ if (isReviewMode && correctAnswerButNotSelected(rowIndex, columnIndex)) {
379
+ const color = isDarkMode.value ? brandColors.jungleGreen : brandColors.cadaverous
380
+ return {
381
+ color: `${color} !important`,
401
382
  }
402
383
  }
384
+ }
403
385
 
404
- @Emit('emitSelectedMatrixChoice')
405
- emitSelectedMatrixChoice (matrixChoiceKeys: TMatrixChoiceKey[]) {
406
- return matrixChoiceKeys
386
+ const checkboxClicked = (rowIndex: number, columnIndex: number) => {
387
+ const row = matrixCheckboxGrid.value?.[rowIndex]
388
+ if (row) {
389
+ row[columnIndex] = !row[columnIndex]
407
390
  }
391
+ }
408
392
 
409
- @Watch('matrixCheckboxGrid', { deep: true })
410
- matrixCheckboxGridChange () {
411
- if (this.matrixChoiceLayout && this.matrixCheckboxGrid) {
412
- const selectedCheckboxChoices: TMatrixChoiceKey[] = []
413
-
414
- this.matrixCheckboxGrid.forEach((row, rowIndex) => {
415
- row.forEach((choice, choiceIndex) => {
416
- if (
417
- choice &&
418
- this.matrixChoiceLayout[rowIndex] &&
419
- this.matrixChoiceLayout[rowIndex][choiceIndex]
420
- ) {
421
- const choiceKey = this.matrixChoiceLayout[rowIndex][choiceIndex] as TMatrixChoiceKey
393
+ const emitSelectedMatrixChoice = (matrixChoiceKeys: TMatrixChoiceKey[]) => {
394
+ emit('emitSelectedMatrixChoice', matrixChoiceKeys)
395
+ }
396
+
397
+ watch(matrixCheckboxGrid, () => {
398
+ if (matrixChoiceLayout.value && matrixCheckboxGrid.value) {
399
+ const selectedCheckboxChoices: TMatrixChoiceKey[] = []
400
+
401
+ matrixCheckboxGrid.value?.forEach((row, rowIndex) => {
402
+ row.forEach((choice, choiceIndex) => {
403
+ if (choice && matrixChoiceLayout?.value?.[rowIndex]?.[choiceIndex]) {
404
+ const choiceKey = matrixChoiceLayout.value?.[rowIndex]?.[choiceIndex] as TMatrixChoiceKey | null
405
+ if (choiceKey) {
422
406
  selectedCheckboxChoices.push(choiceKey)
423
407
  }
424
- })
425
- })
426
- this.emitSelectedMatrixChoice(selectedCheckboxChoices)
427
- }
408
+ }
409
+ })
410
+ })
411
+ emitSelectedMatrixChoice(selectedCheckboxChoices)
428
412
  }
413
+ }, { deep: true })
429
414
 
430
- @Watch('matrixRadioGrid', { deep: true })
431
- matrixRadioGridChange () {
432
- if (this.matrixChoiceLayout && this.matrixRadioGrid) {
433
- const selectedRadioButtonChoices: TMatrixChoiceKey[] = []
415
+ watch(matrixRadioGrid, () => {
416
+ if (matrixChoiceLayout.value && matrixRadioGrid.value) {
417
+ const selectedRadioButtonChoices: TMatrixChoiceKey[] = []
434
418
 
435
- this.matrixRadioGrid.forEach((row, rowIndex) => {
436
- const choiceKey = row.value
437
- if (choiceKey && this.matrixChoiceLayout[rowIndex]) {
438
- selectedRadioButtonChoices.push(choiceKey)
439
- }
440
- })
441
- this.emitSelectedMatrixChoice(selectedRadioButtonChoices)
442
- }
419
+ matrixRadioGrid.value?.forEach((row, rowIndex) => {
420
+ const choiceKey = row.value
421
+ if (choiceKey && matrixChoiceLayout.value?.[rowIndex]) {
422
+ selectedRadioButtonChoices.push(choiceKey)
423
+ }
424
+ })
425
+ emitSelectedMatrixChoice(selectedRadioButtonChoices)
443
426
  }
427
+ }, { deep: true })
444
428
 
445
- @Watch('selectedMatrixChoices')
446
- selectedMatrixChoicesChange () {
447
- if ((this.reviewMode || this.showMatrixAnswers) && this.question.type === 'Matrix Checkbox') {
448
- const selectedCheckboxGrid = this.convertSelectedMatrixChoiceToCheckboxGrid()
449
- this.matrixCheckboxGrid = selectedCheckboxGrid ? selectedCheckboxGrid : this.defaultCheckboxGrid
450
- }
429
+ watch(selectedMatrixChoices, () => {
430
+ if ((reviewMode.value || showMatrixAnswers.value) && question.value.type === 'Matrix Checkbox') {
431
+ const selectedCheckboxGrid = convertSelectedMatrixChoiceToCheckboxGrid()
432
+ matrixCheckboxGrid.value = selectedCheckboxGrid ? selectedCheckboxGrid : defaultCheckboxGrid.value
433
+ }
451
434
 
452
- if ((this.reviewMode || this.showMatrixAnswers) && this.question.type === 'Matrix Radio Button') {
453
- const selectedRadioBtnGrid = this.convertSelectedMatrixChoiceToRadioBtnGrid()
454
- this.matrixRadioGrid = selectedRadioBtnGrid
455
- }
435
+ if ((reviewMode.value || showMatrixAnswers.value) && question.value.type === 'Matrix Radio Button') {
436
+ const selectedRadioBtnGrid = convertSelectedMatrixChoiceToRadioBtnGrid()
437
+ matrixRadioGrid.value = selectedRadioBtnGrid
456
438
  }
457
- }
439
+ })
458
440
 
459
441
  </script>
460
442
 
461
443
  <style lang="scss">
462
- @import '../../../styles/colors';
463
- @import '../../../styles/breakpoints';
444
+ @use '@/styles/breakpoints' as *;
445
+ @use '@/styles/colors' as *;
464
446
 
465
447
  .uikit-question-matrix-choices-container {
466
448
  width: 100%;
@@ -1,25 +1,26 @@
1
1
  <script setup lang="ts">
2
2
  import RadioButton from '../../Forms/RadioButton.vue'
3
3
  import { dark as vDark } from '../../../directives'
4
+ import type { TMatrixChoiceKey } from '../question'
4
5
 
5
6
  defineProps<{
6
7
  isDarkMode: boolean
7
- choices: string[]
8
+ choices?: TMatrixChoiceKey[]
8
9
  labels?: string[]
9
10
  showAnswers: boolean
10
11
  disabled: boolean
11
12
  }>()
12
13
 
13
- const selectedChoice = defineModel<string>()
14
+ const selectedChoice = defineModel<TMatrixChoiceKey | null>({ default: null })
14
15
 
15
- const selectChoice = (choiceKey: string) => {
16
+ const selectChoice = (choiceKey: TMatrixChoiceKey) => {
16
17
  selectedChoice.value = choiceKey
17
18
  }
18
19
  </script>
19
20
 
20
21
  <template>
21
22
  <ul
22
- v-if="choices.length"
23
+ v-if="choices && choices.length"
23
24
  class="uikit-matrix-radio-group"
24
25
  :class="{'uikit-matrix-radio-group--disabled': showAnswers}"
25
26
  v-dark="isDarkMode"
@@ -73,8 +74,8 @@ const selectChoice = (choiceKey: string) => {
73
74
  </template>
74
75
 
75
76
  <style lang="scss" scoped>
76
- @import '../../../styles/breakpoints';
77
- @import '../../../styles/colors';
77
+ @use '@/styles/breakpoints' as *;
78
+ @use '@/styles/colors' as *;
78
79
 
79
80
  .uikit-matrix-radio-group {
80
81
  display: flex;