Sprites.Media.List

The one media list module. It holds the live, paged listing every media page shows (Browser), the inline chooser a caller fills a selection from (Picker), the small shared parts they build on (the paging engine, the preview and name cells, the head, the pager, the empty states, and the filter controls), and the windows that wrap them (Window.Rename, Window.Delete, Window.Picker). Every item is one store envelope { id, media, platform, name, thumb, modified, info }, so one set of parts lists any media. Each editor saves its own thumbnail, so a row only reads the envelope.

Sprites.Media.List

Sprites.Media.List.Browser Void

Sprites.Media.List.Browser(hostId, media, platform)

The on-page media list: the live, paged listing every media page shows, with the toolbar above and the pager below, in a list or grid view. It mounts into hostId as a column and stays live as items are saved here or in another tab. media locks the listing to one media type and drops that filter and column; platform locks it to one platform the same way; either left out shows every value and its filter. Both are plain strings fixed at build.

InputTypeDescription
hostIdStringThe id of the element to mount the listing into.
mediaStringA media key to lock to, for example 'sprite', or left out for every media.
platformStringA platform to lock to, for example 'nes', or left out for every platform.

Returns nothing; it builds the listing.

Sprites.Media.List.Browser('ex-browser', 'sprite');
The whole sprite listing from one call, live against your saved sprites. Toggle List and Grid, filter and page. With none saved it shows the empty note in place of the rows.

Sprites.Media.List.Picker Void

Sprites.Media.List.Picker(selectedIds, mode, media, platform)

The inline media picker: a name filtered, paged list of one media and platform, each row toggling its membership of selectedIds. It mutates selectedIds directly, so a caller that wants a cancel wraps it in Window.Picker over a draft. In 'single' mode a click keeps just that row selected; in 'multiple' mode a click adds or removes the row.

InputTypeDescription
selectedIdsSprites.Reactive.ValueThe two-way array of chosen ids the rows toggle.
modeString or Sprites.Reactive.Value'single' or 'multiple'.
mediaString or Sprites.Reactive.ValueThe media key to list.
platformString or Sprites.Reactive.ValueThe platform to list, or the empty string for all.

Returns nothing; it builds the picker.

const chosen = Sprites.Reactive.Value([]);
Sprites.Media.List.Picker(chosen, 'multiple', 'sprite', '');
const chosenText = Sprites.Text.Join(chosen, ', ');
Sprites.Ui.Dom.Text(' chosen = ', chosenText);
Click rows to add and remove them; the chosen ids follow. Set mode to 'single' for a one-of chooser.

Sprites.Media.List.Window.Rename Void

Sprites.Media.List.Window.Rename(item, visible)

The rename window for one row: the snapshot and commit pattern. It seeds a draft from the row's name as it opens, and Save writes it back through the rename driver; Cancel leaves the name as it was.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record, with id and name.
visibleSprites.Reactive.ValueThe two-way show flag; set it true to open the window.

Returns nothing; it builds the window.

const item = Sprites.Reactive.Value({ id: 'a', name: 'Hero' });
const visible = Sprites.Reactive.Value(false);
Sprites.Ui.Button.SetValue(visible, true, 'Rename');
Sprites.Media.List.Window.Rename(item, visible);
The button opens the window, so nothing pops up until you ask. This record is not in the store, so Save has nothing to write; on a real row it renames it.

Sprites.Media.List.Window.Delete Void

Sprites.Media.List.Window.Delete(item, visible)

The delete window for one row: it shows the name, and Yes removes the record then closes; No leaves it. Opened from a button, so it never pops up on its own.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record, with id and name.
visibleSprites.Reactive.ValueThe two-way show flag; set it true to open the window.

Returns nothing; it builds the window.

const item = Sprites.Reactive.Value({ id: 'a', name: 'Hero' });
const visible = Sprites.Reactive.Value(false);
Sprites.Ui.Button.SetValue(visible, true, 'Delete');
Sprites.Media.List.Window.Delete(item, visible);
The button opens the confirm. This record is not saved, so Yes removes nothing; on a real row it deletes it.

Sprites.Media.List.Window.Picker Void

Sprites.Media.List.Window.Picker(visible, value, mode, media, platform)

The modal media picker window: it wraps the inline Picker over a draft seeded from value as the window opens, so choices stay apart from value until Select. Select commits the draft to value and closes; Cancel closes and leaves value as it was.

