Skip to content
Snippets Groups Projects
Button.vue 3.17 KiB
Newer Older
<script setup lang="ts">
Дмитрий Малюгин's avatar
Дмитрий Малюгин committed
import { computed } from 'vue';
import { convertThemeToColorBlackDefault, convertThemeToColorWhiteDefault } from '@/app/helpers';
Дмитрий Малюгин's avatar
Дмитрий Малюгин committed
  label?: string;
  iconPos?: 'left' | 'top' | 'right' | 'bottom';
  textStyle?: 'bold' | 'italic';
  border?:
    | 'white'
    | 'slate'
    | 'blue'
    | 'sky'
    | 'teal'
    | 'green'
    | 'yellow'
    | 'orange'
    | 'pink'
    | 'fuchsia'
    | 'purple'
    | 'indigo'
    | 'rose'
    | 'red'
    | 'black';
  size?: 'small' | 'medium' | 'large' | 'extraLarge';
  textColor?:
    | 'white'
    | 'slate'
    | 'blue'
    | 'sky'
    | 'teal'
    | 'green'
    | 'yellow'
    | 'orange'
    | 'pink'
    | 'fuchsia'
    | 'purple'
    | 'indigo'
    | 'rose'
    | 'red'
    | 'black';
  theme?:
    | 'white'
    | 'slate'
    | 'blue'
    | 'sky'
    | 'teal'
    | 'green'
    | 'yellow'
    | 'orange'
    | 'pink'
    | 'fuchsia'
    | 'purple'
    | 'indigo'
    | 'rose'
    | 'red'
Дмитрий Малюгин's avatar
Дмитрий Малюгин committed
    | 'black';
Дмитрий Малюгин's avatar
Дмитрий Малюгин committed
const props = defineProps<Props>();
const themeColor = computed(() => convertThemeToColorWhiteDefault(props.theme));
const textColor = computed(() => convertThemeToColorBlackDefault(props.textColor));
const borderColor = computed(() =>
  props.border ? convertThemeToColorBlackDefault(props.border) : ''
);
const textSize = computed(() => {
  if (!props?.size || props.size === 'medium') return '16px';
  switch (props.size) {
    case 'small':
      return '12px';
    case 'large':
      return '20px';
    case 'extraLarge':
      return '24px';
Дмитрий Малюгин's avatar
Дмитрий Малюгин committed
});
const buttonPadding = computed(() => {
  if (!props?.size || props.size === 'medium') return '0.75rem 0.5rem';
  switch (props.size) {
    case 'small':
      return '0.5rem 0.375rem';
    case 'large':
      return '1.2rem 0.8rem';
    case 'extraLarge':
      return '1.8rem 1.2rem';
  }
Дмитрий Малюгин's avatar
Дмитрий Малюгин committed
});
</script>

<template>
  <button
    :class="[
      'button',
      {
        'flex-column': iconPos === 'top' || iconPos === 'bottom',
        border: borderColor
    :style="`padding: ${buttonPadding}`"
    <span :style="`background-color: ${themeColor}`" class="background"></span>
      :style="`color: ${textColor}; font-size: ${textSize}`"
          bold: textStyle === 'bold',
          italic: textStyle === 'italic'
      >{{ label ?? 'Button' }}</span
          'order-1': iconPos === 'left' || iconPos === 'top'
  </button>
</template>

<style scoped>
.button {
  position: relative;
  border-radius: 5px;
  display: flex;
  align-items: center;
  user-select: none;
}
.button:hover .background {
  filter: brightness(90%);
}
.background {
  width: 100%;
  height: 100%;
  position: absolute;
  z-index: -1;
  top: 0;
  left: 0;
  border-radius: 5px;
  transition: filter 0.2s ease-in-out;
}
.icon {
  display: flex;
  align-items: center;
  justify-content: center;
}
.flex-column {
  flex-direction: column;
}
}
.bold {
  font-weight: bold;
}
.italic {
  font-style: italic;
}
.border {
  border: 2px solid v-bind(borderColor);
}