D. Playlists
<fb-playlist-tabs>
Playlist tab strip with ArrowLeft/ArrowRight keyboard navigation, drag reordering, edge resizing, and overflow scrolling.
<fb-playlist-tabs></fb-playlist-tabs>| Attribute | Type | Default | Description |
|---|---|---|---|
active-index | string | — | Read-only active playlist index |
count | string | — | Read-only playlist count |
native-context | boolean | false | Also 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.
Events:
el.addEventListener('fb-playlist-select', e => {
console.log('Selected playlist:', e.detail.index);
});
el.addEventListener('fb-playlist-context', e => {
console.log('Context request:', e.detail.index, 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.newOrder);
});<fb-resizable-header>
Resizable column header with drag reordering and click-to-sort behavior. It is typically paired with <fb-playlist-view>.
<fb-resizable-header columns='[{"id":"title","label":"Title","width":"2fr"}]'></fb-resizable-header>| Attribute | Type | Default | Description |
|---|---|---|---|
columns | string (JSON) | [] | Column descriptors with id, optional label/name, width (for example 1fr), sortable, and fixed fields |
sort-column | string | — | 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 CSSgrid-template-columnsvalue for synchronizing a playlist viewcolumnIds— current visual order of column IDs
Events:
// 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.
<fb-playlist-view row-height="24"></fb-playlist-view>| Attribute | Type | Default | Description |
|---|---|---|---|
playlist | string | — | Playlist index; defaults to the active playlist (observed) |
columns | string | 'index,title,artist,album,duration' | Comma-separated column IDs (observed) |
row-height | string | '32' | Row height in pixels (observed) |
grid-template | string | — | CSS grid-template-columns value, typically copied from <fb-resizable-header> (observed) |
formats | string (JSON) | {} | Map of custom column IDs to Title Formatting expressions (observed) |
track-count | string | — | Read-only total track count |
selected-count | string | — | Read-only selected track count |
CSS Parts: viewport, scroll-content, row, row-{column}
Each row part may reflect the selected, focused, and playing states as attributes.
Events:
el.addEventListener('fb-track-select', e => {
console.log('Selected:', e.detail.index, e.detail.indices);
});
el.addEventListener('fb-track-play', e => {
console.log('Play:', e.detail.index);
});
el.addEventListener('fb-track-context', e => {
console.log('Context request:', e.detail.indices, e.detail.x, e.detail.y);
});<fb-queue-view>
Playback queue view. Double-clicking a row removes that queue entry.
<fb-queue-view columns="index,title,artist,duration">
<span slot="empty">The queue is empty</span>
</fb-queue-view>| Attribute | Type | Default | Description |
|---|---|---|---|
columns | string | 'index,title,artist,duration' | Comma-separated column IDs |
empty | boolean | — | Read-only reflection of whether the queue is empty |
count | string | — | Read-only queue-entry count |
CSS Parts: container, row, row-{column}, emptySlots: empty
Events:
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.
<fb-playlist-selector></fb-playlist-selector>| Attribute | Type | Default | Description |
|---|---|---|---|
selected-index | string | — | Read-only selected playlist index |
selected-name | string | — | Read-only selected playlist name |
CSS Parts: select
Events:
el.addEventListener('fb-playlist-pick', e => {
console.log('Selected:', e.detail.index, e.detail.name);
});