@pocketprep/ui-kit 3.7.2 → 3.7.3

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.
@@ -438,7 +438,7 @@ watch(selectedBuildListChoiceOrder, () => {
438
438
  top: -8px;
439
439
  bottom: -8px;
440
440
  left: 8px;
441
- right: 10px;
441
+ right: 14px;
442
442
  border-radius: 11px;
443
443
  pointer-events: none;
444
444
 
@@ -27,6 +27,7 @@ const {
27
27
  isDarkMode,
28
28
  showMPMCAnswers,
29
29
  selectedMPMCChoices,
30
+ mpmcChoices,
30
31
  } = useQuestionContext()
31
32
 
32
33
  const mpmcRadioGrid = ref<IMPMCRadioOptions[] | undefined>(undefined)
@@ -37,8 +38,7 @@ const mpmcLabels = computed(() => {
37
38
  })
38
39
 
39
40
  const questionChoices = computed(() => {
40
- const choices = question.value.choices
41
- return choices
41
+ return mpmcChoices.value
42
42
  })
43
43
 
44
44
  const choiceKeysByLabelIndexObj = computed(() => {
@@ -144,7 +144,7 @@ const radioButtonColor = (choice: TChoiceKey) => {
144
144
  }
145
145
 
146
146
  &:hover {
147
- background: $fog;
147
+ background: $pearl;
148
148
  }
149
149
  }
150
150
 
@@ -231,6 +231,7 @@ const toggleSummaryExplanationImageLongAlt = () => {
231
231
  &--mpmc-question {
232
232
  max-width: 492px;
233
233
  margin-left: 4px;
234
+ margin-top: 8px;
234
235
  }
235
236
 
236
237
  &--tablet-portrait {
@@ -1,6 +1,6 @@
1
1
  import { inject, ref } from 'vue'
2
2
  import * as InjectionKeys from './injectionSymbols'
3
- import type { TChoice, TChoiceKey, TMatrixChoiceKey, TBuildListChoice } from '../question'
3
+ import type { TChoice, TChoiceKey, TMatrixChoiceKey, TBuildListChoice, TMPMCChoice } from '../question'
4
4
 
5
5
  export const useQuestionContext = () => {
6
6
  const question = inject(InjectionKeys.questionKey)
@@ -16,6 +16,7 @@ export const useQuestionContext = () => {
16
16
  choiceScores,
17
17
  choices: inject(InjectionKeys.choicesKey, ref<TChoice[]>([])),
18
18
  buildListChoices: inject(InjectionKeys.buildListChoicesKey, ref<TBuildListChoice[]>([])),
19
+ mpmcChoices: inject(InjectionKeys.mpmcChoicesKey, ref<TMPMCChoice[]>([])),
19
20
  questionEl: inject(InjectionKeys.questionElKey, ref(null)),
20
21
  breakpointsWithEl: inject(InjectionKeys.breakpointsWithElKey, ref({
21
22
  breakpoints: {
@@ -11,12 +11,14 @@ import type {
11
11
  TMatrixChoiceScores,
12
12
  TBuildListChoiceScores,
13
13
  TQuizMode,
14
+ TMPMCChoice,
14
15
  } from '../question'
15
16
  import type { ComputedRef, InjectionKey, Ref } from 'vue'
16
17
 
17
18
  export const questionKey = Symbol('question') as InjectionKey<ComputedRef<Study.Class.QuestionJSON>>
18
19
  export const choicesKey = Symbol('choices') as InjectionKey<ComputedRef<TChoice[]>>
19
- export const buildListChoicesKey = Symbol('choices') as InjectionKey<ComputedRef<TBuildListChoice[]>>
20
+ export const buildListChoicesKey = Symbol('buildListChoices') as InjectionKey<ComputedRef<TBuildListChoice[]>>
21
+ export const mpmcChoicesKey = Symbol('mpmcChoices') as InjectionKey<ComputedRef<TMPMCChoice[]>>
20
22
  export const questionElKey = Symbol('questionEl') as InjectionKey<Ref<Element | null>>
21
23
  export const breakpointsWithElKey = Symbol('breakpointsWithEl') as InjectionKey<Ref<{
22
24
  breakpoints: {
@@ -470,6 +470,7 @@ import type {
470
470
  TBuildListChoiceKey,
471
471
  TChoice,
472
472
  TBuildListChoice,
473
+ TMPMCChoice,
473
474
  TChoiceScores,
474
475
  TMatrixChoiceScores,
475
476
  TBuildListChoiceScores,
@@ -800,6 +801,10 @@ const buildListChoices = computed(() => {
800
801
  return shuffledChoices
801
802
  })
802
803
 
804
+ const mpmcChoices = computed(() => {
805
+ return shuffleMPMCChoices([ ...props.question.choices ])
806
+ })
807
+
803
808
  const isCorrect = computed(() => {
804
809
  // In order to be correct, user must have selected all the answers and none of the distractors
805
810
  return showAnswers.value
@@ -946,11 +951,11 @@ const isMatrixQuestionAnswered = computed(() => {
946
951
 
947
952
  const isMPMCQuestionAnswered = computed(() => {
948
953
  const mpmcLabels = question.value.mpmcLabels
949
- const mpmcChoices = question.value.choices
954
+ const mpmcQuestionChoices = question.value.choices
950
955
  const selectedMPMCLabelIndexes: number[] = []
951
956
 
952
957
  selectedMPMCChoices.value.forEach(choice => {
953
- const mpmcChoiceObj = mpmcChoices.find(c => c.id === choice)
958
+ const mpmcChoiceObj = mpmcQuestionChoices.find(c => c.id === choice)
954
959
  if (
955
960
  mpmcChoiceObj?.labelIndex !== undefined
956
961
  && !selectedMPMCLabelIndexes.includes(mpmcChoiceObj?.labelIndex)
@@ -1044,7 +1049,8 @@ const keydownListener = (e: KeyboardEvent) => {
1044
1049
  }
1045
1050
  break
1046
1051
  case 'KeyX':
1047
- showAnswers.value && toggleExplanation()
1052
+ (showAnswers.value || showMatrixAnswers.value || showBuildListOrder.value || showMPMCAnswers.value)
1053
+ && toggleExplanation()
1048
1054
  break
1049
1055
  case 'Escape':
1050
1056
  emitClose()
@@ -1191,6 +1197,30 @@ const shuffleBuildListChoices = (choicesToShuffle: TBuildListChoice[]): TBuildLi
1191
1197
  : sortedChoices
1192
1198
  }
1193
1199
 
1200
+ const shuffleMPMCChoices = (choicesToShuffle: TMPMCChoice[]): TMPMCChoice[]=> {
1201
+ const sortedChoices = choicesToShuffle.sort((a, b) => {
1202
+ const hashChar = (char: string, num: number) => ((num << 5) - num) + char.charCodeAt(0)
1203
+
1204
+ const aHash = a.text?.split('')
1205
+ .reduce((acc: number, char: string) => hashChar(char, acc) & hashChar(char, acc), 0)
1206
+ const bHash = b.text?.split('')
1207
+ .reduce((acc: number, char: string) => hashChar(char, acc) & hashChar(char, acc), 0)
1208
+
1209
+ return (aHash || 0) - (bHash || 0)
1210
+ })
1211
+
1212
+ return props.answerSeed
1213
+ ? props.answerSeed.reduce<TMPMCChoice[]>((acc, i) => {
1214
+ const sortedChoice = sortedChoices[i]
1215
+ if (sortedChoice) {
1216
+ acc.push(sortedChoice)
1217
+ }
1218
+
1219
+ return acc
1220
+ }, [])
1221
+ : sortedChoices
1222
+ }
1223
+
1194
1224
  const choiceFocusOut = (event: FocusEvent) => {
1195
1225
  const relatedTarget = event.relatedTarget
1196
1226
  if (
@@ -1454,7 +1484,6 @@ const clickCheckMatrixAnswer = () => {
1454
1484
  const clickCheckMPMCAnswer = () => {
1455
1485
  if (!props.hideAnswer) {
1456
1486
  showMPMCAnswers.value = true
1457
-
1458
1487
  emitCheckAnswer({
1459
1488
  isCorrect: isMPMCQuestionCorrect.value,
1460
1489
  selectedChoices: selectedMPMCChoices.value,
@@ -1624,10 +1653,7 @@ onMounted(() => {
1624
1653
  showBuildListOrder.value = props.initialShowAnswers
1625
1654
  }
1626
1655
 
1627
- if (
1628
- props.allowKeyboardShortcuts
1629
- && !isMPMCQuestion.value
1630
- ) {
1656
+ if (props.allowKeyboardShortcuts) {
1631
1657
  window.addEventListener('keydown', keydownListener)
1632
1658
  }
1633
1659
 
@@ -1652,6 +1678,7 @@ onBeforeUnmount(() => {
1652
1678
  provide(InjectionKeys.questionKey, question)
1653
1679
  provide(InjectionKeys.choicesKey, choices)
1654
1680
  provide(InjectionKeys.buildListChoicesKey, buildListChoices)
1681
+ provide(InjectionKeys.mpmcChoicesKey, mpmcChoices)
1655
1682
  provide(InjectionKeys.questionElKey, questionEl)
1656
1683
  provide(InjectionKeys.breakpointsWithElKey, breakpointsWithEl)
1657
1684
  provide(InjectionKeys.quizLengthKey, quizLength)
@@ -17,6 +17,12 @@ export type TBreakPointsObject = {
17
17
 
18
18
  export type TChoice = { text?: string; key: TChoiceKey }
19
19
  export type TBuildListChoice = { text?: string; key: TBuildListChoiceKey }
20
+ export type TMPMCChoice = {
21
+ text?: string
22
+ id?: string
23
+ isCorrect?: boolean
24
+ labelIndex?: number
25
+ }
20
26
 
21
27
  export type TChoiceScores = Partial<Record<TChoiceKey, number>> & {
22
28
  totalAnswered: number
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pocketprep/ui-kit",
3
- "version": "3.7.2",
3
+ "version": "3.7.3",
4
4
  "description": "Pocket Prep UI Kit",
5
5
  "author": "pocketprep",
6
6
  "scripts": {