@pocketprep/ui-kit 3.4.8 → 3.4.10

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.
@@ -11,9 +11,9 @@
11
11
  class="uikit-question-choices-container__choice-container"
12
12
  :class="{
13
13
  'uikit-question-choices-container__choice-container--hover':
14
- !showAnswers && choiceKeyHover === choice.key,
14
+ !showAnswers && hoverChoiceKey === choice.key,
15
15
  'uikit-question-choices-container__choice-container--focus':
16
- !showAnswers && choiceKeyFocus === choice.key,
16
+ !showAnswers && focusChoiceKey === choice.key,
17
17
  'uikit-question-choices-container__choice-container--selected': !showAnswers
18
18
  && selectedChoices.includes(choice.key),
19
19
  'uikit-question-choices-container__choice-container--correct':
@@ -29,7 +29,7 @@
29
29
  }"
30
30
  @mousedown.prevent
31
31
  @mouseover="emitChoiceMouseOver(choice.key)"
32
- @mouseleave="emitChoiceMouseleave"
32
+ @mouseleave="emitChoiceMouseLeave"
33
33
  @focusin="emitChoiceFocusIn(choice.key)"
34
34
  @focusout="emitChoiceFocusOut($event)"
35
35
  @click.stop="emitSelectedChoice(choice.key)"
@@ -181,7 +181,7 @@
181
181
  :aria-checked="choiceStrikes.includes(choice.key) ? 'true' : 'false'"
182
182
  :class="{
183
183
  'uikit-question-choices-container__strikethrough--visible': !showAnswers
184
- && [ choiceKeyHover, choiceKeyFocus ].includes(choice.key),
184
+ && [ hoverChoiceKey, focusChoiceKey ].includes(choice.key),
185
185
  'uikit-question-choices-container__strikethrough--active': choiceStrikes.includes(choice.key),
186
186
  }"
187
187
  @mousedown.prevent
@@ -324,14 +324,6 @@ export default class ChoicesContainer extends Vue {
324
324
  'tablet-landscape': 1439,
325
325
  } }) breakpoints!: TBreakPointsObject
326
326
 
327
- choiceKeyHover: TChoiceKey | null = null
328
- choiceKeyFocus: TChoiceKey | null = null
329
-
330
- mounted () {
331
- this.choiceKeyHover = this.hoverChoiceKey
332
- this.choiceKeyFocus = this.focusChoiceKey
333
- }
334
-
335
327
  stripText (string?: string) {
336
328
  return string?.replace(/<[^\s>]+[^>]*>/gi, ' ').trim()
337
329
  }
