fix album tracklist column picker cutoff and scroll containment issues

This commit is contained in:
kveld9
2026-04-14 23:27:57 -03:00
parent 19b7c8ec06
commit eb061bd9de
3 changed files with 57 additions and 41 deletions
+37 -33
View File
@@ -532,6 +532,41 @@ export default function AlbumTrackList({
}
return (
<>
{/* Column visibility picker - fuera del tracklist para evitar overflow cutoff */}
<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>
{COLUMNS.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>
)}
</div>
</div>
<div
className="tracklist"
ref={tracklistRef}
@@ -573,42 +608,10 @@ export default function AlbumTrackList({
)}
{/* ── Header ── */}
<div style={{ position: 'relative' }}>
<div className="tracklist-header-wrapper">
<div className="tracklist-header" style={gridStyle}>
{visibleCols.map((colDef, colIndex) => renderHeaderCell(colDef, colIndex))}
</div>
{/* Column visibility picker */}
<div className="tracklist-col-picker" ref={pickerRef}>
<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>
{COLUMNS.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>
)}
</div>
</div>
{/* ── Tracks ── */}
@@ -649,5 +652,6 @@ export default function AlbumTrackList({
))}
</div>
</>
);
}
+18 -6
View File
@@ -921,6 +921,7 @@
display: flex;
flex-direction: column;
gap: 0;
position: relative; /* Para que el picker posicionado absoluto funcione */
}
.album-detail-header {
@@ -1396,7 +1397,13 @@
/* ─ Tracklist ─ */
.tracklist {
padding: 0 var(--space-6) var(--space-6);
overflow-x: auto;
/* El scroll horizontal ahora es natural de la página, no confinado al tracklist */
overflow-x: visible;
}
/* Wrapper para el header con position relative para el picker */
.tracklist-header-wrapper {
position: relative;
}
.col-center {
@@ -1490,14 +1497,19 @@
}
/* ── Column visibility picker ── */
/* Wrapper fuera del tracklist - alineado a la derecha del álbum */
.tracklist-col-picker-wrapper {
display: flex;
justify-content: flex-end;
padding: 0 var(--space-6);
margin-bottom: 4px;
z-index: 50;
}
.tracklist-col-picker {
position: absolute;
top: 0;
right: 0;
height: 100%;
position: relative;
display: flex;
align-items: center;
padding-right: 4px;
}
.tracklist-col-picker-btn {