@pocketprep/ui-kit 3.4.52 → 3.4.54

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"
@@ -38,10 +38,11 @@
38
38
  ref="uikit-question-summary__summary-dropdown-explanation"
39
39
  class="uikit-question-summary__summary-dropdown-explanation"
40
40
  >
41
+ <slot name="explanationTopExperiment"></slot>
41
42
  <div
42
43
  v-dark="isDarkMode"
43
44
  class="uikit-question-summary__summary-dropdown-explanation-text"
44
- v-html="question.explanation"
45
+ v-html="summary"
45
46
  />
46
47
  <img
47
48
  v-if="explanationImageUrl"
@@ -97,7 +98,7 @@
97
98
  </div>
98
99
  </div>
99
100
  <Icon
100
- v-if="isCorrect"
101
+ v-if="isQuestionCorrect"
101
102
  v-dark="isDarkMode"
102
103
  type="correct"
103
104
  class="uikit-question-summary__summary-correct-icon"
@@ -118,6 +119,7 @@ import Icon from '../../Icons/Icon.vue'
118
119
  import PocketButton from '../../Buttons/Button.vue'
119
120
  import { breakpoint, dark } from '../../../directives'
120
121
  import type { TBreakPointsObject } from './../question'
122
+ import { highlightKeywordsInText } from '../../../utils'
121
123
 
122
124
  @Component({
123
125
  components: {
@@ -139,15 +141,31 @@ export default class Summary extends Vue {
139
141
  @Prop({ default: undefined }) reference!: string | undefined
140
142
  @Prop({ default: false }) hideReferences!: boolean
141
143
  @Prop({ default: false }) isCorrect!: boolean
144
+ @Prop({ default: false }) isMatrixQuestionCorrect!: boolean
142
145
  @Prop({ default: false }) isUnanswered!: boolean
143
146
  @Prop({ default: false }) reviewMode!: boolean
144
147
  @Prop({ default: false }) isDarkMode!: boolean
148
+ @Prop({ default: false }) isMatrixQuestion!: boolean
145
149
  @Prop({ default: null }) questionEl!: Element | null
146
150
  @Prop({ default: {
147
151
  'mobile': 767,
148
152
  'tablet-portrait': 1023,
149
153
  'tablet-landscape': 1439,
150
154
  } }) breakpoints!: TBreakPointsObject
155
+ @Prop({ default: [] }) keywordDefinitions!: { keyword: string; definition: string }[]
156
+
157
+ get isQuestionCorrect () {
158
+ return (!this.isMatrixQuestion && this.isCorrect) || (this.isMatrixQuestion && this.isMatrixQuestionCorrect)
159
+ }
160
+
161
+ get summary () {
162
+ return highlightKeywordsInText({
163
+ text: this.question.explanation || '',
164
+ keywordDefinitions: this.keywordDefinitions,
165
+ isDarkMode: this.isDarkMode,
166
+ location: 'explanation',
167
+ })
168
+ }
151
169
 
152
170
  @Emit('toggleSummaryExplanation')
153
171
  toggleSummaryExplanation () {
@@ -186,6 +204,7 @@ export default class Summary extends Vue {
186
204
  display: inline-block;
187
205
  }
188
206
 
207
+
189
208
  &__summary-title {
190
209
  font-weight: 600;
191
210
  font-size: 15.5px;
@@ -289,6 +308,12 @@ export default class Summary extends Vue {
289
308
  margin: 0;
290
309
  }
291
310
  }
311
+
312
+ .keyword-highlight {
313
+ span {
314
+ font-size: 16px;
315
+ }
316
+ }
292
317
  }
293
318
 
294
319
  &__summary-dropdown-explanation-image {