mirror of https://github.com/rancher/dashboard.git
189 lines
3.5 KiB
Vue
189 lines
3.5 KiB
Vue
<script>
|
|
import { _VIEW } from '@/config/query-params';
|
|
export default {
|
|
props: {
|
|
// The name of the input, for grouping
|
|
name: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
|
|
// The value for this option
|
|
val: {
|
|
required: true,
|
|
validator: x => true,
|
|
},
|
|
|
|
// The selected value...
|
|
value: {
|
|
required: true,
|
|
validator: x => true,
|
|
},
|
|
|
|
// The label shown next to the radio
|
|
label: {
|
|
type: String,
|
|
default: ''
|
|
},
|
|
|
|
disabled: {
|
|
type: Boolean,
|
|
default: false
|
|
},
|
|
|
|
mode: {
|
|
type: String,
|
|
default: 'edit',
|
|
}
|
|
},
|
|
|
|
data() {
|
|
return { isChecked: this.value === this.val };
|
|
},
|
|
|
|
computed: {
|
|
isDisabled() {
|
|
return this.mode === _VIEW || this.disabled;
|
|
},
|
|
|
|
muteLabel() {
|
|
// Don't mute the label if the mode if view and the button is checked
|
|
return this.disabled && !(this.mode === _VIEW && this.isChecked);
|
|
}
|
|
},
|
|
|
|
watch: {
|
|
value(neu) {
|
|
this.isChecked = this.val === neu;
|
|
if ( this.isChecked ) {
|
|
this.$refs.custom.focus();
|
|
}
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
clicked(e) {
|
|
if (this.isDisabled) {
|
|
return;
|
|
}
|
|
|
|
if (e.srcElement?.tagName === 'A') {
|
|
return;
|
|
}
|
|
|
|
this.$emit('input', this.val);
|
|
},
|
|
}
|
|
};
|
|
</script>
|
|
|
|
<template>
|
|
<label
|
|
class="radio-container"
|
|
@keydown.enter="clicked($event)"
|
|
@keydown.space="clicked($event)"
|
|
@click.stop="clicked($event)"
|
|
>
|
|
<input
|
|
:id="_uid+'-radio'"
|
|
:disabled="isDisabled"
|
|
:name="name"
|
|
:value="''+val"
|
|
:checked="isChecked"
|
|
type="radio"
|
|
:tabindex="-1"
|
|
@click.stop.prevent
|
|
/>
|
|
<span
|
|
ref="custom"
|
|
:class="[ isDisabled ? 'text-muted' : '', 'radio-custom']"
|
|
:tabindex="isDisabled ? -1 : 0"
|
|
:aria-label="label"
|
|
:aria-checked="isChecked"
|
|
role="radio"
|
|
/>
|
|
<label
|
|
v-if="label"
|
|
:class="[ muteLabel ? 'text-muted' : '', 'radio-label']"
|
|
v-html="label"
|
|
>
|
|
<slot name="label">{{ label }}</slot>
|
|
</label>
|
|
</label>
|
|
</template>
|
|
|
|
<style lang='scss'>
|
|
.radio-view {
|
|
display: flex;
|
|
flex-direction: column;
|
|
LABEL {
|
|
color: var(--input-label)
|
|
}
|
|
}
|
|
|
|
.radio-group {
|
|
.text-label {
|
|
display: block;
|
|
padding-bottom: 5px;
|
|
}
|
|
}
|
|
|
|
.radio-container {
|
|
position: relative;
|
|
display: inline-flex;
|
|
align-items: center;
|
|
margin: 0;
|
|
cursor: pointer;
|
|
user-select: none;
|
|
border-radius: var(--border-radius);
|
|
padding-bottom: 5px;
|
|
|
|
.radio-label {
|
|
margin: 3px 10px 0px 5px;
|
|
}
|
|
|
|
.radio-custom {
|
|
height: 14px;
|
|
width: 14px;
|
|
min-height: 14px;
|
|
min-width: 14px;
|
|
background-color: var(--input-bg);
|
|
border-radius: 50%;
|
|
transition: all 0.3s ease-out;
|
|
border: 1.5px solid var(--border);
|
|
|
|
&:focus {
|
|
outline: none;
|
|
border-radius: 50%;
|
|
}
|
|
}
|
|
|
|
input {
|
|
display: none;
|
|
}
|
|
|
|
.radio-custom {
|
|
&[aria-checked="true"] {
|
|
background-color: var(--dropdown-text);
|
|
-webkit-transform: rotate(0deg) scale(1);
|
|
-ms-transform: rotate(0deg) scale(1);
|
|
transform: rotate(0deg) scale(1);
|
|
opacity:1;
|
|
border: 1.5px solid var(--dropdown-text);
|
|
|
|
// Ensure that checked radio buttons are greyed out when not enabled
|
|
&.text-muted {
|
|
background-color: var(--disabled-bg);
|
|
border-color: var(--disabled-bg);
|
|
}
|
|
}
|
|
}
|
|
|
|
input:disabled ~ .radio-custom:not([aria-checked="true"]) {
|
|
background-color: var(--disabled-bg);
|
|
opacity: .25;
|
|
}
|
|
}
|
|
|
|
</style>
|