Reworking button question widget to work with 3 different button components

This commit is contained in:
Max 2022-01-20 09:13:49 -05:00
parent e3b1272429
commit 80560902f0
5 changed files with 197 additions and 71 deletions

View file

@ -6,29 +6,33 @@
}}</span> }}</span>
</div> </div>
<div class="w-100 d-flex justify-content-center"> <div class="w-100 d-flex justify-content-center">
<fieldset class="w-100" :class="isVehicleQuestion ? vehicleQuestionClasses : isHorizontal ? horizontalClasses : ''" role="radiogroup" :aria-labelledby="groupName ? groupName + '-radio-group' : ''"> <fieldset class="w-100" :class="isVehicleQuestion ? vehicleQuestionClasses : ''" role="radiogroup" :aria-labelledby="groupName ? groupName + '-radio-group' : ''">
<legend class="sr-only">{{groupName}}</legend> <legend class="sr-only">{{groupName}}</legend>
<component :is="buttonType" v-for="answer in answers" :key="answer" <div :class="isRow ? 'row g-2' : isColumn ? columnClasses : 'w-100'">
:buttonID="answer" <component :is="buttonType" v-for="answer in answers" :key="answer"
@mouseup="chooseAnswer(answer)" :buttonID="answer.Name ? answer.Name : answer"
@keyup.space="chooseAnswer(answer)" @mouseup="chooseAnswer(answer.Name ? answer.Name : answer)"
:loaderEnabled="loaderEnabled" @keyup.space="chooseAnswer(answer.Name ? answer.Name : answer)"
:loaderColor="loaderColor" :loaderEnabled="loaderEnabled"
:loaderPosition="loaderPosition" :loaderColor="loaderColor"
:sizeInRem="sizeInRem" :loaderPosition="loaderPosition"
data-test="button" :sizeInRem="sizeInRem"
:groupName="groupName" data-test="button"
:textPosition="textPosition" :groupName="groupName"
:value="modelValue" :textPosition="textPosition"
screenReaderOnlyText="(opens new window)" screenReaderOnlyText="(opens new window)"
:isMultiSelect="isMultiSelect" :isMultiSelect="isMultiSelect"
:ariaLabelBy="ariaLabelBy" :isHorizontal="isHorizontal"
:isRequired="isRequired" :ariaLabelBy="ariaLabelBy"
:buttonImage="buttonImage" :isRequired="isRequired"
:buttonLabel="buttonLabel" :buttonImage="answer.AnswerImageUrl"
:altText="altText" :buttonImageId="answer.ImageId"
:buttonLabelSubCopy="buttonLabelSubCopy" :buttonLabel="answer.Text ? answer.Text : answer"
/> :altText="altText"
:buttonLabelSubCopy="answer.SubText"
:value="modelValue"
/>
</div>
</fieldset> </fieldset>
</div> </div>
</div> </div>
@ -72,7 +76,10 @@ export default {
isRequired: Boolean, isRequired: Boolean,
isVehicleQuestion: Boolean, isVehicleQuestion: Boolean,
isHorizontal: Boolean, isHorizontal: Boolean,
isColumn: Boolean,
isRow: Boolean,
buttonImage: String, buttonImage: String,
buttonImageId: String,
buttonLabel: String, buttonLabel: String,
altText: String, altText: String,
buttonLabelSubCopy: String, buttonLabelSubCopy: String,
@ -80,7 +87,7 @@ export default {
data() { data() {
return { return {
vehicleQuestionClasses: 'container-fluid overflow-scroll position-absolute px-5 pt-1 py-0', vehicleQuestionClasses: 'container-fluid overflow-scroll position-absolute px-5 pt-1 py-0',
horizontalClasses: 'd-flex flex-row p-0' columnClasses: 'd-flex flex-row p-0'
}; };
}, },
methods: { methods: {

View file

@ -53,39 +53,33 @@
<fieldset> <fieldset>
<legend class="sr-only">Functioning as Checkbox</legend> <legend class="sr-only">Functioning as Checkbox</legend>
<div class="row g-2"> <div class="row g-2">
<div class="col-4"> <listCard
<listCard isMultiSelect
isMultiSelect buttonImage="windshield-damage.svg"
buttonImage="windshield-damage.svg" buttonLabel="Windshield"
buttonLabel="Windshield" altText=""
altText="" buttonID="List Card Checkbox 1"
buttonID="List Card Checkbox 1" groupID="checkbox-demo-1"
groupID="checkbox-demo-1" buttonLabelSubCopy="Description"
buttonLabelSubCopy="Description" />
/> <listCard
</div> isMultiSelect
<div class="col-4"> buttonImage="side-window-damage-right-all.svg"
<listCard buttonLabel="Windshield"
isMultiSelect altText=""
buttonImage="side-window-damage-right-all.svg" buttonID="List Card Checkbox 2"
buttonLabel="Windshield" groupID="checkbox-demo-1"
altText="" buttonLabelSubCopy="Description with more than one line"
buttonID="List Card Checkbox 2" />
groupID="checkbox-demo-1" <listCard
buttonLabelSubCopy="Description with more than one line" isMultiSelect
/> buttonImage="windshield-damage.svg"
</div> buttonLabel="Windshield"
<div class="col-4"> altText=""
<listCard buttonID="List Card Checkbox 3"
isMultiSelect groupID="checkbox-demo-1"
buttonImage="windshield-damage.svg" buttonLabelSubCopy=""
buttonLabel="Windshield" />
altText=""
buttonID="List Card Checkbox 3"
groupID="checkbox-demo-1"
buttonLabelSubCopy=""
/>
</div>
</div> </div>
</fieldset> </fieldset>
<div class="row my-4"> <div class="row my-4">
@ -778,7 +772,7 @@
:answers="horizontalCheckboxAnswers" :answers="horizontalCheckboxAnswers"
buttonType="listButtonHorizontal" buttonType="listButtonHorizontal"
:isMultiSelect="true" :isMultiSelect="true"
:isHorizontal="true" isColumn
ariaLabelBy="checkbox" ariaLabelBy="checkbox"
groupName="checkbox-list-horizontal" groupName="checkbox-list-horizontal"
questionText="List Button Horizontal as checkbox" questionText="List Button Horizontal as checkbox"
@ -786,12 +780,70 @@
<buttonQuestion <buttonQuestion
:answers="horizontalRadioAnswers" :answers="horizontalRadioAnswers"
buttonType="listButtonHorizontal" buttonType="listButtonHorizontal"
:isHorizontal="true" isColumn
ariaLabelBy="radio" ariaLabelBy="radio"
groupName="radio-list-horizontal" groupName="radio-list-horizontal"
questionText="List Button Horizontal as radio" questionText="List Button Horizontal as radio"
sizeInRem="1" sizeInRem="1"
/> />
<buttonQuestion
:answers="listCardCheckBox"
buttonType="listCard"
isMultiSelect
ariaLabelBy="check_card"
groupName="check-list-card"
questionText="List Card as checkbox"
/>
<buttonQuestion
:answers="listCardRadio"
buttonType="listCard"
ariaLabelBy="radio_card"
groupName="radio-card"
questionText="List Card as radio"
/>
<buttonQuestion
isMultiSelect
isHorizontal
:answers="listCardCheckBoxHorizontal"
buttonType="listCard"
ariaLabelBy="horizontal_check_card"
groupName="horizontal_check-card"
questionText="List Card Horizontal as checkbox"
/>
<buttonQuestion
isMultiSelect
isHorizontal
:answers="listCardCheckBoxHorizontalSubText"
buttonType="listCard"
ariaLabelBy="horizontal_check_card-st"
groupName="horizontal_check-card-st"
questionText="With Subtext"
/>
<buttonQuestion
isHorizontal
:answers="listRadioHorizontal"
buttonType="listCard"
ariaLabelBy="horizontal_radio_card"
groupName="horizontal_cradio-card"
questionText="List Card Horizontal as radio"
/>
<buttonQuestion
isHorizontal
:answers="listRadioHorizontalSubText"
buttonType="listCard"
ariaLabelBy="horizontal_radio_card-st"
groupName="horizontal_cradio-card-st"
questionText="With Subtext"
/>
<buttonQuestion
isMultiSelect
isRow
:answers="listCardGroup"
buttonType="listCard"
ariaLabelBy="horizontal_radio_card-group"
groupName="horizontal_cradio-card-group"
questionText="In column layout"
/>
</div> </div>
</template> </template>
@ -829,6 +881,66 @@ export default {
radioAnswers: ['Radio Answer 1', 'Radio Answer 2', 'Radio Answer 3'], radioAnswers: ['Radio Answer 1', 'Radio Answer 2', 'Radio Answer 3'],
horizontalCheckboxAnswers: ['HCB Answer 1', 'HCB Answer 2', 'HCB Answer 3'], horizontalCheckboxAnswers: ['HCB Answer 1', 'HCB Answer 2', 'HCB Answer 3'],
horizontalRadioAnswers: ['HR Answer 1', 'HR Answer 2', 'HR Answer 3'], horizontalRadioAnswers: ['HR Answer 1', 'HR Answer 2', 'HR Answer 3'],
listCardCheckBox: [{
Name: 'List-Card-CB',
Text: "List Card CB",
SubText: "checkbox",
ImageId: '53343ce4-5b6a-46aa-a80a-f948c1723955',
AnswerImageUrl: "side-window-damage-right-all.svg"
}],
listCardRadio: [{
Name: 'List-Card-R',
Text: "List Card R",
SubText: "Radio",
ImageId: '53343ce4-5b6a-46aa-a80a-f948c1723955',
AnswerImageUrl: "side-window-damage-right-all.svg"
}],
listCardCheckBoxHorizontalSubText: [{
Name: 'List-Card-CBHst',
Text: "List Card CBHst",
SubText: "With Subtext",
ImageId: '53343ce4-5b6a-46aa-a80a-f948c1723955',
AnswerImageUrl: "side-window-damage-right-all.svg"
}],
listCardCheckBoxHorizontal: [{
Name: 'List-Card-CBH',
Text: "List Card CBH",
ImageId: '53343ce4-5b6a-46aa-a80a-f948c1723955',
AnswerImageUrl: "side-window-damage-right-all.svg"
}],
listRadioHorizontalSubText: [{
Name: 'List-Card-RHst',
Text: "List Card RHst",
SubText: "With Subtext",
ImageId: '53343ce4-5b6a-46aa-a80a-f948c1723955',
AnswerImageUrl: "side-window-damage-right-all.svg"
}],
listRadioHorizontal: [{
Name: 'List-Card-RH',
Text: "List Card RH",
ImageId: '53343ce4-5b6a-46aa-a80a-f948c1723955',
AnswerImageUrl: "side-window-damage-right-all.svg"
}],
listCardGroup: [{
Name: 'Side-Window-1',
Text: "Side Window",
SubText: "With Subtext",
ImageId: '53343ce4-5b6a-46aa-a80a-f948c1723955',
AnswerImageUrl: "side-window-damage-right-all.svg"
},
{
Name: 'Side-Window-2',
Text: "Side Window",
SubText: "With Subtext that is more than one line",
ImageId: '53343ce4-5b6a-46aa-a80a-f948c1723955',
AnswerImageUrl: "side-window-damage-right-all.svg"
},
{
Name: 'Side-Window-3',
Text: "Side Window",
ImageId: '53343ce4-5b6a-46aa-a80a-f948c1723955',
AnswerImageUrl: "side-window-damage-right-all.svg"
}],
}; };
}, },
}; };

