DigitalConsumer.FixMyGlass/src/digital-components/textarea-question/textarea-question.vue
2023-07-10 10:05:45 -04:00

112 lines
3 KiB
Vue

<template>
<div class="textarea-question">
<div class="label-wrapper mb-1" :aria-label="questionText">
<!-- Wrap label and span because v-html prevents v-if from displaying if v-if <span> is inside <label>-->
<label for="textarea-question" class="fw-bold" v-html="questionText"></label>
<span v-if="!isRequired" class="fw-normal ms-1">(Optional)</span>
</div>
<textarea
id="textareaQuestion"
ref="textarea"
v-model="value"
v-maska="mask"
@keyup="updateCount"
class="p-4"
:maxlength="maxLength"
role="textbox"
aria-multiline="true"
:aria-required="isRequired">
</textarea>
<p
tabindex="0"
class="caption mt-2 mb-0"
id="charactersRemaining"
:class="[urgentCountdown ? 'urgent-countdown' : '']">
{{ remainingCount }}/{{ maxLength }} characters remaining
</p>
</div>
</template>
<script>
export default {
name: "textareaQuestion",
props: {
cmsWidgetName: String,
isRequired: Boolean,
maxLength: {
type: Number,
default: 250,
},
modelValue: String,
},
// TODO: At some point in the future we should probably add the tie in to validation here in case the field must be populated for some other use cases
setup() {},
computed: {
questionText() {
return this.getCmsContent(this.cmsWidgetName, "QuestionText");
},
value: {
get: function () {
return this.modelValue;
},
set: function (newValue) {
this.$emit("update:modelValue", newValue);
},
},
remainingCount() {
return this.maxLength - this.value.length;
},
urgentCountdown() {
return this.remainingCount <= this.maxLength * 0.1 ? true : false;
},
mask() {
// Allow any character but only the max length number of times.
return {
mask: `x*${this.maxLength}`,
tokens: {
x: {
pattern: /.|\n|\r/,
},
},
};
},
},
};
</script>
<style lang="scss">
.textarea-question {
display: flex;
flex-direction: column;
label {
color: $black;
}
.label-wrapper {
display: flex;
align-items: center;
label {
span {
color: $gray-500;
}
}
}
textarea {
border-radius: 0.5rem;
border: 1px solid $gray-500;
height: 88px;
&:focus {
box-shadow: 0 0 0 2.5px $blue;
outline: none;
}
&:hover {
box-shadow: 0 0 0 4px $blue-300;
}
}
p {
color: $gray-500;
&.urgent-countdown {
color: $red;
}
}
}
</style>