Skip to content

Commit f170ef1

Browse files
committed
fix: improve responsive design for linear scale question component
Signed-off-by: Christian Hartmann <chris-hartmann@gmx.de>
1 parent 3a1682b commit f170ef1

1 file changed

Lines changed: 80 additions & 13 deletions

File tree

src/components/Questions/QuestionLinearScale.vue

Lines changed: 80 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -47,19 +47,31 @@
4747
ref="lowest"
4848
v-model="optionsLabelLowest"
4949
class="label-input-field"
50-
:label="t('forms', 'Label (optional)')"
51-
:aria-label="t('forms', 'Label for lowest value')"
50+
:label="t('forms', 'Label for lowest value')"
51+
:placeholder="t('forms', 'Label (optional)')"
5252
resize="none"
5353
@input="resizeLabel('lowest')"
5454
@blur="onBlur('lowest')">
5555
</NcTextArea>
56-
<div v-else-if="optionsLabelLowest !== ''" class="label-lowest">
56+
<div
57+
v-else-if="optionsLabelLowest !== ''"
58+
:id="labelId"
59+
class="label-lowest">
5760
{{ optionsLabelLowest }}
5861
</div>
59-
<div class="question__content__options">
62+
<fieldset class="question__content__options">
63+
<legend class="hidden-visually">
64+
{{
65+
t('forms', 'From {firstOption} to {lastOption}', {
66+
firstOption: optionsLabelLowest,
67+
lastOption: optionsLabelHighest,
68+
})
69+
}}
70+
</legend>
6071
<NcCheckboxRadioSwitch
61-
v-for="option in scaleOptions"
72+
v-for="(option, index) in scaleOptions"
6273
:key="option"
74+
:aria-describedby="index === 0 ? labelId : undefined"
6375
:disabled="!readOnly"
6476
:checked="questionValues"
6577
:value="option.toString()"
@@ -70,7 +82,7 @@
7082
@keydown.enter.exact.prevent="onKeydownEnter">
7183
{{ option }}
7284
</NcCheckboxRadioSwitch>
73-
</div>
85+
</fieldset>
7486
<NcTextArea
7587
v-if="!readOnly"
7688
ref="highest"
@@ -133,6 +145,13 @@ export default {
133145
return this.values
134146
},
135147
148+
/**
149+
* ID for the label for the lowest option
150+
*/
151+
labelId() {
152+
return 'q' + this.index + '__label_lowest'
153+
},
154+
136155
optionsLowest: {
137156
get() {
138157
return this.extraSettings?.optionsLowest ?? 1
@@ -152,8 +171,8 @@ export default {
152171
optionsLabelLowest: {
153172
get() {
154173
return (
155-
this.extraSettings?.optionsLabelLowest ??
156-
t('forms', 'Strongly disagree')
174+
this.extraSettings?.optionsLabelLowest
175+
?? t('forms', 'Strongly disagree')
157176
)
158177
},
159178
set(value) {
@@ -163,8 +182,8 @@ export default {
163182
optionsLabelHighest: {
164183
get() {
165184
return (
166-
this.extraSettings?.optionsLabelHighest ??
167-
t('forms', 'Strongly agree')
185+
this.extraSettings?.optionsLabelHighest
186+
?? t('forms', 'Strongly agree')
168187
)
169188
},
170189
set(value) {
@@ -251,45 +270,93 @@ export default {
251270
<style lang="scss" scoped>
252271
.question__content {
253272
display: flex;
254-
padding-block-start: var(--clickable-area-small);
273+
274+
@media (max-width: 768px) {
275+
flex-wrap: wrap; // Allow wrapping for smaller screens
276+
}
277+
278+
@media (min-width: 769px) {
279+
padding-block-start: var(--clickable-area-small);
280+
}
255281
256282
&__options {
257283
width: 100%;
258284
display: flex;
259285
flex-direction: row;
260286
justify-content: space-evenly;
261287
flex-grow: 1;
288+
289+
@media (max-width: 768px) {
290+
flex-direction: column; // Stack options vertically on smaller screens
291+
align-items: flex-start; // Align items to the left
292+
}
262293
}
263294
264295
&__edit {
265296
margin-inline-start: -12px;
297+
298+
@media (max-width: 768px) {
299+
margin-inline-end: calc(var(--clickable-area-large) - 2px);
300+
}
301+
}
302+
303+
:deep(.checkbox-content) {
304+
display: flex;
305+
flex-direction: row; // Labels next to checkboxes by default
306+
align-items: center;
307+
text-align: center;
308+
309+
@media (min-width: 769px) {
310+
flex-direction: column; // Labels above checkboxes on larger screens
311+
align-items: center;
312+
}
266313
}
267314
268315
:deep(.checkbox-content__text) {
269316
position: absolute;
270-
margin-block-start: calc(-1 * var(--clickable-area-large));
271-
margin-inline-start: 8px;
317+
margin-block-start: calc(-1 * var(--clickable-area-small));
318+
319+
@media (max-width: 768px) {
320+
margin-block-start: 0;
321+
margin-inline-start: var(--default-clickable-area);
322+
}
272323
}
273324
274325
.label-input-field {
275326
width: 120px;
276327
align-self: center;
277328
min-height: fit-content;
278329
flex-shrink: 0;
330+
331+
@media (max-width: 768px) {
332+
width: 100%; // Full width on smaller screens
333+
padding-block: var(--default-grid-baseline);
334+
}
279335
}
280336
281337
.label-lowest {
282338
width: 120px;
283339
align-self: center;
284340
text-align: start;
285341
flex-shrink: 0;
342+
343+
@media (max-width: 768px) {
344+
width: 100%; // Full width on smaller screens
345+
padding-block: var(--default-grid-baseline);
346+
}
286347
}
287348
288349
.label-highest {
289350
width: 120px;
290351
align-self: center;
291352
text-align: end;
292353
flex-shrink: 0;
354+
355+
@media (max-width: 768px) {
356+
text-align: start;
357+
width: 100%; // Full width on smaller screens
358+
padding-block: var(--default-grid-baseline);
359+
}
293360
}
294361
}
295362
</style>

0 commit comments

Comments
 (0)