Skip to content
Snippets Groups Projects
Commit 40a7af53 authored by Дмитрий Малюгин's avatar Дмитрий Малюгин :clock4:
Browse files

feat: size for Table and fix filter

parent ce8f2f96
No related branches found
No related tags found
1 merge request!3Table (partially), Checkbox, Tag, Select and Knob
...@@ -24,6 +24,7 @@ export interface ITableProps { ...@@ -24,6 +24,7 @@ export interface ITableProps {
data: ITableItem[][]; data: ITableItem[][];
multipleSort?: boolean; multipleSort?: boolean;
gap?: string; gap?: string;
size?: TSize;
showAllLines?: boolean; showAllLines?: boolean;
stripedRows?: boolean; stripedRows?: boolean;
center?: boolean; center?: boolean;
......
...@@ -18,6 +18,7 @@ const meta: Meta = { ...@@ -18,6 +18,7 @@ const meta: Meta = {
data: { control: 'text' }, data: { control: 'text' },
fontSize: { control: 'text' }, fontSize: { control: 'text' },
gap: { control: 'text' }, gap: { control: 'text' },
size: { control: 'select', options: ['small', 'normal', 'large', 'huge'] },
showAllLines: { control: 'boolean' }, showAllLines: { control: 'boolean' },
stripedRows: { control: 'boolean' }, stripedRows: { control: 'boolean' },
center: { control: 'boolean' }, center: { control: 'boolean' },
...@@ -125,12 +126,14 @@ export const Full: Story = { ...@@ -125,12 +126,14 @@ export const Full: Story = {
name: 'Name', name: 'Name',
type: 'text', type: 'text',
sortable: true, sortable: true,
initSort: 'none',
}, },
{ {
name: 'Age', name: 'Age',
type: 'number', type: 'number',
sortable: true, sortable: true,
filterable: true, filterable: true,
initSort: 'down',
}, },
{ {
name: 'Hobbies', name: 'Hobbies',
...@@ -138,12 +141,15 @@ export const Full: Story = { ...@@ -138,12 +141,15 @@ export const Full: Story = {
padding: '30px', padding: '30px',
filterable: true, filterable: true,
sortable: true, sortable: true,
initSort: 'none',
}, },
{ {
name: 'Country', name: 'Country',
type: 'text', type: 'text',
initSort: 'none',
}, },
], ],
data: [ data: [
[ [
{ {
...@@ -216,12 +222,14 @@ export const Full: Story = { ...@@ -216,12 +222,14 @@ export const Full: Story = {
}, },
], ],
], ],
fontSize: '20px',
fontSize: '24px',
showAllLines: true, showAllLines: true,
border: 'fuchsia', border: 'fuchsia',
theme: 'black', theme: 'black',
stripedRows: true, stripedRows: true,
darknessTextColor: '500', darknessTextColor: '500',
center: true, center: true,
size: 'large',
}, },
}; };
...@@ -3,10 +3,11 @@ import type { ITableProps } from '@interfaces/componentsProps'; ...@@ -3,10 +3,11 @@ import type { ITableProps } from '@interfaces/componentsProps';
import { computed, ref, watch } from 'vue'; import { computed, ref, watch } from 'vue';
import { convertThemeToColor, convertThemeToSecondaryColor, convertThemeToTextColor } from '@helpers/common'; import { convertThemeToColor, convertThemeToSecondaryColor, convertThemeToTextColor } from '@helpers/common';
import type { ITableItem } from '@interfaces/componentsProp'; import type { ITableItem } from '@interfaces/componentsProp';
import { calcGap, calcRows } from '@stories/components/Table/helpers'; import { calcAdditionalHeight, calcGap, calcRows } from '@stories/components/Table/helpers';
import TableHeader from '@stories/components/Table/TableHeader.vue'; import TableHeader from '@stories/components/Table/TableHeader.vue';
const props = withDefaults(defineProps<ITableProps>(), { const props = withDefaults(defineProps<ITableProps>(), {
size: 'normal',
theme: 'white', theme: 'white',
darknessTheme: '500', darknessTheme: '500',
fontSize: '16px', fontSize: '16px',
...@@ -23,6 +24,7 @@ const isRegisterSensitive = ref<boolean>(false); ...@@ -23,6 +24,7 @@ const isRegisterSensitive = ref<boolean>(false);
watch(props.columns, () => (columns.value = props.columns)); watch(props.columns, () => (columns.value = props.columns));
const initGap = computed(() => calcGap(props.gap, props.fontSize)); const initGap = computed(() => calcGap(props.gap, props.fontSize));
const additionalHeightFromSize = computed(() => calcAdditionalHeight(props.size, props.fontSize));
const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme));
const color = computed(() => const color = computed(() =>
props.textColor props.textColor
...@@ -44,7 +46,8 @@ const rows = computed<ITableItem[][]>(() => ...@@ -44,7 +46,8 @@ const rows = computed<ITableItem[][]>(() =>
data.value!, data.value!,
sortStateActive.value, sortStateActive.value,
props.multipleSort, props.multipleSort,
props.columns[sortStateActive.value[0] ?? 0].type, columnToFilter.value,
props.columns[columnToFilter.value ?? 0].type,
filterValue.value, filterValue.value,
isRegisterSensitive.value, isRegisterSensitive.value,
), ),
...@@ -95,6 +98,7 @@ const cancelFilter = () => { ...@@ -95,6 +98,7 @@ const cancelFilter = () => {
:sortState="sortState" :sortState="sortState"
:columnToFilter="columnToFilter" :columnToFilter="columnToFilter"
:initGap="initGap" :initGap="initGap"
:additionalHeightFromSize="additionalHeightFromSize"
:theme="theme" :theme="theme"
:themeColor="themeColor" :themeColor="themeColor"
:secondaryColor="secondaryColor" :secondaryColor="secondaryColor"
...@@ -116,7 +120,7 @@ const cancelFilter = () => { ...@@ -116,7 +120,7 @@ const cancelFilter = () => {
}" }"
v-for="item of row" v-for="item of row"
:key="item.value" :key="item.value"
:style="`padding: calc(${initGap} / 2) ${initGap}; text-align: ${center ? 'center' : 'start'}`" :style="`padding: calc(${initGap} / 2 + ${additionalHeightFromSize}) ${initGap}; text-align: ${center ? 'center' : 'start'}`"
> >
{{ item.value }} {{ item.value }}
</td> </td>
......
...@@ -17,6 +17,7 @@ interface Props { ...@@ -17,6 +17,7 @@ interface Props {
sortState: string[]; sortState: string[];
columnToFilter: number; columnToFilter: number;
initGap: string; initGap: string;
additionalHeightFromSize: string;
theme: TThemeColor; theme: TThemeColor;
themeColor: string; themeColor: string;
secondaryColor: string; secondaryColor: string;
...@@ -54,7 +55,7 @@ const isColumnTypeText = computed(() => props.columns[props.columnToFilter].type ...@@ -54,7 +55,7 @@ const isColumnTypeText = computed(() => props.columns[props.columnToFilter].type
}" }"
v-for="(column, index) of columns" v-for="(column, index) of columns"
:key="column.name" :key="column.name"
:style="`padding: calc(${initGap} / 2) ${initGap}`" :style="`padding: calc(${initGap} / 2 + ${additionalHeightFromSize}) ${initGap}`"
> >
<div <div
:style="`justify-content: ${center ? 'center' : 'start'}; gap: ${center ? '0' : initGap}; padding: ${calcColumnPadding(column, center, initGap)}`" :style="`justify-content: ${center ? 'center' : 'start'}; gap: ${center ? '0' : initGap}; padding: ${calcColumnPadding(column, center, initGap)}`"
...@@ -67,7 +68,7 @@ const isColumnTypeText = computed(() => props.columns[props.columnToFilter].type ...@@ -67,7 +68,7 @@ const isColumnTypeText = computed(() => props.columns[props.columnToFilter].type
<button <button
v-if="column.sortable" v-if="column.sortable"
@click.prevent="emit('changeColumnSortMode', index)" @click.prevent="emit('changeColumnSortMode', index)"
style="min-width: 20px; min-height: 20px" :style="`min-width: ${fontSize}; min-height: ${fontSize}; max-height: ${fontSize}`"
> >
<SortVerticalIcon v-show="sortState[index] === 'none'" :color="color" :size="iconSize" /> <SortVerticalIcon v-show="sortState[index] === 'none'" :color="color" :size="iconSize" />
<SortDownIcon v-show="sortState[index] === 'down'" :color="color" :size="iconSize" /> <SortDownIcon v-show="sortState[index] === 'down'" :color="color" :size="iconSize" />
...@@ -77,7 +78,7 @@ const isColumnTypeText = computed(() => props.columns[props.columnToFilter].type ...@@ -77,7 +78,7 @@ const isColumnTypeText = computed(() => props.columns[props.columnToFilter].type
v-if="column.filterable" v-if="column.filterable"
@pointerdown="emit('setFilter', index)" @pointerdown="emit('setFilter', index)"
:id="`filter${index}`" :id="`filter${index}`"
style="position: relative" :style="`position: relative; width: ${fontSize}; max-height: ${fontSize}`"
> >
<FilterIcon :color="color" :size="iconSize" /> <FilterIcon :color="color" :size="iconSize" />
</button> </button>
......
import type { ITableColumn, ITableItem, TTableColumnType } from '@interfaces/componentsProp'; import type { ITableColumn, ITableItem, TTableColumnType } from '@interfaces/componentsProp';
import type { TSize } from '@interfaces/common';
export const calcRows = ( export const calcRows = (
initRows: ITableItem[][], initRows: ITableItem[][],
sortStateActive: [number, string] | [], sortStateActive: [number, string] | [],
multipleSort: boolean, multipleSort: boolean,
columnToFilter: number,
columnToFilterType: TTableColumnType, columnToFilterType: TTableColumnType,
filterValue: string, filterValue: string,
isRegisterSensitive: boolean, isRegisterSensitive: boolean,
) => { ) => {
// ['up', 'down', ...] // ['up', 'down', ...]
let rows = [...initRows]; let rows = [...initRows];
const sortIndex = sortStateActive[0];
if (filterValue && sortIndex) { if (filterValue) {
rows = rows.filter((row) => { rows = rows.filter((row) => {
const item = isRegisterSensitive ? row[sortIndex].value : row[sortIndex].value.toLowerCase(); const item = isRegisterSensitive ? row[columnToFilter].value : row[columnToFilter].value.toLowerCase();
return item.startsWith(isRegisterSensitive ? filterValue : filterValue.toLowerCase()); return item.startsWith(isRegisterSensitive ? filterValue : filterValue.toLowerCase());
}); });
} }
...@@ -41,6 +42,7 @@ export const calcRows = ( ...@@ -41,6 +42,7 @@ export const calcRows = (
} else { } else {
const index = sortStateActive[0]; const index = sortStateActive[0];
const value = sortStateActive[1]; const value = sortStateActive[1];
console.log('index, value, columnToFilterType:', index, value, columnToFilterType);
if (columnToFilterType === 'number') if (columnToFilterType === 'number')
return rows.sort((a, b) => return rows.sort((a, b) =>
value === 'down' ? +a[index].value - +b[index].value : +b[index].value - +a[index].value, value === 'down' ? +a[index].value - +b[index].value : +b[index].value - +a[index].value,
...@@ -59,5 +61,17 @@ export const calcGap = (gap: string, fontSize: string) => ...@@ -59,5 +61,17 @@ export const calcGap = (gap: string, fontSize: string) =>
? '10px' ? '10px'
: '15px'); : '15px');
export const calcAdditionalHeight = (size: TSize, fontSize: string) => {
if (size === 'normal') return '0px';
const isTwoLetters = isFinite(+fontSize.at(-3)!);
const value = isTwoLetters ? fontSize.slice(0, -2) : fontSize.slice(0, -3);
const unit = isTwoLetters ? fontSize.slice(-2) : fontSize.slice(-3);
if (size === 'large') return +value / 2 + unit;
if (size === 'huge') return value + unit;
return -+value / 4 + unit;
};
export const calcColumnPadding = (column: ITableColumn, center: boolean, gap: string) => export const calcColumnPadding = (column: ITableColumn, center: boolean, gap: string) =>
center ? `0px calc(${gap} / 2 + ${column.padding ?? '0px'} / 2)` : `0 ${column.padding ?? '0px'} 0 0`; center ? `0px calc(${gap} / 2 + ${column.padding ?? '0px'} / 2)` : `0 ${column.padding ?? '0px'} 0 0`;
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment