# ZeenCheckbox

Компонент checkbox input для форм

# Примеры:

  • Checkbox: false

  • Несколько связанных чекбоксов: []

  • Disabled не отмеченный: false

  • Disabled отмеченный: true

  • С ошибкой: false

  • Все верно: false

  • С кастомными цветами: работающий и disabled

# props

Название Тип Обязательный По умолчанию Описание
value any + - то, значение, которое хотим сохранять в data родителя
modelValue any + - сюда передается значение из v-model
label string - - label рядом с чекбоксом
disabled boolean - - если true, то чекбокс становится disabled
name string - -
hasError boolean - - если true, то добавляется класс zeen-checkbox_error
hasCorrect boolean - - если true, то добавляется класс zeen-checkbox_correct
color object - {} объект с кастомными цветами (подробнее см.ниже)

# Кастомные цвета в объекте color

Название Тип Обязательный По умолчанию
checkboxBackgroundColor цвет фона чекбокса - берет значение из темы ($input-background-color)
checkboxCheckedBackgroundColor цвет фона отмеченного чекбокса - берет значение из темы ($checkbox-checked-background-color)
checkboxDisabledBackgroundColor цвет фона неотмеченного чекбокса в состоянии disabled - берет значение из темы ($checkbox-disabled-background-color)
checkboxLabelColor цвет фона лейбла - берет значение из темы ($checkbox-label-color)
errorColor цвет лейбла и фона отмеченного чекбокса при hasError = true - берет значение из темы ($input-error-color)
correctColor цвет лейбла и фона отмеченного чекбокса при hasCorrect = true - берет значение из темы ($input-correct-color)

# Source Code - исходный код компонента

<template>
  <div
    :id="`zeen-checkbox-${componentId}`"
    class="zeen-checkbox"
    :class="{
      'zeen-checkbox_error': hasError,
      'zeen-checkbox_correct': hasCorrect,
    }"
  >
    <div class="zeen-checkbox__checkbox">
      <input
        class="zeen-checkbox__real"
        :value="value"
        :name="name"
        type="checkbox"
        v-model="model"
        :disabled="disabled"
        :id="componentId"
      />
      <span class="zeen-checkbox__pseudo">
        <span class="zeen-checkbox__pseudo-icon">
          <slot name="icon">
            <svg class="svg-icon" width="13" height="10" viewBox="0 0 13 10" xmlns="http://www.w3.org/2000/svg">
              <path
                d="M4.375 7.454 1.921 4.999A.709.709 0 1 0 .919 6.002l3.456 3.456 8-8a.706.706 0 0 0-.998-1L4.375 7.455z"
              />
            </svg>
          </slot>
        </span>
      </span>
    </div>
    <label class="zeen-checkbox__label" :for="componentId" v-html="label"></label>
  </div>
</template>

<script>
import componentIdSsr from '../../../mixins/componentIdSsr'

export default {
  name: 'ZeenCheckbox',
  mixins: [componentIdSsr],
  model: {
    prop: 'modelValue',
    event: 'change',
  },
  props: {
    value: {
      required: true,
    },
    modelValue: {
      required: true,
    },
    label: {
      type: String,
      required: false,
    },
    disabled: {
      type: Boolean,
      required: false,
    },
    name: {
      type: String,
      required: false,
    },
    hasError: {
      type: Boolean,
      required: false,
    },
    hasCorrect: {
      type: Boolean,
      required: false,
    },
  },
  computed: {
    model: {
      get() {
        return this.modelValue
      },
      set(val) {
        this.$emit('change', val)
      },
    },
  },
}
</script>

<style lang="scss">
:root {
  /* Размеры */
  --checkbox-size: 21px;
  --checkbox-label-size: var(--main-small-text);
  --checkbox-label-font-weight: normal;
  --checkbox-label-offset-left: 10px;
  --checkbox-border-radius: 5px;
  --checkbox-icon-width: 10px;
  --checkbox-icon-height: 10px;

  /* Цвета */
  --checkbox-background-color: #f00; //var(--input-background-color);
  --checkbox-label-color: var(--main-text-color);
  --checkbox-checked-background-color: var(--main-color);

  --checkbox-error-label-color: var(--main-danger-color);
  --checkbox-error-checked-background-color: var(--main-danger-color);

  --checkbox-correct-label-color: var(--main-success-color);
  --checkbox-correct-background-color: var(--main-success-color);

  --checkbox-disabled-background-color: var(--input-disable-color);
  --checkbox-icon-color: var(--main-light);
}
</style>

<style lang="scss" scoped>
.zeen-checkbox {
  display: flex;
  align-items: center;

  &_error {
    --checkbox-label-color: var(--checkbox-error-label-color);
    --checkbox-checked-background-color: var(--checkbox-error-checked-background-color);
  }

  &_correct {
    --checkbox-label-color: var(--checkbox-correct-label-color);
    --checkbox-checked-background-color: var(--checkbox-correct-background-color);
  }

  &__label {
    font-size: var(--checkbox-label-size);
    font-weight: var(--checkbox-label-font-weight);
    line-height: 1.4;
    color: var(--checkbox-label-color);
    padding: 0 0 0 var(--checkbox-label-offset-left);
    cursor: pointer;
  }

  &__pseudo {
    display: flex;
    align-items: center;
    justify-content: center;
    border-radius: var(--checkbox-border-radius);
    background: var(--checkbox-background-color);
  }

  &__pseudo-icon {
    display: none;
  }

  &__real {
    position: absolute;
    opacity: 0;
    margin: 0;
    cursor: pointer;

    &:disabled {
      cursor: auto;

      &,
      &:checked {
        --checkbox-checked-background-color: var(--checkbox-disabled-background-color);
      }
    }

    & + .zeen-checkbox__pseudo {
      transition: background-color 0.25s ease;
    }

    &:checked + .zeen-checkbox__pseudo {
      background-color: var(--checkbox-checked-background-color);

      & .zeen-checkbox__pseudo-icon {
        display: flex;
      }
    }
  }
}

.zeen-checkbox__real,
.zeen-checkbox__real:checked + .zeen-checkbox__pseudo,
.zeen-checkbox__pseudo {
  width: var(--checkbox-size);
  height: var(--checkbox-size);
}

.icon {
  width: var(--checkbox-icon-width);
  height: var(--checkbox-icon-height);
}

.svg-icon {
  fill: var(--checkbox-icon-color);
}
</style>