File size: 1,689 Bytes
4d70170
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
<script lang="ts">
import { computed, defineComponent, ref } from 'vue'
import { useDisabledChild } from '../composables/useDisabled'

export default defineComponent({
  name: 'VueSwitch',
  props: {
    icon: {
      type: String,
      default: null,
    },

    modelValue: {
      type: Boolean,
      required: true,
    },

    disabled: {
      type: Boolean,
      default: false,
    },
  },
  emits: ['update:modelValue'],
  setup(props, { emit }) {
    const focused = ref(false)
    const model = computed({
      get: () => props.modelValue,
      set: (value) => {
        emit('update:modelValue', value)
      },
    })

    const { finalDisabled } = useDisabledChild(props)

    const toggleValue = () => {
      if (finalDisabled.value) {
        return
      }
      model.value = !model.value
    }

    const toggleWithFocus = () => {
      focused.value = true
      toggleValue()
    }

    return {
      focused,
      model,
      finalDisabled,
      toggleValue,
      toggleWithFocus,
    }
  },
})
</script>

<template>
  <div
    class="vue-ui-switch"
    :class="{
      selected: model,
      disabled: finalDisabled,
      focus: focused,
    }"
    :tabindex="disabled ? -1 : 0"
    role="checkbox"
    :aria-disabled="disabled ? true : null"
    :aria-checked="!!model"
    @click="toggleValue"
    @keydown.enter="toggleWithFocus"
    @keydown.space="toggleWithFocus"
    @blur="focused = false"
  >
    <div class="content">
      <VueIcon
        v-if="icon"
        :icon="icon"
      />
      <span class="slot">
        <slot />
      </span>
      <div class="wrapper">
        <div class="bullet" />
      </div>
    </div>
  </div>
</template>