Skip to content

Commit 1a0803c

Browse files
committed
fix(linear-scale): add custom wrapper instead of CSS hack
Also use proper BEM. Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 6be7bdc commit 1a0803c

1 file changed

Lines changed: 73 additions & 83 deletions

File tree

src/components/Questions/QuestionLinearScale.vue

Lines changed: 73 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,15 @@
3939
</template>
4040

4141
<div
42-
:class="
43-
readOnly
44-
? 'question__content'
45-
: 'question__content question__content__edit'
46-
">
42+
class="question__content question-linear-scale"
43+
:class="{
44+
question__content__edit: !readOnly,
45+
}">
4746
<NcTextArea
4847
v-if="!readOnly"
4948
ref="lowest"
5049
:model-value="optionsLabelLowest"
51-
class="label-input-field"
50+
class="question-linear-scale__label-input"
5251
:label="t('forms', 'Label for lowest value')"
5352
:placeholder="t('forms', 'Label (optional)')"
5453
resize="none"
@@ -59,10 +58,10 @@
5958
<div
6059
v-else-if="optionsLabelLowest !== ''"
6160
:id="labelId"
62-
class="label-lowest">
61+
class="question-linear-scale__label question-linear-scale__label-lowest">
6362
{{ optionsLabelLowest }}
6463
</div>
65-
<fieldset class="question__content__options">
64+
<fieldset class="question-linear-scale__options">
6665
<legend class="hidden-visually">
6766
{{
6867
t('forms', 'From {firstOption} to {lastOption}', {
@@ -71,34 +70,39 @@
7170
})
7271
}}
7372
</legend>
74-
<NcCheckboxRadioSwitch
73+
<div
7574
v-for="(option, index) in scaleOptions"
7675
:key="option"
77-
:aria-describedby="index === 0 ? labelId : undefined"
78-
:disabled="!readOnly"
79-
:checked="questionValues"
80-
:value="option.toString()"
81-
:name="`${id}-answer`"
82-
type="radio"
83-
:required="checkRequired(option)"
84-
@update:checked="onChange"
85-
@keydown.enter.exact.prevent="onKeydownEnter">
86-
{{ option }}
87-
</NcCheckboxRadioSwitch>
76+
class="question-linear-scale__option">
77+
<label :for="`linear-scale-${id}-${option}`">{{ option }}</label>
78+
<NcCheckboxRadioSwitch
79+
:id="`linear-scale-${id}-${option}`"
80+
:aria-describedby="index === 0 ? labelId : undefined"
81+
:disabled="!readOnly"
82+
:model-value="questionValues"
83+
:value="option.toString()"
84+
:name="`${id}-answer`"
85+
type="radio"
86+
:required="checkRequired(option)"
87+
@update:modelValue="onChange"
88+
@keydown.enter.exact.prevent="onKeydownEnter" />
89+
</div>
8890
</fieldset>
8991
<NcTextArea
9092
v-if="!readOnly"
9193
ref="highest"
9294
:model-value="optionsLabelHighest"
93-
class="label-input-field"
95+
class="question-linear-scale__label-input"
9496
:label="t('forms', 'Label (optional)')"
9597
:aria-label="t('forms', 'Label for highest value')"
9698
resize="none"
9799
@input="resizeLabel('highest')"
98100
@blur="onBlur('highest')"
99101
@update:model-value="onOptionsLabelHighestChange">
100102
</NcTextArea>
101-
<div v-else-if="optionsLabelHighest !== ''" class="label-highest">
103+
<div
104+
v-else-if="optionsLabelHighest !== ''"
105+
class="question-linear-scale__label question-linear-scale__label-highest">
102106
{{ optionsLabelHighest }}
103107
</div>
104108
</div>
@@ -281,23 +285,6 @@ export default {
281285
flex-wrap: wrap; // Allow wrapping for smaller screens
282286
}
283287
284-
@media (min-width: 769px) {
285-
padding-block-start: var(--clickable-area-small);
286-
}
287-
288-
&__options {
289-
width: 100%;
290-
display: flex;
291-
flex-direction: row;
292-
justify-content: space-evenly;
293-
flex-grow: 1;
294-
295-
@media (max-width: 768px) {
296-
flex-direction: column; // Stack options vertically on smaller screens
297-
align-items: flex-start; // Align items to the left
298-
}
299-
}
300-
301288
&__edit {
302289
margin-inline-start: -12px;
303290
@@ -306,62 +293,65 @@ export default {
306293
}
307294
}
308295
309-
:deep(.checkbox-content) {
310-
display: flex;
311-
flex-direction: row; // Labels next to checkboxes by default
312-
align-items: center;
313-
text-align: center;
296+
.question-linear-scale {
297+
&__label {
298+
width: 120px;
299+
align-self: center;
300+
flex-shrink: 0;
314301
315-
@media (min-width: 769px) {
316-
flex-direction: column; // Labels above checkboxes on larger screens
317-
align-items: center;
318-
}
319-
}
302+
&-lowest {
303+
text-align: start;
304+
}
320305
321-
:deep(.checkbox-content__text) {
322-
position: absolute;
323-
margin-block-start: calc(-1 * var(--clickable-area-small));
306+
&-highest {
307+
text-align: end;
324308
325-
@media (max-width: 768px) {
326-
margin-block-start: 0;
327-
margin-inline-start: var(--default-clickable-area);
309+
@media (max-width: 768px) {
310+
text-align: start;
311+
}
312+
}
313+
314+
@media (max-width: 768px) {
315+
width: 100%; // Full width on smaller screens
316+
padding-block: var(--default-grid-baseline);
317+
}
328318
}
329-
}
330319
331-
.label-input-field {
332-
width: 120px;
333-
align-self: center;
334-
min-height: fit-content;
335-
flex-shrink: 0;
320+
&__label-input {
321+
width: 120px;
322+
align-self: center;
323+
min-height: fit-content;
324+
flex-shrink: 0;
336325
337-
@media (max-width: 768px) {
338-
width: 100%; // Full width on smaller screens
339-
padding-block: var(--default-grid-baseline);
326+
@media (max-width: 768px) {
327+
width: 100%; // Full width on smaller screens
328+
padding-block: var(--default-grid-baseline);
329+
}
340330
}
341-
}
342331
343-
.label-lowest {
344-
width: 120px;
345-
align-self: center;
346-
text-align: start;
347-
flex-shrink: 0;
332+
&__options {
333+
width: 100%;
334+
display: flex;
335+
flex-direction: row;
336+
align-items: center;
337+
justify-content: space-evenly;
338+
flex-grow: 1;
348339
349-
@media (max-width: 768px) {
350-
width: 100%; // Full width on smaller screens
351-
padding-block: var(--default-grid-baseline);
340+
@media (max-width: 768px) {
341+
flex-direction: column; // Stack options vertically on smaller screens
342+
align-items: flex-start; // Align items to the left
343+
}
352344
}
353-
}
354345
355-
.label-highest {
356-
width: 120px;
357-
align-self: center;
358-
text-align: end;
359-
flex-shrink: 0;
346+
&__option {
347+
display: flex;
348+
flex-direction: column;
349+
align-items: center;
350+
justify-content: center;
360351
361-
@media (max-width: 768px) {
362-
text-align: start;
363-
width: 100%; // Full width on smaller screens
364-
padding-block: var(--default-grid-baseline);
352+
@media (max-width: 768px) {
353+
flex-direction: row-reverse;
354+
}
365355
}
366356
}
367357
}

0 commit comments

Comments
 (0)