mirror of
https://github.com/Psychotoxical/psysonic.git
synced 2026-07-22 07:15:47 +00:00
cc8e6cc811
* 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)
74 lines
2.4 KiB
TypeScript
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>
|
|
);
|
|
}
|