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

feat: 'Paginator' in process

parent 3e47e850
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -113,6 +113,8 @@ import StarIcon from '@icons/Mono/StarIcon.vue';
import StarFilledIcon from '@icons/Mono/StarFilledIcon.vue';
import ArrowLeftShortIcon from '@icons/Mono/ArrowLeftShortIcon.vue';
import ArrowDoubleLeftShortIcon from '@icons/Mono/ArrowDoubleLeftShortIcon.vue';
import ArrowRightShortIcon from '@icons/Mono/ArrowRightShortIcon.vue';
import ArrowDoubleRightShortIcon from '@icons/Mono/ArrowDoubleRightShortIcon.vue';

const gentleIcons = {
  Age18Icon,
@@ -129,6 +131,8 @@ const gentleIcons = {
  ArrowForwardIcon,
  ArrowLeftIcon,
  ArrowRightIcon,
  ArrowRightShortIcon,
  ArrowDoubleRightShortIcon,
  ArrowShortDownIcon,
  ArrowsVerticalIcon,
  AtIcon,
+4 −0
Original line number Diff line number Diff line
@@ -60,7 +60,11 @@ export interface IPaginatorProps {
  value?: number;
  total?: number;
  itemsPerPage?: number;
  itemsPerPageOptions?: number[];
  size?: TSize;
  fontSize?: string;
  theme?: TThemeColor;
  darknessTheme?: TDarkness;
}

export interface IMDProps {
+9 −33
Original line number Diff line number Diff line
@@ -15,22 +15,12 @@ const meta: Meta = {
  },
  argTypes: {
    value: { control: 'number' },
    max: { control: 'number' },
    width: { control: 'text' },
    height: { control: 'text' },
    labelBefore: { control: 'text' },
    labelAfter: { control: 'text' },
    showLabel: { control: 'boolean' },
    noBorder: { control: 'boolean' },
    total: { control: 'number' },
    itemsPerPage: { control: 'number' },
    itemsPerPageOptions: { control: 'object' },
    size: { control: 'select', options: ['small', 'normal', 'large', 'huge'] },
    fontSize: { control: 'text' },
    colorGaps: { control: 'object' },
    colorInactiveGaps: { control: 'object' },
    darknessTheme: { control: 'select', options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'] },
    darknessInactiveTheme: {
      control: 'select',
      options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'],
    },
    theme: {
      control: 'select',
      options: [
@@ -51,26 +41,6 @@ const meta: Meta = {
        'black',
      ],
    },
    inactiveTheme: {
      control: 'select',
      options: [
        'white',
        'blue',
        'sky',
        'cyan',
        'teal',
        'green',
        'yellow',
        'orange',
        'pink',
        'fuchsia',
        'purple',
        'indigo',
        'rose',
        'red',
        'black',
      ],
    },
  },
  args: {},
} satisfies Meta<typeof Paginator>;
@@ -82,3 +52,9 @@ type Story = StoryObj<typeof meta>;
export const Simple: Story = {
  args: {},
};

export const Full: Story = {
  args: {
    itemsPerPageOptions: ['10', '20', '30'],
  },
};
+55 −12
Original line number Diff line number Diff line
<script setup lang="ts">
import ArrowDoubleLeftShortIcon from '@icons/Mono/ArrowDoubleLeftShortIcon.vue';
import ArrowDoubleRightShortIcon from '@icons/Mono/ArrowDoubleRightShortIcon.vue';
import ArrowLeftShortIcon from '@icons/Mono/ArrowLeftShortIcon.vue';
import ArrowRightShortIcon from '@icons/Mono/ArrowRightShortIcon.vue';
import type { IPaginatorProps } from '@interfaces/componentsProps';
import PaginatorItem from '@components/Paginator/PaginatorItem.vue';
import { computed, ref } from 'vue';
import { computed, ref, type Ref } from 'vue';
import Select from '@components/Select/Select.vue';
import type { ISelectOption } from '@interfaces/componentsProp';

const props = withDefaults(defineProps<IPaginatorProps>(), {
  total: 10,
  size: 'normal',
  theme: 'black',
  darknessTheme: '500',
  itemsPerPage: 1,
});

const current = ref<number | undefined>(props.value);
const current = defineModel({
  default: 1,
}) as Ref<number>;

const perPage = ref(props.itemsPerPage);

const itemsLength = computed(() => Math.floor(props.total / perPage.value));
const selectOptions = computed(() =>
  !props.itemsPerPageOptions ? [{ value: '1' }] : props.itemsPerPageOptions.map((item) => ({ value: String(item) })),
) as unknown as ISelectOption[];
const isStartDisabled = computed(() => current.value === 1);
const isEndDisabled = computed(() => current.value === itemsLength.value);
const items = computed(() => {
  if (!current.value) return [1, 2, 3, 4, 5];
  const start = Math.floor(current.value / 5);
  return [start + 1, start + 2, start + 3, start + 4, start + 5];
  const center = current.value;
  const length = itemsLength.value;
  if (center - 2 < 2) return [1, 2, 3, 4, 5];
  if (center + 2 > length) return [length - 5, length - 4, length - 3, length - 1, length];
  return [center - 2, center - 1, center, center + 1, center + 2];
});
const iconSize = computed(() => {
  const size = props.size;
  if (size === 'normal') return '20';
  if (size === 'normal') return '10';
  if (size === 'large') return '25';
  if (size === 'huge') return '30';
  return '15';
});
const itemSize = computed(() => `${+iconSize.value * 1.5}px`);
const fontSize = computed(() => {
  const size = props.size;
  if (size === 'normal') return '16px';
  if (size === 'large') return '26px';
  if (size === 'huge') return '32px';
  return '36px';
});
const itemSize = computed(() => `${+iconSize.value * 2.5}px`);
</script>

<template>
  <section class="container">
    <PaginatorItem class="paginatorItem">
      <ArrowDoubleLeftShortIcon :size="iconSize" />
    <PaginatorItem @click="current = 1" :disable="isStartDisabled" class="paginatorItem">
      <ArrowDoubleLeftShortIcon :color="isStartDisabled ? '#aaa' : 'black'" :size="iconSize" />
    </PaginatorItem>
    <PaginatorItem class="paginatorItem">
      <ArrowLeftShortIcon :size="iconSize" />
    <PaginatorItem @click="current--" :disable="isStartDisabled" class="paginatorItem">
      <ArrowLeftShortIcon :color="isStartDisabled ? '#aaa' : 'black'" :size="iconSize" />
    </PaginatorItem>
    <PaginatorItem v-for="item of items" :key="item" class="paginatorItem">
      {{ item }}
    <PaginatorItem
      v-for="item of items"
      :key="item"
      @click="current = item"
      :active="current === item"
      class="paginatorItem"
    >
      <span class="digital">{{ item }}</span>
    </PaginatorItem>
    <PaginatorItem @click="isEndDisabled ? '' : current++" :disable="isEndDisabled" class="paginatorItem">
      <ArrowRightShortIcon :color="isEndDisabled ? '#aaa' : 'black'" :size="iconSize" />
    </PaginatorItem>
    <PaginatorItem @click="isEndDisabled ? '' : (current = total)" :disable="isEndDisabled" class="paginatorItem">
      <ArrowDoubleRightShortIcon :color="isEndDisabled ? '#aaa' : 'black'" :size="iconSize" />
    </PaginatorItem>
    <Select v-if="itemsPerPageOptions" v-model="perPage" :options="selectOptions"></Select>
  </section>
</template>

@@ -51,5 +89,10 @@ const itemSize = computed(() => `${+iconSize.value * 1.5}px`);
.paginatorItem {
  width: v-bind(itemSize);
  height: v-bind(itemSize);
  user-select: none;
}
.digital {
  font-size: v-bind(fontSize);
  font-weight: bold;
}
</style>
+44 −8
Original line number Diff line number Diff line
<script setup lang="ts"></script>
<script setup lang="ts">
defineProps<{
  active?: boolean;
  disable?: boolean;
}>();
</script>

<template>
  <div class="item">
    <div class="bg"></div>
  <div
    :class="[
      'item',
      {
        disable,
      },
    ]"
  >
    <div
      :class="[
        'bg',
        {
          active,
          disableBg: disable,
        },
      ]"
    ></div>
    <slot />
  </div>
</template>
@@ -14,25 +34,41 @@
  justify-content: center;
  align-items: center;
  cursor: pointer;
  line-height: 1.2;
}
.item:hover > .bg {
  opacity: 1;
}
.item:active > .bg {
  opacity: 1;
  background-color: rgba(0, 0, 0, 0.2) !important;
  background-color: rgba(0, 0, 0, 0.2);
}
.bg {
  width: 100%;
  height: 100%;
  width: 120%;
  height: 120%;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 2;
  padding: 10px;
  z-index: -1;
  border-radius: 50%;
  background-color: rgba(0, 0, 0, 0.1);
  opacity: 0;
  transition: all 0.15s ease;
  transition: all 0.2s ease;
}
.item > .active {
  background-color: black !important;
  opacity: 1;
}
.active + * {
  color: white;
}
.disable {
  cursor: auto;
  pointer-events: none;
}
.disableBg {
  background-color: white !important;
}
</style>
Loading