InputTypeDescription
visibleSprites.Reactive.ValueThe two-way show flag; set it true to open the window.
valueSprites.Reactive.ValueThe caller's array of chosen ids, written only on Select.
modeString or Sprites.Reactive.Value'single' or 'multiple'.
mediaString or Sprites.Reactive.ValueThe media key to list.
platformString or Sprites.Reactive.ValueThe platform to list, or the empty string for all.

Returns nothing; it builds the window.

const visible = Sprites.Reactive.Value(false);
const value = Sprites.Reactive.Value([]);
Sprites.Ui.Button.SetValue(visible, true, 'Choose sprites');
const valueText = Sprites.Text.Join(value, ', ');
Sprites.Ui.Dom.Text(' value = ', valueText);
Sprites.Media.List.Window.Picker(visible, value, 'multiple', 'sprite', '');
The button opens the modal. Choose rows, then Select writes them to value; Cancel leaves value untouched.

Sprites.Media.List.Page Object

Sprites.Media.List.Page(query)

The paging engine over a store query. It runs the query and derives one page of it, returning the reactive parts a listing needs as a plain bag of values: items, pageItems, page, shownPage, pageCount, manyPages and isEmpty. page is the value a pager sets.

InputTypeDescription
querySprites.Reactive.ValueA ReadOnly scope of { media, platform, sort, search }.

Returns a plain object of reactive values.

const query = Sprites.Reactive.ReadOnly({ media: 'sprite', platform: '', sort: 'modified', search: '' });
const bag = Sprites.Media.List.Page(query);
Sprites.Ui.Loading(() => {
  Sprites.Ui.Dom.Text('page ', bag.shownPage, ' of ', bag.pageCount);
});
The bag's derived values, live against your saved sprites.

Sprites.Media.List.PageSize Number

How many rows fill one page of a listing. The paging engine divides the list by it, and the pager steps and clamps against the page count it gives.

Value 12.

Sprites.Ui.Dom.Text('PageSize = ', Sprites.Media.List.PageSize);
The rows per page, shown live.

Sprites.Media.List.BrowserColumns Number

The colspan an empty message spans in a browser table, its full column count. EmptyRow uses it so a browser with no rows still shows its head over one message row.

Value 6.

Sprites.Ui.Dom.Text('BrowserColumns = ', Sprites.Media.List.BrowserColumns);
The browser table's column count, shown live.

Sprites.Media.List.PickerColumns Number

The colspan an empty message spans in a picker table, its full column count. EmptyRow uses it so a picker with no rows still shows its head over one message row.

Value 2.

Sprites.Ui.Dom.Text('PickerColumns = ', Sprites.Media.List.PickerColumns);
The picker table's column count, shown live.

Sprites.Media.List.Medias Array

The media types the filter dropdown offers, each a [value, label] pair. The value is the media key the store holds; the label is the nav's name for it. MediaFilter walks it to build its options.

const medias = Sprites.Reactive.Value(Sprites.Media.List.Medias);
Sprites.Reactive.Each(medias, (pair) => {
  const value = Sprites.Array.At(pair, 0);
  const label = Sprites.Array.At(pair, 1);
  Sprites.Ui.Dom.Tag('div', () => {
    Sprites.Ui.Dom.Text(value, ' → ', label);
  });
});
Every media key and the label the filter shows for it.

Sprites.Media.List.Platforms Array

The platforms the filter dropdown offers, each a [value, label] pair. PlatformFilter walks it to build its options.

const platforms = Sprites.Reactive.Value(Sprites.Media.List.Platforms);
Sprites.Reactive.Each(platforms, (pair) => {
  const value = Sprites.Array.At(pair, 0);
  const label = Sprites.Array.At(pair, 1);
  Sprites.Ui.Dom.Tag('div', () => {
    Sprites.Ui.Dom.Text(value, ' → ', label);
  });
});
Every platform key and the label the filter shows for it.

Sprites.Media.List.Paths Object

The URL folder for a media key, where the folder differs from the key. A plain lookup of the overrides; keys left out use their own name. Path reads it, falling back to the key.

const paths = Sprites.Reactive.Value(Sprites.Media.List.Paths);
const binary = Sprites.Object.Field(paths, 'binary');
const threed = Sprites.Object.Field(paths, 'threed');
Sprites.Ui.Dom.Text('binary → ', binary, ', threed → ', threed);
The folder overrides for two keys, read from the lookup.

Sprites.Media.List.Labels Object

The display label for a media key, a plain lookup; keys left out fall back to the key. Label reads it, falling back to the key.

const labels = Sprites.Reactive.Value(Sprites.Media.List.Labels);
const sequencer = Sprites.Object.Field(labels, 'sequencer');
const threed = Sprites.Object.Field(labels, 'threed');
Sprites.Ui.Dom.Text('sequencer → ', sequencer, ', threed → ', threed);
The display labels for two keys, read from the lookup.

Sprites.Media.List.Label Text

Sprites.Media.List.Label(media)

The display label for a media key, or the key itself when it is unknown. media is a reactive value, so the label follows it.

InputTypeDescription
mediaString or Sprites.Reactive.ValueA media key, for example 'sequencer'.

Returns the label as a reactive text value.

const media = Sprites.Reactive.Value('sequencer');
const label = Sprites.Media.List.Label(media);
Sprites.Ui.Dom.Text('label = ', label);
The key 'sequencer' maps to its label, Audio.

Sprites.Media.List.Path Text

Sprites.Media.List.Path(media)

The URL folder for a media key: its override, or the key itself. media is a reactive value, so the folder follows it.

InputTypeDescription
mediaString or Sprites.Reactive.ValueA media key, for example 'binary'.

Returns the folder as a reactive text value.

const media = Sprites.Reactive.Value('binary');
const folder = Sprites.Media.List.Path(media);
Sprites.Ui.Dom.Text('folder = ', folder);
The key 'binary' lives under the data folder.

Sprites.Media.List.Href Text

Sprites.Media.List.Href(item)

The editor link for a row: <folder>/<platform>/?id=<id>. item is a reactive record.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record, with media, platform and id.

Returns the link as a reactive text value.

const item = Sprites.Reactive.Value({ media: 'sprite', platform: 'nes', id: 'a' });
const href = Sprites.Media.List.Href(item);
Sprites.Ui.Dom.Text('href = ', href);
The record's editor link, built from its media, platform and id.

Sprites.Media.List.Thumb Void

Sprites.Media.List.Thumb(item)

The thumbnail image of a row: the saved thumb scaled to fit and centred, pixelated so small art stays crisp. It is the bare image, wrapped by Preview and PreviewLink in their box.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record whose thumb is a data URL.

Returns nothing; it builds the image.

const item = Sprites.Reactive.Value({ thumb: 'data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%228%22 height=%228%22%3E%3Crect width=%228%22 height=%228%22 fill=%22%233cb44b%22/%3E%3C/svg%3E' });
Sprites.Ui.Dom.Tag('span', () => {
  Sprites.Ui.Dom.Style('display', 'inline-block');
  Sprites.Ui.Dom.Style('width', '48px');
  Sprites.Ui.Dom.Style('height', '48px');
  Sprites.Media.List.Thumb(item);
});
The record's thumbnail, scaled into a sized box.

Sprites.Media.List.Preview Void

Sprites.Media.List.Preview(item)

The plain preview box of a row: a fixed square with a checkerboard backdrop holding the thumbnail, so a transparent part shows the checker through. It is not a link, so a picker row selects rather than navigates.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record, its thumb a data URL.

Returns nothing; it builds the box.

const item = Sprites.Reactive.Value({ thumb: 'data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%228%22 height=%228%22%3E%3Crect width=%228%22 height=%228%22 fill=%22%233cb44b%22/%3E%3C/svg%3E' });
Sprites.Media.List.Preview(item);
The square preview box, checker behind the thumbnail.

Sprites.Media.List.Name Void

Sprites.Media.List.Name(item)

The plain name of a row: it fills the rest of its cell and truncates with an ellipsis when the name runs long.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record, with name.

Returns nothing; it builds the name.

const item = Sprites.Reactive.Value({ name: 'Hero of a very long name' });
Sprites.Media.List.Name(item);
The record's name, clipped with an ellipsis when long.

Sprites.Media.List.Paging Void

Sprites.Media.List.Paging(page, shownPage, pageCount, items)

The pager under a listing: a back button, a one based page input clamped in range, a forward button, and the range label. The input writes the clamped page.

