Commit 8d1d03d1 authored by Дмитрий Малюгин's avatar Дмитрий Малюгин 🕓
Browse files

feat: init 'Carousel'

parent ebce247b
Loading
Loading
Loading
Loading
+10 −0
Original line number Diff line number Diff line
@@ -79,6 +79,16 @@ export interface IPaginatorProps {
  darknessTheme?: TDarkness;
}

export interface ICarouselProps {
  itemsProps: unknown[];
  width?: string;
  size?: TSize;
  perView?: number;
  perScroll?: number;
  theme?: TThemeColor;
  darknessTheme?: TDarkness;
}

export interface IMDProps {
  items: IMDItemProps[];
  size?: TSize;
+105 −0
Original line number Diff line number Diff line
import type { Meta, StoryObj } from '@storybook/vue3';

import Carousel from './Carousel.vue';

const meta: Meta = {
  title: 'Components/Carousel',
  component: Carousel,
  tags: ['pick'],
  parameters: {
    docs: {
      description: {
        component: 'A component to define number inputs with a dial.',
      },
    },
  },
  argTypes: {
    buttons: { control: 'boolean' },
    showLabel: { control: 'boolean' },
    colorAsTheme: { control: 'boolean' },
    textBold: { control: 'boolean' },
    min: { control: 'number' },
    max: { control: 'number' },
    step: { control: 'number' },
    fontSize: { control: 'text' },
    textBefore: { control: 'text' },
    textAfter: { control: 'text' },
    colorGaps: { control: 'object' },
    size: { control: 'select', options: ['small', 'normal', 'large', 'huge'] },
    background: { control: 'color' },
    darknessTheme: { control: 'select', options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'] },
    darknessNegativeTheme: {
      control: 'select',
      options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'],
    },
    darknessColor: { control: 'select', options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'] },
    theme: {
      control: 'select',
      options: [
        'white',
        'blue',
        'sky',
        'cyan',
        'teal',
        'green',
        'yellow',
        'orange',
        'pink',
        'fuchsia',
        'purple',
        'indigo',
        'rose',
        'red',
        'black',
      ],
    },
    negativeTheme: {
      control: 'select',
      options: [
        'white',
        'blue',
        'sky',
        'cyan',
        'teal',
        'green',
        'yellow',
        'orange',
        'pink',
        'fuchsia',
        'purple',
        'indigo',
        'rose',
        'red',
        'black',
      ],
    },
    color: {
      control: 'select',
      options: [
        'white',
        'blue',
        'sky',
        'cyan',
        'teal',
        'green',
        'yellow',
        'orange',
        'pink',
        'fuchsia',
        'purple',
        'indigo',
        'rose',
        'red',
        'black',
      ],
    },
  },
} satisfies Meta<typeof Carousel>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Simple: Story = {
  args: {},
};
+46 −0
Original line number Diff line number Diff line
<script setup lang="ts">
import type { ICarouselProps } from '@interfaces/componentsProps';
import CarouselArrowContainer from '@components/Carousel/CarouselArrowContainer.vue';
import { computed, ref } from 'vue';
import { convertThemeToColor, convertThemeToTextColor } from '@helpers/common';
import ArrowLeftShortIcon from '@icons/Mono/ArrowLeftShortIcon.vue';
import ArrowRightShortIcon from '@icons/Mono/ArrowRightShortIcon.vue';

const props = withDefaults(defineProps<ICarouselProps>(), {
  itemsProps: () => [],
  size: 'normal',
});

const current = ref(1);

const itemsLength = computed(() => Math.ceil(props.itemsProps.length / props.perView));
const color = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
const textColor = computed(() => convertThemeToTextColor(props.theme, props.darknessTheme));
const isStartDisabled = computed(() => current.value === 1);
const isEndDisabled = computed(() => current.value === itemsLength.value);
const iconSize = computed(() => {
  const size = props.size;
  if (size === 'normal') return '10';
  if (size === 'large') return '15';
  if (size === 'huge') return '18';
  return '7';
});
</script>

<template>
  <section :style="`width: ${width}; min-height: 100px`" class="carouselContainer">
    <CarouselArrowContainer :textColor="textColor" :color="color" :disable="isStartDisabled">
      <ArrowLeftShortIcon :color="isStartDisabled ? '#aaa' : textColor" :size="iconSize" />
    </CarouselArrowContainer>
    <slot />
    <CarouselArrowContainer :textColor="textColor" :color="color" :disable="isEndDisabled">
      <ArrowRightShortIcon :color="isEndDisabled ? '#aaa' : textColor" :size="iconSize" />
    </CarouselArrowContainer>
  </section>
</template>

<style scoped>
.carouselContainer {
  display: flex;
}
</style>
+86 −0
Original line number Diff line number Diff line
<script setup lang="ts">
defineProps<{
  disable?: boolean;
  textColor: string;
  color: string;
}>();
</script>

<template>
  <div class="arrowContainer">
    <div
      :class="[
        'icon',
        {
          disable,
        },
      ]"
    >
      <div
        :class="[
          'bg',
          {
            disableBg: disable,
          },
        ]"
      ></div>
      <slot />
    </div>
  </div>
</template>

<style scoped>
.arrowContainer {
  width: 50px;
  min-height: 100%;
  display: flex;
  justify-content: center;
  align-items: center;
}
.icon {
  position: relative;
  display: flex;
  justify-content: center;
  align-items: center;
  cursor: pointer;
  line-height: 1.2;
  color: v-bind(textColor);
}
.icon::before {
  content: '';
  position: absolute;
  width: 100%;
  height: 100%;
  border-radius: 50%;
  z-index: -1;
  background-color: v-bind(color);
}
.icon:hover > .bg {
  background-color: v-bind(textColor);
  opacity: 0.1;
}
.icon:active > .bg {
  opacity: 0.2;
}
.bg {
  width: 100%;
  height: 100%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  padding: 10px;
  z-index: 5;
  border-radius: 50%;
  background-color: transparent;
  opacity: 0;
  transition: all 0.2s ease;
}
.disable {
  cursor: auto;
  pointer-events: none;
}
.disableBg {
  background-color: white !important;
}
</style>