Skip to content

D. Playlists ​

<fb-playlist-tabs> ​

Playlist tab strip with ArrowLeft/ArrowRight keyboard navigation, drag reordering, edge resizing, and overflow scrolling.

html
<fb-playlist-tabs></fb-playlist-tabs>
AttributeTypeDefaultDescription
active-indexstring—Read-only active playlist index
countstring—Read-only playlist count
native-contextbooleanfalseAlso opens the native playlist context menu when present

Read-only Host States: dragging while a tab is being dragged; overflow while the tab strip overflows

CSS Parts: tabs-container, tab, tab-name, tab-count, drop-indicator, add-button

Each tab part receives a locked attribute when the playlist is locked, and carries its playlist's GUID as data-guid.

Tabs bind playlists by GUID: additions or removals of other playlists do not change a tab's target playlist; clicking a tab for a deleted playlist triggers no selection. fb-playlist-select and fb-playlist-reorder fire after the host completes the operation.

Events:

js
el.addEventListener('fb-playlist-select', e => {
  console.log('Selected playlist:', e.detail.index, e.detail.guid);
});
el.addEventListener('fb-playlist-context', e => {
  // Act on e.detail.guid once the menu closes; the index may name another playlist by then.
  console.log('Context request:', e.detail.guid, e.detail.x, e.detail.y);
});
el.addEventListener('fb-playlist-add', e => {
  console.log('New playlist created');
});
el.addEventListener('fb-playlist-reorder', e => {
  console.log('Reordered:', e.detail.fromIndex, e.detail.toIndex, e.detail.newOrderGuids);
});

<fb-resizable-header> ​

Resizable column header with drag reordering and click-to-sort behavior. It is typically paired with <fb-playlist-view>.

html
<fb-resizable-header columns='[{"id":"title","label":"Title","width":"2fr"}]'></fb-resizable-header>
AttributeTypeDefaultDescription
columnsstring (JSON)[]Column descriptors with id, optional label/name, width (for example 1fr), sortable, and fixed fields
sort-columnstring—Current sort column ID (observed and reflected)
sort-direction'asc' | 'desc''asc'Current sort direction (observed and reflected)

fixed columns cannot be resized or reordered. Read-only Host States: resizing and reordering

CSS Parts: header, cell, cell-{id}, resize-handle, sort-icon, sort-active, drop-indicator, drag-ghost, label

Read-only JavaScript Properties:

  • gridTemplate — current CSS grid-template-columns value for synchronizing a playlist view
  • columnIds — current visual order of column IDs

Events:

js
// Column resize
el.addEventListener('fb-column-resize', e => {
  console.log('Width:', e.detail.column, e.detail.width);
  // Keep the playlist view aligned with the header.
  playlistView.setAttribute('grid-template', e.detail.gridTemplate);
});

// Column reorder
el.addEventListener('fb-column-reorder', e => {
  console.log('Reordered:', e.detail.fromIndex, '→', e.detail.toIndex);
  console.log('New order:', e.detail.columns);
});

// Column sort
el.addEventListener('fb-column-sort', e => {
  console.log('Sort:', e.detail.column, e.detail.direction);
});

// Header context request
el.addEventListener('fb-header-context', e => {
  console.log('Header context:', e.detail.x, e.detail.y);
});

<fb-playlist-view> ​

Virtualized playlist view with an rAF-driven DOM pool. It supports Ctrl/Shift selection, Enter to play, Delete to remove, and Ctrl+A to select all.

html
<fb-playlist-view row-height="24"></fb-playlist-view>
AttributeTypeDefaultDescription
playliststring—The playlist's guid (a value starting with {) or its index; omitted, the active playlist (observed). See below
columnsstring'index,title,artist,album,duration'Comma-separated column IDs (observed)
row-heightstring'32'Row height in pixels (observed)
grid-templatestring—CSS grid-template-columns value, typically copied from <fb-resizable-header> (observed)
formatsstring (JSON){}Map of custom column IDs to Title Formatting expressions (observed)
track-countstring—Read-only total track count
selected-countstring—Read-only selected track count

The play_count, first_played, last_played and added columns show foo_playcount's fields, and rating shows five clickable stars. To display any other column listed by fb.playlist.getAvailableColumns(), map the column's pattern to a custom column ID in formats and include that ID in columns. Do not use the column's name as an ID, as it represents localized display text that varies with the foobar2000 language.

html
<fb-playlist-view columns="index,title,play_count,rating,mood"
  formats='{"mood":"%mood%"}'></fb-playlist-view>

CSS Parts: viewport, scroll-content, row, row-{column}

Each row part may reflect the selected, focused, and playing states as attributes.

A GUID in playlist keeps the view on that playlist while others are added, removed or reordered, and leaves it empty once the playlist is removed. An index shows whichever playlist is at that position and is looked up again after playlists are added, removed or reordered. Without the attribute the view follows the active playlist and shows nothing while there is none. Once the target playlist is determined, the component references it by GUID in subsequent host invocations and carries playlistGuid in all event details.

Events:

js
el.addEventListener('fb-track-select', e => {
  console.log('Selected:', e.detail.index, e.detail.indices, e.detail.playlistGuid);
});
el.addEventListener('fb-track-play', e => {
  console.log('Play:', e.detail.index, e.detail.playlistGuid);
});
el.addEventListener('fb-track-context', e => {
  console.log('Context request:', e.detail.indices, e.detail.playlistGuid, e.detail.x, e.detail.y);
});

<fb-queue-view> ​

Playback queue view. Double-clicking a row removes that queue entry.

html
<fb-queue-view columns="index,title,artist,duration">
  <span slot="empty">The queue is empty</span>
</fb-queue-view>
AttributeTypeDefaultDescription
columnsstring'index,title,artist,duration'Comma-separated column IDs
emptyboolean—Read-only reflection of whether the queue is empty
countstring—Read-only queue-entry count

CSS Parts: container, row, row-{column}, empty
Slots: empty

Events:

js
el.addEventListener('fb-queue-context', e => {
  console.log('Context request:', e.detail.index, e.detail.x, e.detail.y);
});
el.addEventListener('fb-queue-remove', e => {
  console.log('Removed:', e.detail.index);
});

<fb-playlist-selector> ​

Playlist dropdown selector.

html
<fb-playlist-selector></fb-playlist-selector>
AttributeTypeDefaultDescription
selected-indexstring—Read-only selected playlist index
selected-namestring—Read-only selected playlist name

CSS Parts: select

Events:

js
el.addEventListener('fb-playlist-pick', e => {
  console.log('Selected:', e.detail.index, e.detail.guid, e.detail.name);
});