InputTypeDescription
pageSprites.Reactive.ValueThe two-way page number the pager sets.
shownPageSprites.Reactive.ValueThe clamped page the input follows.
pageCountSprites.Reactive.ValueThe number of pages.
itemsArray or Sprites.Reactive.ValueThe full list, for the range label.

Returns nothing; it builds the pager.

const page = Sprites.Reactive.Value(1);
const pageCount = Sprites.Reactive.Value(4);
const shownPage = Sprites.Maths.Clamp(page, 1, pageCount);
const items = Sprites.Reactive.Value(Array(40).fill(0));
Sprites.Media.List.Paging(page, shownPage, pageCount, items);
Forty items across four pages; step and type to move, the input clamps in range.

Sprites.Media.List.EmptyRow Void

Sprites.Media.List.EmptyRow(message, columns)

The empty message as one table row spanning every column, so a table with no rows still shows its head and a plain note.

InputTypeDescription
messageString or Sprites.Reactive.ValueThe note to show.
columnsNumberThe colspan to cover, the table's column count.

Returns nothing; it builds the row.

Sprites.Ui.Dom.Tag('table', () => {
  Sprites.Ui.Dom.Tag('tbody', () => {
    Sprites.Media.List.EmptyRow('You have not created any sprites yet.', 3);
  });
});
One message row spanning three columns.

Sprites.Media.List.EmptyNote Void

Sprites.Media.List.EmptyNote(message)

The empty message as a plain note, for the grid view where there is no table to span.

InputTypeDescription
messageString or Sprites.Reactive.ValueThe note to show.

Returns nothing; it builds the note.

Sprites.Media.List.EmptyNote('You have not created anything yet.');
The plain empty note.

Sprites.Media.List.ViewToggle Void

Sprites.Media.List.ViewToggle(view)

The list and grid view toggle: a two option segment bound to view, which holds 'list' or 'grid'.

InputTypeDescription
viewSprites.Reactive.ValueThe two-way view value the toggle sets.

Returns nothing; it builds the toggle.

const view = Sprites.Reactive.Value('list');
Sprites.Media.List.ViewToggle(view);
Sprites.Ui.Dom.Text(' view = ', view);
Pick List or Grid; the value follows.

Sprites.Media.List.SortControl Void

Sprites.Media.List.SortControl(sort)

The sort control: a label and a dropdown bound to sort, which holds 'modified' or 'name'.

InputTypeDescription
sortSprites.Reactive.ValueThe two-way sort value.

Returns nothing; it builds the control.

const sort = Sprites.Reactive.Value('modified');
Sprites.Media.List.SortControl(sort);
Sprites.Ui.Dom.Text(' sort = ', sort);
Change the sort; the value follows.

Sprites.Media.List.SearchControl Void

Sprites.Media.List.SearchControl(search)

The search control: a label and a text field bound to search, the name filter.

InputTypeDescription
searchSprites.Reactive.ValueThe two-way search text.

Returns nothing; it builds the control.

const search = Sprites.Reactive.Value('');
Sprites.Media.List.SearchControl(search);
Sprites.Ui.Dom.Text(' search = ', search);
Type in the field; the value follows.

Sprites.Media.List.MediaFilter Void

Sprites.Media.List.MediaFilter(media)

The media filter: a dropdown of every media type plus an all option, bound to media.

InputTypeDescription
mediaSprites.Reactive.ValueThe two-way media key the query scopes by.

Returns nothing; it builds the filter.

const media = Sprites.Reactive.Value('');
Sprites.Media.List.MediaFilter(media);
Sprites.Ui.Dom.Text(' media = ', media);
Pick a media type; the value follows.

Sprites.Media.List.PlatformFilter Void

Sprites.Media.List.PlatformFilter(platform)

The platform filter: a dropdown of every platform plus an all option, bound to platform.

InputTypeDescription
platformSprites.Reactive.ValueThe two-way platform the query scopes by.

Returns nothing; it builds the filter.

const platform = Sprites.Reactive.Value('');
Sprites.Media.List.PlatformFilter(platform);
Sprites.Ui.Dom.Text(' platform = ', platform);
Pick a platform; the value follows.

Sprites.Media.List.ClearButton Void

Sprites.Media.List.ClearButton(clear)

The clear filters button. clear is a command value whose lens resets the filters.

InputTypeDescription
clearSprites.Reactive.ValueA command value that resets the filters on click.

Returns nothing; it builds the button.

