Property Inspector
Configurable settings for the plugin.
Stream Deck's integrated HTML5 Property Inspector allows you to communicate with your plugin from Stream Deck software. We recommend using our integrated CSS and tools. Our PISamples plugin demonstrates all supported HTML elements in the Property Inspector.
Stream Deck's Property Inspector (PI) is an HTML5 view based on a standard Flexbox-Layout. We've included some layout and styling to get you started quickly. PI's main view is wrapped in a HTML-node with the class
sdpi-wrapper
.<div class="sdpi-wrapper">
...
your content goes here
...
<div>
To make sure proper styling is applied to the wrapper's contents, you would link our included stylesheet in the
<head>
section of PI's HTML page. Alternatively, you can clone one of the included samples and start from there.<head>
<meta charset="utf-8" />
<title>My Property Inspector</title>
<link rel="stylesheet" href="sdpi.css">
</head>
​
<body>
<div class="sdpi-wrapper">
...
<div>
</body>
Standard elements of Stream Deck's PI consist of a
label
and a value
, each of which can be identified by their respective classes: sdpi-item-label
and sdpi-item-value
. Since you can add multiple label/value pairs, each of these pairs are wrapped into an sdpi-item
node. <div class="sdpi-item">
is basically all that's required. Add a type
to the sdpi-item
to use the included helper CSS.<div class="sdpi-item" type="textarea">
HTML-Element | SDPI-element | Description |
---|---|---|
type="field" <optional> | An input control, which lets the user enter short text (e.g. her name). | |
type="password" | An input control, which lets the user enter obscured text. Instead of characters, the field shows '•'. Text-input is contained in the element's value . | |
type="email" | An input control, which lets the user enter an email-address. Validation is NOT performed automatically. | |
type="date" | An input control to enter a date. | |
type="month" | An input control to select/display a month. | |
type="week" | An input control to select/display a week. | |
type="time" | An input control to select/display a time. | |
type="datetime-local" | An input control to select/display a date/time string in ISO format (e.g. "2019-01-06T12:22"). | |
type="button" <optional> | A styled HTML-button. | |
type="textarea" | An input control, which lets the user enter multiple lines of text. | |
type="select" | A regular select element can have options to select from. | |
type="checkbox" | A checkbox which lets a user selet ('check') one or more of one or more choices. | |
type="radio" | A radio-button (mostly used in a group of radio-buttons) which lets a user select only one of a number of choices. | |
type="range" | A range (or slider) control, to let the user adjust a value (e.g. number or color) | |
type="color" | Shows a color-preview and let the user open a color-picker to change it's value visually | |
type="file" | A file-upload element with label, which opens a file-dialog and lets the user choose a file. It differs a bit from the regular file selector, in that it allows you to pick up the full path of the selected file. (You will find a sample how to do this in the PISamples plugin. | |
type="list" | A regular list element to show items to select from. Ordered, unordered lists and some other list-types are supported. (Btw: in the PISamples plugin, there's a short utility javascript, which already make the lists interactive/clickable... Click here for more info​ | |
type="table" | Also table elements are supported, where each cell can contain a (clickable) value (in the PISamples plugin, you'll find a short utility javascript, which already make the table interactive/clickable... Click here for more info​ | |
type="group" | A container, which allows grouping of arbitrary HTML elements (as the ones mentioned above) | |
​ | A regular <hr> element will add a horizontal line and some spacing | |
class="sdpi-heading" | Draws an horizontal line and additionally a nicely centered heading | |
type="meter" | ||
type="progress" | A progressbar, typically showing the state of a certain progess (e.g. completion). More info (mozilla.org)​ | |
​ | The details element is a complete widget on it's own. It therefore occupies the full width of the PI's view by default. It can be used to create an interactive widget that the user can open and close. You can put any content into it. | |
​ | The message element is similar to the details element. It doesn't show an disclosure-triangle, but you can add some notification icons to it. It can be used to create an interactive widget that the user can open and close. You can put any content into it. |
Note that only 'flat'
sdpi-item
structures are supported. That means, sdpi-item
within another sdpi-item
is unsupported (some exceptions apply, see Group). Adding id
attributes to your elements is recommended.<div class="sdpi-item">
<div class="sdpi-item-label">Name</div>
<input class="sdpi-item-value" id="myname" value="" placeholder="Enter your name">
</div>
<div class="sdpi-item">
<div class="sdpi-item-label">Email</div>
<input class="sdpi-item-value" id="myemail" value="" placeholder="Enter your email-address">
</div>

Property Inspector Input
The
required
attributeIf you want to notify the user of a
required
value, you can simply add a required
control, which shows a tiny exclamation mark, as long as there's no text in the field.
Property Inspector Input
<div type="textarea" class="sdpi-item" id="required_text">
<div class="sdpi-item-label">Some Text</div>
<span class="sdpi-item-value">
<input type="text" id="mytext" required></input>
</span>
</div>
A checkmark is displayed in completed fields:

Property Inspector Input Completed Checkmark
The
pattern
attributeYou can use the
pattern
attribute to specify a pattern to validate the IP-Address.<div class="sdpi-item" id="your_name" title="This field lets you enter an IP-Adress. The little exclamation mark changes to a checkmark, if the condition is met (e.g. you entered an IP-address.).">
<div class="sdpi-item-label">IP-Address</div>
<input class="sdpi-item-value" id="myipaddress" value="" placeholder="e.g. 192.168.61.1" required pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}">
</div>
Here are some example patterns:
- 8 characters or more:
pattern=".{6,}"
- 2-character country code (e.g. EN):
pattern="[A-Za-z]{2}"
Pattern | Description |
---|---|
pattern="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}" | IP-address |
pattern=".{8,}" | 8 characters or more |
pattern="[A-Za-z]{2}" | 2 character country code |
pattern="[^'\x22]+" | no single or double quotes |
pattern="(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).{4,}" | at least 4 characters, 1 uppercase, 1 lowercase and 1 number |
If you need to enter some more text, you can easily add a
textarea
control, which allows for multi-line text.<div type="textarea" class="sdpi-item" id="message_only">
<div class="sdpi-item-label">Message</div>
<span class="sdpi-item-value textarea">
<textarea type="textarea" id="mytextarea"></textarea>
</span>
</div>

Textarea
You can add info-text to the bottom of the textarea by adding a
label
right after the textarea
and giving the label a for
attribute with the value of the textarea's id.
Textarea
<div type="textarea" class="sdpi-item" id="message_only">
<div class="sdpi-item-label">Message</div>
<span class="sdpi-item-value textarea">
<textarea type="textarea" maxlength="50" id="txa1"></textarea>
<label for="txa1" >0/50</label>
</span>
</div>
Adding a little Javascript to PI's webview, can make this into a nice counter:
document.querySelectorAll('textarea').forEach(e => {
const maxl = e.getAttribute('maxlength');
e.targets = document.querySelectorAll(`[for='${e.id}']`);
if (e.targets.length) {
let fn = () => {
for(t of e.targets) {
t.innerText = maxl ? `${e.value.length}/${maxl}` : `${e.value.length}`;
}
};
fn();
e.onkeyup = fn;
}
});
<div class="sdpi-item">
<div class="sdpi-item-label">Button</div>
<button class="sdpi-item-value" id="mybutton">Click Me</button>
</div>

Full Button
By default, the button's width takes the full available width. We included a couple of utility-classes in
sdpi.css
to restrict width of a button. E.g class max20
limits the width to approx 20% of the total width:
Button
<div class="sdpi-item">
<div class="sdpi-item-label">Button</div>
<button class="sdpi-item-value max20" id="mybutton">Click Me</button>
</div>
Placing two buttons side by side will automatically arrange them horizontally (by the limits of the available space).

Multiple Buttons
<div class="sdpi-item">
<div class="sdpi-item-label">Button</div>
<button class="sdpi-item-value" id="mybutton">Click Me</button>
<button class="sdpi-item-value" id="myotherbutton">Or Me</button>
</div>
This also works for other combinations of elements:

Button and Dropdown
<div class="sdpi-item">
<div class="sdpi-item-label">Button</div>
<select class="sdpi-item-value select" id="myselect">
<option value="[email protected]">Jane Doe</option>
<option value="[email protected]">Some Guy</option>
</select>
<button class="sdpi-item-value">Or Me</button>
</div>
Creating a HTML5 select box with a label is straightforward:

Dropdown
<div class="sdpi-item" id="select_single">
<div class="sdpi-item-label">Select</div>
<select class="sdpi-item-value select" id="myselect">
<option value="20">20</option>
<option value="50">50</option>
<option value="100">100</option>
</select>
</div>
HTML5
optgroups
inside the select are supported as well:
Group Dropdown
<div class="sdpi-item" id="select_single">
<div class="sdpi-item-label">Select</div>
<select class="sdpi-item-value select" id="myselect">
<optgroup label="Women">
<option value="[email protected]">Jane Doe</option>
<option value="[email protected]">Some Girl</option>
<option value="[email protected]">Yoko Hama</option>
</optgroup>
<optgroup label="Men">
<option value="[email protected]">John Doe</option>
<option value="[email protected]">Some Man</option>
<option value="[email protected]">Another Chap</option>
</optgroup>
</select>
</div>
Creating a HTML5 checkboxes with a label is getting more involved because there's no themeable checkbox available in today's browsers and HTML renderers. Creating checkboxes generally works the same way:
A single checkbox doesn't require a separate value-container, so you can put the
sdpi-item-value
class right onto the input-element:<div type="checkbox" class="sdpi-item">
<div class="sdpi-item-label">Check Me </div>
<input class="sdpi-item-value" id="chk0" type="checkbox" value="left">
<label for="chk0"><span></span>left</label>
</div>
In order to let the PI know there are a group of checkboxes, you just put these checkboxes into a
sdpi-item-value
wrapper... <div type="checkbox" class="sdpi-item">
<div class="sdpi-item-label">Check Me</div>
<div class="sdpi-item-value ">
<input id="chk1" type="checkbox" value="left">
<label for="chk1"><span></span>left</label>
<input id="chk2" type="checkbox" value="right">
<label for="chk2"§><span></span>right</label>
</div>
</div>

Checkboxes
Please note the additional
<span>
element, which is used to override the browser's default checkbox. It remains empty and serves just as a placeholder. This is a common technique to allow drawing custom checkboxes, radio-buttons, etc.If you need more than 2 or 3 checkboxes, alignment can get tricky and you end up with this:
<div type="checkbox" class="sdpi-item">
<div class="sdpi-item-label">Check Me</div>
<div class="sdpi-item-value ">
<input id="chk1" type="checkbox" value="left">
<label for="chk1" class="sdpi-item-label"><span></span>Monday</label>
<input id="chk2" type="checkbox" value="right">
<label for="chk2" class="sdpi-item-label"><span></span>Tuesday</label>
<input id="chk3" type="checkbox" value="left">
<label for="chk3" class="sdpi-item-label"><span></span>Wednesday</label>
<input id="chk4" type="checkbox" value="right">
<label for="chk4" class="sdpi-item-label"><span></span>Thursday</label>
<input id="chk5" type="checkbox" value="left">
<label for="chk5" class="sdpi-item-label"><span></span>Friday</label>
<input id="chk6" type="checkbox" value="right">
<label for="chk6" class="sdpi-item-label"><span></span>Saturday</label>
</div>
</div>

Multiple Checkboxes Alignment
We added a helper-node
sdpi-item-child
, which you can use to group checkboxes/radio-buttons and their labels for easier alignment. Please note the min100
class in the parent element sdpi-item-value min100
, which means the subsequent sdpi-item-value
elements will be at least 100px wide. You can add CSS or even inline-styles to override this behavior. Using the sdpi-item-child
class to 'group' input and label, will produce a much nicer output:<div type="checkbox" class="sdpi-item" id="multi-items">
<div class="sdpi-item-label">Select day</div>
<div class="sdpi-item-value min100">
<div class="sdpi-item-child">
<input id="days1" type="checkbox" value="left">
<label for="days1" class="sdpi-item-label"><span></span>Monday</label>
</div>
<div class="sdpi-item-child">
<input id="days2" type="checkbox" value="right">
<label for="days2" class="sdpi-item-label"><span></span>Tuesday</label>
</div>
<div class="sdpi-item-child">
<input id="days3" type="checkbox" value="center">
<label for="days3" class="sdpi-item-label"><span></span>Wednesday</label>
</div>
<div class="sdpi-item-child">
<input id="days4" type="checkbox" value="red" checked>
<label for="days4" class="sdpi-item-label"><span></span>Thursday</label>
</div>
<div class="sdpi-item-child">
<input id="days5" type="checkbox" value="green">
<label for="days5" class="sdpi-item-label"><span></span>Friday</label>
</div>
<div class="sdpi-item-child">
<input id="days6" type="checkbox" value="blue">
<label for="days6" class="sdpi-item-label"><span></span>Saturday</label>
</div>
</div>
</div>
Creating an input of type
radio
follows the same logic as creating an input of type checkbox
:
Radio Buttons
<div type="radio" class="sdpi-item" id="adjust_radio">
<div class="sdpi-item-label">Adjust Radio</div>
<div class="sdpi-item-value ">
<span class="sdpi-item-child">
<input id="rdio1" type="radio" name="rdio" >
<label for="rdio1" class="sdpi-item-label"><span></span>on</label>
</span>
<span class="sdpi-item-child">
<input id="rdio2" type="radio" value="off" name="rdio" checked>
<label for="rdio2" class="sdpi-item-label"><span></span>off</label>
</span>
<span class="sdpi-item-child">
<input id="rdio3" type="radio" value="mute" name="rdio">
<label for="rdio3" class="sdpi-item-label"><span></span>mute</label>
</span>
</div>
</div>
Creating a slider (aka. HTML5
range
control) is as easy as changing the 'type' attribute of the input.
Range
<div type="range" class="sdpi-item" id="temperatureslider">
<div class="sdpi-item-label">Temperature</div>
<div class="sdpi-item-value">
<input type="range" min="0" max="100" value=37>
</div>
</div>
For control-items like this, you can avoid the additional
<div class="sdpi-item-value">
and add the class directly to the input, like so:
<div type="range" class="sdpi-item" id="temperatureslider">
<div class="sdpi-item-label">Temperature</div>
<input type="range" class="sdpi-item-value" min="0" max="100" value=37>
</div>
To add labels to a range, however, a range must be grouped into an
sdpi-item-value
, and labels get added as span
elements:
Range With Labels
<div type="range" class="sdpi-item" id="range_with_meters">
<div class="sdpi-item-label">Range (with label)</div>
<div class="sdpi-item-value">
<span class="clickable" value="0">0</span>
<input type="range" min="0" max="100" value=74>
<span class="clickable" value="100">100</span>
</div>
</div>
Note: In the PISamples-plugin, a
span
of class clickable
is intercepted, and the value of its 'range' element is set to the value specified in the 'value' attribute of the span
element. If you leave out the value
attribute from the span
element, PI tries to use the value in the span
text-node.Adding a datalist to a range produces
steps
. Pi's slider will snap to those steps.
Range with Datalist
<div type="range" class="sdpi-item" id="range_with_datalist">
<div class="sdpi-item-label">Range (with datalist)</div>
<div class="sdpi-item-value">
<span class="clickable" value="0">0</span>
<input type="range" min="0" max="100" step="25" list="numbers">
<datalist id="numbers">
<option>25</option>
<option>50</option>
<option>75</option>
</datalist>
<span class="clickable" value="100">100</span>
</div>
</div>
Creating a color-selector is as easy as changing the 'type' attribute of the input.
<div type="range" class="sdpi-item" id="temperatureslider">
<div class="sdpi-item-label">Temperature</div>
<div class="sdpi-item-value">
<input type="color" id="mycolor" value="#ff0000">
</div>
</div>

Color
or the shorter version, which produces the same output:
<div type="color" class="sdpi-item" id="colorselection">
<div class="sdpi-item-label">Color</div>
<input type="color" class="sdpi-item-value" id="mycolor" value="#ff0000">
</div>
To present some pre-defined color values, you can add a datalist to the color control. To make sure the list gets appended properly, set the
list
attribute of the input
control to the id
of the datalist
. (in our example 'clrs')
Color With Selection
<div type="color" class="sdpi-item" id="colorselection">
<div class="sdpi-item-label">Color</div>
<input type="color" id="mycolorselection" class="sdpi-item-value" value="#3333cc" list="clrs" >
<datalist id="clrs">
<option>#ff0000</option>
<option>#0000ff</option>
<option>#00ff00</option>
<option>#ffff00</option>
<option>#3333cc</option>
<option>#00ffff</option>
</datalist>