# ZeenButtonSmall

Компонент маленькой кнопки

# Примеры:

  • Кнопка-ссылка

    Связаться с нами
    Связаться с нами
    Связаться с нами
  • Кнопка обычная

  • Disabled

  • Кнопка c кастомными цветами

  • Кнопка с шириной по контенту и по родителю

  • Лоадер в кнопке (нажми). На время работы лоадера кнопка становится неактивной, однако сохраняет изначальные цвета своей темы.

  • Кнопки c иконками

# props

Название Тип Обязательный По умолчанию Описание
href string - - ссылка
to string или object - - путь для router-link
theme string - fill-main fill-main - фон имеет главный цвет, а текст - дополнительный; fill-additional - фон имеет дополнительный цвет, а текст - главный; outline - фон прозрачный, текст и бордер имеют главный цвет
size string - contentWidth contentWidth - ширина кнопки определяется содержимым, parentWidth - шириной родителя
isLoading boolean - - состояние загрузки
disabled boolean - - если true кнопка становится disabled
color object - {} объект с кастомными цветами (подробнее см.ниже)

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

Название Тип Обязательный По умолчанию
buttonSmallMainColor главный цвет - берет значение из темы ($button-small-main-color)
buttonSmallAditionalColor дополнительный цвет - берет значение из темы ($button-small-additional-color)
buttonSmallHoverColor цвет для состояния ховера - берет значение из темы ($button-small-hover-color)
buttonSmallClickColor цвет для состояний focus и active - берет значение из темы ($button-small-click-color)

# Иконки

Компонент имеет 2 именованных слота для иконок - rightIcon и leftIcon.

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

<template>
  <component
    :is="getElement"
    :id="`zeen-button-small-${componentId}`"
    class="zeen-button-small"
    :class="{
      'zeen-button-small_fill-main': theme === 'fill-main',
      'zeen-button-small_fill-additional': theme === 'fill-additional',
      'zeen-button-small_outline': theme === 'outline',
      'zeen-button-small_parent-width': size === 'parentWidth',
      'zeen-button-small_is-loading': isLoading,
    }"
    :href="href"
    :to="to"
    :disabled="disabled || isLoading"
    v-on="$listeners"
    v-bind="$attrs"
  >
    <div class="zeen-button-small__content">
      <slot name="leftIcon"></slot>
      <slot></slot>
      <slot name="rightIcon"></slot>
    </div>
    <slot name="loading" v-if="isLoading">
      <div class="zeen-button-small__loader">{{ loadingText }}</div>
    </slot>
  </component>
</template>

<script>
export default {
  name: 'ZeenButtonSmall',
  props: {
    loadingText: {
      type: String,
      default: 'Загрузка...',
    },
    href: {
      type: String,
      default: null,
    },
    to: {
      validator: (prop) => typeof prop === 'object' || typeof prop === 'string',
      default: null,
    },
    theme: {
      type: String,
      default: 'fill-main',
      validator: (theme) => ['fill-main', 'fill-additional', 'outline'].includes(theme),
    },
    size: {
      type: String,
      default: 'contentWidth',
      validator: (size) => ['contentWidth', 'parentWidth'].includes(size),
    },
    isLoading: {
      type: Boolean,
      required: false,
    },
    disabled: {
      type: Boolean,
      required: false,
    },
    color: {
      type: Object,
      default: () => {
        return {}
      },
    },
  },
  computed: {
    componentId() {
      return this._uid
    },
    getElement() {
      if (this.href) {
        return 'a'
      } else if (this.to) {
        return 'router-link'
      }

      return 'button'
    },
  },
}
</script>

<style>
:root {
  /* Размеры */
  --button-small-font-size: var(--main-smallest-text);
  --button-small-padding-horizontal: 19px;
  --button-small-padding-vertical: 9px;
  --button-small-border-radius: var(--main-input-radius);
  --button-small-line-height: calc(var(--button-small-font-size) * 1.33);
  --button-border-width: var(--main-input-border-width);

  /* Цвета */
  --button-small-color: var(--main-light);
  --button-small-color-hover: var(--main-hover-color);
  --button-small-click-color: var(--main-active-color);
  --button-small-background: var(--main-color);
  --button-small-border-color: var(--main-color, transparent);
  --button-small-color-disable: var(--main-disable-text-color);
  --button-small-background-disable: var(--main-disable-color);
}
</style>

<style lang="scss" scoped>
@import '/src/styles/mixins.scss';

.zeen-button-small {
  --button-small-color-private: var(--button-small-color);
  --button-small-color-hover-private: var(--button-small-color-hover);
  --button-small-color-click-private: var(--button-small-click-color);
  --button-small-background-private: var(--button-small-background);
  --button-small-border-color-private: var(--button-small-border-color);

  position: relative;
  display: inline-flex;
  justify-content: center;
  align-items: center;
  padding: var(--button-small-padding-vertical) var(--button-small-padding-horizontal);
  border: var(--button-border-width) solid var(--button-small-border-color-private);
  box-sizing: border-box;
  border-radius: var(--button-small-border-radius);
  font-weight: 600;
  font-size: var(--button-small-font-size);
  line-height: var(--button-small-line-height);
  text-align: center;
  cursor: pointer;
  box-shadow: none;
  transition: background-color 0.25s ease, color 0.25s ease, opacity 0.25s ease;
  white-space: nowrap;
  text-decoration: none;
  font-family: inherit;

  color: var(--button-small-color-private);
  background: var(--button-small-background-private);

  &:focus,
  &:active,
  &:visited,
  &:hover {
    outline: none;
    text-decoration: none !important;
  }

  &_fill-main {
    &:hover {
      --button-small-background-private: var(--button-small-color-hover-private);
    }

    &:focus,
    &:active {
      --button-small-background-private: var(--button-small-color-click-private);
    }
  }

  &_fill-additional {
    background: transparent;
    --button-small-color-private: var(--button-small-background-private);
    border-color: transparent;

    &:focus,
    &:active {
      --button-small-color-private: var(--button-small-color-click-private);
    }
  }

  &_outline {
    background: transparent;
    --button-small-color-private: var(--button-small-background-private);
    --button-small-border-color-private: var(--button-small-color-private);

    &:hover {
      --button-small-color-private: var(--button-small-color-hover-private);
      --button-small-border-color-private: var(--button-small-color-hover-private);
    }

    &:focus,
    &:active {
      --button-small-color-private: var(--button-small-color-click-private);
      --button-small-border-color-private: var(--button-small-color-click-private);
    }
  }

  &:disabled,
  &:disabled:hover,
  &:disabled:focus {
    cursor: not-allowed;

    --button-small-color-private: var(--button-small-color-disable);
    --button-small-background-private: var(--button-small-background-disable);
    --button-small-border-color-private: var(--button-small-background-disable);
  }

  &_parent-width {
    width: 100%;
  }

  &_is-loading {
    .zeen-button__content {
      opacity: 0;
    }
  }

  &__content {
    display: flex;
    align-items: center;
    justify-content: center;
    gap: var(--button-small-gap);

    svg > * {
      stroke: var(--button-small-color);
    }
  }

  &__loader {
    display: flex;
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
  }
}

.btn-icon {
  width: 12px;
  height: 12px;

  &_left {
    margin-right: 10px;
  }

  &_right {
    margin-left: 10px;
  }
}
</style>