From 72b2dca7594128e9d2d0fe480793b57a530656b8 Mon Sep 17 00:00:00 2001 From: jeffvli Date: Mon, 9 Feb 2026 10:08:25 -0800 Subject: [PATCH] add detail table header --- .../item-detail-list/item-detail.module.css | 74 +++++++++++++- .../item-detail-list/item-detail.tsx | 96 +++++++++++++++++-- .../item-table-list-column.tsx | 2 +- .../components/album-list-header-filters.tsx | 1 - 4 files changed, 162 insertions(+), 11 deletions(-) diff --git a/src/renderer/components/item-list/item-detail-list/item-detail.module.css b/src/renderer/components/item-list/item-detail-list/item-detail.module.css index a1e85f6c4..49cf02d3d 100644 --- a/src/renderer/components/item-list/item-detail-list/item-detail.module.css +++ b/src/renderer/components/item-list/item-detail-list/item-detail.module.css @@ -1,7 +1,9 @@ .container { position: relative; + flex: 1 1 auto; width: 100%; - height: 100%; + min-height: 0; + overflow: auto; } .placeholder { @@ -11,6 +13,76 @@ width: 100%; } +.wrapper { + display: flex; + flex-direction: column; + width: 100%; + height: 100%; + min-height: 0; +} + +.detail-list-header { + display: grid; + flex-shrink: 0; + grid-template-columns: 240px 1fr; + gap: var(--theme-spacing-md); + padding: 0 var(--theme-spacing-md); + font-size: var(--theme-font-size-sm); + color: var(--theme-colors-foreground-muted); + background-color: var(--theme-colors-background); + border-bottom: 1px solid var(--theme-colors-border); +} + +.header-left { + min-width: 0; +} + +.header-right { + min-width: 0; + overflow: hidden; +} + +.tracks-table-header { + display: flex; + flex-wrap: nowrap; + align-items: center; + width: 100%; + min-width: 0; +} + +.tracks-table-header-size-compact { + height: 32px; + min-height: 32px; +} + +.tracks-table-header-size-default { + height: 40px; + min-height: 40px; +} + +.tracks-table-header-size-large { + height: 48px; + min-height: 48px; +} + +.track-header-cell { + min-width: 0; + padding-right: var(--theme-spacing-sm); + padding-left: var(--theme-spacing-sm); + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.track-header-cell-no-h-padding { + padding-right: 0; + padding-left: 0; +} + +.track-header-cell-with-vertical-border { + border-right: 1px solid var(--theme-colors-border); +} + .row { display: grid; grid-template-columns: 240px 1fr; diff --git a/src/renderer/components/item-list/item-detail-list/item-detail.tsx b/src/renderer/components/item-list/item-detail-list/item-detail.tsx index f4195186a..c176501b0 100644 --- a/src/renderer/components/item-list/item-detail-list/item-detail.tsx +++ b/src/renderer/components/item-list/item-detail-list/item-detail.tsx @@ -40,6 +40,7 @@ import { SONG_TABLE_COLUMNS, } from '/@/renderer/components/item-list/item-table-list/default-columns'; import { useItemDragDropState } from '/@/renderer/components/item-list/item-table-list/hooks/use-item-drag-drop-state'; +import { columnLabelMap } from '/@/renderer/components/item-list/item-table-list/item-table-list-column'; import { ItemControls, ItemTableListColumnConfig } from '/@/renderer/components/item-list/types'; import { albumQueries } from '/@/renderer/features/albums/api/album-api'; import { @@ -60,6 +61,7 @@ import { ItemListKey, TableColumn } from '/@/shared/types/types'; interface ItemDetailListProps { currentPage?: number; data?: unknown[]; + enableHeader?: boolean; getItem?: (index: number) => unknown; internalState?: ItemListStateActions; itemCount?: number; @@ -601,9 +603,75 @@ const RowComponent = memo((props: RowComponentProps): ReactElement => { RowComponent.displayName = 'ItemDetailRow'; +interface DetailListHeaderProps { + columnWidthPercents: number[]; + enableVerticalBorders: boolean; + trackColumns: ItemTableListColumnConfig[]; + trackTableSize: 'compact' | 'default' | 'large'; +} + +const DetailListHeader = memo( + ({ + columnWidthPercents, + enableVerticalBorders, + trackColumns, + trackTableSize, + }: DetailListHeaderProps) => { + return ( +
+
+
+
+ {trackColumns.map((col, colIndex) => { + const percent = columnWidthPercents[colIndex] ?? 0; + const { fixedWidth, isFixedColumn } = getTrackColumnFixed(col.id); + const isLastColumn = colIndex === trackColumns.length - 1; + const style: React.CSSProperties = { + flex: isFixedColumn ? `0 0 ${fixedWidth}px` : `${percent} 1 0`, + minWidth: isFixedColumn ? fixedWidth : 0, + textAlign: + col.align === 'start' + ? 'left' + : col.align === 'end' + ? 'right' + : 'center', + }; + return ( +
+ {columnLabelMap[col.id] ?? ''} +
+ ); + })} +
+
+
+ ); + }, +); + +DetailListHeader.displayName = 'DetailListHeader'; + export const ItemDetailList = ({ currentPage, data, + enableHeader = true, getItem, itemCount: externalItemCount, items, @@ -785,14 +853,26 @@ export const ItemDetailList = ({ }, [initialize, osInstance]); return ( -
- ) => ReactElement} - rowCount={itemCount} - rowHeight={rowHeight} - rowProps={rowProps} - /> +
+ {enableHeader && ( + + )} +
+ ) => ReactElement + } + rowCount={itemCount} + rowHeight={rowHeight} + rowProps={rowProps} + /> +
); }; 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 86422b20f..54ca49524 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 @@ -885,7 +885,7 @@ export const TableColumnHeaderContainer = ( ); }; -const columnLabelMap: Record = { +export const columnLabelMap: Record = { [TableColumn.ACTIONS]: ( diff --git a/src/renderer/features/albums/components/album-list-header-filters.tsx b/src/renderer/features/albums/components/album-list-header-filters.tsx index 80fc18c78..c3b56dc2c 100644 --- a/src/renderer/features/albums/components/album-list-header-filters.tsx +++ b/src/renderer/features/albums/components/album-list-header-filters.tsx @@ -101,7 +101,6 @@ export const AlbumListHeaderFilters = ({ toggleGenreTarget }: { toggleGenreTarge listKey: ItemListKey.ALBUM_DETAIL, optionsConfig: { autoFitColumns: { hidden: true }, - enableHeader: { hidden: true }, }, tableColumnsData: SONG_TABLE_COLUMNS, }}