[Vue] Checkbox

Checkbox.vue

<template>
<div class="checkbox" :class="[computedClass, color, size]" @change="inputChange()">
  <input 
    type="checkbox"
    :id="checkId"
    :name="nameVal"
    :disabled="disabled"
    v-model="inputModel"
  >
  <label :for="checkId" v-if="label">{{ label }}</label>
</div>
</template>

<script>
export default {
  props: {
    id: {type:String, default:''},
    name: {type:String, default:''},
    label: {type:String, default: ''},
    color: {type:String, default: 'primary'},
    size: {type:String, default: ''},
    checked: {type:Boolean, default: false},
    disabled: {type:Boolean, default: false}
  },
  data () {
    return {
      checkId: '',
      nameVal: '',
      inputModel: this.checked
    }
  },
  mounted () {
    if (this.id === '' || this.name === '') {
      this.checkId = 'check_' + Math.random().toString(9).substr(2,3)
      this.nameVal = this.checkId
    } else {
      this.checkId = this.id
      this.nameVal = this.name
    }
  },
  watch: {
    checked (newValue) {
      this.inputModel = newValue
    }
  },
  computed: {
    computedClass () {
      let computedClass = 'off'
      if (this.inputModel) computedClass = 'on'
      if (this.disabled) computedClass = 'disabled'
      return computedClass
    }
  },
  methods: {
    inputChange() {
      this.$emit('input', this.inputModel)
    }
  }
}
</script>

_checkbox.scss

@include palette();
@include regularSize(medium, 1.4);
@include regularSize(large, 1.8);

.checkbox, .checkbox-group {
  position: relative;
  &.on label:before {
    border: 0;
    content: '\e876';
    color: color(white);
    font-family: 'Material Icons';
    text-align: center;
  }

  input[type='checkbox']:checked + label:before {
    background-size: 70%;
  }
  
  &.disabled input, 
  &.disabled label,
  &.disabled label:before {
    cursor: not-allowed;
    color: color(gray100);
    border-color: color(gray100) !important;
  }

  input {
    background: transparent;
    appearance: none;
    width: $inputSize;
    height: $inputSize;
    position: absolute;
    outline: none;
    top: 0;
    left: 0;
    margin: 0;
    padding: 0;
    opacity: 0;
  }

  label {
    position: relative;
    display: inline-block;
    line-height: $inputSize;
    height: $inputSize;
    padding-left: calc(#{$inputSize + 5});
    margin-right: 20px;
    white-space: nowrap;
    cursor: pointer;

    &:before {
      content: '';
      cursor: pointer;
      display: block;
      position: absolute;
      top: 0;
      left: 0;
      width: $inputSize;
      height: $inputSize;
      @include borderSize(2px);
      border-style: solid;
      border-color: color(secondary);
      color: color(secondary);
      transition: 500ms;
      border-radius: 4px;
      box-sizing: border-box;
      background-size: 0;
      transition: all .2s ease;
    }
  }
}

.checkbox-group {
  &.space {margin: 2px 0;}

  input[type='checkbox']:checked + label:before {
    border: 0;
    content: '\e876';
    color: color(white);
    font-family: 'Material Icons';
    text-align: center;
  }

  &.disabled input, &.disabled label, &.disabled label:before {
    cursor: not-allowed;
    color: color(gray200);
    border-color: color(gray200);
  }
}

CheckList.vue

<template>
  <ul>
    <li>
      <v-checkbox v-for="item in items" :key="item.id" :id="item.id" :color="item.color" :label="item.label" :size="item.size" />
    </li>
  </ul>
</template>

<script>
import VCheckbox from '../components/Checkbox'
export default {
  components: {
    VCheckbox
  },
  data () {
    return {
      items: [
        {id:'chk01', label:'Checkbox1', color:'primary',  size:'medium'},
        {id:'chk02', label:'Checkbox2', color:'secondary',size:'medium'},
        {id:'chk03', label:'Checkbox3', color:'accent',   size:'medium'},
        {id:'chk04', label:'Checkbox4', color:'error',    size:'medium'},
        {id:'chk05', label:'Checkbox5', color:'info',     size:'medium'}
      ]
    }
  },
  methods: {
    clickCheckbox () {
      console.log('click')
    },
    callback () {
      console.log('checkAllClick!')
    }
  }
}
</script>