You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This repository is work in progress and highly experimental at the moment.
This repository collects web components that are used to control views in the Edirom. It consists of:
edirom-control-bar — a wrapper web component for different constellations of control elements.
different control elements in the form of small web components:
edirom-button-widget — a square icon button widget for use inside a control bar.
edirom-spin-box-widget — a step navigator with previous/next buttons and a text input.
edirom-spacer-widget — a layout helper that fills available space between control widgets.
edirom-select-widget — a single-choice selector built on a native <select>.
edirom-multi-select-widget — an icon button that opens a checkbox list (dropdown or bottom sheet) for choosing several values.
All widgets follow an external-state-only pattern: a user action dispatches a …-requested event, and the host application confirms it by setting the corresponding attribute. A demo page for manual testing lives in demo/index.html (serve the parent Web-Components directory, because the widgets import edirom-icon from ../edirom-core-web-components).
edirom-button-widget
A square icon button for use inside an edirom-control-bar. It renders an edirom-icon (from edirom-core-web-components) centred inside a rounded container. The element maintains a 1:1 aspect ratio and fills the full height of its parent.
The button operates as a state carousel: it holds a list of named states (each with an associated icon), displays the icon of the current state, and on each click dispatches a request for the next state without advancing itself. The calling application is responsible for setting the new current-state attribute in response to that event.
Attributes
Attribute
Type
Default
Description
states-data
JSON string (array)
'[]'
Stringified array of state objects. Each object must have a name (string) and an iconName (string) key. The array order defines the carousel sequence.
current-state
string
—
The name of the active state. When set, the button renders the corresponding icon. If the name is not found in states-data, an error is logged and the button does not update. If absent, the button renders with an empty icon.
State object shape:
{ "name": "unlocked", "iconName": "lock_open" }
Events
Event
bubbles
composed
detail
Description
button-state-requested
✅
✅
{ requestedState: string }
Fired on click. requestedState is the name of the next state in carousel order. The component does not change state on its own — set current-state externally to confirm the transition.
CSS Custom Properties
Property
Default
Description
--secondary-color
#ffffff00 (transparent)
Background colour of the button inner container.
--button-widget-padding
2px
Padding inside the button inner container.
Usage
<scripttype="module" src="edirom-button-widget.js"></script><!-- Two-state lock toggle --><edirom-button-widgetstates-data='[{"name":"unlocked","iconName":"lock_open"},{"name":"locked","iconName":"lock_closed"}]'
current-state="unlocked"></edirom-button-widget><!-- Handling the state-change request externally --><script>constbtn=document.querySelector('edirom-button-widget');btn.addEventListener('button-state-requested',(e)=>{btn.setAttribute('current-state',e.detail.requestedState);});</script><!-- Inside a control bar --><edirom-control-bargap="8px"><edirom-button-widgetstates-data='[{"name":"play","iconName":"play"},{"name":"pause","iconName":"pause"}]'
current-state="play"></edirom-button-widget><edirom-spacer-widget></edirom-spacer-widget><edirom-button-widgetstates-data='[{"name":"unlocked","iconName":"lock_open"},{"name":"locked","iconName":"lock_closed"}]'
current-state="unlocked"></edirom-button-widget></edirom-control-bar>
edirom-control-bar
A horizontal flex-row container for control widgets. It fills the full width and height of its parent and centers all child widgets vertically. Widgets are inserted via the default slot — no slot="..." attribute needed on children.
Attributes
Attribute
Type
Default
Description
layout-mode
"desktop" | "mobile"
"desktop"
Switches the template. Desktop uses 8px horizontal padding, mobile uses 4px.
gap
CSS length string
"0"
Gap between child widgets, passed directly to the CSS gap property (e.g. "8px", "0.5rem").
Usage
<scriptsrc="edirom-control-bar.js"></script><scriptsrc="edirom-spacer-widget.js"></script><!-- Basic bar --><edirom-control-bargap="8px"><edirom-button>Back</edirom-button><edirom-button>Forward</edirom-button></edirom-control-bar><!-- Left group / right group separated by a spacer --><edirom-control-bargap="8px"><edirom-button>Left</edirom-button><edirom-spacer-widget></edirom-spacer-widget><edirom-slider></edirom-slider><edirom-menu></edirom-menu></edirom-control-bar><!-- Three groups with unequal spacing between them --><edirom-control-bargap="8px"><edirom-button>Left</edirom-button><edirom-spacer-widget></edirom-spacer-widget><edirom-button>Center</edirom-button><edirom-spacer-widgetgrow="2"></edirom-spacer-widget><edirom-button>Right</edirom-button></edirom-control-bar><!-- Mobile layout --><edirom-control-barlayout-mode="mobile" gap="4px"><edirom-button>A</edirom-button><edirom-spacer-widget></edirom-spacer-widget><edirom-button>B</edirom-button></edirom-control-bar>
edirom-spacer-widget
A layout helper that expands to fill available space in the flex row of an edirom-control-bar. Inserting a spacer between two widgets pushes the widgets on either side to opposite ends of the bar. Multiple spacers with different grow values create proportional spacing groups.
Attributes
Attribute
Type
Default
Description
grow
Number
1
Maps to CSS flex-grow. A spacer-widget with grow="2" consumes twice the available space compared to a default spacer-widget.
Usage
<!-- Equal spacing on both sides of a centered group --><edirom-control-bargap="8px"><edirom-spacer-widget></edirom-spacer-widget><edirom-button>Centered</edirom-button><edirom-spacer-widget></edirom-spacer-widget></edirom-control-bar><!-- Weighted: center item closer to the right --><edirom-control-bargap="8px"><edirom-spacer-widgetgrow="2"></edirom-spacer-widget><edirom-button>Skewed right</edirom-button><edirom-spacer-widget></edirom-spacer-widget></edirom-control-bar>
edirom-spin-box-widget
A step navigator for use inside an edirom-control-bar. It displays a text input flanked by a previous (eo_previous) and a next (eo_next) icon button. The user can step through a predefined list of values by clicking the icons or by typing a value into the text field and pressing Enter.
Like edirom-button-widget, this component follows an external-state-only pattern: clicking a button or submitting a text value dispatches a request event but does not change the current step. The host application must set the current-step attribute in response to validate and confirm the transition.
Attributes
Attribute
Type
Default
Description
steps-data
JSON string (array)
'[]'
Stringified array of step values. Each element can be a string or an integer (e.g. '["Step 1", 2, "5", 100]'). The array order defines the navigation sequence. All values are compared as strings internally.
current-step
string
—
The value of the active step. Must match a value in steps-data when compared as a string (e.g. set "2" to match the integer 2). If the value is not found, a warning is logged and the display is not updated. When steps-data contains duplicate values, the occurrence nearest to the previously resolved index is selected (first occurrence on initial load).
carrousel
"true" | "false"
"false"
When "true", navigation wraps around: stepping past the last value continues at the first, and vice versa. When "false", the previous button is hidden at the first step and the next button is hidden at the last step.
label
string
—
Optional short label rendered above the text input in a small font (~60% of the host font size). The label is left-aligned and truncated with an ellipsis (…) when it is wider than the input field. When set to a non-empty string, the input shrinks to 75% of the component height and its font size is reduced to 75% to leave room for the label. When absent or empty, the input occupies the full height and font size (no visual change).
Events
Event
bubbles
composed
detail
Description
spin-box-step-requested
✅
✅
{ requestedStep: string }
Fired when the user clicks a navigation icon or submits a valid value via the text input (Enter key). requestedStep is the string value of the target step. The component does not change step on its own — set current-step externally to confirm the transition. If the user types a value not present in steps-data, no event is fired and the input reverts to the current step.
CSS Custom Properties
Property
Default
Description
--spin-box-input-width
4ch
Width of the text input field.
--spin-box-gap
0
Gap between the previous icon, text input, and next icon.
--spin-box-border-color
#ccc
Border colour of the text input.
--spin-box-input-color
fieldtext (browser default)
Text colour of the text input.
--spin-box-input-background
field (browser default)
Background colour of the text input.
--spin-box-border-radius
4px
Border radius of the text input.
--spin-box-input-padding
0 2px
Padding inside the text input.
Usage
<scripttype="module" src="edirom-spin-box-widget.js"></script><!-- Basic step navigation --><edirom-spin-box-widgetsteps-data='["Schritt 1", 2, "5", 100, "another string"]'
current-step="Schritt 1"></edirom-spin-box-widget><!-- Handling the step-change request externally --><script>constspin=document.querySelector('edirom-spin-box-widget');spin.addEventListener('spin-box-step-requested',(e)=>{spin.setAttribute('current-step',e.detail.requestedStep);});</script><!-- Carrousel mode --><edirom-spin-box-widgetsteps-data='["A", "B", "C"]'
current-step="A"
carrousel="true"></edirom-spin-box-widget><!-- Custom input width --><style>.wide-spin-box{--spin-box-input-width:10ch;}</style><edirom-spin-box-widgetclass="wide-spin-box"
steps-data='["Largo", "Andante", "Allegro", "Presto"]'
current-step="Andante"></edirom-spin-box-widget><!-- With a label above the input --><edirom-spin-box-widgetsteps-data='[1, 2, 3, 4, 5]'
current-step="1"
label="Annotationen"></edirom-spin-box-widget><!-- Inside a control bar --><edirom-control-bargap="8px"><edirom-spacer-widget></edirom-spacer-widget><edirom-spin-box-widgetsteps-data='[1, 2, 3, 4, 5]'
current-step="1"></edirom-spin-box-widget><edirom-spacer-widget></edirom-spacer-widget></edirom-control-bar>
edirom-select-widget
A single-choice selector for use inside an edirom-control-bar, built on a native <select>. Phones show their own picker (wheel or sheet) with the full option labels, while the closed field can be kept compact and is truncated with an ellipsis. Keyboard and screen-reader support come from the native element.
The component knows nothing about its content: options are a generic list of values and labels (movements, works, languages, view types, …). Choosing an option dispatches a request event and does not change the value on its own — set value externally to confirm it. Until then the field shows the confirmed value again.
Attributes
Attribute
Type
Default
Description
options-data
JSON string (array)
'[]'
Stringified array of options. Each element is either an object { "value": string, "label"?: string, "group"?: string, "disabled"?: boolean } or a plain string/number (used as value and label). Options sharing a group are rendered in an <optgroup> with that label.
value
string
—
The confirmed value. If it is absent or not found in options-data, the placeholder is shown (and a warning is logged for an unknown value).
label
string
—
Optional short caption rendered above the field in a small font, like the label of edirom-spin-box-widget. With a label the field shrinks to 75% of the height and font size.
placeholder
string
''
Text shown while no valid value is confirmed. It cannot be chosen by the user.
accessible-label
string
value of label
Accessible name of the field (aria-label). Use it when there is no visible label.
disabled
boolean
—
Disables the field.
custom-picker
boolean
—
Opt-in: in browsers that support customizable selects (appearance: base-select) the open list is styled with the widget's theme instead of the platform picker. Leave it off to keep the native picker on phones.
Events
Event
bubbles
composed
detail
Description
select-value-requested
✅
✅
{ requestedValue: string }
Fired when the user chooses an option. Set value to confirm it.
CSS Custom Properties
Property
Default
Description
--select-widget-max-width
none
Maximum width of the widget (e.g. 10ch for a compact field in a mobile control bar).
--select-widget-color
fieldtext
Text colour of the field.
--select-widget-background
field
Background colour of the field.
--select-widget-border-color
#ccc
Border colour of the field (and of the custom picker).
--select-widget-border-radius
4px
Border radius of the field.
--select-widget-padding
0 2px
Padding inside the field.
--select-widget-picker-background
var(--tertiary-color, Canvas)
Background of the open list (only with custom-picker).
--select-widget-picker-color
var(--primary-color, CanvasText)
Text colour of the open list (only with custom-picker).
Parts and states
Selector
Description
::part(inner), ::part(label), ::part(select)
The wrapper, the caption and the native <select>.
:state(empty)
No valid value is confirmed (the placeholder is shown).
Usage
<scripttype="module" src="edirom-select-widget.js"></script><edirom-select-widgetlabel="Movement"
options-data='[{"value":"m1","label":"Allegro"},{"value":"m2","label":"Adagio"}]'
value="m1"></edirom-select-widget><script>constselect=document.querySelector('edirom-select-widget');select.addEventListener('select-value-requested',(e)=>{select.setAttribute('value',e.detail.requestedValue);});</script><!-- Compact inside a mobile control bar --><style>#movement-select{--select-widget-max-width:10ch;}</style>
edirom-multi-select-widget
A multiple-choice selector for use inside an edirom-control-bar: a square icon button (same look as edirom-button-widget) that opens a panel with a checkbox list. The panel uses the native Popover API, so it lives in the top layer and closes on Escape or a click outside without extra script.
layout-mode="desktop" (default): a dropdown anchored to the button (CSS anchor positioning, which flips above the button when there is no room below; a script fallback places it in browsers without anchor positioning).
layout-mode="mobile": a bottom sheet over a dimmed page, with touch-sized rows.
Like the other widgets it is content-agnostic (voices, annotation categories, layers, overlays, …) and follows the external-state pattern: a change dispatches multi-select-values-requested, and the checkboxes show the confirmed selected-values until the host sets them.
Attributes
Attribute
Type
Default
Description
options-data
JSON string (array)
'[]'
Stringified array of options, in display order. Each element is either an object { "value": string, "label"?: string, "group"?: string, "disabled"?: boolean } or a plain string/number. Options sharing a group are rendered in a <fieldset> with that legend. Duplicate values are ignored.
selected-values
JSON string (array)
'[]'
The confirmed selection, as an array of values.
icon
string
—
Name of the edirom-icon shown in the button (e.g. eo_voice_filter).
label
string
—
Heading of the panel, also the button's tooltip and accessible name.
accessible-label
string
value of label
Overrides the accessible name and tooltip of the button.
select-all-label
string
—
When set, a "select all" checkbox with this text is shown above the options. It is mixed (indeterminate) when only some options are selected; unchecking it keeps the first min-selected options.
min-selected
integer
0
Minimum number of selected options. When it is reached, the remaining selected checkboxes are disabled.
max-selected
integer
—
Maximum number of selected options. When it is reached, the unselected checkboxes are disabled.
commit-mode
"immediate" | "confirm"
"immediate"
immediate: every checkbox change dispatches a request. confirm: changes are collected and dispatched on the apply button; cancel, Escape or a click outside discard them.
apply-label / cancel-label
string
"OK" / "Cancel"
Texts of the buttons in confirm mode.
close-label
string
"Close"
Accessible name and tooltip of the close button (✕) in the top right corner of the panel. It closes the panel and, in confirm mode, discards unapplied changes.
layout-mode
"desktop" | "mobile"
"desktop"
Dropdown or bottom sheet (see above).
disabled
boolean
—
Disables the button (and closes an open panel).
Events
Event
bubbles
composed
detail
Description
multi-select-values-requested
✅
✅
{ requestedValues: string[] }
Fired on a change (immediate mode) or on apply (confirm mode). The values are in options order. Set selected-values to confirm them.
multi-select-toggle
✅
✅
{ open: boolean }
Fired when the panel opens or closes.
Properties and methods
Member
Description
open (read-only)
Whether the panel is open.
show() / hide()
Opens / closes the panel (e.g. to close it on a "back" gesture).
selectedValues (read-only)
The confirmed values, in options order.
CSS Custom Properties
Property
Default
Description
--secondary-color
#ffffff00 (transparent)
Background colour of the button.
--button-widget-padding
2px
Padding inside the button.
--multi-select-accent
var(--primary-color, AccentColor)
Checkbox colour (accent-color), focus ring and apply button.
--multi-select-panel-background
var(--tertiary-color, Canvas)
Background of the panel.
--multi-select-panel-color
var(--primary-color, CanvasText)
Text colour of the panel.
--multi-select-panel-border-color
20% of the text colour
Border of the panel.
--multi-select-panel-width
max-content
Width of the dropdown (desktop).
--multi-select-panel-max-height
min(70vh, 30rem) (desktop), 60dvh (mobile)
Maximum height of the panel; the list scrolls inside it.
Some, but not all, options are selected (e.g. to show that a filter is active).
:state(none)
No option is selected.
Usage
<scripttype="module" src="edirom-multi-select-widget.js"></script><edirom-multi-select-widgeticon="eo_voice_filter"
label="Select parts"
select-all-label="All parts"
min-selected="1"
layout-mode="mobile"
options-data='[{"value":"cl","label":"Clarinet"},{"value":"vl1","label":"Violin I"},{"value":"vc","label":"Violoncello"}]'
selected-values='["cl","vl1","vc"]'></edirom-multi-select-widget><script>constvoices=document.querySelector('edirom-multi-select-widget');voices.addEventListener('multi-select-values-requested',(e)=>{voices.setAttribute('selected-values',JSON.stringify(e.detail.requestedValues));});</script><!-- Highlight the button while a filter is active --><style>edirom-multi-select-widget:state(partial){--secondary-color:#aaa;}</style>
About
Collection of different control UI widgets used in the Edirom and the Control Bar web component to wrap these widgets