fix(playlists): hide '#' and Channel by the table's width, not the window's (E28)
Beside the playlist rail an 800 px window left the table 432 px: the fixed columns took all of it and the title column was 0 px wide, its thumbnail drawn over the channel. The table is an @container now and the columns hide under 42rem of its own width (narrowHidden, was phoneHidden).
This commit is contained in:
@@ -558,17 +558,22 @@ describe("Playlists · the header's '…'", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("Playlists · a phone-width table", () => {
|
||||
it("leaves out '#' and Channel below sm, header and cells alike, so the title keeps a width", async () => {
|
||||
describe("Playlists · a narrow table", () => {
|
||||
it("leaves out '#' and Channel while the TABLE is narrow, header and cells alike, so the title keeps a width", async () => {
|
||||
mount({ 1: [vid("A", 0)] });
|
||||
await screen.findByRole("button", { name: "card.play — Video A" });
|
||||
const phoneHidden = (el: Element) =>
|
||||
el.classList.contains("hidden") && el.classList.contains("sm:table-cell");
|
||||
// By the table's own width (its @container), not the viewport's: beside the rail a desktop
|
||||
// window left the table 432 px and the title 0.
|
||||
expect(document.querySelector("table")!.parentElement!.classList.contains("@container")).toBe(
|
||||
true,
|
||||
);
|
||||
const narrowHidden = (el: Element) =>
|
||||
el.classList.contains("hidden") && el.classList.contains("@2xl:table-cell");
|
||||
const heads = [...document.querySelectorAll("thead th")];
|
||||
const cells = [...document.querySelectorAll("tbody tr:first-child td")];
|
||||
// Columns: grip, #, title, channel, length, "…".
|
||||
expect(heads.map(phoneHidden)).toEqual([false, true, false, true, false, false]);
|
||||
expect(cells.map(phoneHidden)).toEqual([false, true, false, true, false, false]);
|
||||
expect(heads.map(narrowHidden)).toEqual([false, true, false, true, false, false]);
|
||||
expect(cells.map(narrowHidden)).toEqual([false, true, false, true, false, false]);
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
@@ -125,7 +125,7 @@ function Row({
|
||||
<td
|
||||
key={col.key}
|
||||
style={col.width ? { width: col.width } : undefined}
|
||||
className={`px-2 py-1.5 align-middle ${col.nowrap ? "whitespace-nowrap" : ""} ${alignClass(col.align)}${col.phoneHidden ? " hidden sm:table-cell" : ""}`}
|
||||
className={`px-2 py-1.5 align-middle ${col.nowrap ? "whitespace-nowrap" : ""} ${alignClass(col.align)}${col.narrowHidden ? " hidden @2xl:table-cell" : ""}`}
|
||||
>
|
||||
{col.key === GRIP_KEY ? (
|
||||
// The one cell the column defs can't render: the handle needs this row's sortable
|
||||
@@ -907,8 +907,9 @@ export default function Playlists() {
|
||||
// drag; now that the keyboard can, they ARE the instructions for the feature.
|
||||
accessibility={dndA11y}
|
||||
>
|
||||
{/* Not clipped, so the header's filter popovers can overflow the table box. */}
|
||||
<div className="max-w-5xl mx-auto">
|
||||
{/* Not clipped, so the header's filter popovers can overflow the table box. A container,
|
||||
so a narrow column hides by the table's width, not the window's (`narrowHidden`). */}
|
||||
<div className="@container max-w-5xl mx-auto">
|
||||
{/* 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. */}
|
||||
|
||||
@@ -38,7 +38,7 @@ export function playlistColumns({
|
||||
nowrap: true,
|
||||
hideInCard: true,
|
||||
// The position number is the first thing a phone row can spare; the order still shows.
|
||||
phoneHidden: true,
|
||||
narrowHidden: true,
|
||||
// Sorting by "#" ascending is the stored order itself — that is what makes it a truthful
|
||||
// default for the header arrow, and a one-click way back from any other sort.
|
||||
sortable: true,
|
||||
@@ -89,7 +89,7 @@ export function playlistColumns({
|
||||
key: "channel",
|
||||
header: t("playlists.colChannel"),
|
||||
width: "12rem",
|
||||
phoneHidden: true,
|
||||
narrowHidden: true,
|
||||
nowrap: true,
|
||||
sortable: true,
|
||||
sortValue: (v) => v.channel_title ?? "",
|
||||
|
||||
@@ -214,7 +214,7 @@ export function ColumnHead<T>({
|
||||
<th
|
||||
key={col.key}
|
||||
style={col.width ? { width: col.width } : undefined}
|
||||
className={`relative font-medium px-2 py-2 whitespace-nowrap bg-bg ${alignClass(col.align)}${col.phoneHidden ? " hidden sm:table-cell" : ""}`}
|
||||
className={`relative font-medium px-2 py-2 whitespace-nowrap bg-bg ${alignClass(col.align)}${col.narrowHidden ? " hidden @2xl:table-cell" : ""}`}
|
||||
aria-sort={
|
||||
col.sortable
|
||||
? isSorted
|
||||
|
||||
@@ -38,8 +38,10 @@ export interface Column<T> {
|
||||
hideInCard?: boolean;
|
||||
cardLabel?: boolean;
|
||||
// A column a table WITHOUT the card fallback (the playlist's drag-reorderable hybrid) leaves out
|
||||
// below `sm`: on a phone its fixed widths alone overran the screen and left the title no width.
|
||||
phoneHidden?: boolean;
|
||||
// while the TABLE is narrower than 42rem: its fixed widths alone overran the box and left the title
|
||||
// no width. The table's own width, not the viewport's (an `@container` round it): beside the
|
||||
// playlist rail a desktop window gave the table 432 px, and the title column was 0 px wide.
|
||||
narrowHidden?: boolean;
|
||||
}
|
||||
|
||||
export type FilterMap = Record<string, string | string[]>;
|
||||
|
||||
Reference in New Issue
Block a user