use percentage based column widths to autofit

This commit is contained in:
jeffvli
2026-02-08 20:28:32 -08:00
parent 31c3f1b062
commit 177bb156cb
3 changed files with 34 additions and 20 deletions
@@ -82,6 +82,11 @@
color: var(--theme-colors-foreground-muted); color: var(--theme-colors-foreground-muted);
} }
.row .right {
min-width: 0;
overflow: hidden;
}
.row .tracks-table { .row .tracks-table {
width: 100%; width: 100%;
font-size: var(--theme-font-size-sm); font-size: var(--theme-font-size-sm);
@@ -48,6 +48,7 @@ interface ItemDetailListProps {
} }
interface RowData { interface RowData {
columnWidthPercents: number[];
controls?: ItemControls; controls?: ItemControls;
data: unknown[]; data: unknown[];
getItem?: (index: number) => unknown; getItem?: (index: number) => unknown;
@@ -60,6 +61,7 @@ interface RowData {
interface TrackRowProps { interface TrackRowProps {
columns: ItemTableListColumnConfig[]; columns: ItemTableListColumnConfig[];
columnWidthPercents: number[];
internalState: ItemListStateActions; internalState: ItemListStateActions;
isMutatingFavorite: boolean; isMutatingFavorite: boolean;
onFavoriteClick: (song: Song) => void; onFavoriteClick: (song: Song) => void;
@@ -74,6 +76,7 @@ const textAlignFromAlign = (align: ItemTableListColumnConfig['align']) =>
const TrackRow = memo( const TrackRow = memo(
({ ({
columns, columns,
columnWidthPercents,
internalState, internalState,
isMutatingFavorite, isMutatingFavorite,
onFavoriteClick, onFavoriteClick,
@@ -184,21 +187,16 @@ const TrackRow = memo(
onClick={handleRowClick} onClick={handleRowClick}
ref={dragRef ?? undefined} ref={dragRef ?? undefined}
> >
{columns.map((col) => { {columns.map((col, colIndex) => {
const widthStyle = col.autoSize const percent = columnWidthPercents[colIndex] ?? 0;
? { minWidth: col.width }
: {
maxWidth: col.width,
minWidth: col.width,
width: col.width,
};
const style: React.CSSProperties = { const style: React.CSSProperties = {
fontFamily: fontFamily:
col.id === TableColumn.DURATION || col.id === TableColumn.TRACK_NUMBER col.id === TableColumn.DURATION || col.id === TableColumn.TRACK_NUMBER
? 'monospace' ? 'monospace'
: undefined, : undefined,
minWidth: 0,
textAlign: textAlignFromAlign(col.align), textAlign: textAlignFromAlign(col.align),
...widthStyle, width: `${percent}%`,
}; };
const CellComponent = getDetailListCellComponent(col.id); const CellComponent = getDetailListCellComponent(col.id);
const content = ( const content = (
@@ -236,6 +234,7 @@ type RowContentProps = Omit<RowComponentProps<RowData>, 'style'>;
const RowContent = memo( const RowContent = memo(
({ ({
columnWidthPercents,
controls, controls,
data, data,
getItem, getItem,
@@ -363,6 +362,7 @@ const RowContent = memo(
{songs.map((song, rowIndex) => ( {songs.map((song, rowIndex) => (
<TrackRow <TrackRow
columns={trackColumns} columns={trackColumns}
columnWidthPercents={columnWidthPercents}
internalState={internalState} internalState={internalState}
isMutatingFavorite={isMutatingFavorite} isMutatingFavorite={isMutatingFavorite}
key={song.id} key={song.id}
@@ -381,6 +381,7 @@ const RowContent = memo(
(prev, next) => (prev, next) =>
prev.index === next.index && prev.index === next.index &&
prev.data === next.data && prev.data === next.data &&
prev.columnWidthPercents === next.columnWidthPercents &&
prev.getItem === next.getItem && prev.getItem === next.getItem &&
prev.internalState === next.internalState && prev.internalState === next.internalState &&
prev.isMutatingFavorite === next.isMutatingFavorite && prev.isMutatingFavorite === next.isMutatingFavorite &&
@@ -477,6 +478,14 @@ export const ItemDetailList = ({
}, [tableConfig?.columns]); }, [tableConfig?.columns]);
const trackTableSize = tableConfig?.size ?? 'default'; const trackTableSize = tableConfig?.size ?? 'default';
const columnWidthPercents = useMemo(() => {
const total = trackColumns.reduce((sum, c) => sum + c.width, 0);
if (total <= 0) {
return trackColumns.map(() => 100 / Math.max(1, trackColumns.length));
}
return trackColumns.map((c) => (c.width / total) * 100);
}, [trackColumns]);
const handleRowsRendered = useCallback( const handleRowsRendered = useCallback(
(range: { startIndex: number; stopIndex: number }) => { (range: { startIndex: number; stopIndex: number }) => {
if (onRangeChanged) { if (onRangeChanged) {
@@ -503,6 +512,7 @@ export const ItemDetailList = ({
const rowProps = useMemo<RowData>( const rowProps = useMemo<RowData>(
() => ({ () => ({
columnWidthPercents,
controls, controls,
data: dataSource, data: dataSource,
getItem, getItem,
@@ -514,6 +524,7 @@ export const ItemDetailList = ({
trackTableSize, trackTableSize,
}), }),
[ [
columnWidthPercents,
controls, controls,
dataSource, dataSource,
getItem, getItem,
@@ -32,16 +32,15 @@ export const AlbumListInfiniteDetail = ({
const listQueryFn = api.controller.getAlbumList; const listQueryFn = api.controller.getAlbumList;
const { dataVersion, getItem, itemCount, loadedItems, onRangeChanged } = const { getItem, itemCount, loadedItems, onRangeChanged } = useItemListInfiniteLoader({
useItemListInfiniteLoader({ eventKey: ItemListKey.ALBUM,
eventKey: ItemListKey.ALBUM, itemsPerPage,
itemsPerPage, itemType: LibraryItem.ALBUM,
itemType: LibraryItem.ALBUM, listCountQuery,
listCountQuery, listQueryFn,
listQueryFn, query,
query, serverId,
serverId, });
});
const { handleOnScrollEnd, scrollOffset } = useItemListScrollPersist({ const { handleOnScrollEnd, scrollOffset } = useItemListScrollPersist({
enabled: saveScrollOffset, enabled: saveScrollOffset,
@@ -50,7 +49,6 @@ export const AlbumListInfiniteDetail = ({
return ( return (
<ItemDetailList <ItemDetailList
data={loadedItems} data={loadedItems}
dataVersion={dataVersion}
getItem={getItem} getItem={getItem}
itemCount={itemCount} itemCount={itemCount}
onRangeChanged={onRangeChanged} onRangeChanged={onRangeChanged}