@@ -339,25 +331,21 @@ export default class ChoicesContainer extends Vue {
339
331
 
340
332
  @Emit('emitChoiceFocusIn')
341
333
  emitChoiceFocusIn (choiceKey: TChoiceKey) {
342
- this.choiceKeyFocus = choiceKey
343
334
  return choiceKey
344
335
  }
345
336
 
346
337
  @Emit('emitChoiceFocusOut')
347
338
  emitChoiceFocusOut (event: FocusEvent) {
348
- this.choiceKeyFocus = null
349
339
  return event
350
340
  }
351
341
 
352
342
  @Emit('emitChoiceMouseOver')
353
343
  emitChoiceMouseOver (choiceKey: TChoiceKey) {
354
- this.choiceKeyHover = choiceKey
355
344
  return choiceKey
356
345
  }
357
346
 
358
- @Emit('emitChoiceMouseleave')
359
- emitChoiceMouseleave () {
360
- this.choiceKeyHover = null
347
+ @Emit('emitChoiceMouseLeave')
348
+ emitChoiceMouseLeave () {
361
349
  return
362
350
  }
363
351
 
@@ -0,0 +1,333 @@
1
+ <template>
2
+ <div
3
+ v-if="showExplanation && !showPaywall"
4
+ v-breakpoint:questionEl="breakpoints"
5
+ v-dark="isDarkMode"
6
+ class="uikit-question-explanation"
7
+ >
8
+ <div
9
+ ref="explanation"
10
+ v-dark="isDarkMode"
11
+ class="uikit-question-explanation__explanation-title"
12
+ tabindex="-1"
13
+ >
14
+ Explanation Details
15
+ </div>
16
+ <div
17
+ v-dark="isDarkMode"
18
+ v-breakpoint:questionEl="breakpoints"
19
+ class="uikit-question-explanation__explanation-text"
20
+ v-html="question.explanation"
21
+ />
22
+ <img
23
+ v-if="explanationImageUrl"
24
+ v-dark="isDarkMode"
25
+ v-breakpoint:questionEl="breakpoints"
26
+ class="uikit-question-explanation__explanation-image"
27
+ :class="{
28
+ 'uikit-question-explanation__explanation-image--long-alt': explanationImageLongAlt,
29
+ }"
30
+ :src="explanationImageUrl"
31
+ :alt="`${explanationImageAlt}. Extended image description below.`"
32
+ >
33
+ <PocketButton
34
+ v-if="explanationImageLongAlt"
35
+ v-breakpoint:questionEl="breakpoints"
36
+ type="tertiary-small"
37
+ class="uikit-question-explanation__toggle-explanation-img-description"
38
+ :class="{
39
+ 'uikit-question-explanation__toggle-explanation-img-description--open': showExplanationImageLongAlt,
40
+ }"
41
+ :is-dark-mode="isDarkMode"
42
+ :aria-expanded="showExplanationImageLongAlt ? 'true' : 'false'"
43
+ @click.stop="toggleExplanationImageLongAlt"
44
+ @mousedown.prevent
45
+ >
46
+ <span class="uikit-question-explanation__toggle-explanation-img-description-text">Image Description</span>
47
+ <Icon
48
+ class="uikit-question-explanation__toggle-explanation-img-description-icon"
49
+ :class="{
50
+ 'uikit-question-explanation__toggle-explanation-img-description-icon--up':
51
+ showExplanationImageLongAlt,
52
+ }"
53
+ type="accordionArrow"
54
+ />
55
+ </PocketButton>
56
+ <div
57
+ v-if="showExplanationImageLongAlt"
58
+ ref="uikit-question-explanation__explanation-img-description"
59
+ v-dark="isDarkMode"
60
+ class="uikit-question-explanation__explanation-img-description"
61
+ tabindex="-1"
62
+ v-html="explanationImageLongAlt"
63
+ />
64
+ <div
65
+ v-if="reference && !hideReferences"
66
+ v-dark="isDarkMode"
67
+ class="uikit-question-explanation__reference"
68
+ >
69
+ <span class="uikit-question-explanation__reference-label">Reference: </span>
70
+ <div v-html="reference" />
71
+ </div>
72
+ <div
73
+ v-if="!reviewMode"
74
+ v-dark="isDarkMode"
75
+ class="uikit-question-explanation__explanation-close"
76
+ tabindex="0"
77
+ role="button"
78
+ aria-label="Close explanation"
79
+ @keydown.enter.stop="toggleExplanation"
80
+ @click.stop="toggleExplanation"
81
+ @mousedown.prevent
82
+ >
83
+ <Icon type="close" />
84
+ </div>
85
+ </div>
86
+ </template>
87
+
88
+ <script lang="ts">
89
+ import { Component, Emit, Prop, Vue } from 'vue-facing-decorator'
90
+ import type { Study } from '@pocketprep/types'
91
+ import Icon from '../../Icons/Icon.vue'
92
+ import PocketButton from '../../Buttons/Button.vue'
93
+ import { breakpoint, dark } from '../../../directives'
94
+ import type { TBreakPointsObject } from './../question'
95
+
96
+ @Component({
97
+ components: {
98
+ Icon,
99
+ PocketButton,
100
+ },
101
+ directives: {
102
+ dark,
103
+ breakpoint,
104
+ },
105
+ })
106
+ export default class Explanation extends Vue {
107
+ @Prop() question!: Study.Class.QuestionJSON
108
+ @Prop({ default: false }) showExplanation!: boolean
109
+ @Prop({ default: false }) showPaywall!: boolean
110
+ @Prop({ default: false }) showExplanationImageLongAlt!: boolean
111
+ @Prop({ default: null }) explanationImageUrl!: string | null
112
+ @Prop({ default: undefined }) explanationImageAlt!: string | undefined
113
+ @Prop({ default: undefined }) explanationImageLongAlt!: string | undefined
114
+ @Prop({ default: false }) reviewMode!: boolean
115
+ @Prop({ default: undefined }) reference!: string | undefined
116
+ @Prop({ default: false }) hideReferences!: boolean
117
+ @Prop({ default: false }) isDarkMode!: boolean
118
+ @Prop({ default: null }) questionEl!: Element | null
119
+ @Prop({ default: {
120
+ 'mobile': 767,
121
+ 'tablet-portrait': 1023,
122
+ 'tablet-landscape': 1439,
123
+ } }) breakpoints!: TBreakPointsObject
124
+
125
+ @Emit('toggleExplanationImageLongAlt')
126
+ toggleExplanationImageLongAlt () {
127
+ return
128
+ }
129
+
130
+ @Emit('toggleExplanation')
131
+ toggleExplanation () {
132
+ return
133
+ }
134
+ }
135
+ </script>
136
+
137
+ <style lang="scss">
138
+ @import '../../../styles/colors';
139
+ @import '../../../styles/breakpoints';
140
+
141
+ .uikit-question-explanation {
142
+ position: relative;
143
+ background-color: $white;
144
+ border: 1px solid rgba($pewter, 0.85);
145
+ border-bottom: 0;
146
+ border-radius: 6px 6px 0 0;
147
+ padding: 42px 60px 72px;
148
+ box-sizing: border-box;
149
+ max-width: 565px;
150
+ min-height: 100%;
151
+
152
+ &--tablet-landscape {
153
+ max-width: 460px;
154
+ padding: 42px 36px 72px;
155
+ }
156
+
157
+ &--dark {
158
+ border-color: $slate;
159
+ background-color: $mariner;
160
+ }
161
+
162
+ &__explanation-close {
163
+ position: absolute;
164
+ width: 30px;
165
+ height: 30px;
166
+ top: 12px;
167
+ right: 12px;
168
+ color: $brand-blue;
169
+ cursor: pointer;
170
+ outline: none;
171
+
172
+ &:hover {
173
+ color: $brand-black;
174
+ }
175
+
176
+ &:focus::before {
177
+ content: '';
178
+ left: -1px;
179
+ top: -1px;
180
+ width: 100%;
181
+ height: 100%;
182
+ position: absolute;
183
+ border: 1px solid $brand-blue;
184
+ border-radius: 5px;
185
+ }
186
+
187
+ &--dark {
188
+ color: $banana-bread;
189
+
190
+ &:hover {
191
+ color: $butterscotch;
192
+ }
193
+
194
+ &:focus::before {
195
+ border-color: $banana-bread;
196
+ }
197
+ }
198
+
199
+ svg {
200
+ width: 100%;
201
+ height: 100%;
202
+ }
203
+ }
204
+
205
+ &__explanation-title {
206
+ font-weight: 600;
207
+ font-size: 17.5px;
208
+ letter-spacing: -0.1px;
209
+ line-height: 25px;
210
+ outline: none;
211
+
212
+ &--dark {
213
+ color: $fog;
214
+ }
215
+ }
216
+
217
+ &__explanation-text {
218
+ font-weight: 400;
219
+ font-size: 16.5px;
220
+ letter-spacing: -0.1px;
221
+ line-height: 26px;
222
+ margin-bottom: 24px;
223
+ word-break: break-word;
224
+
225
+ &--dark {
226
+ color: $white;
227
+ }
228
+
229
+ &--tablet-landscape {
230
+ margin-bottom: 24px;
231
+ font-size: 16px;
232
+ line-height: 24px;
233
+ }
234
+
235
+ strong,
236
+ b {
237
+ font-weight: 600;
238
+ }
239
+ }
240
+
241
+ &__explanation-image {
242
+ display: block;
243
+ position: relative;
244
+ left: 50%;
245
+ transform: translateX(-50%);
246
+ width: calc(100% + 24px);
247
+ margin-bottom: 24px;
248
+ border: 1px solid $fog;
249
+
250
+ &--long-alt {
251
+ margin-bottom: 0;
252
+ }
253
+
254
+ &--dark {
255
+ border: 1px solid $jet;
256
+ }
257
+
258
+ &--tablet-landscape {
259
+ width: calc(100% + 16px);
260
+ }
261
+ }
262
+
263
+ &__toggle-explanation-img-description {
264
+ margin-top: 24px;
265
+
266
+ &--open {
267
+ margin-bottom: 6px;
268
+ }
269
+
270
+ &--tablet-landscape {
271
+ margin-top: 12px;
272
+ }
273
+ }
274
+
275
+ &__explanation-img-description {
276
+ outline: none;
277
+ color: $ash;
278
+ font-size: 15px;
279
+ font-weight: 500;
280
+ letter-spacing: -0.2px;
281
+ line-height: 22px;
282
+ margin-bottom: 24px;
283
+
284
+ &--dark {
285
+ color: $fog;
286
+ }
287
+
288
+ p {
289
+ margin: 0;
290
+ }
291
+ }
292
+
293
+ &__toggle-explanation-img-description-text {
294
+ outline: none;
295
+ }
296
+
297
+ &__toggle-explanation-img-description-icon {
298
+ margin-left: 8px;
299
+
300
+ &--up {
301
+ transform: rotate(180deg);
302
+ }
303
+ }
304
+
305
+ &__reference {
306
+ padding-top: 24px;
307
+ border-top: 1px solid $fog;
308
+ font-size: 15px;
309
+ letter-spacing: -0.1px;
310
+ line-height: 22px;
311
+ font-weight: 600;
312
+ word-break: break-word;
313
+
314
+ &--dark {
315
+ color: $white;
316
+ border-top-color: rgba($fog, 0.28);
317
+ }
318
+
319
+ p {
320
+ margin: 6px 0 8pt 0;
321
+ font-size: 15px;
322
+ letter-spacing: -0.1px;
323
+ font-weight: 400;
324
+ font-style: italic;
325
+ }
326
+ }
327
+
328
+ &__reference-label {
329
+ font-weight: 600;
330
+ }
331
+
332
+ }
333
+ </style>
@@ -0,0 +1,104 @@
1
+ <template>
2
+ <div
3
+ v-if="globalMetrics"
4
+ class="uikit-question-stats-summary"
5
+ >
6
+ <div v-dark="isDarkMode" class="uikit-question-stats-summary__stats-summary-total">
7
+ <div class="uikit-question-stats-summary__stats-summary-value">
8
+ {{ choiceScores.totalAnswered }}
9
+ </div>
10
+ <div v-dark="isDarkMode" class="uikit-question-stats-summary__stats-summary-label">
11
+ Studiers Answered
12
+ </div>
13
+ </div>
14
+ <div v-dark="isDarkMode" class="uikit-question-stats-summary__stats-summary-correct">
15
+ <div class="uikit-question-stats-summary__stats-summary-value">
16
+ {{ Math.round((choiceScores.answeredCorrectly / choiceScores.totalAnswered) * 100) }}%
17
+ </div>
18
+ <div v-dark="isDarkMode" class="uikit-question-stats-summary__stats-summary-label">
19
+ Answered Correctly
20
+ </div>
21
+ </div>
22
+ </div>
23
+ </template>
24
+
25
+ <script lang="ts">
26
+ import { Component, Vue, Prop } from 'vue-facing-decorator'
27
+ import type { Study } from '@pocketprep/types'
28
+ import { dark, breakpoint } from '../../../directives'
29
+ import type { TChoiceScores } from './../question'
30
+
31
+
32
+ @Component({
33
+ directives: {
34
+ dark,
35
+ breakpoint,
36
+ },
37
+ })
38
+ export default class StatsSummary extends Vue {
39
+ @Prop({ default: null }) globalMetrics!: Study.Class.GlobalQuestionMetricJSON | null
40
+ @Prop() choiceScores!: TChoiceScores
41
+ @Prop({ default: false }) isDarkMode!: boolean
42
+ }
43
+
44
+ </script>
45
+
46
+ <style lang="scss">
47
+ @import '../../../styles/colors';
48
+ @import '../../../styles/breakpoints';
49
+
50
+ .uikit-question-stats-summary {
51
+ margin-top: 24px;
52
+ display: flex;
53
+ width: 100%;
54
+ max-width: 492px;
55
+ padding-bottom: 50px;
56
+
57
+ &__stats-summary-total {
58
+ display: flex;
59
+ flex-direction: column;
60
+ align-items: center;
61
+ flex: 1;
62
+ margin-right: 16px;
63
+ background-color: rgba($sky-blue, 0.8);
64
+ padding: 9px 0;
65
+ border-radius: 6px;
66
+
67
+ &--dark {
68
+ background-color: $brand-black;
69
+ }
70
+ }
71
+
72
+ &__stats-summary-correct {
73
+ display: flex;
74
+ flex-direction: column;
75
+ align-items: center;
76
+ flex: 1;
77
+ background-color: rgba($cadaverous, 0.13);
78
+ padding: 9px 0;
79
+ border-radius: 6px;
80
+
81
+ &--dark {
82
+ background-color: $brand-black;
83
+ }
84
+ }
85
+
86
+ &__stats-summary-value {
87
+ font-weight: 600;
88
+ font-size: 26px;
89
+ letter-spacing: 0.26px;
90
+ line-height: 31px;
91
+ }
92
+
93
+ &__stats-summary-label {
94
+ color: $ash;
95
+ font-size: 13px;
96
+ line-height: 16px;
97
+ text-align: center;
98
+
99
+ &--dark {
100
+ color: $white;
101
+ }
102
+ }
103
+ }
104
+ </style>