From b4bc1f79a9b7b4e442377dbfd8c3b528cc578a06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=94=D0=BC=D0=B8=D1=82=D1=80=D0=B8=D0=B9=20=D0=9C=D0=B0?= =?UTF-8?q?=D0=BB=D1=8E=D0=B3=D0=B8=D0=BD?= <d.malygin@iqdev.digital> Date: Wed, 22 Jan 2025 18:31:00 +0500 Subject: [PATCH] feat: add Checkbox to 'Table' and init others types of columns --- src/common/interfaces/componentsProp.ts | 17 +++++++- src/common/interfaces/componentsProps.ts | 2 + src/components/Table/Table.stories.ts | 25 ++++++++++-- src/components/Table/Table.vue | 50 +++++++++++++++++------- src/components/Table/helpers.ts | 15 ++++--- 5 files changed, 85 insertions(+), 24 deletions(-) diff --git a/src/common/interfaces/componentsProp.ts b/src/common/interfaces/componentsProp.ts index ae44f55..69d53ab 100644 --- a/src/common/interfaces/componentsProp.ts +++ b/src/common/interfaces/componentsProp.ts @@ -1,7 +1,15 @@ import type { TDarkness, TIcon, TPosition, TTextStyle, TThemeColor } from '@interfaces/common'; +import type { + ICheckboxProps, + IKnobProps, + IProgressBarProps, + IRatingProps, + ISelectProps, +} from '@interfaces/componentsProps'; export interface ITableColumn { name: string; + options?: ITableColumnOptions; type?: TTableColumnType; editable?: boolean; filterable?: boolean; @@ -11,10 +19,17 @@ export interface ITableColumn { } export interface ITableItem { - value: string; + value: string | boolean; editable?: boolean; } +export interface ITableColumnOptions + extends ICheckboxProps, + ISelectProps, + IRatingProps, + IProgressBarProps, + IKnobProps {} + export type TTableColumnType = | 'checkbox' | 'number' diff --git a/src/common/interfaces/componentsProps.ts b/src/common/interfaces/componentsProps.ts index 48ee7d8..9346010 100644 --- a/src/common/interfaces/componentsProps.ts +++ b/src/common/interfaces/componentsProps.ts @@ -160,6 +160,7 @@ export interface IPopupProps { export interface ISelectProps { options: ISelectOption[]; groups?: ISelectGroup[]; + selected?: string; width?: string; placeholder?: string; openIcon?: TIcon; @@ -255,6 +256,7 @@ export interface ITagProps { } export interface ICheckboxProps { + active?: boolean; label?: string; labelPos?: TPosition; name?: string; diff --git a/src/components/Table/Table.stories.ts b/src/components/Table/Table.stories.ts index ba0bc02..6513ad2 100644 --- a/src/components/Table/Table.stories.ts +++ b/src/components/Table/Table.stories.ts @@ -133,7 +133,6 @@ export const Full: Story = { type: 'number', sortable: true, filterable: true, - initSort: 'down', }, { name: 'Hobbies', @@ -146,7 +145,12 @@ export const Full: Story = { { name: 'Country', type: 'text', - initSort: 'none', + }, + { + name: 'Is gay', + type: 'checkbox', + sortable: true, + initSort: 'up', }, ], @@ -164,6 +168,9 @@ export const Full: Story = { { value: 'USA', }, + { + value: false, + }, ], [ { @@ -176,7 +183,10 @@ export const Full: Story = { value: 'Football', }, { - value: 'Canadaaaaaaaaaaaa', + value: 'USA', + }, + { + value: true, }, ], [ @@ -192,6 +202,9 @@ export const Full: Story = { { value: 'Russia', }, + { + value: false, + }, ], [ { @@ -206,6 +219,9 @@ export const Full: Story = { { value: 'Russia', }, + { + value: false, + }, ], [ { @@ -220,6 +236,9 @@ export const Full: Story = { { value: 'Russia', }, + { + value: false, + }, ], ], fontSize: '24px', diff --git a/src/components/Table/Table.vue b/src/components/Table/Table.vue index be0a5e2..edcef9f 100644 --- a/src/components/Table/Table.vue +++ b/src/components/Table/Table.vue @@ -5,6 +5,7 @@ import { convertThemeToColor, convertThemeToSecondaryColor, convertThemeToTextCo import type { ITableItem } from '@interfaces/componentsProp'; import { calcAdditionalHeight, calcGap, calcRows } from '@components/Table/helpers'; import TableHeader from '@components/Table/TableHeader.vue'; +import Checkbox from '@components/Checkbox/Checkbox.vue'; const props = withDefaults(defineProps<ITableProps>(), { size: 'normal', @@ -23,16 +24,12 @@ const isRegisterSensitive = ref<boolean>(false); watch(props.columns, () => (columns.value = props.columns)); +const columnToSortIndex = props.columns.findIndex((column) => column.initSort && column.initSort !== 'none'); +if (columnToSortIndex) sortStateActive.value = [columnToSortIndex, props.columns[columnToSortIndex].initSort]; + const initGap = computed(() => calcGap(props.gap ?? '5px', props.fontSize)); const additionalHeightFromSize = computed(() => calcAdditionalHeight(props.size, props.fontSize)); -const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); -const color = computed(() => - props.textColor - ? convertThemeToColor(props.textColor, props.darknessTextColor) - : convertThemeToTextColor(props.theme, props.darknessTheme), -); -const secondaryColor = computed<string>(() => convertThemeToSecondaryColor(props.theme, props.darknessTheme)); -const darkCellColor = computed(() => convertThemeToSecondaryColor(props.theme, String(+props.darknessTheme + 300))); +const types = computed(() => props.columns.map((column) => column.type)); // ['', 'up', 'none', '', 'none', ...] const sortState = computed<string[]>(() => { const result = []; @@ -53,9 +50,17 @@ const rows = computed<ITableItem[][]>(() => ), ); +const themeColor = computed(() => convertThemeToColor(props.theme, props.darknessTheme)); +const color = computed(() => + props.textColor + ? convertThemeToColor(props.textColor, props.darknessTextColor) + : convertThemeToTextColor(props.theme, props.darknessTheme), +); +const secondaryColor = computed<string>(() => convertThemeToSecondaryColor(props.theme, props.darknessTheme)); +const darkCellColor = computed(() => convertThemeToSecondaryColor(props.theme, String(+props.darknessTheme + 300))); + const changeColumnSortMode = (index: number) => { const cur = sortState.value[index]; - console.log(index, cur); const newValue = cur === 'none' ? 'down' : cur === 'down' ? 'up' : 'none'; if (cur === 'up') { sortStateActive.value = []; @@ -113,17 +118,24 @@ const cancelFilter = () => { /> </thead> <tbody> - <tr v-for="(row, index) of rows" :key="index"> + <tr v-for="(row, rowIndex) of rows" :key="rowIndex"> <td :class="{ leftBorder: showAllLines, - darkRow: stripedRows && index % 2, + darkRow: stripedRows && rowIndex % 2, }" - v-for="item of row" + v-for="(item, columnIndex) of row" :key="item.value" - :style="`padding: calc(${initGap} / 2 + ${additionalHeightFromSize}) ${initGap}; text-align: ${center ? 'center' : 'start'}`" + :style="`padding: calc(${initGap} / 2 + ${additionalHeightFromSize}) ${initGap}`" > - {{ item.value }} + <div :class="['cell', { cellCenter: center }]"> + <span v-if="~['text', 'number'].indexOf(types[columnIndex] ?? '')">{{ item.value }}</span> + <Checkbox + v-else-if="types[columnIndex] === 'checkbox'" + :active="item.value as boolean" + v-bind="columns[columnIndex].options" + /> + </div> </td> </tr> </tbody> @@ -154,6 +166,16 @@ tr::after { border-top: 1px solid v-bind(secondaryColor); border-right: 1px solid v-bind(secondaryColor); } +.cell { + display: inline-flex; + + width: 100%; + height: 100%; +} +.cellCenter { + justify-content: center; + align-items: center; +} .leftBorder { border-left: 1px solid v-bind(secondaryColor); } diff --git a/src/components/Table/helpers.ts b/src/components/Table/helpers.ts index 47e87a7..5a2fc8b 100644 --- a/src/components/Table/helpers.ts +++ b/src/components/Table/helpers.ts @@ -14,7 +14,6 @@ export const calcRows = ( // ['up', 'down', ...] let rows = [...initRows]; if (filterValue) { - console.log('oh...'); rows = rows.filter((row) => { const item = isRegisterSensitive ? row[indexColumnToFilter].value : row[indexColumnToFilter].value.toLowerCase(); return item.startsWith(isRegisterSensitive ? filterValue : filterValue.toLowerCase()); @@ -43,14 +42,18 @@ export const calcRows = ( } else { const index = sortStateActive[0]; const value = sortStateActive[1]; - console.log(value, index, columnToSortType); - if (columnToSortType === 'number') + if (~['text', 'select'].indexOf(columnToSortType)) + return rows.sort((a, b) => { + if (typeof a[index].value === 'string' && typeof b[index].value === 'string') + return value === 'down' + ? a[index].value.localeCompare(b[index].value) + : b[index].value.localeCompare(a[index].value); + return 0; + }); + if (~['number', 'checkbox', 'rating', 'progressBar', 'knob'].indexOf(columnToSortType)) return rows.sort((a, b) => value === 'down' ? +a[index].value - +b[index].value : +b[index].value - +a[index].value, ); - return rows.sort((a, b) => - value === 'down' ? a[index].value.localeCompare(b[index].value) : b[index].value.localeCompare(a[index].value), - ); } }; -- GitLab