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

feat: start to do component 'Table'

parent 07695a3b
Loading
Loading
Loading
Loading
+212 −0
Original line number Diff line number Diff line
import type { Meta, StoryObj } from '@storybook/vue3';

import Table from './Table.vue';

const meta: Meta = {
  title: 'Components/Table',
  component: Table,
  tags: ['autodocs'],
  parameters: {
    docs: {
      description: {
        component: 'A component that is used as a Table. Can be used with icon.',
      },
    },
  },
  argTypes: {
    columns: { control: 'object' },
    data: { control: 'object' },
    size: { control: 'select', options: ['small', 'normal', 'large', 'huge'] },
    fontSize: { control: 'text' },
    gap: { control: 'text' },
    width: { control: 'text' },
    showAllLines: { control: 'boolean' },
    darknessTheme: { control: 'select', options: ['100', '200', '300', '400', '500', '600', '700', '800', '900'] },
    darknessTextColor: {
      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',
      ],
    },
    textColor: {
      control: 'select',
      options: [
        'white',
        'blue',
        'sky',
        'cyan',
        'teal',
        'green',
        'yellow',
        'orange',
        'pink',
        'fuchsia',
        'purple',
        'indigo',
        'rose',
        'red',
        'black',
      ],
    },
    border: {
      control: 'select',
      options: [
        'white',
        'blue',
        'sky',
        'cyan',
        'teal',
        'green',
        'yellow',
        'orange',
        'pink',
        'fuchsia',
        'purple',
        'indigo',
        'rose',
        'red',
        'black',
      ],
    },
  },
  args: {},
} satisfies Meta<typeof Table>;

export default meta;

type Story = StoryObj<typeof meta>;

export const Primary: Story = {
  args: {
    columns: [
      {
        name: 'Name',
        type: 'text',
      },
      {
        name: 'Age',
        type: 'text',
      },
      {
        name: 'Hobbies',
        type: 'text',
      },
    ],
    data: [
      [
        {
          value: 'Pete',
        },
        {
          value: '30',
        },
        {
          value: 'Chess',
        },
      ],
      [
        {
          value: 'John',
        },
        {
          value: '25',
        },
        {
          value: 'Football',
        },
      ],
    ],
  },
};

export const Full: Story = {
  args: {
    columns: [
      {
        name: 'Name',
        type: 'text',
      },
      {
        name: 'Age',
        type: 'text',
      },
      {
        name: 'Hobbies',
        type: 'text',
      },
      {
        name: 'Country',
        type: 'text',
      },
    ],

    data: [
      [
        {
          value: 'Pete',
        },
        {
          value: '30',
        },
        {
          value: 'Chess',
        },
        {
          value: 'USA',
        },
      ],
      [
        {
          value: 'John',
        },
        {
          value: '25',
        },
        {
          value: 'Football',
        },
        {
          value: 'Canada',
        },
      ],
      [
        {
          value: 'Дима',
        },
        {
          value: '22',
        },
        {
          value: 'Frontend',
        },
        {
          value: 'Russia',
        },
      ],
    ],

    fontSize: '32px',
    showAllLines: true,
    gap: '70px',
    border: 'fuchsia',
    theme: 'black',
  },
};
+98 −0
Original line number Diff line number Diff line
<script setup lang="ts">
import type { ITableProps } from '@interfaces/componentsProps';
import { computed } from 'vue';
import { convertThemeToColor, convertThemeToSecondaryColor, convertThemeToTextColor } from '@helpers/common';

const props = withDefaults(defineProps<ITableProps>(), {
  gap: '5px',
  theme: 'white',
  darknessTheme: 500,
  fontSize: '16px',
});
const gap = computed(() => props.gap);
// const emit = defineEmits(['']);
const data = defineModel('data');
// watch(, () => {});
const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
const color = computed(() =>
  props.textColor
    ? convertThemeToColor(props.textColor, props.darknessTextColor)
    : convertThemeToTextColor(props.theme, props.darknessTheme),
);
const borderColor = computed(() => convertThemeToSecondaryColor(props.theme, props.darknessTheme));
</script>

<template>
  <table
    :style="`background-color: ${themeColor}; color: ${color}`"
    :class="{
      tableLines: showAllLines,
    }"
  >
    <thead>
      <tr>
        <th
          :class="{
            leftBorder: showAllLines,
          }"
          v-for="column of columns"
          :key="column.name"
          class="columnHeader"
          style="padding: 5px 0 5px 5px"
        >
          <div class="columnFlex">
            {{ column.name }}
            <div></div>
          </div>
        </th>
      </tr>
    </thead>
    <tbody>
      <tr v-for="(row, index) of data" :key="index">
        <td
          :class="{
            leftBorder: showAllLines,
          }"
          v-for="item of row"
          :key="item.value"
          style="padding: 5px"
        >
          {{ item.value }}
        </td>
      </tr>
    </tbody>
  </table>
</template>

<style scoped>
table {
  border-collapse: collapse;
}
table * {
  font-size: v-bind(fontSize);
}
tr {
  position: relative;
}
tr::after {
  content: '';
  position: absolute;
  bottom: 0;
  left: 0;
  width: 100%;
  height: 1px;
  background-color: v-bind(borderColor);
}
.columnFlex {
  display: flex;
  gap: v-bind(gap);
  font-weight: bold;
}
.tableLines {
  border-top: 1px solid v-bind(borderColor);
  border-right: 1px solid v-bind(borderColor);
}
.leftBorder {
  border-left: 1px solid v-bind(borderColor);
}
</style>