Input Switch v1.0
The <e-input-switch> component is a component that can be used for .
Usage
An e-input-switch has attributes that must be provided,
<e-input-switch
id=""
checked=""
inherit=""
required=""
/>
Attributes
id | Type: String | required
label | Type: String | Default:''
options | Type: Array | Default:selectOptions
Examples
Below a few interactive examples of e-input-switch can be found.
Default
<e-input-switch
id="inputSwitch"
checked=""
inherit=""
required=""
/>
Labelled, label='switchInput with Label'
<div class="input-example-field">
<e-input-label
:id="'inputSwitchWithLabel'"
:value="'switchInput with Label'"
/>
<e-input-switch
:id="'inputSwitchWithLabel'"
checked=""
inherit=""
required="false"
/>
</div>
Source Code
e-input-switch.vue
<script setup lang="ts">
import { computed, ref } from 'vue';
import { EInput_Switch } from 'types/e-input/interfaces/EInput_Switch';
export type Props = EInput_Switch;
const props = withDefaults(defineProps<Props>(), {
value: '',
label: '',
checked: false,
inherited: false,
required: false,
disabled: false,
meta: () => {
return {
disabled: false
};
}
});
const emit = defineEmits<{
(e: 'blur', event: FocusEvent): void;
(e: 'keyup.enter', event: KeyboardEvent): void;
(e: 'update:checked', value: boolean): void;
(e: 'update:value', value: string): void;
}>();
const input = ref<HTMLInputElement>();
const classes = computed(() => {
return {
inherited: props.inherited
};
});
const isChecked = computed(() => props.checked || props.value == 'true');
const isDisabled = computed(() => props.disabled ?? props.meta?.disabled);
function emitUpdate(event: InputEvent) {
const target = event.target as HTMLInputElement;
emit('update:checked', target.checked);
emit('update:value', `${target.checked}`);
}
</script>
<template>
<label class="e-input-switch">
<input
v-bind="$attrs"
:id="id"
ref="input"
class="input-switch"
:class="classes"
type="checkbox"
:checked="isChecked"
:disabled="isDisabled"
:required="required"
@change="emitUpdate"
/>
<span class="switch" />
</label>
</template>
<style scoped lang="scss">
$switch-container-width: 50px;
$switch-size: calc($switch-container-width / 2);
$e-switch-light-gray: #e2e8f0;
$e-switch-gray: #cbd5e0;
$e-switch-dark-gray: #a0aec0;
$e-switch-teal: #4fd1c5;
$e-switch-dark-teal: #319795;
.e-input-switch {
cursor: pointer;
display: flex;
align-items: center;
flex: 0 1 auto;
padding-left: 15px;
.switch {
/* Vertically center the inner circle */
display: flex;
align-items: center;
position: relative;
height: $switch-size;
flex-basis: $switch-container-width;
/* Make the container element rounded */
border-radius: $switch-size;
background-color: $e-switch-light-gray;
/* In case the label gets really long, the toggle shouldn't shrink. */
flex-shrink: 0;
transition: background-color 0.25s ease-in-out;
&::before {
content: '';
position: absolute;
/* Move a little bit the inner circle to the right */
left: 1px;
height: calc($switch-size - 4px);
width: calc($switch-size - 4px);
/* Make the inner circle fully rounded */
border-radius: 9999px;
background-color: var(--e-white);
border: 2px solid $e-switch-light-gray;
transition: transform 0.375s ease-in-out;
}
}
/* Visually hide the checkbox input */
.input-switch {
position: absolute;
width: 1px;
height: 1px;
padding: 0;
margin: -1px;
overflow: hidden;
clip: rect(0, 0, 0, 0);
white-space: nowrap;
border-width: 0;
&:checked {
+ .switch {
background-color: $e-switch-teal;
&::before {
border-color: $e-switch-teal;
/* Move the inner circle to the right */
transform: translateX(calc($switch-container-width - $switch-size));
}
}
}
&:hover,
&:focus-within {
+ .switch {
background-color: var(--e-input-focus-background);
&::before {
border-color: $e-switch-gray;
}
}
&:checked {
+ .switch::before {
border-color: $e-switch-dark-teal;
}
}
}
&:disabled {
+ .switch {
background-color: $e-switch-gray;
&::before {
background-color: $e-switch-dark-gray;
border-color: $e-switch-dark-gray;
}
}
&:checked {
+ .switch::before {
border-color: $e-switch-dark-gray;
}
}
}
&.inherited {
+ .switch {
&::before {
/* Move the inner circle to the right */
transform: translateX(calc(($switch-container-width * 0.5) - ($switch-size * 0.5)));
}
}
}
}
}
</style>