@pocketprep/ui-kit 3.6.0 → 3.7.0
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 +11672 -11335
- package/dist/@pocketprep/ui-kit.js.map +1 -1
- package/dist/@pocketprep/ui-kit.umd.cjs +13 -12
- package/dist/@pocketprep/ui-kit.umd.cjs.map +1 -1
- package/lib/components/Forms/Radio.vue +1 -8
- package/lib/components/Quiz/Question/BuildListChoicesContainer.vue +7 -13
- package/lib/components/Quiz/Question/ChoicesContainer.vue +1 -9
- package/lib/components/Quiz/Question/MPMCChoicesContainer.vue +472 -0
- package/lib/components/Quiz/Question/MPMCRadioGroup.vue +169 -0
- package/lib/components/Quiz/Question/MobileMatrixChoicesContainer.vue +1 -9
- package/lib/components/Quiz/Question/MobileMatrixRadioGroup.vue +1 -9
- package/lib/components/Quiz/Question/StatsSummary.vue +10 -2
- package/lib/components/Quiz/Question/Summary.vue +23 -6
- package/lib/components/Quiz/Question/composables.ts +8 -0
- package/lib/components/Quiz/Question/injectionSymbols.ts +6 -1
- package/lib/components/Quiz/Question.vue +199 -23
- package/lib/utils.ts +8 -0
- package/package.json +2 -2
|
@@ -72,6 +72,7 @@
|
|
|
72
72
|
import { ref } from 'vue'
|
|
73
73
|
import { dark as vDark } from '../../directives'
|
|
74
74
|
import RadioButton from './RadioButton.vue'
|
|
75
|
+
import { stripHtmlTags } from '../../utils'
|
|
75
76
|
|
|
76
77
|
interface IItem {
|
|
77
78
|
value: string | number
|
|
@@ -115,14 +116,6 @@ const keyPressedItem = (e: KeyboardEvent) => {
|
|
|
115
116
|
}
|
|
116
117
|
}
|
|
117
118
|
|
|
118
|
-
const stripHtmlTags = (string?: string) => {
|
|
119
|
-
if (string) {
|
|
120
|
-
const div = document.createElement('div')
|
|
121
|
-
div.innerHTML = string
|
|
122
|
-
return div.textContent || ''
|
|
123
|
-
}
|
|
124
|
-
return ''
|
|
125
|
-
}
|
|
126
119
|
</script>
|
|
127
120
|
|
|
128
121
|
<style lang="scss">
|
|
@@ -163,6 +163,7 @@ import Icon from '../../Icons/Icon.vue'
|
|
|
163
163
|
import { dark as vDark, breakpoint as vBreakpoint } from '../../../directives'
|
|
164
164
|
import { useQuestionContext } from './composables'
|
|
165
165
|
import type { TBuildListChoice } from '../question'
|
|
166
|
+
import { stripHtmlTags } from '../../../utils'
|
|
166
167
|
|
|
167
168
|
const emit = defineEmits<{
|
|
168
169
|
'reorderBuildList': [ choices: TBuildListChoice[] ]
|
|
@@ -196,15 +197,6 @@ const prefersReducedMotion = () => {
|
|
|
196
197
|
return window.matchMedia('(prefers-reduced-motion: reduce)').matches
|
|
197
198
|
}
|
|
198
199
|
|
|
199
|
-
const stripHtmlTags = (string?: string) => {
|
|
200
|
-
if (string) {
|
|
201
|
-
const div = document.createElement('div')
|
|
202
|
-
div.innerHTML = string
|
|
203
|
-
return div.textContent || ''
|
|
204
|
-
}
|
|
205
|
-
return ''
|
|
206
|
-
}
|
|
207
|
-
|
|
208
200
|
const updateOrderedChoices = () => {
|
|
209
201
|
// Map the selectedBuildListChoiceOrder keys to full TBuildListChoice objects
|
|
210
202
|
if (selectedBuildListChoiceOrder.value.length) {
|
|
@@ -269,8 +261,6 @@ const moveChoiceUp = (index: number) => {
|
|
|
269
261
|
newChoices[ index ] = previousItem
|
|
270
262
|
newChoices[ index - 1 ] = currentItem
|
|
271
263
|
orderedChoices.value = newChoices
|
|
272
|
-
emit('reorderBuildList', newChoices)
|
|
273
|
-
|
|
274
264
|
// Announce the move
|
|
275
265
|
const choiceText = stripHtmlTags(currentItem.text || '')
|
|
276
266
|
announceMove(choiceText, index, orderedChoices.value.length)
|
|
@@ -300,7 +290,6 @@ const moveChoiceDown = (index: number) => {
|
|
|
300
290
|
newChoices[ index ] = nextItem
|
|
301
291
|
newChoices[ index + 1 ] = currentItem
|
|
302
292
|
orderedChoices.value = newChoices
|
|
303
|
-
emit('reorderBuildList', newChoices)
|
|
304
293
|
|
|
305
294
|
// Announce the move
|
|
306
295
|
const choiceText = stripHtmlTags(currentItem.text || '')
|
|
@@ -352,7 +341,12 @@ const handleCardKeydown = (event: KeyboardEvent, index: number) => {
|
|
|
352
341
|
}
|
|
353
342
|
}
|
|
354
343
|
|
|
355
|
-
|
|
344
|
+
|
|
345
|
+
watch(orderedChoices, () => {
|
|
346
|
+
const newChoices = orderedChoices.value
|
|
347
|
+
emit('reorderBuildList', newChoices)
|
|
348
|
+
}, { deep: true })
|
|
349
|
+
|
|
356
350
|
</script>
|
|
357
351
|
|
|
358
352
|
<style lang="scss">
|
|
@@ -277,6 +277,7 @@ import PocketButton from '../../Buttons/Button.vue'
|
|
|
277
277
|
import { dark as vDark, breakpoint as vBreakpoint } from '../../../directives'
|
|
278
278
|
import { useQuestionContext } from './composables'
|
|
279
279
|
import type { TChoiceKey } from '../question'
|
|
280
|
+
import { stripHtmlTags } from '../../../utils'
|
|
280
281
|
|
|
281
282
|
const emit = defineEmits<{
|
|
282
283
|
'emitChoiceFocusIn': [ choiceKey: TChoiceKey ]
|
|
@@ -318,15 +319,6 @@ const {
|
|
|
318
319
|
breakpointsWithEl,
|
|
319
320
|
} = useQuestionContext()
|
|
320
321
|
|
|
321
|
-
const stripHtmlTags = (string?: string) => {
|
|
322
|
-
if (string) {
|
|
323
|
-
const div = document.createElement('div')
|
|
324
|
-
div.innerHTML = string
|
|
325
|
-
return div.textContent || ''
|
|
326
|
-
}
|
|
327
|
-
return ''
|
|
328
|
-
}
|
|
329
|
-
|
|
330
322
|
const emitChoiceFocusIn = (choiceKey: TChoiceKey) => {
|
|
331
323
|
emit('emitChoiceFocusIn', choiceKey)
|
|
332
324
|
}
|
|
@@ -0,0 +1,472 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
import { computed, onMounted, ref, watch } from 'vue'
|
|
3
|
+
import { dark as vDark } from '../../../directives'
|
|
4
|
+
import type { TChoiceKey } from './../question'
|
|
5
|
+
import { useQuestionContext } from './composables'
|
|
6
|
+
import { stripHtmlTags } from '../../../utils'
|
|
7
|
+
import Icon from '../../Icons/Icon.vue'
|
|
8
|
+
import MPMCRadioGroup from './MPMCRadioGroup.vue'
|
|
9
|
+
|
|
10
|
+
interface IMPMCRadioOptions {
|
|
11
|
+
choices: TChoiceKey[]
|
|
12
|
+
value: TChoiceKey | null
|
|
13
|
+
label?: string
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
const emit = defineEmits<{
|
|
17
|
+
'emitSelectedMPMCChoice': [mpmcChoiceKeys: TChoiceKey[]]
|
|
18
|
+
}>()
|
|
19
|
+
|
|
20
|
+
const {
|
|
21
|
+
// questionEl is used by the breakpoint directive
|
|
22
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
23
|
+
questionEl,
|
|
24
|
+
question,
|
|
25
|
+
isMPMCQuestionCorrect,
|
|
26
|
+
reviewMode,
|
|
27
|
+
isDarkMode,
|
|
28
|
+
showMPMCAnswers,
|
|
29
|
+
selectedMPMCChoices,
|
|
30
|
+
} = useQuestionContext()
|
|
31
|
+
|
|
32
|
+
const mpmcRadioGrid = ref<IMPMCRadioOptions[] | undefined>(undefined)
|
|
33
|
+
const expandedPartNumbers = ref<number[]>([])
|
|
34
|
+
|
|
35
|
+
const mpmcLabels = computed(() => {
|
|
36
|
+
return question.value.mpmcLabels || []
|
|
37
|
+
})
|
|
38
|
+
|
|
39
|
+
const questionChoices = computed(() => {
|
|
40
|
+
const choices = question.value.choices
|
|
41
|
+
|
|
42
|
+
// Shuffle mpmc choices
|
|
43
|
+
return [ ...choices ].sort(() => Math.random() - 0.5)
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const choiceKeysByLabelIndexObj = computed(() => {
|
|
47
|
+
// Create an object with the keys being the mpmc label indexes
|
|
48
|
+
// and the values being an array of corresponding choiceKeys to the mpmc label
|
|
49
|
+
const groupedChoiceKeyByLabelIndex: { [key: number]: TChoiceKey[] } = {}
|
|
50
|
+
|
|
51
|
+
questionChoices.value?.forEach(choice => {
|
|
52
|
+
const labelIndex = choice.labelIndex
|
|
53
|
+
|
|
54
|
+
if (labelIndex !== undefined) {
|
|
55
|
+
if (!groupedChoiceKeyByLabelIndex[labelIndex]) {
|
|
56
|
+
groupedChoiceKeyByLabelIndex[labelIndex] = []
|
|
57
|
+
}
|
|
58
|
+
groupedChoiceKeyByLabelIndex[labelIndex].push(choice.id as TChoiceKey)
|
|
59
|
+
}
|
|
60
|
+
})
|
|
61
|
+
|
|
62
|
+
return groupedChoiceKeyByLabelIndex
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
const choiceTextsByLabelIndex = computed(() => {
|
|
66
|
+
const grouped: { [key: number]: string[] } = {}
|
|
67
|
+
|
|
68
|
+
questionChoices.value?.forEach(choice => {
|
|
69
|
+
const labelIndex = choice.labelIndex
|
|
70
|
+
|
|
71
|
+
if (labelIndex !== undefined) {
|
|
72
|
+
if (!grouped[labelIndex]) {
|
|
73
|
+
grouped[labelIndex] = []
|
|
74
|
+
}
|
|
75
|
+
grouped[labelIndex].push(choice.text || '')
|
|
76
|
+
}
|
|
77
|
+
})
|
|
78
|
+
|
|
79
|
+
return grouped
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
const selectedChoiceTextsByLabelIndex = computed(() => {
|
|
83
|
+
const selectedTexts: { [key: number]: string } = {}
|
|
84
|
+
|
|
85
|
+
mpmcRadioGrid.value?.forEach((part, labelIndex) => {
|
|
86
|
+
if (part.value) {
|
|
87
|
+
const choiceIndex = choiceKeysByLabelIndexObj.value[labelIndex]?.findIndex(key => key === part.value)
|
|
88
|
+
if (choiceIndex !== undefined && choiceIndex !== -1) {
|
|
89
|
+
const choiceText = choiceTextsByLabelIndex.value[labelIndex]?.[choiceIndex]
|
|
90
|
+
if (choiceText) {
|
|
91
|
+
selectedTexts[labelIndex] = stripHtmlTags(choiceText)
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
})
|
|
96
|
+
|
|
97
|
+
return selectedTexts
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
const defaultRadioButtonGrid = computed(() => {
|
|
101
|
+
return mpmcLabels.value.map((_label, labelIndex) => {
|
|
102
|
+
const choices = choiceKeysByLabelIndexObj.value[labelIndex] || []
|
|
103
|
+
return {
|
|
104
|
+
choices: choices,
|
|
105
|
+
value: null as TChoiceKey | null,
|
|
106
|
+
} as IMPMCRadioOptions
|
|
107
|
+
})
|
|
108
|
+
})
|
|
109
|
+
|
|
110
|
+
onMounted(() => {
|
|
111
|
+
mpmcRadioGrid.value = convertSelectedMPMCChoiceToRadioBtnGrid()
|
|
112
|
+
})
|
|
113
|
+
|
|
114
|
+
const toggleChoiceDropdown = (labelIndex: number) => {
|
|
115
|
+
const includedPartNumberIndex = expandedPartNumbers.value.findIndex(part => part === labelIndex)
|
|
116
|
+
if (includedPartNumberIndex === -1) {
|
|
117
|
+
expandedPartNumbers.value.push(labelIndex)
|
|
118
|
+
} else {
|
|
119
|
+
expandedPartNumbers.value.splice(includedPartNumberIndex, 1)
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
const openChoiceDropdown = (labelIndex: number) => {
|
|
124
|
+
const includedPartNumberIndex = expandedPartNumbers.value.findIndex(part => part === labelIndex)
|
|
125
|
+
if (includedPartNumberIndex === -1) {
|
|
126
|
+
expandedPartNumbers.value.push(labelIndex)
|
|
127
|
+
} else {
|
|
128
|
+
expandedPartNumbers.value.splice(includedPartNumberIndex, 1)
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
const getRadioGroupChoiceKeySelection = (labelIndex: number) => {
|
|
133
|
+
return mpmcRadioGrid.value?.[labelIndex]?.value
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
const getRadioGroupChoiceKeys = (labelIndex: number) => {
|
|
137
|
+
const choices = mpmcRadioGrid.value?.[labelIndex]?.choices
|
|
138
|
+
return choices
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
const getRadioGroupChoicesText = (labelIndex: number) => {
|
|
142
|
+
return choiceTextsByLabelIndex.value[labelIndex] || []
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
const updateRadioPartSelection = (labelIndex: number, choiceKey: TChoiceKey | null) => {
|
|
146
|
+
const part = mpmcRadioGrid.value?.[labelIndex]
|
|
147
|
+
if (part) {
|
|
148
|
+
part.value = choiceKey
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
const correctPart = (labelIndex: number) => {
|
|
153
|
+
if (mpmcRadioGrid.value?.[labelIndex]) {
|
|
154
|
+
const partVal = mpmcRadioGrid.value[labelIndex]?.value
|
|
155
|
+
if (partVal) {
|
|
156
|
+
return partVal.startsWith('a')
|
|
157
|
+
}
|
|
158
|
+
return false
|
|
159
|
+
}
|
|
160
|
+
return false
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
const convertSelectedMPMCChoiceToRadioBtnGrid = () => {
|
|
164
|
+
const radioBtnGrid = defaultRadioButtonGrid.value
|
|
165
|
+
|
|
166
|
+
selectedMPMCChoices.value.forEach(choice => {
|
|
167
|
+
const choiceObj = questionChoices.value?.find(c => c.id === choice)
|
|
168
|
+
if (choiceObj?.labelIndex !== undefined) {
|
|
169
|
+
const labelIndex = choiceObj.labelIndex
|
|
170
|
+
const radioBtnGridPart = radioBtnGrid?.[labelIndex]
|
|
171
|
+
if (radioBtnGridPart) {
|
|
172
|
+
radioBtnGridPart.value = choice
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
})
|
|
176
|
+
|
|
177
|
+
return radioBtnGrid
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
const emitSelectedMPMCChoice = (mpmcChoiceKeys: TChoiceKey[]) => {
|
|
181
|
+
emit('emitSelectedMPMCChoice', mpmcChoiceKeys)
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
watch(mpmcRadioGrid, () => {
|
|
185
|
+
if (mpmcRadioGrid.value && (!reviewMode.value || !showMPMCAnswers.value)) {
|
|
186
|
+
const selectedRadioButtonChoices: TChoiceKey[] = []
|
|
187
|
+
|
|
188
|
+
mpmcRadioGrid.value.forEach((part) => {
|
|
189
|
+
if (part.value) {
|
|
190
|
+
selectedRadioButtonChoices.push(part.value)
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
emitSelectedMPMCChoice(selectedRadioButtonChoices)
|
|
195
|
+
}
|
|
196
|
+
}, { deep: true })
|
|
197
|
+
|
|
198
|
+
watch(showMPMCAnswers, () => {
|
|
199
|
+
if (showMPMCAnswers) {
|
|
200
|
+
expandedPartNumbers.value = []
|
|
201
|
+
}
|
|
202
|
+
})
|
|
203
|
+
|
|
204
|
+
watch(selectedMPMCChoices, () => {
|
|
205
|
+
if ((reviewMode.value || showMPMCAnswers.value)) {
|
|
206
|
+
const selectedRadioBtnGrid = convertSelectedMPMCChoiceToRadioBtnGrid()
|
|
207
|
+
mpmcRadioGrid.value = selectedRadioBtnGrid
|
|
208
|
+
}
|
|
209
|
+
})
|
|
210
|
+
|
|
211
|
+
</script>
|
|
212
|
+
|
|
213
|
+
<template>
|
|
214
|
+
<div
|
|
215
|
+
class="uikit-question-mpmc-choices-container"
|
|
216
|
+
>
|
|
217
|
+
<div
|
|
218
|
+
class="uikit-question-mpmc-choices-container__choices-container"
|
|
219
|
+
:class="{
|
|
220
|
+
'uikit-question-mpmc-choices-container__choices-container--correct':
|
|
221
|
+
(showMPMCAnswers || reviewMode) && isMPMCQuestionCorrect,
|
|
222
|
+
'uikit-question-mpmc-choices-container__choices-container--incorrect':
|
|
223
|
+
(showMPMCAnswers || reviewMode) && !isMPMCQuestionCorrect,
|
|
224
|
+
}"
|
|
225
|
+
v-dark="isDarkMode"
|
|
226
|
+
>
|
|
227
|
+
<div
|
|
228
|
+
v-for="(label, labelIndex) in mpmcLabels"
|
|
229
|
+
class="uikit-question-mpmc-choices-container__part-container"
|
|
230
|
+
:key="labelIndex"
|
|
231
|
+
v-dark="isDarkMode"
|
|
232
|
+
:tabindex="0"
|
|
233
|
+
role="button"
|
|
234
|
+
:aria-expanded="expandedPartNumbers.includes(labelIndex)"
|
|
235
|
+
:aria-label="
|
|
236
|
+
`${stripHtmlTags(label)}. ${expandedPartNumbers.includes(labelIndex) ? 'Expanded' : 'Collapsed'}.`
|
|
237
|
+
"
|
|
238
|
+
@keydown.enter="openChoiceDropdown(labelIndex)"
|
|
239
|
+
@keydown.space.prevent="openChoiceDropdown(labelIndex)"
|
|
240
|
+
>
|
|
241
|
+
<div
|
|
242
|
+
class="uikit-question-mpmc-choices-container__part"
|
|
243
|
+
:class="{
|
|
244
|
+
'uikit-question-mpmc-choices-container__part--expanded':
|
|
245
|
+
expandedPartNumbers.includes(labelIndex),
|
|
246
|
+
}"
|
|
247
|
+
v-dark="isDarkMode"
|
|
248
|
+
@click.stop="toggleChoiceDropdown(labelIndex)"
|
|
249
|
+
>
|
|
250
|
+
<Icon
|
|
251
|
+
v-if="(showMPMCAnswers || reviewMode) && correctPart(labelIndex)"
|
|
252
|
+
v-dark="isDarkMode"
|
|
253
|
+
class="uikit-question-mpmc-choices-container__part-label-correct-icon"
|
|
254
|
+
type="check"
|
|
255
|
+
/>
|
|
256
|
+
<Icon
|
|
257
|
+
v-if="(showMPMCAnswers || reviewMode) && !correctPart(labelIndex)"
|
|
258
|
+
v-dark="isDarkMode"
|
|
259
|
+
class="uikit-question-mpmc-choices-container__part-label-incorrect-icon"
|
|
260
|
+
type="incorrect"
|
|
261
|
+
/>
|
|
262
|
+
<div
|
|
263
|
+
class="uikit-question-mpmc-choices-container__part-label"
|
|
264
|
+
:class="{
|
|
265
|
+
'uikit-question-mpmc-choices-container__part-label--review-mode':
|
|
266
|
+
showMPMCAnswers || reviewMode,
|
|
267
|
+
}"
|
|
268
|
+
v-dark="isDarkMode"
|
|
269
|
+
>
|
|
270
|
+
{{ stripHtmlTags(label) }}
|
|
271
|
+
<Icon
|
|
272
|
+
class="uikit-question-mpmc-choices-container__toggle-part-icon"
|
|
273
|
+
:class="{
|
|
274
|
+
'uikit-question-mpmc-choices-container__toggle-part-icon--up':
|
|
275
|
+
expandedPartNumbers.includes(labelIndex),
|
|
276
|
+
}"
|
|
277
|
+
v-dark="isDarkMode"
|
|
278
|
+
type="accordionArrow"
|
|
279
|
+
/>
|
|
280
|
+
</div>
|
|
281
|
+
<div
|
|
282
|
+
v-if="selectedChoiceTextsByLabelIndex[labelIndex]"
|
|
283
|
+
class="uikit-question-mpmc-choices-container__selected-choice-text"
|
|
284
|
+
v-dark="isDarkMode"
|
|
285
|
+
>
|
|
286
|
+
{{ selectedChoiceTextsByLabelIndex[labelIndex] }}
|
|
287
|
+
</div>
|
|
288
|
+
</div>
|
|
289
|
+
<div
|
|
290
|
+
v-if="expandedPartNumbers.includes(labelIndex)"
|
|
291
|
+
>
|
|
292
|
+
<MPMCRadioGroup
|
|
293
|
+
:modelValue="getRadioGroupChoiceKeySelection(labelIndex)"
|
|
294
|
+
:show-answers="showMPMCAnswers"
|
|
295
|
+
class="uikit-question-mpmc-choices-container__radio-btns"
|
|
296
|
+
:choices="getRadioGroupChoiceKeys(labelIndex)"
|
|
297
|
+
:choices-text="getRadioGroupChoicesText(labelIndex)"
|
|
298
|
+
:is-dark-mode="isDarkMode"
|
|
299
|
+
:disabled="false"
|
|
300
|
+
@update:modelValue="updateRadioPartSelection(labelIndex, $event)"
|
|
301
|
+
/>
|
|
302
|
+
</div>
|
|
303
|
+
</div>
|
|
304
|
+
</div>
|
|
305
|
+
</div>
|
|
306
|
+
</template>
|
|
307
|
+
|
|
308
|
+
<style lang="scss">
|
|
309
|
+
@use '@/styles/breakpoints' as *;
|
|
310
|
+
@use '@/styles/colors' as *;
|
|
311
|
+
|
|
312
|
+
.uikit-question-mpmc-choices-container {
|
|
313
|
+
width: 100%;
|
|
314
|
+
max-width: 492px;
|
|
315
|
+
|
|
316
|
+
&__choices-container {
|
|
317
|
+
cursor: pointer;
|
|
318
|
+
position: relative;
|
|
319
|
+
outline: none;
|
|
320
|
+
transition: 0.1s width ease;
|
|
321
|
+
|
|
322
|
+
&::after {
|
|
323
|
+
content: '';
|
|
324
|
+
position: absolute;
|
|
325
|
+
top: -8px;
|
|
326
|
+
bottom: -8px;
|
|
327
|
+
left: -8px;
|
|
328
|
+
right: -8px;
|
|
329
|
+
border-radius: 11px;
|
|
330
|
+
pointer-events: none;
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
&--incorrect {
|
|
334
|
+
&::after {
|
|
335
|
+
display: block;
|
|
336
|
+
border: 2px solid $pepper;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
&--dark::after {
|
|
340
|
+
border-color: $rosa;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
&--correct {
|
|
345
|
+
&::after {
|
|
346
|
+
display: block;
|
|
347
|
+
border: 2px solid $cadaverous;
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
&--dark::after {
|
|
351
|
+
border-color: $jungle-green;
|
|
352
|
+
}
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
&__part-container {
|
|
357
|
+
margin-bottom: 16px;
|
|
358
|
+
border-radius: 5px;
|
|
359
|
+
background: $white;
|
|
360
|
+
box-shadow: 0 1px 4px 0 rgba($ash, 0.30);
|
|
361
|
+
outline: none;
|
|
362
|
+
transition: box-shadow 0.2s ease;
|
|
363
|
+
|
|
364
|
+
&:focus {
|
|
365
|
+
border: 1px solid $brand-blue;
|
|
366
|
+
}
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
&--dark {
|
|
370
|
+
border-radius: 5px;
|
|
371
|
+
background: $brand-black;
|
|
372
|
+
box-shadow: 0 1px 4px 0 $jet;
|
|
373
|
+
|
|
374
|
+
&:focus {
|
|
375
|
+
border: 1px solid $banana-bread;
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
&__part {
|
|
381
|
+
cursor: pointer;
|
|
382
|
+
padding: 12px 36px 12px 15px;
|
|
383
|
+
align-items: center;
|
|
384
|
+
align-content: flex-start;
|
|
385
|
+
flex-wrap: wrap;
|
|
386
|
+
border-radius: 5px;
|
|
387
|
+
border: 0.5px solid rgba($pewter, 0.85);
|
|
388
|
+
background: $white;
|
|
389
|
+
|
|
390
|
+
&--dark {
|
|
391
|
+
background: $brand-black;
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
&--expanded {
|
|
395
|
+
border-radius: 5px 5px 0px 0px;
|
|
396
|
+
}
|
|
397
|
+
}
|
|
398
|
+
|
|
399
|
+
&__part-label-correct-icon,
|
|
400
|
+
&__part-label-incorrect-icon {
|
|
401
|
+
position: absolute;
|
|
402
|
+
right: 0;
|
|
403
|
+
margin-right: 12px;
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
&__part-label-correct-icon {
|
|
407
|
+
color: $cadaverous;
|
|
408
|
+
width: 18px;
|
|
409
|
+
height: 18px;
|
|
410
|
+
|
|
411
|
+
&--dark {
|
|
412
|
+
color: $jungle-green;
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
|
|
416
|
+
&__part-label-incorrect-icon {
|
|
417
|
+
color: $pepper;
|
|
418
|
+
|
|
419
|
+
&--dark {
|
|
420
|
+
color: $rosa;
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
|
|
424
|
+
&__part-label {
|
|
425
|
+
color: $brand-black;
|
|
426
|
+
font-size: 16px;
|
|
427
|
+
font-weight: 600;
|
|
428
|
+
line-height: 23px;
|
|
429
|
+
letter-spacing: -0.1px;
|
|
430
|
+
|
|
431
|
+
&--dark {
|
|
432
|
+
color: $barely-background;
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
&--review-mode {
|
|
436
|
+
width: 285px;
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
&__selected-choice-text {
|
|
441
|
+
color: $brand-black;
|
|
442
|
+
font-size: 14px;
|
|
443
|
+
font-weight: 400;
|
|
444
|
+
line-height: 19px;
|
|
445
|
+
margin-top: 4px;
|
|
446
|
+
|
|
447
|
+
&--dark {
|
|
448
|
+
color: $barely-background;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
&__toggle-part-icon {
|
|
453
|
+
position: absolute;
|
|
454
|
+
margin-top: 8px;
|
|
455
|
+
margin-left: 8px;
|
|
456
|
+
color: $brand-blue;
|
|
457
|
+
|
|
458
|
+
&--up {
|
|
459
|
+
transform: rotate(180deg);
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
&--dark {
|
|
463
|
+
color: $banana-bread;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
&__radio-btns {
|
|
468
|
+
width: 100%;
|
|
469
|
+
max-width: 492px;
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
</style>
|