Merge branch 'develop' into feature/CSR-18
This commit is contained in:
commit
f92a18ba4f
22 changed files with 474 additions and 117 deletions
|
|
@ -1,6 +1,9 @@
|
||||||
import { shallowMount } from "@vue/test-utils";
|
import { shallowMount } from "@vue/test-utils";
|
||||||
import buttonQuestion from "@/common-components/button-question/button-question";
|
import buttonQuestion from "@/common-components/button-question/button-question";
|
||||||
import { nextTick } from "vue";
|
import { nextTick } from "vue";
|
||||||
|
import { getMountOptions } from "@/helpers/unit-test-helper.js";
|
||||||
|
import store from "@/store";
|
||||||
|
jest.mock("@/store",()=>{return{};},{virtual:true});
|
||||||
|
|
||||||
describe("buttonQuestion.vue", () => {
|
describe("buttonQuestion.vue", () => {
|
||||||
it("Should show overflow classes on fieldset if isOverflowScrollable is true", () => {
|
it("Should show overflow classes on fieldset if isOverflowScrollable is true", () => {
|
||||||
|
|
@ -45,6 +48,65 @@ describe("buttonQuestion.vue", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Fieldset classes should contain ui-radio if button type is radio", () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(buttonQuestion, {
|
||||||
|
propsData: {
|
||||||
|
buttonType: "radio",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// Assert
|
||||||
|
const Div = wrapper.find('fieldset div');
|
||||||
|
expect(Div.classes()).toContain("ui-radio");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
// testing a computed property
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("getColLength should return '12' if prop isWide is set to true", () => {
|
||||||
|
// Act
|
||||||
|
const localThis = { isWide: true }
|
||||||
|
|
||||||
|
expect(buttonQuestion.computed.getColLength.call(localThis)).toBe("12");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("getColLength should return '' if prop isWide is set to false", () => {
|
||||||
|
// Act
|
||||||
|
const localThis = {
|
||||||
|
isWide: false,
|
||||||
|
answers: ['a', 'b']
|
||||||
|
}
|
||||||
|
|
||||||
|
expect(buttonQuestion.computed.getColLength.call(localThis)).toBe("");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Should return answer.Text if prop useTextForValue is true", async () => {
|
||||||
|
// Act
|
||||||
|
const localThis = { useTextForValue: true };
|
||||||
|
const answer = { 'Name': 'testName', 'Text': 'testText' };
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(buttonQuestion.methods.getValues.call(localThis, answer)).toBe('testText');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Should return answer.Name if prop useTextForValue is false and answer.Name exists", async () => {
|
||||||
|
// Act
|
||||||
|
const localThis = { useTextForValue: false };
|
||||||
|
const answer = { 'Name': 'testName', 'Text': 'testText' };
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(buttonQuestion.methods.getValues.call(localThis, answer)).toBe('testName');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe("buttonQuestion.vue", () => {
|
describe("buttonQuestion.vue", () => {
|
||||||
it("Should trigger event modelValue change to new value on when radio button selected", async () => {
|
it("Should trigger event modelValue change to new value on when radio button selected", async () => {
|
||||||
// Act
|
// Act
|
||||||
|
|
@ -76,3 +138,54 @@ describe("buttonQuestion.vue", () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Should add a value to this.selectedValues if prop isMultiSelect is true, checkValue is true and this.selectedValues already exists", () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(buttonQuestion, {
|
||||||
|
propsData: {
|
||||||
|
isMultiSelect: true,
|
||||||
|
modelValue: [ 'a', 'b' ]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const val = { checkValue: true, value: "2021", }
|
||||||
|
wrapper.vm.handleCheckedChanged(val);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.selectedValues).toEqual(["a", "b", "2021"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Should remove a value to this.selectedValues if prop isMultiSelect is true, checkValue is false and this.selectedValues already exists", () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(buttonQuestion, {
|
||||||
|
propsData: {
|
||||||
|
isMultiSelect: true,
|
||||||
|
modelValue: [ 'a', 'b' ]
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const val = { checkValue: false, value: "a", }
|
||||||
|
wrapper.vm.handleCheckedChanged(val);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.selectedValues).toEqual(["b"]);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
describe("buttonQuestion.vue", () => {
|
||||||
|
it("Should do nothing to this.selectedValues if this.selectedValues is not an array", () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(buttonQuestion, {
|
||||||
|
propsData: {
|
||||||
|
isMultiSelect: true,
|
||||||
|
modelValue: 'a',
|
||||||
|
}
|
||||||
|
});
|
||||||
|
const val = { checkValue: true, value: "c", }
|
||||||
|
wrapper.vm.handleCheckedChanged(val);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
expect(wrapper.vm.selectedValues).toEqual("a");
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
<span class="fs-5 fw-bold w-100" :class="this.buttonType === 'radio' ? 'text-start' : 'text-center'">{{ questionText }}</span>
|
<span class="fs-5 fw-bold w-100" :class="this.buttonType === 'radio' ? 'text-start' : 'text-center'">{{ questionText }}</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="getFieldSetClasses" :role="isMultiSelect ? 'group' : 'radiogroup'" :aria-labelledby="groupName ? groupName + '-radio-group' : ''">
|
<fieldset class="w-100" :aria-required=isRequired :class="getFieldSetClasses" :role="isMultiSelect ? 'group' : 'radiogroup'" :aria-labelledby="groupName ? groupName + '-radio-group' : ''">
|
||||||
<legend class="sr-only" :data-focus-target="groupName" tabindex="-1">
|
<legend class="sr-only" :data-focus-target="groupName" tabindex="-1">
|
||||||
{{(isMultiSelect && answers && answers.length > 1) ? 'Select one or more options below.' : 'Select an option below.' }}
|
{{(isMultiSelect && answers && answers.length > 1) ? 'Select one or more options below.' : 'Select an option below.' }}
|
||||||
</legend>
|
</legend>
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,7 @@
|
||||||
:answers="answersToDisplay"
|
:answers="answersToDisplay"
|
||||||
:groupName="groupName"
|
:groupName="groupName"
|
||||||
buttonType="listCard"
|
buttonType="listCard"
|
||||||
|
isRequired
|
||||||
v-model="selectedValues"
|
v-model="selectedValues"
|
||||||
validationRules="damage-location-required"
|
validationRules="damage-location-required"
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@
|
||||||
v-model="selectedValues"
|
v-model="selectedValues"
|
||||||
:validationRules="validationRules"
|
:validationRules="validationRules"
|
||||||
:suppressError="suppressError"
|
:suppressError="suppressError"
|
||||||
|
:isRequired=isRequired
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
|
@ -36,6 +37,7 @@ export default ({
|
||||||
validationRules: String,
|
validationRules: String,
|
||||||
suppressError: Boolean,
|
suppressError: Boolean,
|
||||||
cmsWidgetName: String,
|
cmsWidgetName: String,
|
||||||
|
isRequired: Boolean,
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
initializeComponent(replaceOptions){
|
initializeComponent(replaceOptions){
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@
|
||||||
buttonType="listCard"
|
buttonType="listCard"
|
||||||
v-model="selectedDoorSidesValues"
|
v-model="selectedDoorSidesValues"
|
||||||
validationRules="damage-side-required"
|
validationRules="damage-side-required"
|
||||||
|
isRequired
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
|
@ -22,6 +23,7 @@
|
||||||
filterByVehicleCategory
|
filterByVehicleCategory
|
||||||
v-model="selectedDriverSideReplaceOptionsValues"
|
v-model="selectedDriverSideReplaceOptionsValues"
|
||||||
validationRules="driver-side-options-required"
|
validationRules="driver-side-options-required"
|
||||||
|
isRequired
|
||||||
/>
|
/>
|
||||||
<replaceOptionsQuestion
|
<replaceOptionsQuestion
|
||||||
ref="passengerSideOptions"
|
ref="passengerSideOptions"
|
||||||
|
|
@ -32,6 +34,7 @@
|
||||||
filterByVehicleCategory
|
filterByVehicleCategory
|
||||||
v-model="selectedPassengerSideReplaceOptionsValues"
|
v-model="selectedPassengerSideReplaceOptionsValues"
|
||||||
validationRules="passenger-side-options-required"
|
validationRules="passenger-side-options-required"
|
||||||
|
isRequired
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
v-model="selectedRearReplaceOptions"
|
v-model="selectedRearReplaceOptions"
|
||||||
groupName="BackGlassReplaceOptionsQuestion"
|
groupName="BackGlassReplaceOptionsQuestion"
|
||||||
validationRules="replace-options-required"
|
validationRules="replace-options-required"
|
||||||
|
isRequired
|
||||||
/>
|
/>
|
||||||
<funnel-footer
|
<funnel-footer
|
||||||
cmsWidgetName="FunnelFooterWidget"
|
cmsWidgetName="FunnelFooterWidget"
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
useTextForValue
|
useTextForValue
|
||||||
v-model="selectedChipCountValues"
|
v-model="selectedChipCountValues"
|
||||||
:validationRules="validationRules"
|
:validationRules="validationRules"
|
||||||
|
isRequired
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,7 @@
|
||||||
v-model="selectedValues"
|
v-model="selectedValues"
|
||||||
:suppressError="suppressError"
|
:suppressError="suppressError"
|
||||||
:validationRules="validationRules"
|
:validationRules="validationRules"
|
||||||
|
isRequired
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</transition>
|
</transition>
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,7 @@
|
||||||
v-model="selectedWindshieldReplaceOptionsValues"
|
v-model="selectedWindshieldReplaceOptionsValues"
|
||||||
validationRules="windshield-replace-options-required|prevent-split-and-single-together"
|
validationRules="windshield-replace-options-required|prevent-split-and-single-together"
|
||||||
:suppressError="hasSplitSingleConflict"
|
:suppressError="hasSplitSingleConflict"
|
||||||
|
isRequired
|
||||||
/>
|
/>
|
||||||
<alert
|
<alert
|
||||||
class="my-3"
|
class="my-3"
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
selectingInitiatesLoad
|
selectingInitiatesLoad
|
||||||
:questionText="questionText"
|
:questionText="questionText"
|
||||||
:answers="makes"
|
:answers="makes"
|
||||||
groupName="Choose Vehicle Make"
|
groupName="ChooseVehicleMake"
|
||||||
textPosition="text-start"
|
textPosition="text-start"
|
||||||
v-model="selectedValueAsArray"
|
v-model="selectedValueAsArray"
|
||||||
isRequired=true
|
isRequired=true
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
selectingInitiatesLoad
|
selectingInitiatesLoad
|
||||||
:questionText="questionText"
|
:questionText="questionText"
|
||||||
:answers="models"
|
:answers="models"
|
||||||
groupName="Choose Vehicle Model"
|
groupName="ChooseVehicleModel"
|
||||||
textPosition="text-start"
|
textPosition="text-start"
|
||||||
v-model="selectedValueAsArray"
|
v-model="selectedValueAsArray"
|
||||||
isRequired=true
|
isRequired=true
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
selectingInitiatesLoad
|
selectingInitiatesLoad
|
||||||
:questionText="questionText"
|
:questionText="questionText"
|
||||||
:answers="styles"
|
:answers="styles"
|
||||||
groupName="Choose Vehicle Style"
|
groupName="ChooseVehicleStyle"
|
||||||
textPosition="text-start"
|
textPosition="text-start"
|
||||||
v-model="selectedValueAsArray"
|
v-model="selectedValueAsArray"
|
||||||
isRequired=true
|
isRequired=true
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
selectingInitiatesLoad
|
selectingInitiatesLoad
|
||||||
:questionText="questionText"
|
:questionText="questionText"
|
||||||
:answers="years"
|
:answers="years"
|
||||||
groupName="Choose Vehicle Year"
|
groupName="ChooseVehicleYear"
|
||||||
textPosition="text-start"
|
textPosition="text-start"
|
||||||
v-model="selectedValueAsArray"
|
v-model="selectedValueAsArray"
|
||||||
isRequired=true
|
isRequired=true
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@
|
||||||
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
|
<funnelSubHeader cmsWidgetName="FunnelSubHeaderWidget" />
|
||||||
<div class="row my-2">
|
<div class="row my-2">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<textboxQuestion cmsWidgetName="VinNumber" v-model="vin" inputId="vin" disableAutoFill validationRules="vin-required|vin-format" :isDisabled=isVinFieldReadOnly />
|
<textboxQuestion cmsWidgetName="VinNumber" v-model="vin" inputId="vin" isRequired disableAutoFill validationRules="vin-required|vin-format" :isDisabled=isVinFieldReadOnly />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row my-2">
|
<div class="row my-2">
|
||||||
|
|
@ -21,12 +21,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="row my-2">
|
<div class="row my-2">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<textboxQuestion cmsWidgetName="ServiceZIP" v-model="zip" inputId="zip" mask="#####" disableAutoFill validationRules="zip-required" />
|
<textboxQuestion cmsWidgetName="ServiceZIP" v-model="zip" inputId="zip" mask="#####" isRequired disableAutoFill validationRules="zip-required" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="row my-2">
|
<div class="row my-2">
|
||||||
<div class="col">
|
<div class="col">
|
||||||
<textboxQuestion cmsWidgetName="EmailAddress" v-model="email" inputId="email" disableAutoFill validationRules="email-address-required|email-address-format" />
|
<textboxQuestion cmsWidgetName="EmailAddress" v-model="email" inputId="email" isRequired disableAutoFill validationRules="email-address-required|email-address-format" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<alert
|
<alert
|
||||||
|
|
|
||||||
|
|
@ -75,7 +75,7 @@ html {
|
||||||
}
|
}
|
||||||
input:checked:focus {
|
input:checked:focus {
|
||||||
+ label {
|
+ label {
|
||||||
box-shadow: 0 0 0 1px $blue;
|
box-shadow: 0 0 0 2.5px $blue;
|
||||||
border-radius: .5rem;
|
border-radius: .5rem;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -100,7 +100,7 @@ describe("list-button-horizontal.vue", () => {
|
||||||
const label = wrapper.find("label");
|
const label = wrapper.find("label");
|
||||||
|
|
||||||
wrapper.vm.handleCheckChange = jest.fn();
|
wrapper.vm.handleCheckChange = jest.fn();
|
||||||
wrapper.vm.handleClick();
|
wrapper.vm.triggerButton();
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
|
|
@ -123,7 +123,7 @@ describe("list-button-horizontal.vue", () => {
|
||||||
const label = wrapper.find("label");
|
const label = wrapper.find("label");
|
||||||
|
|
||||||
wrapper.vm.handleCheckChange = jest.fn();
|
wrapper.vm.handleCheckChange = jest.fn();
|
||||||
wrapper.vm.handleClick();
|
wrapper.vm.triggerButton();
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
|
|
@ -146,7 +146,7 @@ describe("list-button-horizontal.vue", () => {
|
||||||
const label = wrapper.find("label");
|
const label = wrapper.find("label");
|
||||||
|
|
||||||
wrapper.vm.handleCheckChange = jest.fn();
|
wrapper.vm.handleCheckChange = jest.fn();
|
||||||
wrapper.vm.handleClick();
|
wrapper.vm.triggerButton();
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
|
|
@ -195,4 +195,54 @@ describe("list-button-horizontal.vue", () => {
|
||||||
// Assert
|
// Assert
|
||||||
expect(wrapper.componentVM.checkValue).toEqual("Car-Front");
|
expect(wrapper.componentVM.checkValue).toEqual("Car-Front");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should run handleCheckChange if selectingInitiatesLoad is false and handleInputChange is triggered", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listButtonHorizontal, {
|
||||||
|
propsData: {
|
||||||
|
selectingInitiatesLoad: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.handleInputChange();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleCheckChange).toBeCalled;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should do nothing if isMultiSelect is true and handleKeyupArrow is triggered", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listButtonHorizontal, {
|
||||||
|
propsData: {
|
||||||
|
isMultiSelect: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.handleKeyupArrow();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleKeyupArrow).toHaveReturned;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should run handleCheckChange if selectingInitiatesLoad is false and handleKeyupArrow is triggered", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listButtonHorizontal, {
|
||||||
|
propsData: {
|
||||||
|
selectingInitiatesLoad: false,
|
||||||
|
isMultiSelect: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.handleKeyupArrow();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleCheckChange).toBeCalled;
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,11 @@
|
||||||
<div
|
<div
|
||||||
class="list-group list-button-horizontal d-flex flex-column w-100 mb-2"
|
class="list-group list-button-horizontal d-flex flex-column w-100 mb-2"
|
||||||
:class="[(errors.length > 0 || hasError) ? 'has-error' : '']"
|
:class="[(errors.length > 0 || hasError) ? 'has-error' : '']"
|
||||||
@mouseup="handleClick(value)"
|
@keyup.space="triggerButton()"
|
||||||
@keyup.space="handleClick(value)"
|
@keyup.up="handleKeyupArrow()"
|
||||||
|
@keyup.down="handleKeyupArrow()"
|
||||||
|
@keyup.left="handleKeyupArrow()"
|
||||||
|
@keyup.right="handleKeyupArrow()"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
||||||
|
|
@ -12,13 +15,14 @@
|
||||||
:value="value"
|
:value="value"
|
||||||
:aria-required="isRequired"
|
:aria-required="isRequired"
|
||||||
v-model="checkValue"
|
v-model="checkValue"
|
||||||
@change="!selectingInitiatesLoad ? handleCheckChange() : ''"
|
@change="handleInputChange()"
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
:for="buttonID"
|
:for="buttonID"
|
||||||
:aria-labelledby="buttonID"
|
:aria-labelledby="buttonID"
|
||||||
class="d-flex flex-column justify-content-center py-3 px-4"
|
class="d-flex flex-column justify-content-center py-3 px-4"
|
||||||
|
@mouseup="triggerButton()"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="m-0"
|
class="m-0"
|
||||||
|
|
@ -31,13 +35,16 @@
|
||||||
class="m-0 small"
|
class="m-0 small"
|
||||||
:class="textPosition"
|
:class="textPosition"
|
||||||
>
|
>
|
||||||
{{buttonLabelSubCopy}}
|
{{ buttonLabelSubCopy }}
|
||||||
</span>
|
</span>
|
||||||
<span v-if="screenReaderOnlyText" class="sr-only">
|
<span
|
||||||
{{screenReaderOnlyText}}
|
v-if="screenReaderOnlyText"
|
||||||
|
class="sr-only"
|
||||||
|
>
|
||||||
|
{{ screenReaderOnlyText }}
|
||||||
</span>
|
</span>
|
||||||
<loader
|
<loader
|
||||||
v-if="isLoaderDisplayed && !isMultiSelect"
|
v-if="isLoaderDisplayed && selectingInitiatesLoad"
|
||||||
:class="[loaderColor, loaderPosition]"
|
:class="[loaderColor, loaderPosition]"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -77,27 +84,47 @@ export default {
|
||||||
checkValue: Boolean,
|
checkValue: Boolean,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created(){
|
created() {
|
||||||
if(Array.isArray(this.selectedValues)){
|
if (Array.isArray(this.selectedValues)) {
|
||||||
this.checkValue = this.isMultiSelect ? this.selectedValues.includes(this.value) : this.selectedValues[0];
|
this.checkValue = this.isMultiSelect
|
||||||
|
? this.selectedValues.includes(this.value)
|
||||||
|
: this.selectedValues[0];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
displayLoader() {
|
displayLoader() {
|
||||||
this.isLoaderDisplayed = true;
|
this.isLoaderDisplayed = true;
|
||||||
},
|
},
|
||||||
handleClick(value) {
|
handleInputChange() {
|
||||||
if(this.selectingInitiatesLoad) {
|
if(!this.selectingInitiatesLoad) {
|
||||||
this.displayLoader();
|
this.handleCheckChange();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleKeyupArrow() {
|
||||||
|
if (this.isMultiSelect) {
|
||||||
|
return; // Prevent arrow keys from doing anything if element is a checkbox
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.selectingInitiatesLoad) {
|
||||||
this.handleCheckChange();
|
this.handleCheckChange();
|
||||||
}
|
}
|
||||||
this.handleChange(value);
|
this.handleChange(this.value);
|
||||||
},
|
},
|
||||||
handleCheckChange(newValue, oldValue){
|
triggerButton() {
|
||||||
const isInitialization = typeof(oldValue) === 'function';
|
if(this.selectingInitiatesLoad) {
|
||||||
if (!isInitialization) {
|
this.displayLoader();
|
||||||
this.$emit('isCheckedChanged', { checkValue: this.checkValue, value: this.value.toString() });
|
this.handleCheckChange();
|
||||||
}
|
}
|
||||||
|
this.handleChange(this.value);
|
||||||
|
},
|
||||||
|
handleCheckChange() {
|
||||||
|
const emitEvent = {
|
||||||
|
checkValue: this.checkValue, // only read on checkboxes, on handleCheckedChanged on button-question
|
||||||
|
value: this.value.toString(),
|
||||||
|
buttonId: this.buttonID && this.buttonID.toString(),
|
||||||
|
};
|
||||||
|
this.$emit("isCheckedChanged", emitEvent);
|
||||||
|
this.$emit("update:modelValue", emitEvent);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -105,6 +132,7 @@ export default {
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const inputType = props.isMultiSelect ? "checkbox" : "radio";
|
const inputType = props.isMultiSelect ? "checkbox" : "radio";
|
||||||
|
|
||||||
const fieldOptions = {
|
const fieldOptions = {
|
||||||
type: inputType,
|
type: inputType,
|
||||||
checkedValue: props.value,
|
checkedValue: props.value,
|
||||||
|
|
@ -118,13 +146,11 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
checked,
|
|
||||||
handleChange,
|
handleChange,
|
||||||
errors,
|
errors,
|
||||||
} = useField(props.groupName, props.validationRules, fieldOptions);
|
} = useField(props.groupName, props.validationRules, fieldOptions);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
checked,
|
|
||||||
handleChange,
|
handleChange,
|
||||||
errors,
|
errors,
|
||||||
fieldOptions, // only need to expose this for unit test purposes
|
fieldOptions, // only need to expose this for unit test purposes
|
||||||
|
|
@ -137,10 +163,11 @@ export default {
|
||||||
.list-button-horizontal {
|
.list-button-horizontal {
|
||||||
input[type="radio"],
|
input[type="radio"],
|
||||||
input[type="checkbox"] {
|
input[type="checkbox"] {
|
||||||
|
position: absolute;
|
||||||
|
height: 0;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
width: 0;
|
width: 0;
|
||||||
height: 0;
|
|
||||||
position: absolute;
|
|
||||||
&:focus-visible + label {
|
&:focus-visible + label {
|
||||||
box-shadow: 0 0 0 2.5px $blue;
|
box-shadow: 0 0 0 2.5px $blue;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
|
|
|
||||||
|
|
@ -96,11 +96,8 @@ describe("list-button.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
||||||
const label = wrapper.find("label");
|
|
||||||
|
|
||||||
wrapper.vm.handleCheckChange = jest.fn();
|
wrapper.vm.handleCheckChange = jest.fn();
|
||||||
wrapper.vm.handleClick();
|
wrapper.vm.triggerButton();
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
|
|
@ -119,10 +116,8 @@ describe("list-button.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
||||||
const label = wrapper.find("label");
|
|
||||||
wrapper.vm.handleCheckChange = jest.fn();
|
wrapper.vm.handleCheckChange = jest.fn();
|
||||||
wrapper.vm.handleClick();
|
wrapper.vm.triggerButton();
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
const loader = wrapper.find("loader-stub");
|
const loader = wrapper.find("loader-stub");
|
||||||
|
|
@ -140,11 +135,8 @@ describe("list-button.vue", () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
|
|
||||||
const label = wrapper.find("label");
|
|
||||||
|
|
||||||
wrapper.vm.handleCheckChange = jest.fn();
|
wrapper.vm.handleCheckChange = jest.fn();
|
||||||
wrapper.vm.handleClick();
|
wrapper.vm.triggerButton();
|
||||||
|
|
||||||
await nextTick();
|
await nextTick();
|
||||||
|
|
||||||
|
|
@ -197,4 +189,53 @@ describe("list-button.vue", () => {
|
||||||
expect(wrapper.componentVM.checkValue).toEqual("Car-Front");
|
expect(wrapper.componentVM.checkValue).toEqual("Car-Front");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should run handleCheckChange if selectingInitiatesLoad is false and handleInputChange is triggered", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listButton, {
|
||||||
|
propsData: {
|
||||||
|
selectingInitiatesLoad: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.handleInputChange();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleCheckChange).toBeCalled;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should do nothing if isMultiSelect is true and handleKeyupArrow is triggered", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listButton, {
|
||||||
|
propsData: {
|
||||||
|
isMultiSelect: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.handleKeyupArrow();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleKeyupArrow).toHaveReturned;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should run handleCheckChange if selectingInitiatesLoad is false and handleKeyupArrow is triggered", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listButton, {
|
||||||
|
propsData: {
|
||||||
|
selectingInitiatesLoad: false,
|
||||||
|
isMultiSelect: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.handleKeyupArrow();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleCheckChange).toBeCalled;
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -2,8 +2,11 @@
|
||||||
<div
|
<div
|
||||||
class="list-group list-button d-flex flex-column w-100 mb-2"
|
class="list-group list-button d-flex flex-column w-100 mb-2"
|
||||||
:class="[(errors.length > 0 || hasError) ? 'has-error' : '']"
|
:class="[(errors.length > 0 || hasError) ? 'has-error' : '']"
|
||||||
@mouseup="handleClick(value)"
|
@keyup.space="triggerButton()"
|
||||||
@keyup.space="handleClick(value)"
|
@keyup.up="handleKeyupArrow()"
|
||||||
|
@keyup.down="handleKeyupArrow()"
|
||||||
|
@keyup.left="handleKeyupArrow()"
|
||||||
|
@keyup.right="handleKeyupArrow()"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
||||||
|
|
@ -12,13 +15,14 @@
|
||||||
:value="value"
|
:value="value"
|
||||||
:aria-required="isRequired"
|
:aria-required="isRequired"
|
||||||
v-model="checkValue"
|
v-model="checkValue"
|
||||||
@change="!selectingInitiatesLoad ? handleCheckChange() : ''"
|
@change="handleInputChange()"
|
||||||
>
|
>
|
||||||
<label
|
<label
|
||||||
tabindex="-1"
|
tabindex="-1"
|
||||||
:for="buttonID"
|
:for="buttonID"
|
||||||
:aria-labelledby="buttonID"
|
:aria-labelledby="buttonID"
|
||||||
class="d-flex flex-column justify-content-center py-3 px-4"
|
class="d-flex flex-column justify-content-center py-3 px-4"
|
||||||
|
@mouseup="triggerButton()"
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
class="m-0"
|
class="m-0"
|
||||||
|
|
@ -40,7 +44,7 @@
|
||||||
{{ screenReaderOnlyText }}
|
{{ screenReaderOnlyText }}
|
||||||
</span>
|
</span>
|
||||||
<loader
|
<loader
|
||||||
v-if="isLoaderDisplayed && !isMultiSelect"
|
v-if="isLoaderDisplayed && selectingInitiatesLoad"
|
||||||
:class="[this.loaderColor, this.loaderPosition]"
|
:class="[this.loaderColor, this.loaderPosition]"
|
||||||
/>
|
/>
|
||||||
</label>
|
</label>
|
||||||
|
|
@ -80,33 +84,47 @@ export default {
|
||||||
checkValue: Boolean,
|
checkValue: Boolean,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
created(){
|
created() {
|
||||||
if(Array.isArray(this.selectedValues)){
|
if (Array.isArray(this.selectedValues)) {
|
||||||
this.checkValue = this.isMultiSelect ? this.selectedValues.includes(this.value) : this.selectedValues[0];
|
this.checkValue = this.isMultiSelect
|
||||||
|
? this.selectedValues.includes(this.value)
|
||||||
|
: this.selectedValues[0];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
displayLoader() {
|
displayLoader() {
|
||||||
this.isLoaderDisplayed = true;
|
this.isLoaderDisplayed = true;
|
||||||
},
|
},
|
||||||
handleClick(value) {
|
handleInputChange() {
|
||||||
|
if(!this.selectingInitiatesLoad) {
|
||||||
|
this.handleCheckChange();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
handleKeyupArrow() {
|
||||||
|
if (this.isMultiSelect) {
|
||||||
|
return; // Prevent arrow keys from doing anything if element is a checkbox
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!this.selectingInitiatesLoad) {
|
||||||
|
this.handleCheckChange();
|
||||||
|
}
|
||||||
|
this.handleChange(this.value);
|
||||||
|
},
|
||||||
|
triggerButton() {
|
||||||
if(this.selectingInitiatesLoad) {
|
if(this.selectingInitiatesLoad) {
|
||||||
this.displayLoader();
|
this.displayLoader();
|
||||||
this.handleCheckChange();
|
this.handleCheckChange();
|
||||||
}
|
}
|
||||||
this.handleChange(value);
|
this.handleChange(this.value);
|
||||||
},
|
},
|
||||||
handleCheckChange(value, oldValue){
|
handleCheckChange() {
|
||||||
const isInitialization = typeof(oldValue) === 'function';
|
const emitEvent = {
|
||||||
if (!isInitialization) {
|
checkValue: this.checkValue, // only read on checkboxes, on handleCheckedChanged on button-question
|
||||||
const emitEvent = {
|
value: this.value.toString(),
|
||||||
checkValue: this.checkValue,
|
buttonId: this.buttonID && this.buttonID.toString(),
|
||||||
value: this.value.toString(),
|
};
|
||||||
buttonId: this.buttonID.toString(),
|
this.$emit("isCheckedChanged", emitEvent);
|
||||||
};
|
this.$emit("update:modelValue", emitEvent);
|
||||||
this.$emit('isCheckedChanged', emitEvent);
|
|
||||||
this.$emit("update:modelValue", emitEvent);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
|
|
@ -128,13 +146,11 @@ export default {
|
||||||
}
|
}
|
||||||
|
|
||||||
const {
|
const {
|
||||||
checked,
|
|
||||||
handleChange,
|
handleChange,
|
||||||
errors,
|
errors,
|
||||||
} = useField(props.groupName, props.validationRules, fieldOptions);
|
} = useField(props.groupName, props.validationRules, fieldOptions);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
checked,
|
|
||||||
handleChange,
|
handleChange,
|
||||||
errors,
|
errors,
|
||||||
fieldOptions, // only need to expose this for unit test purposes
|
fieldOptions, // only need to expose this for unit test purposes
|
||||||
|
|
@ -154,10 +170,10 @@ export default {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
|
|
||||||
&:focus-visible + label {
|
&:focus-visible + label {
|
||||||
box-shadow: 0 0 0 2.5px $blue inset;
|
box-shadow: 0 0 0 2.5px $blue;
|
||||||
}
|
}
|
||||||
&:focus + label {
|
&:focus + label {
|
||||||
box-shadow: 0 0 0 2.5px $blue inset;
|
box-shadow: 0 0 0 2.5px $blue;
|
||||||
}
|
}
|
||||||
&:checked + label {
|
&:checked + label {
|
||||||
color: $black;
|
color: $black;
|
||||||
|
|
@ -165,6 +181,9 @@ export default {
|
||||||
background: $blue-100;
|
background: $blue-100;
|
||||||
box-shadow: 0 0 0 1px $blue;
|
box-shadow: 0 0 0 1px $blue;
|
||||||
}
|
}
|
||||||
|
&:checked:focus + label {
|
||||||
|
box-shadow: 0 0 0 2.5px $blue;
|
||||||
|
}
|
||||||
&:checked + label p,
|
&:checked + label p,
|
||||||
&:checked + label span {
|
&:checked + label span {
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
import { shallowMount } from "@vue/test-utils";
|
import { shallowMount } from "@vue/test-utils";
|
||||||
import listCard from "./list-card";
|
import listCard from "./list-card";
|
||||||
|
import { nextTick } from "vue";
|
||||||
|
|
||||||
describe("list-card.vue", () => {
|
describe("list-card.vue", () => {
|
||||||
it("Should return input type checkbox if isMultiSelect is true", async () => {
|
it("Should return input type checkbox if isMultiSelect is true", async () => {
|
||||||
|
|
@ -18,7 +19,6 @@ describe("list-card.vue", () => {
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const input = wrapper.find("input");
|
const input = wrapper.find("input");
|
||||||
|
|
||||||
expect(input.attributes().type).toEqual("checkbox");
|
expect(input.attributes().type).toEqual("checkbox");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -38,7 +38,6 @@ describe("list-card.vue", () => {
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const paragraph = wrapper.find("p");
|
const paragraph = wrapper.find("p");
|
||||||
|
|
||||||
expect(paragraph.text()).toEqual("Windshield");
|
expect(paragraph.text()).toEqual("Windshield");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -59,7 +58,6 @@ describe("list-card.vue", () => {
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const paragraph = wrapper.find("p:nth-of-type(2)");
|
const paragraph = wrapper.find("p:nth-of-type(2)");
|
||||||
|
|
||||||
expect(paragraph.text()).toEqual("Test");
|
expect(paragraph.text()).toEqual("Test");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -80,7 +78,6 @@ describe("list-card.vue", () => {
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const label = wrapper.find("label");
|
const label = wrapper.find("label");
|
||||||
|
|
||||||
expect(label.attributes().for).toEqual("List Card Checkbox");
|
expect(label.attributes().for).toEqual("List Card Checkbox");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -101,7 +98,6 @@ describe("list-card.vue", () => {
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const input = wrapper.find("input");
|
const input = wrapper.find("input");
|
||||||
|
|
||||||
expect(input.attributes().name).toEqual("radio 1");
|
expect(input.attributes().name).toEqual("radio 1");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -122,7 +118,6 @@ describe("list-card.vue", () => {
|
||||||
|
|
||||||
// Assert
|
// Assert
|
||||||
const input = wrapper.find("input");
|
const input = wrapper.find("input");
|
||||||
|
|
||||||
expect(input.attributes()["aria-required"]).toEqual("true");
|
expect(input.attributes()["aria-required"]).toEqual("true");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
@ -247,5 +242,88 @@ describe("list-card.vue", () => {
|
||||||
expect(wrapper.vm.fieldOptions.initialValue).toEqual([ 'Windshield' ]);
|
expect(wrapper.vm.fieldOptions.initialValue).toEqual([ 'Windshield' ]);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it("Should run handleCheckChange if selectingInitiatesLoad is false and handleInputChange is triggered", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listCard, {
|
||||||
|
propsData: {
|
||||||
|
selectingInitiatesLoad: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.handleInputChange();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleCheckChange).toBeCalled;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should do nothing if isMultiSelect is true and handleKeyupArrow is triggered", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listCard, {
|
||||||
|
propsData: {
|
||||||
|
isMultiSelect: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.handleKeyupArrow();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleKeyupArrow).toHaveReturned;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should run handleCheckChange if selectingInitiatesLoad is false and handleKeyupArrow is triggered", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listCard, {
|
||||||
|
propsData: {
|
||||||
|
selectingInitiatesLoad: false,
|
||||||
|
isMultiSelect: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.handleKeyupArrow();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleCheckChange).toBeCalled;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should run handleChange if triggerButton is triggered", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listCard, {
|
||||||
|
propsData: {
|
||||||
|
selectingInitiatesLoad: false,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.triggerButton();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleChange).toBeCalled;
|
||||||
|
expect(wrapper.vm.handleCheckChange).not.toBeCalled;
|
||||||
|
expect(wrapper.vm.displayLoader).not.toBeCalled;
|
||||||
|
});
|
||||||
|
|
||||||
|
it("Should run handleCheckChange and displayLoader if triggerButton is triggered and seletingInitiatesLoad is true", async () => {
|
||||||
|
// Act
|
||||||
|
const wrapper = shallowMount(listCard, {
|
||||||
|
propsData: {
|
||||||
|
selectingInitiatesLoad: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
wrapper.vm.triggerButton();
|
||||||
|
|
||||||
|
await nextTick();
|
||||||
|
|
||||||
|
expect(wrapper.vm.handleCheckChange).toBeCalled;
|
||||||
|
expect(wrapper.vm.displayLoader).toBeCalled;
|
||||||
|
});
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,11 @@
|
||||||
isWide ? 'horizontal' : '',
|
isWide ? 'horizontal' : '',
|
||||||
(errors.length > 0 || hasError) ? 'has-error' : '',
|
(errors.length > 0 || hasError) ? 'has-error' : '',
|
||||||
]"
|
]"
|
||||||
@mouseup="handleChange(value)"
|
@keyup.space="triggerButton()"
|
||||||
@keyup.space="handleChange(value)"
|
@keyup.up="handleKeyupArrow()"
|
||||||
|
@keyup.down="handleKeyupArrow()"
|
||||||
|
@keyup.left="handleKeyupArrow()"
|
||||||
|
@keyup.right="handleKeyupArrow()"
|
||||||
>
|
>
|
||||||
<input
|
<input
|
||||||
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
:type="isMultiSelect ? 'checkbox' : 'radio'"
|
||||||
|
|
@ -16,13 +19,15 @@
|
||||||
:value="value"
|
:value="value"
|
||||||
:aria-required="isRequired"
|
:aria-required="isRequired"
|
||||||
v-model="checkValue"
|
v-model="checkValue"
|
||||||
@change="handleCheckChange(value)"
|
@change="handleInputChange()"
|
||||||
/>
|
/>
|
||||||
<label
|
<label
|
||||||
|
tabindex="-1"
|
||||||
:for="buttonID"
|
:for="buttonID"
|
||||||
|
:aria-labelledby="buttonID"
|
||||||
class="d-flex w-100 align-items-center px-2 h-100"
|
class="d-flex w-100 align-items-center px-2 h-100"
|
||||||
:class="getLabelClasses"
|
:class="getLabelClasses"
|
||||||
tabindex="-1"
|
@mouseup="triggerButton()"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
:id="buttonImageId"
|
:id="buttonImageId"
|
||||||
|
|
@ -93,15 +98,6 @@ export default {
|
||||||
: this.selectedValues[0];
|
: this.selectedValues[0];
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
watch: {
|
|
||||||
// Changing this will impact pre-selection data loads on vehicle-parts.
|
|
||||||
// If changed, please regression test that vehicle-parts data still loads correctly with previous selections.
|
|
||||||
modelValue(newVal) {
|
|
||||||
if (newVal !== undefined) {
|
|
||||||
this.checkValue = newVal.value;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
computed: {
|
computed: {
|
||||||
getLabelClasses() {
|
getLabelClasses() {
|
||||||
if (this.isWide) {
|
if (this.isWide) {
|
||||||
|
|
@ -116,16 +112,44 @@ export default {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
handleCheckChange(newValue, oldValue) {
|
handleInputChange() {
|
||||||
const isInitialization = typeof oldValue === "function";
|
if(!this.selectingInitiatesLoad) {
|
||||||
if (!isInitialization) {
|
this.handleCheckChange();
|
||||||
const emitEvent = {
|
}
|
||||||
checkValue: this.checkValue,
|
},
|
||||||
value: this.value.toString(),
|
handleKeyupArrow() {
|
||||||
buttonId: this.buttonID.toString(),
|
if (this.isMultiSelect) {
|
||||||
};
|
return; // Prevent arrow keys from doing anything if element is a checkbox
|
||||||
this.$emit("isCheckedChanged", emitEvent);
|
}
|
||||||
this.$emit("update:modelValue", emitEvent);
|
|
||||||
|
if(!this.selectingInitiatesLoad) {
|
||||||
|
this.handleCheckChange();
|
||||||
|
}
|
||||||
|
this.handleChange(this.value);
|
||||||
|
},
|
||||||
|
triggerButton() {
|
||||||
|
if(this.selectingInitiatesLoad) {
|
||||||
|
this.displayLoader();
|
||||||
|
this.handleCheckChange();
|
||||||
|
}
|
||||||
|
this.handleChange(this.value);
|
||||||
|
},
|
||||||
|
handleCheckChange() {
|
||||||
|
const emitEvent = {
|
||||||
|
checkValue: this.checkValue, // only read on checkboxes, on handleCheckedChanged on button-question
|
||||||
|
value: this.value.toString(),
|
||||||
|
buttonId: this.buttonID && this.buttonID.toString(),
|
||||||
|
};
|
||||||
|
this.$emit("isCheckedChanged", emitEvent);
|
||||||
|
this.$emit("update:modelValue", emitEvent);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
// Changing this will impact pre-selection data loads on vehicle-parts.
|
||||||
|
// If changed, please regression test that vehicle-parts data still loads correctly with previous selections.
|
||||||
|
modelValue(newVal) {
|
||||||
|
if (newVal !== undefined) {
|
||||||
|
this.checkValue = newVal.value;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -213,18 +237,17 @@ export default {
|
||||||
box-shadow: 0 0 0 1px $blue;
|
box-shadow: 0 0 0 1px $blue;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
&:focus-visible + label {
|
||||||
|
box-shadow: 0 0 0 2.5px $blue;
|
||||||
|
border-radius: 0.5rem;
|
||||||
|
}
|
||||||
&:focus + label {
|
&:focus + label {
|
||||||
box-shadow: 0 0 0 2.5px $blue;
|
box-shadow: 0 0 0 2.5px $blue;
|
||||||
border-radius: 0.5rem;
|
border-radius: 0.5rem;
|
||||||
}
|
}
|
||||||
|
&:checked:focus + label {
|
||||||
&:checked {
|
box-shadow: 0 0 0 2.5px $blue;
|
||||||
&:focus + label {
|
|
||||||
box-shadow: 0 0 0 2.5px $blue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
&:checked + label {
|
&:checked + label {
|
||||||
p {
|
p {
|
||||||
color: $black;
|
color: $black;
|
||||||
|
|
|
||||||
|
|
@ -56,19 +56,15 @@ export default {
|
||||||
handleClick(value) {
|
handleClick(value) {
|
||||||
this.handleChange(value);
|
this.handleChange(value);
|
||||||
},
|
},
|
||||||
handleCheckChange(newValue, oldValue) {
|
handleCheckChange() {
|
||||||
const isInitialization = typeof oldValue === "function";
|
const emitEvent = {
|
||||||
if (!isInitialization) {
|
checkValue: this.checkValue,
|
||||||
|
value: this.value.toString(),
|
||||||
|
buttonID: this.buttonID && this.buttonID.toString(),
|
||||||
|
};
|
||||||
|
|
||||||
const emitEvent = {
|
this.$emit("isCheckedChanged", emitEvent);
|
||||||
checkValue: this.checkValue,
|
this.$emit("update:modelValue", emitEvent);
|
||||||
value: this.value.toString(),
|
|
||||||
buttonID: this.buttonID.toString(),
|
|
||||||
};
|
|
||||||
|
|
||||||
this.$emit("isCheckedChanged", emitEvent);
|
|
||||||
this.$emit("update:modelValue", emitEvent);
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
setup(props) {
|
setup(props) {
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue