@pocketprep/ui-kit 3.7.0 → 3.7.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.
- package/dist/@pocketprep/ui-kit.css +1 -1
- package/dist/@pocketprep/ui-kit.js +5483 -5456
- package/dist/@pocketprep/ui-kit.js.map +1 -1
- package/dist/@pocketprep/ui-kit.umd.cjs +9 -9
- package/dist/@pocketprep/ui-kit.umd.cjs.map +1 -1
- package/lib/components/Quiz/Question/BuildListChoicesContainer.vue +118 -45
- package/lib/components/Quiz/Question/Summary.vue +3 -5
- package/package.json +1 -1
|
@@ -12,10 +12,10 @@
|
|
|
12
12
|
{{ announcementMessage }}
|
|
13
13
|
</div>
|
|
14
14
|
<div
|
|
15
|
-
v-breakpoint="breakpointsWithEl"
|
|
16
15
|
class="uikit-question-build-list-choices-container-wrapper"
|
|
17
16
|
>
|
|
18
17
|
<TransitionGroup
|
|
18
|
+
v-dark="isDarkMode"
|
|
19
19
|
v-breakpoint="breakpointsWithEl"
|
|
20
20
|
name="list"
|
|
21
21
|
tag="ol"
|
|
@@ -27,6 +27,7 @@
|
|
|
27
27
|
(showBuildListOrder || reviewMode) && !isBuildListOrderCorrect,
|
|
28
28
|
'uikit-question-build-list-choices-container--teach-group-review':
|
|
29
29
|
(showBuildListOrder || reviewMode) && isTeachGroupReview,
|
|
30
|
+
'uikit-question-build-list-choices-container--review-mode': reviewMode,
|
|
30
31
|
}"
|
|
31
32
|
role="list"
|
|
32
33
|
:aria-label="`Build list with ${orderedChoices.length} items`"
|
|
@@ -46,6 +47,9 @@
|
|
|
46
47
|
v-dark="isDarkMode"
|
|
47
48
|
v-breakpoint="breakpointsWithEl"
|
|
48
49
|
class="uikit-question-build-list-choices-container__choice-number"
|
|
50
|
+
:class="{
|
|
51
|
+
'uikit-question-build-list-choices-container__choice-number--review-mode': reviewMode
|
|
52
|
+
}"
|
|
49
53
|
>
|
|
50
54
|
{{ index + 1 }}
|
|
51
55
|
</div>
|
|
@@ -54,14 +58,14 @@
|
|
|
54
58
|
v-breakpoint="breakpointsWithEl"
|
|
55
59
|
class="uikit-question-build-list-choices-container__choice"
|
|
56
60
|
:class="{
|
|
57
|
-
'uikit-question-build-list-choices-container__choice--
|
|
58
|
-
reviewMode || showBuildListOrder
|
|
61
|
+
'uikit-question-build-list-choices-container__choice--review-mode': reviewMode
|
|
59
62
|
}"
|
|
60
63
|
role="group"
|
|
61
64
|
:aria-label="`Choice ${index + 1}: ${stripHtmlTags(choice.text || '')}`"
|
|
62
|
-
:tabindex="
|
|
65
|
+
:tabindex="-1"
|
|
63
66
|
@keydown="handleCardKeydown($event, index)"
|
|
64
|
-
@click
|
|
67
|
+
@click.prevent
|
|
68
|
+
@mousedown.prevent
|
|
65
69
|
:ref="(el) => setCardRef(el, choice.key)"
|
|
66
70
|
>
|
|
67
71
|
<div
|
|
@@ -72,7 +76,9 @@
|
|
|
72
76
|
'uikit-question-build-list-choices-container__mobile-choice-number--correct':
|
|
73
77
|
(reviewMode || showBuildListOrder) && isChoiceInCorrectPosition(choice, index),
|
|
74
78
|
'uikit-question-build-list-choices-container__mobile-choice-number--incorrect':
|
|
75
|
-
(reviewMode || showBuildListOrder) && !isChoiceInCorrectPosition(choice, index)
|
|
79
|
+
(reviewMode || showBuildListOrder) && !isChoiceInCorrectPosition(choice, index),
|
|
80
|
+
'uikit-question-build-list-choices-container__mobile-choice-number--review-mode':
|
|
81
|
+
reviewMode,
|
|
76
82
|
}"
|
|
77
83
|
>
|
|
78
84
|
{{ index + 1 }}
|
|
@@ -92,7 +98,7 @@
|
|
|
92
98
|
{{ getCorrectPositionOrderNumber(choice) }}
|
|
93
99
|
</div>
|
|
94
100
|
<Icon
|
|
95
|
-
v-if="isChoiceInCorrectPosition(choice, index)"
|
|
101
|
+
v-if="isChoiceInCorrectPosition(choice, index) && !reviewMode"
|
|
96
102
|
v-dark="isDarkMode"
|
|
97
103
|
v-breakpoint="breakpointsWithEl"
|
|
98
104
|
class="uikit-question-build-list-choices-container__answer-correct-icon"
|
|
@@ -100,7 +106,7 @@
|
|
|
100
106
|
|
|
101
107
|
/>
|
|
102
108
|
<Icon
|
|
103
|
-
v-else
|
|
109
|
+
v-else-if="!isChoiceInCorrectPosition(choice, index) && !reviewMode"
|
|
104
110
|
v-dark="isDarkMode"
|
|
105
111
|
v-breakpoint="breakpointsWithEl"
|
|
106
112
|
class="uikit-question-build-list-choices-container__answer-incorrect-icon"
|
|
@@ -119,7 +125,8 @@
|
|
|
119
125
|
index === 0
|
|
120
126
|
}"
|
|
121
127
|
:disabled="index === 0"
|
|
122
|
-
|
|
128
|
+
:tabindex="(showBuildListOrder || reviewMode) ? -1 : 0"
|
|
129
|
+
@click.prevent.stop="moveChoiceUp(index)"
|
|
123
130
|
:aria-label="`Move '${stripHtmlTags(choice.text || '')}' up`"
|
|
124
131
|
:title="'Move up'"
|
|
125
132
|
>
|
|
@@ -138,7 +145,8 @@
|
|
|
138
145
|
index === orderedChoices.length - 1
|
|
139
146
|
}"
|
|
140
147
|
:disabled="index === orderedChoices.length - 1"
|
|
141
|
-
|
|
148
|
+
:tabindex="(showBuildListOrder || reviewMode) ? -1 : 0"
|
|
149
|
+
@click.prevent.stop="moveChoiceDown(index)"
|
|
142
150
|
:aria-label="`Move '${stripHtmlTags(choice.text || '')}' down`"
|
|
143
151
|
:title="'Move down'"
|
|
144
152
|
>
|
|
@@ -187,6 +195,7 @@ const orderedChoices = ref<TBuildListChoice[]>([])
|
|
|
187
195
|
const floatingChoiceKey = ref<string | null>(null)
|
|
188
196
|
const choiceRefs = ref<Map<string, HTMLDivElement>>(new Map())
|
|
189
197
|
const announcementMessage = ref<string>('')
|
|
198
|
+
const isMoveTriggeredByArrowKey = ref<boolean>(false)
|
|
190
199
|
|
|
191
200
|
onMounted(() => {
|
|
192
201
|
updateOrderedChoices()
|
|
@@ -230,11 +239,37 @@ const restoreFocusAfterMove = (movedChoiceKey: string) => {
|
|
|
230
239
|
setTimeout(() => {
|
|
231
240
|
const choiceEl = choiceRefs.value.get(movedChoiceKey)
|
|
232
241
|
if (choiceEl) {
|
|
242
|
+
// Temporarily make the choice focusable for animation
|
|
243
|
+
choiceEl.setAttribute('tabindex', '0')
|
|
233
244
|
choiceEl.focus()
|
|
245
|
+
|
|
246
|
+
// Remove tabindex after animation completes
|
|
247
|
+
const animationDelay = prefersReducedMotion() ? 0 : 350
|
|
248
|
+
setTimeout(() => {
|
|
249
|
+
choiceEl.setAttribute('tabindex', '-1')
|
|
250
|
+
}, animationDelay)
|
|
234
251
|
}
|
|
235
252
|
}, delay)
|
|
236
253
|
}
|
|
237
254
|
|
|
255
|
+
const removeFocusAfterAnimation = (movedChoiceKey: string) => {
|
|
256
|
+
// Don't remove focus if we're in review mode or showing the build list order
|
|
257
|
+
if (showBuildListOrder.value || reviewMode.value) {
|
|
258
|
+
return
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Only remove focus if the move was NOT triggered by arrow keys
|
|
262
|
+
if (!isMoveTriggeredByArrowKey.value) {
|
|
263
|
+
const animationDelay = prefersReducedMotion() ? 0 : 350 // Slightly after animation completes
|
|
264
|
+
setTimeout(() => {
|
|
265
|
+
const choiceEl = choiceRefs.value.get(movedChoiceKey)
|
|
266
|
+
if (choiceEl) {
|
|
267
|
+
choiceEl.blur()
|
|
268
|
+
}
|
|
269
|
+
}, animationDelay)
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
|
|
238
273
|
// For accessibility, we want to announce to the user where they moved the choice
|
|
239
274
|
// to in the ordered list. ie: “Moved Photosynthesis to position 2 of 6.”
|
|
240
275
|
const announceMove = (choiceText: string, newPosition: number, totalItems: number) => {
|
|
@@ -268,6 +303,9 @@ const moveChoiceUp = (index: number) => {
|
|
|
268
303
|
// Restore focus to the moved card
|
|
269
304
|
restoreFocusAfterMove(currentItem.key)
|
|
270
305
|
|
|
306
|
+
// Remove focus after animation if not triggered by arrow key
|
|
307
|
+
removeFocusAfterAnimation(currentItem.key)
|
|
308
|
+
|
|
271
309
|
// Clear floating state after animation completes
|
|
272
310
|
const animationDelay = prefersReducedMotion() ? 0 : 300
|
|
273
311
|
setTimeout(() => {
|
|
@@ -298,6 +336,9 @@ const moveChoiceDown = (index: number) => {
|
|
|
298
336
|
// Restore focus to the moved card
|
|
299
337
|
restoreFocusAfterMove(currentItem.key)
|
|
300
338
|
|
|
339
|
+
// Remove focus after animation
|
|
340
|
+
removeFocusAfterAnimation(currentItem.key)
|
|
341
|
+
|
|
301
342
|
// Clear floating state after animation completes
|
|
302
343
|
const animationDelay = prefersReducedMotion() ? 0 : 300
|
|
303
344
|
setTimeout(() => {
|
|
@@ -321,32 +362,39 @@ const isChoiceInCorrectPosition = (choice: TBuildListChoice, currentIndex: numbe
|
|
|
321
362
|
return correctOrderPosition === currentOrderPosition
|
|
322
363
|
}
|
|
323
364
|
|
|
324
|
-
const handleCardClick = (event: MouseEvent) => {
|
|
325
|
-
if (showBuildListOrder.value || reviewMode.value) {
|
|
326
|
-
event.preventDefault()
|
|
327
|
-
event.stopPropagation()
|
|
328
|
-
}
|
|
329
|
-
}
|
|
330
|
-
|
|
331
365
|
const handleCardKeydown = (event: KeyboardEvent, index: number) => {
|
|
332
366
|
// Handle Alt+Arrow shortcuts for moving cards
|
|
333
367
|
if (event.altKey) {
|
|
334
368
|
if (event.key === 'ArrowUp' || event.key === 'Up') {
|
|
335
369
|
event.preventDefault()
|
|
370
|
+
isMoveTriggeredByArrowKey.value = true
|
|
336
371
|
moveChoiceUp(index)
|
|
372
|
+
// Reset flag after a short delay
|
|
373
|
+
setTimeout(() => {
|
|
374
|
+
isMoveTriggeredByArrowKey.value = false
|
|
375
|
+
}, 100)
|
|
337
376
|
} else if (event.key === 'ArrowDown' || event.key === 'Down') {
|
|
338
377
|
event.preventDefault()
|
|
378
|
+
isMoveTriggeredByArrowKey.value = true
|
|
339
379
|
moveChoiceDown(index)
|
|
380
|
+
// Reset flag after a short delay
|
|
381
|
+
setTimeout(() => {
|
|
382
|
+
isMoveTriggeredByArrowKey.value = false
|
|
383
|
+
}, 100)
|
|
340
384
|
}
|
|
341
385
|
}
|
|
342
386
|
}
|
|
343
387
|
|
|
344
|
-
|
|
345
388
|
watch(orderedChoices, () => {
|
|
346
389
|
const newChoices = orderedChoices.value
|
|
347
390
|
emit('reorderBuildList', newChoices)
|
|
348
391
|
}, { deep: true })
|
|
349
392
|
|
|
393
|
+
watch(selectedBuildListChoiceOrder, () => {
|
|
394
|
+
if ((reviewMode.value || showBuildListOrder.value)) {
|
|
395
|
+
updateOrderedChoices()
|
|
396
|
+
}
|
|
397
|
+
})
|
|
350
398
|
</script>
|
|
351
399
|
|
|
352
400
|
<style lang="scss">
|
|
@@ -378,22 +426,23 @@ watch(orderedChoices, () => {
|
|
|
378
426
|
flex-direction: column;
|
|
379
427
|
gap: 12px;
|
|
380
428
|
list-style: none;
|
|
381
|
-
margin: 0;
|
|
429
|
+
margin: 0 0 0 -46px;
|
|
382
430
|
padding: 0;
|
|
383
431
|
|
|
384
432
|
&::after {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
433
|
+
content: '';
|
|
434
|
+
position: absolute;
|
|
435
|
+
top: -8px;
|
|
436
|
+
bottom: -8px;
|
|
437
|
+
left: 8px;
|
|
438
|
+
right: 10px;
|
|
439
|
+
border-radius: 11px;
|
|
440
|
+
pointer-events: none;
|
|
393
441
|
|
|
394
|
-
|
|
442
|
+
}
|
|
395
443
|
|
|
396
444
|
&--mobile {
|
|
445
|
+
margin: 0;
|
|
397
446
|
&::after {
|
|
398
447
|
content: '';
|
|
399
448
|
position: absolute;
|
|
@@ -407,6 +456,17 @@ watch(orderedChoices, () => {
|
|
|
407
456
|
}
|
|
408
457
|
}
|
|
409
458
|
|
|
459
|
+
&--review-mode:not(&--mobile) {
|
|
460
|
+
margin: 0;
|
|
461
|
+
max-width: 492px;
|
|
462
|
+
width: 100%;
|
|
463
|
+
|
|
464
|
+
&::after {
|
|
465
|
+
left: -8px;
|
|
466
|
+
right: -8px;
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
|
|
410
470
|
&--correct {
|
|
411
471
|
&::after {
|
|
412
472
|
display: block;
|
|
@@ -450,8 +510,12 @@ watch(orderedChoices, () => {
|
|
|
450
510
|
z-index: 10;
|
|
451
511
|
|
|
452
512
|
.uikit-question-build-list-choices-container__choice {
|
|
453
|
-
|
|
454
|
-
|
|
513
|
+
outline: 2px solid $brand-blue;
|
|
514
|
+
outline-offset: 2px;
|
|
515
|
+
|
|
516
|
+
&--dark {
|
|
517
|
+
outline-color: $banana-bread;
|
|
518
|
+
}
|
|
455
519
|
}
|
|
456
520
|
}
|
|
457
521
|
}
|
|
@@ -459,7 +523,7 @@ watch(orderedChoices, () => {
|
|
|
459
523
|
&__choice-number,
|
|
460
524
|
&__mobile-choice-number {
|
|
461
525
|
display: flex;
|
|
462
|
-
align-items:
|
|
526
|
+
align-items: flex-end;
|
|
463
527
|
justify-content: center;
|
|
464
528
|
width: 24px;
|
|
465
529
|
height: 24px;
|
|
@@ -477,13 +541,14 @@ watch(orderedChoices, () => {
|
|
|
477
541
|
}
|
|
478
542
|
|
|
479
543
|
&__choice-number {
|
|
544
|
+
&--review-mode,
|
|
480
545
|
&--mobile {
|
|
481
546
|
display: none;
|
|
482
547
|
}
|
|
483
548
|
}
|
|
484
549
|
|
|
485
550
|
&__mobile-choice-number {
|
|
486
|
-
&:not(&--mobile) {
|
|
551
|
+
&:not(&--mobile, &--review-mode) {
|
|
487
552
|
display: none;
|
|
488
553
|
}
|
|
489
554
|
|
|
@@ -524,28 +589,15 @@ watch(orderedChoices, () => {
|
|
|
524
589
|
box-shadow: 0 1px 4px 0 rgba(71, 89, 103, 0.30);
|
|
525
590
|
outline: none;
|
|
526
591
|
|
|
527
|
-
&:focus:not(&--showing-answer) {
|
|
528
|
-
outline: 2px solid $brand-blue;
|
|
529
|
-
outline-offset: 2px;
|
|
530
|
-
}
|
|
531
|
-
|
|
532
592
|
&--dark {
|
|
533
593
|
border: 1px solid $slate;
|
|
534
594
|
background-color: $brand-black;
|
|
535
595
|
box-shadow: 0 1px 4px 0 rgba(71, 89, 103, 0.30);
|
|
536
|
-
|
|
537
|
-
&:focus:not(&--showing-answer) {
|
|
538
|
-
outline-color: $banana-bread;
|
|
539
|
-
}
|
|
540
596
|
}
|
|
541
597
|
|
|
542
598
|
&--mobile {
|
|
543
599
|
width: 100%;
|
|
544
600
|
}
|
|
545
|
-
|
|
546
|
-
&--showing-answer {
|
|
547
|
-
gap: 27px;
|
|
548
|
-
}
|
|
549
601
|
}
|
|
550
602
|
|
|
551
603
|
&__choice-text {
|
|
@@ -589,9 +641,30 @@ watch(orderedChoices, () => {
|
|
|
589
641
|
cursor: pointer;
|
|
590
642
|
transition: all 0.2s ease;
|
|
591
643
|
|
|
644
|
+
&:focus {
|
|
645
|
+
outline: none;
|
|
646
|
+
border: 2px solid $white;
|
|
647
|
+
box-shadow: 0 0 0 2px $brand-blue-hover;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
&:hover,
|
|
651
|
+
&:focus {
|
|
652
|
+
background-color: $brand-blue-hover;
|
|
653
|
+
}
|
|
654
|
+
|
|
592
655
|
&--dark {
|
|
593
656
|
background-color: $banana-bread;
|
|
594
657
|
color: $brand-black;
|
|
658
|
+
|
|
659
|
+
&:focus {
|
|
660
|
+
border: 2px solid $brand-black;
|
|
661
|
+
box-shadow: 0 0 0 2px $butterscotch;
|
|
662
|
+
}
|
|
663
|
+
|
|
664
|
+
&:hover,
|
|
665
|
+
&:focus {
|
|
666
|
+
background-color: $butterscotch;
|
|
667
|
+
}
|
|
595
668
|
}
|
|
596
669
|
|
|
597
670
|
&--disabled {
|
|
@@ -9,8 +9,8 @@
|
|
|
9
9
|
'uikit-question-summary--matrix-question-review-mode': isMatrixQuestion && reviewMode,
|
|
10
10
|
'uikit-question-summary--mpmc-question': isMPMCQuestion,
|
|
11
11
|
'uikit-question-summary--mpmc-question-review-mode': isMPMCQuestion && reviewMode,
|
|
12
|
-
'uikit-question-summary--build-list-question':
|
|
13
|
-
|
|
12
|
+
'uikit-question-summary--build-list-question-not-review-mode':
|
|
13
|
+
isBuildListQuestion && !reviewMode,
|
|
14
14
|
}"
|
|
15
15
|
>
|
|
16
16
|
<div class="uikit-question-summary__summary-title">
|
|
@@ -218,10 +218,8 @@ const toggleSummaryExplanationImageLongAlt = () => {
|
|
|
218
218
|
max-width: 518px;
|
|
219
219
|
}
|
|
220
220
|
|
|
221
|
-
&--build-list-question {
|
|
221
|
+
&--build-list-question-not-review-mode {
|
|
222
222
|
max-width: 452px;
|
|
223
|
-
margin-left: 38px;
|
|
224
|
-
display: inline-block;
|
|
225
223
|
}
|
|
226
224
|
|
|
227
225
|
&--matrix-question-review-mode#{&}--tablet-landscape,
|