Loading src/common/interfaces/componentsProp.ts +16 −1 Original line number Diff line number Diff line 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; Loading @@ -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' Loading src/common/interfaces/componentsProps.ts +2 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,7 @@ export interface IPopupProps { export interface ISelectProps { options: ISelectOption[]; groups?: ISelectGroup[]; selected?: string; width?: string; placeholder?: string; openIcon?: TIcon; Loading Loading @@ -255,6 +256,7 @@ export interface ITagProps { } export interface ICheckboxProps { active?: boolean; label?: string; labelPos?: TPosition; name?: string; Loading src/components/Table/Table.stories.ts +22 −3 Original line number Diff line number Diff line Loading @@ -133,7 +133,6 @@ export const Full: Story = { type: 'number', sortable: true, filterable: true, initSort: 'down', }, { name: 'Hobbies', Loading @@ -146,7 +145,12 @@ export const Full: Story = { { name: 'Country', type: 'text', initSort: 'none', }, { name: 'Is gay', type: 'checkbox', sortable: true, initSort: 'up', }, ], Loading @@ -164,6 +168,9 @@ export const Full: Story = { { value: 'USA', }, { value: false, }, ], [ { Loading @@ -176,7 +183,10 @@ export const Full: Story = { value: 'Football', }, { value: 'Canadaaaaaaaaaaaa', value: 'USA', }, { value: true, }, ], [ Loading @@ -192,6 +202,9 @@ export const Full: Story = { { value: 'Russia', }, { value: false, }, ], [ { Loading @@ -206,6 +219,9 @@ export const Full: Story = { { value: 'Russia', }, { value: false, }, ], [ { Loading @@ -220,6 +236,9 @@ export const Full: Story = { { value: 'Russia', }, { value: false, }, ], ], fontSize: '24px', Loading src/components/Table/Table.vue +36 −14 Original line number Diff line number Diff line Loading @@ -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', Loading @@ -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 = []; Loading @@ -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 = []; Loading Loading @@ -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> Loading Loading @@ -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); } Loading src/components/Table/helpers.ts +9 −6 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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), ); } }; Loading Loading
src/common/interfaces/componentsProp.ts +16 −1 Original line number Diff line number Diff line 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; Loading @@ -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' Loading
src/common/interfaces/componentsProps.ts +2 −0 Original line number Diff line number Diff line Loading @@ -160,6 +160,7 @@ export interface IPopupProps { export interface ISelectProps { options: ISelectOption[]; groups?: ISelectGroup[]; selected?: string; width?: string; placeholder?: string; openIcon?: TIcon; Loading Loading @@ -255,6 +256,7 @@ export interface ITagProps { } export interface ICheckboxProps { active?: boolean; label?: string; labelPos?: TPosition; name?: string; Loading
src/components/Table/Table.stories.ts +22 −3 Original line number Diff line number Diff line Loading @@ -133,7 +133,6 @@ export const Full: Story = { type: 'number', sortable: true, filterable: true, initSort: 'down', }, { name: 'Hobbies', Loading @@ -146,7 +145,12 @@ export const Full: Story = { { name: 'Country', type: 'text', initSort: 'none', }, { name: 'Is gay', type: 'checkbox', sortable: true, initSort: 'up', }, ], Loading @@ -164,6 +168,9 @@ export const Full: Story = { { value: 'USA', }, { value: false, }, ], [ { Loading @@ -176,7 +183,10 @@ export const Full: Story = { value: 'Football', }, { value: 'Canadaaaaaaaaaaaa', value: 'USA', }, { value: true, }, ], [ Loading @@ -192,6 +202,9 @@ export const Full: Story = { { value: 'Russia', }, { value: false, }, ], [ { Loading @@ -206,6 +219,9 @@ export const Full: Story = { { value: 'Russia', }, { value: false, }, ], [ { Loading @@ -220,6 +236,9 @@ export const Full: Story = { { value: 'Russia', }, { value: false, }, ], ], fontSize: '24px', Loading
src/components/Table/Table.vue +36 −14 Original line number Diff line number Diff line Loading @@ -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', Loading @@ -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 = []; Loading @@ -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 = []; Loading Loading @@ -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> Loading Loading @@ -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); } Loading
src/components/Table/helpers.ts +9 −6 Original line number Diff line number Diff line Loading @@ -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()); Loading Loading @@ -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), ); } }; Loading