const search = Sprites.Reactive.Value('hero');
const clear = Sprites.Reactive.Bindingundefined, () => {
  Sprites.Reactive.Set(search, '');
});
Sprites.Media.List.SearchControl(search);
Sprites.Media.List.ClearButton(clear);
Press Clear filters and the search empties.

Sprites.Media.List.BrowserToolbar Void

Sprites.Media.List.BrowserToolbar(view, sort, search, media, platform, showMedia, showPlatform, clear)

The browser toolbar: the view toggle, the search field, the media and platform filters, the sort control and the clear button, in one compact left aligned row. Each filter shows only when its flag is true, and the row does not stretch to the full width.

InputTypeDescription
viewSprites.Reactive.ValueThe list or grid view value.
sortSprites.Reactive.ValueThe sort value.
searchSprites.Reactive.ValueThe name filter.
mediaSprites.Reactive.ValueThe media filter value.
platformSprites.Reactive.ValueThe platform filter value.
showMediaBooleanWhether the media filter shows.
showPlatformBooleanWhether the platform filter shows.
clearSprites.Reactive.ValueThe clear command.

Returns nothing; it builds the toolbar.

const view = Sprites.Reactive.Value('list');
const sort = Sprites.Reactive.Value('modified');
const search = Sprites.Reactive.Value('');
const media = Sprites.Reactive.Value('');
const platform = Sprites.Reactive.Value('');
const clear = Sprites.Reactive.Bindingundefined, () => {
  Sprites.Reactive.Set(search, '');
});
Sprites.Media.List.BrowserToolbar(view, sort, search, media, platform, true, true, clear);
The full toolbar with both filters shown.

Sprites.Media.List.BrowserActions Void

Sprites.Media.List.BrowserActions(item)

The rename and delete actions of a browser row: a Rename and a Delete button, each opening its own window. Shared by the table row and the grid card.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record, with id and name.

Returns nothing; it builds the buttons and their windows.

const item = Sprites.Reactive.Value({ id: 'a', name: 'Hero' });
Sprites.Media.List.BrowserActions(item);
Rename and Delete, each opening its window. This record is not saved, so neither writes.

Sprites.Media.List.BrowserRow Void

Sprites.Media.List.BrowserRow(item, showMedia, showPlatform)

One browser table row: the preview and name link into the editor, then the media, platform, info and date, and the row's actions. The Media and Platform cells show only when their flag is true. A row is a tr, so it belongs inside a table.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record.
showMediaBooleanWhether the Media cell shows.
showPlatformBooleanWhether the Platform cell shows.

Returns nothing; it builds the row.

const item = Sprites.Reactive.Value({ id: 'a', media: 'sprite', platform: 'nes', name: 'Hero', info: '8×8', modified: 0, thumb: '' });
Sprites.Ui.Dom.Tag('table', () => {
  Sprites.Ui.Dom.Tag('tbody', () => {
    Sprites.Media.List.BrowserRow(item, true, true);
  });
});
A full row with the media and platform cells shown.

Sprites.Media.List.BrowserCard Void

Sprites.Media.List.BrowserCard(item)

One browser grid card: the preview links into the editor, then the name and the row's actions, stacked in a bordered card.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record.

Returns nothing; it builds the card.

const item = Sprites.Reactive.Value({ id: 'a', media: 'sprite', platform: 'nes', name: 'Hero', thumb: '' });
Sprites.Media.List.BrowserCard(item);
One grid card: preview, name and actions.

Sprites.Media.List.BrowserTable Void

Sprites.Media.List.BrowserTable(pageItems, isEmpty, empty, showMedia, showPlatform)

The browser table: a head and a body of browser rows for one page. When the page is empty it shows one message row spanning every column, so the head stays put and the listing reads as present but empty.

InputTypeDescription
pageItemsArray or Sprites.Reactive.ValueThe records for one page.
isEmptyBoolean or Sprites.Reactive.ValueWhether the whole list is empty.
emptyString or Sprites.Reactive.ValueThe empty message.
showMediaBooleanWhether the Media column shows.
showPlatformBooleanWhether the Platform column shows.

Returns nothing; it builds the table.

const a = { id: 'a', media: 'sprite', platform: 'nes', name: 'Hero', info: '8×8', modified: 0, thumb: '' };
const b = { id: 'b', media: 'sprite', platform: 'nes', name: 'Foe', info: '8×8', modified: 0, thumb: '' };
const pageItems = Sprites.Reactive.Value([a, b]);
Sprites.Media.List.BrowserTable(pageItems, false, 'You have no sprites yet.', false, true);
Two rows with the platform column shown; set isEmpty true to see the message row.

