fix(playlists): the table overflowed the page scroller
A truncate cell is white-space:nowrap, so its min-content width is the whole title — under table-layout:auto the Title column grew until Length and the remove button hung off the scroller (measured: table 1059px inside an 855px wrapper, main.scrollWidth 1074 vs clientWidth 887). Fixed layout with a declared width on every column but Title, which absorbs the rest.
This commit is contained in:
@@ -706,7 +706,10 @@ export default function Playlists() {
|
|||||||
>
|
>
|
||||||
{/* Not clipped, so the header's filter popovers can overflow the table box. */}
|
{/* Not clipped, so the header's filter popovers can overflow the table box. */}
|
||||||
<div className="max-w-5xl">
|
<div className="max-w-5xl">
|
||||||
<table className="w-full border-collapse text-sm">
|
{/* table-fixed, not auto: every column but the title has a declared width, so the
|
||||||
|
title absorbs the rest and its `truncate` works. Auto layout sizes columns from
|
||||||
|
min-content, and a nowrap title cell's min-content is the entire title. */}
|
||||||
|
<table className="w-full table-fixed border-collapse text-sm">
|
||||||
<ColumnHead
|
<ColumnHead
|
||||||
columns={columns}
|
columns={columns}
|
||||||
sort={viewSort}
|
sort={viewSort}
|
||||||
|
|||||||
@@ -41,6 +41,11 @@ export function playlistColumns({
|
|||||||
{
|
{
|
||||||
key: "title",
|
key: "title",
|
||||||
header: t("playlists.colTitle"),
|
header: t("playlists.colTitle"),
|
||||||
|
// The flexible column: under `table-fixed` (see Playlists.tsx) width:100% hands it every
|
||||||
|
// pixel the fixed columns don't claim. Auto layout could not do this — a `truncate` cell is
|
||||||
|
// `white-space: nowrap`, so its MIN-content width is the whole title, and the column grew
|
||||||
|
// until Length and the remove button hung off the page scroller.
|
||||||
|
width: "100%",
|
||||||
sortable: true,
|
sortable: true,
|
||||||
sortValue: (v) => v.title ?? "",
|
sortValue: (v) => v.title ?? "",
|
||||||
filter: { kind: "text", get: (v) => v.title ?? "" },
|
filter: { kind: "text", get: (v) => v.title ?? "" },
|
||||||
@@ -60,7 +65,7 @@ export function playlistColumns({
|
|||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
||||||
<button onClick={() => onPlay(v)} className="min-w-0 flex-1 text-left">
|
<button onClick={() => onPlay(v)} className="min-w-0 flex-1 text-left">
|
||||||
<span className="block text-[13px] text-fg truncate max-w-[34rem]">{v.title}</span>
|
<span className="block text-[13px] text-fg truncate">{v.title}</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
@@ -68,17 +73,20 @@ export function playlistColumns({
|
|||||||
{
|
{
|
||||||
key: "channel",
|
key: "channel",
|
||||||
header: t("playlists.colChannel"),
|
header: t("playlists.colChannel"),
|
||||||
|
width: "12rem",
|
||||||
|
nowrap: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
sortValue: (v) => v.channel_title ?? "",
|
sortValue: (v) => v.channel_title ?? "",
|
||||||
filter: { kind: "text", get: (v) => v.channel_title ?? "" },
|
filter: { kind: "text", get: (v) => v.channel_title ?? "" },
|
||||||
render: (v) => (
|
render: (v) => (
|
||||||
<span className="text-[13px] text-muted truncate block max-w-[14rem]">{v.channel_title}</span>
|
<span className="text-[13px] text-muted truncate block">{v.channel_title}</span>
|
||||||
),
|
),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "duration",
|
key: "duration",
|
||||||
header: t("playlists.colDuration"),
|
header: t("playlists.colDuration"),
|
||||||
align: "right",
|
align: "right",
|
||||||
|
width: "5rem",
|
||||||
nowrap: true,
|
nowrap: true,
|
||||||
sortable: true,
|
sortable: true,
|
||||||
// Nulls (live/upcoming, or not yet enriched) sort last in BOTH directions in the old
|
// Nulls (live/upcoming, or not yet enriched) sort last in BOTH directions in the old
|
||||||
|
|||||||
Reference in New Issue
Block a user