mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-10 04:30:25 +02:00
add detail table header
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
.container {
|
.container {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
flex: 1 1 auto;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
min-height: 0;
|
||||||
|
overflow: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.placeholder {
|
.placeholder {
|
||||||
@@ -11,6 +13,76 @@
|
|||||||
width: 100%;
|
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 {
|
.row {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: 240px 1fr;
|
grid-template-columns: 240px 1fr;
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import {
|
|||||||
SONG_TABLE_COLUMNS,
|
SONG_TABLE_COLUMNS,
|
||||||
} from '/@/renderer/components/item-list/item-table-list/default-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 { 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 { ItemControls, ItemTableListColumnConfig } from '/@/renderer/components/item-list/types';
|
||||||
import { albumQueries } from '/@/renderer/features/albums/api/album-api';
|
import { albumQueries } from '/@/renderer/features/albums/api/album-api';
|
||||||
import {
|
import {
|
||||||
@@ -60,6 +61,7 @@ import { ItemListKey, TableColumn } from '/@/shared/types/types';
|
|||||||
interface ItemDetailListProps {
|
interface ItemDetailListProps {
|
||||||
currentPage?: number;
|
currentPage?: number;
|
||||||
data?: unknown[];
|
data?: unknown[];
|
||||||
|
enableHeader?: boolean;
|
||||||
getItem?: (index: number) => unknown;
|
getItem?: (index: number) => unknown;
|
||||||
internalState?: ItemListStateActions;
|
internalState?: ItemListStateActions;
|
||||||
itemCount?: number;
|
itemCount?: number;
|
||||||
@@ -601,9 +603,75 @@ const RowComponent = memo((props: RowComponentProps<RowData>): ReactElement => {
|
|||||||
|
|
||||||
RowComponent.displayName = 'ItemDetailRow';
|
RowComponent.displayName = 'ItemDetailRow';
|
||||||
|
|
||||||
|
interface DetailListHeaderProps {
|
||||||
|
columnWidthPercents: number[];
|
||||||
|
enableVerticalBorders: boolean;
|
||||||
|
trackColumns: ItemTableListColumnConfig[];
|
||||||
|
trackTableSize: 'compact' | 'default' | 'large';
|
||||||
|
}
|
||||||
|
|
||||||
|
const DetailListHeader = memo(
|
||||||
|
({
|
||||||
|
columnWidthPercents,
|
||||||
|
enableVerticalBorders,
|
||||||
|
trackColumns,
|
||||||
|
trackTableSize,
|
||||||
|
}: DetailListHeaderProps) => {
|
||||||
|
return (
|
||||||
|
<header className={styles.detailListHeader} role="rowgroup">
|
||||||
|
<div aria-hidden className={styles.headerLeft} />
|
||||||
|
<div className={styles.headerRight}>
|
||||||
|
<div
|
||||||
|
className={clsx(styles.tracksTableHeader, {
|
||||||
|
[styles.tracksTableHeaderSizeCompact]: trackTableSize === 'compact',
|
||||||
|
[styles.tracksTableHeaderSizeDefault]: trackTableSize === 'default',
|
||||||
|
[styles.tracksTableHeaderSizeLarge]: trackTableSize === 'large',
|
||||||
|
})}
|
||||||
|
role="row"
|
||||||
|
>
|
||||||
|
{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 (
|
||||||
|
<div
|
||||||
|
className={clsx(styles.trackHeaderCell, {
|
||||||
|
[styles.trackHeaderCellNoHPadding]:
|
||||||
|
isNoHorizontalPaddingColumn(col.id),
|
||||||
|
[styles.trackHeaderCellWithVerticalBorder]:
|
||||||
|
enableVerticalBorders && !isLastColumn,
|
||||||
|
})}
|
||||||
|
key={col.id}
|
||||||
|
role="columnheader"
|
||||||
|
style={style}
|
||||||
|
>
|
||||||
|
{columnLabelMap[col.id] ?? ''}
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</header>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
DetailListHeader.displayName = 'DetailListHeader';
|
||||||
|
|
||||||
export const ItemDetailList = ({
|
export const ItemDetailList = ({
|
||||||
currentPage,
|
currentPage,
|
||||||
data,
|
data,
|
||||||
|
enableHeader = true,
|
||||||
getItem,
|
getItem,
|
||||||
itemCount: externalItemCount,
|
itemCount: externalItemCount,
|
||||||
items,
|
items,
|
||||||
@@ -785,14 +853,26 @@ export const ItemDetailList = ({
|
|||||||
}, [initialize, osInstance]);
|
}, [initialize, osInstance]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={styles.container} ref={containerRef}>
|
<div className={styles.wrapper}>
|
||||||
<List
|
{enableHeader && (
|
||||||
onRowsRendered={throttledHandleRowsRendered}
|
<DetailListHeader
|
||||||
rowComponent={RowComponent as (props: RowComponentProps<RowData>) => ReactElement}
|
columnWidthPercents={columnWidthPercents}
|
||||||
rowCount={itemCount}
|
enableVerticalBorders={enableVerticalBorders}
|
||||||
rowHeight={rowHeight}
|
trackColumns={trackColumns}
|
||||||
rowProps={rowProps}
|
trackTableSize={trackTableSize}
|
||||||
/>
|
/>
|
||||||
|
)}
|
||||||
|
<div className={styles.container} ref={containerRef}>
|
||||||
|
<List
|
||||||
|
onRowsRendered={throttledHandleRowsRendered}
|
||||||
|
rowComponent={
|
||||||
|
RowComponent as (props: RowComponentProps<RowData>) => ReactElement
|
||||||
|
}
|
||||||
|
rowCount={itemCount}
|
||||||
|
rowHeight={rowHeight}
|
||||||
|
rowProps={rowProps}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -885,7 +885,7 @@ export const TableColumnHeaderContainer = (
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
const columnLabelMap: Record<TableColumn, ReactNode | string> = {
|
export const columnLabelMap: Record<TableColumn, ReactNode | string> = {
|
||||||
[TableColumn.ACTIONS]: (
|
[TableColumn.ACTIONS]: (
|
||||||
<Flex className={styles.headerIconWrapper}>
|
<Flex className={styles.headerIconWrapper}>
|
||||||
<Icon fill="default" icon="ellipsisHorizontal" />
|
<Icon fill="default" icon="ellipsisHorizontal" />
|
||||||
|
|||||||
@@ -101,7 +101,6 @@ export const AlbumListHeaderFilters = ({ toggleGenreTarget }: { toggleGenreTarge
|
|||||||
listKey: ItemListKey.ALBUM_DETAIL,
|
listKey: ItemListKey.ALBUM_DETAIL,
|
||||||
optionsConfig: {
|
optionsConfig: {
|
||||||
autoFitColumns: { hidden: true },
|
autoFitColumns: { hidden: true },
|
||||||
enableHeader: { hidden: true },
|
|
||||||
},
|
},
|
||||||
tableColumnsData: SONG_TABLE_COLUMNS,
|
tableColumnsData: SONG_TABLE_COLUMNS,
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in New Issue
Block a user