SSR-532 make label trigger radio button and display pointer on hover.

This commit is contained in:
Bryan Mauger 2023-06-16 14:28:14 -04:00
parent 3b2237ce74
commit 12b8c4a2d4

View file

@ -1,139 +1,144 @@
<template> <template>
<!-- Checkbox groups MUST be wrapped in a <fieldset> and <legend> tag and must contain tabindex --> <!-- Checkbox groups MUST be wrapped in a <fieldset> and <legend> tag and must contain tabindex -->
<div class="ui-radio form-check" :class="[(errors.length > 0 || hasError) ? 'has-error' : '']"> <div class="ui-radio form-check" :class="[(errors.length > 0 || hasError) ? 'has-error' : '']">
<input <label class="d-flex align-items-start form-check-label" :for="buttonID">
type="radio" <input
class="form-check-input" type="radio"
aria-checked="false" class="form-check-input"
:name="groupName" aria-checked="false"
:id="buttonID" :name="groupName"
:aria-required="isRequired" :id="buttonID"
:value="value" :aria-required="isRequired"
:v-model="checkValue" :value="value"
@change="handleCheckChange" :v-model="checkValue"
:checked="checkValue" @change="handleCheckChange"
:validationRules="validationRules" :checked="checkValue"
/> :validationRules="validationRules"
<label class="d-flex align-items-start form-check-label" :for="buttonID"> />
<p v-if="buttonLabel" class="m-0">{{ buttonLabel }}</p> <p v-if="buttonLabel" class="m-0">{{ buttonLabel }}</p>
<span v-if="screenReaderOnlyText" class="sr-only">{{ <span v-if="screenReaderOnlyText" class="sr-only">{{
screenReaderOnlyText screenReaderOnlyText
}}</span> }}</span>
</label> </label>
</div> </div>
</template> </template>
<script> <script>
import { useField } from "vee-validate"; import { useField } from "vee-validate";
export default { export default {
name: "radio", name: "radio",
props: { props: {
groupName: String, groupName: String,
buttonLabel: String, buttonLabel: String,
buttonID: String, buttonID: String,
isRequired: Boolean, isRequired: Boolean,
value: { value: {
type: [String, Number], type: [String, Number],
default: "", default: "",
}, },
screenReaderOnlyText: String, screenReaderOnlyText: String,
selectedValues: String, selectedValues: String,
hasError: Boolean, hasError: Boolean,
validationRules: String, validationRules: String,
valueToLogType: String, valueToLogType: String,
}, },
data() { data() {
return { return {
checkValue: Boolean, checkValue: Boolean,
}; };
}, },
created() { created() {
if (this.selectedValues) { if (this.selectedValues) {
this.checkValue = this.selectedValues === this.value; this.checkValue = this.selectedValues === this.value;
this.handleCheckChange(); this.handleCheckChange();
} else{ } else{
this.checkValue = false; this.checkValue = false;
} }
}, },
methods: { methods: {
handleCheckChange() { handleCheckChange() {
this.handleChange(this.value); this.handleChange(this.value);
const emitEvent = { const emitEvent = {
checkValue: this.checkValue, checkValue: this.checkValue,
value: this.value.toString(), value: this.value.toString(),
buttonID: this.buttonID && this.buttonID.toString(), buttonID: this.buttonID && this.buttonID.toString(),
}; };
this.$emit("isCheckedChanged", emitEvent); this.$emit("isCheckedChanged", emitEvent);
this.$emit("update:modelValue", emitEvent); this.$emit("update:modelValue", emitEvent);
}, },
}, },
setup(props) { setup(props) {
const inputType = "radio"; const inputType = "radio";
const { const {
value: inputValue, value: inputValue,
handleChange, handleChange,
errors, errors,
} = useField(props.groupName, props.validationRules, } = useField(props.groupName, props.validationRules,
{ {
type: inputType, type: inputType,
checkedValue: props.value, checkedValue: props.value,
}); });
return { return {
handleChange, handleChange,
errors, errors,
}; };
}, },
}; };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
.form-check { .form-check {
position: relative; position: relative;
.form-check-input { label {
border: 1px solid $gray-500; &:hover {
border-radius: 50%; cursor: pointer;
margin-right: 0.5rem; }
}
&:checked {
background-color: $white; .form-check-input {
background-size: 71%; border: 1px solid $gray-500;
background-position: center; border-radius: 50%;
border: 1px solid $blue; margin-right: 0.5rem;
background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 50' xml:space='preserve'%3e%3ccircle cx='25' cy='25' r='25' fill='%231574A1'/%3e%3c/svg%3e");
+ label { &:checked {
p { background-color: $white;
font-weight: 500; background-size: 71%;
font-size: .875rem; background-position: center;
color: $black; border: 1px solid $blue;
} background-image: url("data:image/svg+xml;charset=UTF-8,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 50 50' xml:space='preserve'%3e%3ccircle cx='25' cy='25' r='25' fill='%231574A1'/%3e%3c/svg%3e");
+ label {
p {
font-weight: 500;
font-size: .875rem;
color: $black;
}
}
}
&:focus {
box-shadow: 0 0 0 2.5px $blue;
}
&, & + label {
margin-top: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
}
&:hover {
.form-check-input {
box-shadow: 0 0 0 4px $blue-300;
}
}
p {
font-weight: 400;
font-size: .875rem;
color: $gray-600;
} }
}
&:focus {
box-shadow: 0 0 0 2.5px $blue;
}
&, & + label {
margin-top: 0;
position: absolute;
top: 50%;
transform: translateY(-50%);
}
} }
</style>
&:hover {
.form-check-input {
box-shadow: 0 0 0 4px $blue-300;
}
}
p {
font-weight: 400;
font-size: .875rem;
color: $gray-600;
}
}
</style>