View file

@ -2,7 +2,8 @@
<div class="list-group list-button-horizontal d-flex flex-column w-100 mb-2"> <div class="list-group list-button-horizontal d-flex flex-column w-100 mb-2">
<input :type="isMultiSelect ? 'checkbox' : 'radio'" :id="buttonID" :name="groupName" :value="buttonID" :aria-required="isRequired" @click="handleClick(value)" :data-focus-target="groupName" /> <input :type="isMultiSelect ? 'checkbox' : 'radio'" :id="buttonID" :name="groupName" :value="buttonID" :aria-required="isRequired" @click="handleClick(value)" :data-focus-target="groupName" />
<label tabindex="-1" :for="buttonID" :aria-labelledby="buttonID" class="d-flex flex-column justify-content-center py-3 px-4"> <label tabindex="-1" :for="buttonID" :aria-labelledby="buttonID" class="d-flex flex-column justify-content-center py-3 px-4">
<span class="m-0" :class="textPosition">{{buttonID}}</span> <span class="m-0" :class="textPosition">{{buttonLabel}}</span>
<span v-if="buttonLabelSubCopy" class="m-0 small" :class="textPosition">{{buttonLabelSubCopy}}</span>
<span v-if="screenReaderOnlyText" class="sr-only">{{screenReaderOnlyText}}</span> <span v-if="screenReaderOnlyText" class="sr-only">{{screenReaderOnlyText}}</span>
<loader v-if="isLoaderDisplayed && !isMultiSelect" :style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}" :class="[loaderColor, loaderPosition]" /> <loader v-if="isLoaderDisplayed && !isMultiSelect" :style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}" :class="[loaderColor, loaderPosition]" />
</label> </label>
@ -20,6 +21,8 @@ export default {
isMultiSelect: Boolean, isMultiSelect: Boolean,
groupName: String, groupName: String,
buttonID: String, buttonID: String,
buttonLabel: String,
buttonLabelSubCopy: String,
screenReaderOnlyText: String, screenReaderOnlyText: String,
textPosition: String, textPosition: String,
loaderEnabled: Boolean, loaderEnabled: Boolean,

View file

@ -2,7 +2,7 @@
<div class="list-group list-button d-flex flex-column w-100 mb-2"> <div class="list-group list-button d-flex flex-column w-100 mb-2">
<input :type="isMultiSelect ? 'checkbox' : 'radio'" :id="buttonID" :name="groupName" :value="buttonID" :aria-required="isRequired" @click="handleClick(value)" :data-focus-target="groupName"> <input :type="isMultiSelect ? 'checkbox' : 'radio'" :id="buttonID" :name="groupName" :value="buttonID" :aria-required="isRequired" @click="handleClick(value)" :data-focus-target="groupName">
<label tabindex="-1" :for="buttonID" :aria-labelledby="buttonID" class="d-flex flex-column justify-content-center py-3 px-4"> <label tabindex="-1" :for="buttonID" :aria-labelledby="buttonID" class="d-flex flex-column justify-content-center py-3 px-4">
<span class="m-0" :class="textPosition">{{ buttonID }}</span> <span class="m-0" :class="textPosition">{{ buttonLabel }}</span>
<span v-if="buttonLabelSubCopy" class="m-0 small" :class="textPosition">{{buttonLabelSubCopy}}</span> <span v-if="buttonLabelSubCopy" class="m-0 small" :class="textPosition">{{buttonLabelSubCopy}}</span>
<span v-if="screenReaderOnlyText" class="sr-only">{{ screenReaderOnlyText }}</span> <span v-if="screenReaderOnlyText" class="sr-only">{{ screenReaderOnlyText }}</span>
<loader v-if="isLoaderDisplayed && !isMultiSelect" :style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}" :class="[this.loaderColor, this.loaderPosition]" /> <loader v-if="isLoaderDisplayed && !isMultiSelect" :style="{width: `${sizeInRem}rem`, height: `${sizeInRem}rem`}" :class="[this.loaderColor, this.loaderPosition]" />
@ -19,6 +19,7 @@ export default {
props: { props: {
isMultiSelect: Boolean, isMultiSelect: Boolean,
groupName: String, groupName: String,
buttonLabel: [Number,String],
buttonID: [Number,String], buttonID: [Number,String],
isRequired: Boolean, isRequired: Boolean,
textPosition: String, textPosition: String,

View file

@ -1,16 +1,18 @@
<template> <template>
<!-- Heavily documented below --> <!-- Heavily documented below -->
<div class="list-card w-100 rounded-3 d-flex align-items-center h-100" :class="isHorizontal ? 'horizontal' : ''"> <div class="col">
<input :type="isMultiSelect ? 'checkbox' : 'radio'" :id="buttonID" :name="groupName" :value="buttonID" :aria-required="isRequired" @click="handleClick(value)" :data-focus-target="groupName" /> <div class="list-card w-100 rounded-3 d-flex align-items-center h-100" :class="isHorizontal ? 'horizontal' : ''">
<label :for="buttonID" class="d-flex w-100 align-items-center px-2 h-100" :class="[isHorizontal ? rowClasses : columnClasses,isHorizontal && buttonLabelSubCopy ? 'checkboxTop' : '']" tabindex="-1"> <input :type="isMultiSelect ? 'checkbox' : 'radio'" :id="buttonID" :name="groupName" :value="buttonID" :aria-required="isRequired" @click="handleClick(value)" :data-focus-target="groupName" />
<img :class="!isHorizontal ? 'order-1' : 'ms-auto order-3'" v-bind:src="require(`@/assets/img/icons/${buttonImage}`)" :alt="altText" /> <label :for="buttonID" class="d-flex w-100 align-items-center px-2 h-100" :class="[isHorizontal ? rowClasses : columnClasses,isHorizontal && buttonLabelSubCopy ? 'checkboxTop' : '']" tabindex="-1">
<p v-if="!isHorizontal" class="small order-3" :class="isMultiSelect ? 'm-0' : 'mt-2 mb-0'">{{buttonLabel}}</p> <img :id="buttonImageId" :class="!isHorizontal ? 'order-1' : 'ms-auto order-3'" v-bind:src="require(`@/assets/img/icons/${buttonImage}`)" :alt="altText" />
<p v-if="buttonLabelSubCopy && !isHorizontal" class="fs-7 m-0 order-4">{{buttonLabelSubCopy}}</p> <p v-if="!isHorizontal" class="small order-3" :class="isMultiSelect ? 'm-0' : 'mt-2 mb-0'">{{buttonLabel}}</p>
<div v-if="isHorizontal" class="order-2"> <p v-if="buttonLabelSubCopy && !isHorizontal" class="fs-7 m-0 order-4">{{buttonLabelSubCopy}}</p>
<p class="m-0 small">{{buttonLabel}}</p> <div v-if="isHorizontal" class="order-2">
<p v-if="buttonLabelSubCopy" class="m-0 fs-7">{{buttonLabelSubCopy}}</p> <p class="m-0 small">{{buttonLabel}}</p>
</div> <p v-if="buttonLabelSubCopy" class="m-0 fs-7">{{buttonLabelSubCopy}}</p>
</label> </div>
</label>
</div>
</div> </div>
</template> </template>
@ -26,6 +28,7 @@ export default {
isHorizontal: Boolean, isHorizontal: Boolean,
//end must choose //end must choose
buttonImage: String,//Required: File name of image buttonImage: String,//Required: File name of image
buttonImageId: String,
buttonLabel: String,//Required: Label text buttonLabel: String,//Required: Label text
isRequired: Boolean, //Required: is aria-required required or not? isRequired: Boolean, //Required: is aria-required required or not?
altText: String,//Leave empty. Screen readers read the buttonLabel text. If alt has content, it will repeat unnecessarily. altText: String,//Leave empty. Screen readers read the buttonLabel text. If alt has content, it will repeat unnecessarily.