Sprites.Media.List.BrowserGrid Void

Sprites.Media.List.BrowserGrid(pageItems, isEmpty, empty)

The browser grid: a wrapping flow of cards for one page, or the empty note when the list is empty.

InputTypeDescription
pageItemsArray or Sprites.Reactive.ValueThe records for one page.
isEmptyBoolean or Sprites.Reactive.ValueWhether the whole list is empty.
emptyString or Sprites.Reactive.ValueThe empty message.

Returns nothing; it builds the grid.

const a = { id: 'a', media: 'sprite', platform: 'nes', name: 'Hero', thumb: '' };
const b = { id: 'b', media: 'sprite', platform: 'nes', name: 'Foe', thumb: '' };
const pageItems = Sprites.Reactive.Value([a, b]);
Sprites.Media.List.BrowserGrid(pageItems, false, 'You have no sprites yet.');
Two cards wrapping in a flow; set isEmpty true to see the note.

Sprites.Media.List.PickerSelected Void

Sprites.Media.List.PickerSelected(item, selectedIds)

The selected indicator cell of a picker row: a tick when the row's id is in selectedIds, empty when it is not. It is a td, so it belongs inside a row.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record, with id.
selectedIdsSprites.Reactive.ValueThe array of chosen ids.

Returns nothing; it builds the cell.

const item = Sprites.Reactive.Value({ id: 'a' });
const selectedIds = Sprites.Reactive.Value(['a']);
Sprites.Ui.Dom.Tag('table', () => {
  Sprites.Ui.Dom.Tag('tbody', () => {
    Sprites.Ui.Dom.Tag('tr', () => {
      Sprites.Media.List.PickerSelected(item, selectedIds);
    });
  });
});
The id is in the array, so the cell shows a tick.

Sprites.Media.List.PickerRow Void

Sprites.Media.List.PickerRow(item, selectedIds, mode)

One picker row: the preview and name, and the selected indicator. The whole row toggles selection on click. In single mode it keeps just this row selected; in multiple mode it adds or removes the row. A selected row lights its background. A row is a tr, so it belongs inside a table.

InputTypeDescription
itemObject or Sprites.Reactive.ValueA store record.
selectedIdsSprites.Reactive.ValueThe two-way array of chosen ids.
modeString or Sprites.Reactive.Value'single' or 'multiple'.

Returns nothing; it builds the row.

const item = Sprites.Reactive.Value({ id: 'a', name: 'Hero', thumb: '' });
const selectedIds = Sprites.Reactive.Value([]);
Sprites.Ui.Dom.Tag('table', () => {
  Sprites.Ui.Dom.Tag('tbody', () => {
    Sprites.Media.List.PickerRow(item, selectedIds, 'multiple');
  });
});
const chosenText = Sprites.Text.Join(selectedIds, ', ');
Sprites.Ui.Dom.Text(' chosen = ', chosenText);
Click the row to add and remove its id.

Sprites.Media.List.PickerTable Void

Sprites.Media.List.PickerTable(pageItems, isEmpty, empty, selectedIds, mode)

The picker table: a head and a body of picker rows for one page. When the page is empty it shows one message row spanning every column.

InputTypeDescription
pageItemsArray or Sprites.Reactive.ValueThe records for one page.
isEmptyBoolean or Sprites.Reactive.ValueWhether the whole list is empty.
emptyString or Sprites.Reactive.ValueThe empty message.
selectedIdsSprites.Reactive.ValueThe two-way array of chosen ids.
modeString or Sprites.Reactive.Value'single' or 'multiple'.

Returns nothing; it builds the table.

const a = { id: 'a', name: 'Grass', thumb: '' };
const b = { id: 'b', name: 'Water', thumb: '' };
const pageItems = Sprites.Reactive.Value([a, b]);
const selectedIds = Sprites.Reactive.Value([]);
Sprites.Media.List.PickerTable(pageItems, false, 'Nothing to choose from.', selectedIds, 'multiple');
const chosenText = Sprites.Text.Join(selectedIds, ', ');
Sprites.Ui.Dom.Text(' chosen = ', chosenText);
Two rows; click to toggle each into the chosen list.