Files
Psychotoxical-psysonic/src/components/albumTrackList/TracklistColumnPicker.tsx
T
Frank Stellmacher cc8e6cc811 fix(playlist): column picker no longer clipped on short lists (#853)
* fix(playlist): columns dropdown no longer clipped on short lists (#839)

The column picker rendered inside `.tracklist` (overflow-x: auto, which
makes overflow-y compute to auto). On a 1-song playlist the downward popover
overflowed the short box → clipped behind suggestions, an extra scrollbar,
and the row vanishing when scrolling that inner bar (the virtualizer tracks
the main viewport, not the tracklist). Move the picker outside `.tracklist`
by reusing the shared TracklistColumnPicker (parametrized with allColumns);
fixes the same latent bug in the favorites tracklist and dedupes three
inline copies into one.

* docs(changelog): playlist/favorites column picker fix (#853)
2026-05-22 19:20:34 +02:00

74 lines
2.4 KiB
TypeScript

import React from 'react';
import { Check, ChevronDown, RotateCcw } from 'lucide-react';
import type { TFunction } from 'i18next';
import type { ColDef } from '../../utils/useTracklistColumns';
interface Props {
/** Every column (required ones are filtered out of the menu). */
allColumns: readonly ColDef[];
pickerRef: React.RefObject<HTMLDivElement | null>;
pickerOpen: boolean;
setPickerOpen: (updater: (v: boolean) => boolean) => void;
colVisible: Set<string>;
toggleColumn: (key: string) => void;
resetColumns: () => void;
t: TFunction;
}
/**
* The column visibility dropdown that sits outside `.tracklist` so the
* popover menu can grow without being clipped by the tracklist's overflow
* box. Lists every non-required column and offers a reset-to-defaults
* button.
*/
export function TracklistColumnPicker({
allColumns,
pickerRef,
pickerOpen,
setPickerOpen,
colVisible,
toggleColumn,
resetColumns,
t,
}: Props) {
return (
<div className="tracklist-col-picker-wrapper" ref={pickerRef}>
<div className="tracklist-col-picker">
<button
className="tracklist-col-picker-btn"
onClick={e => { e.stopPropagation(); setPickerOpen(v => !v); }}
data-tooltip={t('albumDetail.columns')}
>
<ChevronDown size={14} />
</button>
{pickerOpen && (
<div className="tracklist-col-picker-menu">
<div className="tracklist-col-picker-label">{t('albumDetail.columns')}</div>
{allColumns.filter(c => !c.required).map(c => {
const label = c.i18nKey ? t(`albumDetail.${c.i18nKey as string}`) : c.key;
const isOn = colVisible.has(c.key);
return (
<button
key={c.key}
className={`tracklist-col-picker-item${isOn ? ' active' : ''}`}
onClick={() => toggleColumn(c.key)}
>
<span className="tracklist-col-picker-check">
{isOn && <Check size={13} />}
</span>
{label}
</button>
);
})}
<div className="tracklist-col-picker-divider" />
<button className="tracklist-col-picker-reset" onClick={resetColumns}>
<RotateCcw size={13} />
{t('albumDetail.resetColumns')}
</button>
</div>
)}
</div>
</div>
);
}