Skip to content

Commit 2175abc

Browse files
committed
table width and selected range cell borders
1 parent 400dd32 commit 2175abc

1 file changed

Lines changed: 34 additions & 9 deletions

File tree

packages/raga-web-app/src/components/trackTable/trackTable.tsx

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ import { unique } from "radash";
2626
import { memo, useCallback, useMemo, useRef, useState } from "react";
2727
import { Roarr as log } from "roarr";
2828
import { useShallow } from "zustand/shallow";
29+
import { useResizeObserver } from "usehooks-ts";
2930

3031
import { TRACK_TABLE_HEADER_HEIGHT, TRACK_TABLE_ROW_HEIGHT } from "../../common/constants";
3132
import { ClientErrors } from "../../common/errorMessages";
@@ -222,6 +223,12 @@ const TrackTable = memo(({ playlistId }: TrackTableProps) => {
222223
const numTracksInPlaylist = allTrackDefNodes.nodes.length;
223224
const containerElement = useRef<HTMLDivElement | null>(null);
224225
const gridRef = useRef<DataEditorRef | null>(null);
226+
const tableContainerRef = useRef<HTMLDivElement>(null);
227+
const { width: containerWidth = 0 } = useResizeObserver({
228+
// @ts-expect-error - incompatible with stricter React 19 types
229+
ref: tableContainerRef,
230+
box: "border-box",
231+
});
225232

226233
// filter trackDefNodes based on filterQuery value
227234
const [filterQuery, setFilterQuery] = useState<string>("");
@@ -404,21 +411,37 @@ const TrackTable = memo(({ playlistId }: TrackTableProps) => {
404411
const getRowThemeOverride = useCallback(
405412
(row: number) => {
406413
const track = sortedTrackDefs[row];
414+
const isSelected = selection.rows.hasIndex(row);
415+
const isPrevSelected = row > 0 && selection.rows.hasIndex(row - 1);
416+
const themeOverride: Partial<GridTheme> = {};
417+
418+
// Highlight first row of selection range OR row immediately after selection range
419+
const isSelectionEdge = (isSelected && !isPrevSelected) || (!isSelected && isPrevSelected);
420+
if (isSelectionEdge) {
421+
themeOverride.horizontalBorderColor = theme.textDark;
422+
}
423+
424+
// Apply active track background
407425
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
408426
if (track && activeTrackId === track.id) {
409-
return {
410-
bgCell: theme.bgCellMedium,
411-
};
427+
themeOverride.bgCell = theme.bgCellMedium;
412428
}
413429
// Apply hover styling
414-
if (row === hoveredRow) {
415-
return {
416-
bgCell: theme.bgHeaderHovered,
417-
};
430+
else if (row === hoveredRow) {
431+
themeOverride.bgCell = theme.bgHeaderHovered;
418432
}
419-
return undefined;
433+
434+
return Object.keys(themeOverride).length > 0 ? themeOverride : undefined;
420435
},
421-
[sortedTrackDefs, activeTrackId, theme.bgCellMedium, theme.bgHeaderHovered, hoveredRow],
436+
[
437+
sortedTrackDefs,
438+
activeTrackId,
439+
theme.bgCellMedium,
440+
theme.bgHeaderHovered,
441+
theme.textDark,
442+
hoveredRow,
443+
selection,
444+
],
422445
);
423446

424447
// Handle item hover to track which row is being hovered
@@ -441,6 +464,7 @@ const TrackTable = memo(({ playlistId }: TrackTableProps) => {
441464

442465
const table = (
443466
<div
467+
ref={tableContainerRef}
444468
className={classNames(styles.trackTable, { [styles.contextMenuIsOpen]: isContextMenuOpen })}
445469
onClick={(e) => {
446470
// Clear selection when clicking directly on the container div (empty space)
@@ -452,6 +476,7 @@ const TrackTable = memo(({ playlistId }: TrackTableProps) => {
452476
>
453477
<DataEditor
454478
ref={gridRef}
479+
width={containerWidth}
455480
columns={columns}
456481
rows={sortedTrackDefs.length}
457482
getCellContent={getCellContent}

0 commit comments

Comments
 (0)