From 33b0cda2a034f1b2cf65b453fd90386edfb4e015 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Thu, 9 Oct 2025 13:12:53 -0700 Subject: [PATCH] add more table configuration - alternate row colors - row hover highlight - vertical borders - horizontal borders --- .../item-table-list-column.module.css | 24 +++++++- .../item-table-list-column.tsx | 30 ++++++---- .../item-table-list/item-table-list.tsx | 56 +++++++++---------- 3 files changed, 68 insertions(+), 42 deletions(-) diff --git a/src/renderer/components/item-list/item-table-list/item-table-list-column.module.css b/src/renderer/components/item-list/item-table-list/item-table-list-column.module.css index 3dedafff0..17f4a8d6a 100644 --- a/src/renderer/components/item-list/item-table-list/item-table-list-column.module.css +++ b/src/renderer/components/item-list/item-table-list/item-table-list-column.module.css @@ -41,12 +41,30 @@ padding: var(--theme-spacing-xs); } -.container.with-row-border { +.container.with-horizontal-border { border-bottom: 1px solid var(--theme-colors-border); } -.container.data-row.row-hover-enabled:hover::before, -.container.data-row.row-hover-enabled.row-hovered::before { +.container.with-vertical-border { + border-right: 1px solid var(--theme-colors-border); +} + +.container.alternate-row-even { + background-color: initial; +} + +.container.alternate-row-odd { + @mixin dark { + background-color: darken(var(--theme-colors-background), 30%); + } + + @mixin light { + background-color: darken(var(--theme-colors-background), 2%); + } +} + +.container.data-row.row-hover-highlight-enabled:hover::before, +.container.data-row.row-hover-highlight-enabled.row-hovered::before { position: absolute; top: 0; right: 0; diff --git a/src/renderer/components/item-list/item-table-list/item-table-list-column.tsx b/src/renderer/components/item-list/item-table-list/item-table-list-column.tsx index 851ce83cd..d5dab0527 100644 --- a/src/renderer/components/item-list/item-table-list/item-table-list-column.tsx +++ b/src/renderer/components/item-list/item-table-list/item-table-list-column.tsx @@ -154,7 +154,7 @@ export const TableColumnTextContainer = ( const dataIndex = isDataRow ? props.rowIndex - 1 : props.rowIndex; useEffect(() => { - if (!isDataRow || !containerRef.current || !props.enableRowHover) return; + if (!isDataRow || !containerRef.current) return; const container = containerRef.current; const rowIndex = props.rowIndex; @@ -178,19 +178,24 @@ export const TableColumnTextContainer = ( container.removeEventListener('mouseenter', handleMouseEnter); container.removeEventListener('mouseleave', handleMouseLeave); }; - }, [isDataRow, props.rowIndex, props.enableRowHover]); + }, [isDataRow, props.rowIndex, props.enableRowHoverHighlight]); return (
0, + [styles.rowHoverHighlightEnabled]: isDataRow && props.enableRowHoverHighlight, + [styles.withHorizontalBorder]: + props.enableHorizontalBorders && props.enableHeader && props.rowIndex > 0, + [styles.withVerticalBorder]: props.enableVerticalBorders, })} data-row-index={isDataRow ? props.rowIndex : undefined} ref={containerRef} @@ -223,7 +228,7 @@ export const TableColumnContainer = ( const dataIndex = isDataRow ? props.rowIndex - 1 : props.rowIndex; useEffect(() => { - if (!isDataRow || !containerRef.current || !props.enableRowHover) return; + if (!isDataRow || !containerRef.current) return; const container = containerRef.current; const rowIndex = props.rowIndex; @@ -247,19 +252,24 @@ export const TableColumnContainer = ( container.removeEventListener('mouseenter', handleMouseEnter); container.removeEventListener('mouseleave', handleMouseLeave); }; - }, [isDataRow, props.rowIndex, props.enableRowHover]); + }, [isDataRow, props.rowIndex, props.enableRowHoverHighlight]); return (
0, + [styles.rowHoverHighlightEnabled]: isDataRow && props.enableRowHoverHighlight, + [styles.withHorizontalBorder]: + props.enableHorizontalBorders && props.enableHeader && props.rowIndex > 0, + [styles.withVerticalBorder]: props.enableVerticalBorders, })} data-row-index={isDataRow ? props.rowIndex : undefined} ref={containerRef} diff --git a/src/renderer/components/item-list/item-table-list/item-table-list.tsx b/src/renderer/components/item-list/item-table-list/item-table-list.tsx index 06fbc9c7c..85e29914a 100644 --- a/src/renderer/components/item-list/item-table-list/item-table-list.tsx +++ b/src/renderer/components/item-list/item-table-list/item-table-list.tsx @@ -2,7 +2,7 @@ import { useMergedRef } from '@mantine/hooks'; import clsx from 'clsx'; -import { AnimatePresence, motion } from 'motion/react'; +import { AnimatePresence } from 'motion/react'; import { useOverlayScrollbars } from 'overlayscrollbars-react'; import { type JSXElementConstructor, @@ -24,18 +24,21 @@ import { ItemListStateActions, useItemListState, } from '/@/renderer/components/item-list/helpers/item-list-state'; -import { sortTableColumns } from '/@/renderer/components/item-list/helpers/sort-table-columns'; +import { parseTableColumns } from '/@/renderer/components/item-list/helpers/parse-table-columns'; import { ItemListHandle, ItemTableListColumnConfig } from '/@/renderer/components/item-list/types'; import { LibraryItem } from '/@/shared/types/domain-types'; export interface TableItemProps { columns: ItemTableListColumnConfig[]; data: unknown[]; + enableAlternateRowColors?: boolean; enableExpansion?: boolean; enableHeader?: boolean; - enableRowBorders?: boolean; - enableRowHover?: boolean; + enableHorizontalBorders?: boolean; + enableRowHoverHighlight?: boolean; enableSelection?: boolean; + enableVerticalBorders?: boolean; + getRowHeight: (index: number, cellProps: TableItemProps) => number; internalState: ItemListStateActions; itemType: LibraryItem; size?: 'compact' | 'default'; @@ -45,11 +48,13 @@ interface ItemTableListProps { CellComponent: JSXElementConstructor>; columns: ItemTableListColumnConfig[]; data: unknown[]; + enableAlternateRowColors?: boolean; enableExpansion?: boolean; enableHeader?: boolean; - enableRowBorders?: boolean; - enableRowHover?: boolean; + enableHorizontalBorders?: boolean; + enableRowHoverHighlight?: boolean; enableSelection?: boolean; + enableVerticalBorders?: boolean; headerHeight?: number; initialTop?: { behavior?: 'auto' | 'smooth'; @@ -74,11 +79,13 @@ export const ItemTableList = ({ CellComponent, columns, data, - enableExpansion = false, + enableAlternateRowColors = false, + enableExpansion = true, enableHeader = true, - enableRowBorders = false, - enableRowHover = false, - enableSelection = false, + enableHorizontalBorders = false, + enableRowHoverHighlight = true, + enableSelection = true, + enableVerticalBorders = false, headerHeight = 40, initialTop, itemType, @@ -92,7 +99,7 @@ export const ItemTableList = ({ size = 'default', }: ItemTableListProps) => { const totalItemCount = data.length; - const sortedColumns = useMemo(() => sortTableColumns(columns), [columns]); + const sortedColumns = useMemo(() => parseTableColumns(columns), [columns]); const columnCount = sortedColumns.length; const [centerContainerWidth, setCenterContainerWidth] = useState(0); @@ -130,7 +137,7 @@ export const ItemTableList = ({ sortedColumns.forEach((col, idx) => { if (col.pinned === null) { unpinnedIndices.push(idx); - if (col.autoWidth) { + if (col.autoSize) { autoUnpinnedIndices.push(idx); } } @@ -238,7 +245,6 @@ export const ItemTableList = ({ autoHideDelay: 500, pointers: ['mouse', 'pen', 'touch'], theme: 'feishin-os-scrollbar', - visibility: 'visible', }, }, }); @@ -521,7 +527,7 @@ export const ItemTableList = ({ const getRowHeight = useCallback( (index: number, cellProps: TableItemProps) => { - const height = size === 'compact' ? 40 : 68; + const height = size === 'compact' ? 40 : 64; const baseHeight = typeof rowHeight === 'number' ? rowHeight : rowHeight?.(index, cellProps) || height; @@ -653,11 +659,14 @@ export const ItemTableList = ({ const itemProps: TableItemProps = { columns: sortedColumns, data, + enableAlternateRowColors, enableExpansion, enableHeader, - enableRowBorders, - enableRowHover, + enableHorizontalBorders, + enableRowHoverHighlight, enableSelection, + enableVerticalBorders, + getRowHeight, internalState, itemType, size, @@ -704,18 +713,7 @@ export const ItemTableList = ({ }, [imperativeHandle]); return ( - +
)} - +
); };