All files / lib/components form-checkbox.vue

41.67% Statements 15/36
25% Branches 9/36
61.54% Functions 8/13
41.67% Lines 15/36
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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 13218x 18x 18x   18x 18x                     18x       18x     18x         18x                                                                     1x           1x     1x                                                         1x   1x                             1x                          
<template>
    <label :class="button ? btnLabelClasses : labelClasses"
    I       :aria-pressed="button ? (isChecked ? 'true' : 'false') : null"
    >
        <inEput type="checkbox"
               :id="id || null"
               :name="name"
               :value="value"
               :disabled="disabled"
               :required="required"
               ref="check"
               autocomplete="off"
               :aria-required="required ? 'true' : null"
               :class="(custom && !button ) ? 'custom-control-input' : null"
               :checked="isChecked"
               @focusin.native="handleFocus"
               @focusout.native="handleFocus"
               @change="handleChange">
        <span v-if="custom && !button"
              class="custom-control-indicator"
              aria-hidden="true"
        ></span>
        <span :class="(custom && !button) ? 'custom-control-description' : null">
            <slot></slot>
        </span>
    </label>
</template>
 
<script>
import { formMixin, formCustomMixin, formCheckBoxMixin } from '../mixins';
import { arrayIncludes, isArray } from '../utils/array';
 
export default {
    mixins: [formMixin, formCustomMixin, formCheckBoxMixin],
    model: {
        prop: 'checked',
        event: 'change'
    },
    props: {
        value: {
            default: true
        },
        uncheckedValue: {
            default: false
        },
        checked: {
            default: true
        },
        indeterminate: {
            type: Boolean,
            default: false,
        },
        size: {
            type: String,
            default: null
        },
        button: {
            type: Boolean,
            default: false,
        },
        buttonVariant: {
            type: String,
            default: 'secondary',
        }
    },
    computed: {
        labelClasses() {
            return [
                this.size ? `form-control-${this.size}` : '',
                Ithis.custom ? 'custom-checkbox' : '',
                this.checkboxClass
            ];
        },
        btnLabelClasses() {
            return [
                'btn',
                `btn-${this.buttonVariant}`,
                this.size ? `btn-${this.size}` : '',
                this.isChecked ? 'active' : '',
                this.disabled ? 'disabled' : ''
            ];
        },
        isChecked() {
            if (isArray(this.checked)) {
                return arrayIncludes(this.checked, this.value);
            } else {
                return this.checked === this.value;
            }
        }
    },
    watch: {
        indeterminate(newVal, oldVal) {
            this.setIndeterminate(newVal);
        }
    },
    methods: {
        handleChange({ target: { checked } }) {
            if (isArray(this.checked)) {
                if (this.isChecked) {
                    this.$emit('change', this.checked.filter(x => x !== this.value));
                } else {
                    this.$emit('change', [...this.checked, this.value]);
                }
            } else {
                this.$emit('change', checked ? this.value : this.uncheckedValue)
            }
            this.$emit('update:indeterminate', this.$refs.check.indeterminate);
        },
        setIndeterminate(state) {
            this.$refs.check.indeterminate = state;
            // Emit update event to prop
            this.$emit('update:indeterminate', this.$refs.check.indeterminate);
        },
        handleFocus(evt) {
            // Add or remove 'focus' class on label in button mode
            if (this.button && evt.target === this.$refs.check) {
                if (evt.type === 'focusin') {
                    this.$el.classList.add('focus');
                } else if (evt.type === 'focusout') {
                    this.$el.classList.remove('focus');
                }
            }
        }
    },
    mounted() {
        // Set initial indeterminate state
        this.setIndeterminate(this.indeterminate);
    }
};
 
</script>