sdpi-components
Comprehensive reference for sdpi-components (Stream Deck Property Inspector Components) - the official UI library for building Property Inspectors. Covers all components, data sources, Stream Deck Client API, and localization patterns.
SKILL.md
| Name | sdpi-components |
| Description | Comprehensive reference for sdpi-components (Stream Deck Property Inspector Components) - the official UI library for building Property Inspectors. Covers all components, data sources, Stream Deck Client API, and localization patterns. |
name: sdpi-components description: Comprehensive reference for sdpi-components (Stream Deck Property Inspector Components) - the official UI library for building Property Inspectors. Covers all components, data sources, Stream Deck Client API, and localization patterns.
sdpi-components Reference Skill
This skill provides comprehensive guidance for using sdpi-components (Stream Deck Property Inspector Components), the official UI library for building Property Inspectors in Stream Deck plugins.
It is designed to be used with coding agents compatible with the add-skill specification.
References:
When to Use
Use this skill whenever you need to:
- Build or modify Property Inspector UIs using sdpi-components
- Select appropriate components for different input types
- Implement data sources for dynamic content (selects, checkboxes, radios)
- Use Stream Deck Client API for plugin communication
- Handle settings persistence (action-specific or global)
- Debug Property Inspector issues related to sdpi-components
- Review Property Inspector code for best practices with sdpi-components
High‑Level Concepts
Before using sdpi-components, keep these core concepts in mind:
-
sdpi-components
- The official UI library for Stream Deck Property Inspectors.
- Built with Lit.js and compiled to standard web components.
- Provides consistent, accessible UI components that handle settings persistence automatically.
- No build setup required — just include a single JavaScript file.
-
Component structure
- All components are prefixed with
sdpi-(e.g.,<sdpi-textfield>,<sdpi-checkbox>). - Components are typically wrapped in
<sdpi-item>with alabelattribute for consistent layout. - Components support the
settingattribute to bind to settings paths (supports nested paths likefoo.bar.prop).
- All components are prefixed with
-
Settings persistence
- Components automatically persist values to action-specific settings via the
settingattribute. - Use the
globalattribute to persist to global settings (shared across all action instances). - Settings are automatically synced between Property Inspector and plugin.
- Components automatically persist values to action-specific settings via the
-
Communication
- Components handle basic settings communication automatically.
- Use
SDPIComponents.streamDeckClientfor advanced communication patterns. - Supports bidirectional communication: Property Inspector ↔ Plugin.
-
Data sources
- Some components (
<sdpi-select>,<sdpi-checkbox-list>,<sdpi-radio>) support dynamic data sources. - Data sources fetch items from the plugin at runtime.
- Supports hot-reload for real-time updates.
- Some components (
Prerequisites Checklist
Before using sdpi-components, verify all of the following:
-
Property Inspector setup
- You have a Property Inspector HTML file in your plugin's
ui/directory. - The
PropertyInspectorPathis configured inmanifest.json(action or plugin level).
- You have a Property Inspector HTML file in your plugin's
-
Library inclusion
- Decide whether to use local (recommended) or remote (development) reference.
- If using locally, download
sdpi-components.jsfrom releases. - Place
sdpi-components.jsin theui/directory alongside your HTML file.
-
Technical decisions
- Determine which components you need for your settings UI.
- Plan your settings data structure (what properties need to be configured).
- Consider whether you need data sources for dynamic content.
Repository & File Structure
Property Inspector files using sdpi-components should be organized as follows:
my-streamdeck-plugin/
*.sdPlugin/
├── bin/
├── imgs/
├── ui/ # Property Inspector files
│ ├── my-action.html
│ └── sdpi-components.js # Local library (recommended)
└── manifest.json
src/
├── actions/
└── plugin.ts
The ui/ directory contains all Property Inspector HTML files and the sdpi-components.js library.
Step‑by‑Step: Getting Started with sdpi-components
Follow these steps to use sdpi-components in your Property Inspector:
1. Include the library
Local (recommended for distribution):
- Download
sdpi-components.jsfrom the releases page. - Place it in your
ui/directory. - Reference it in your HTML:
<script src="sdpi-components.js"></script>
Remote (development/prototyping only):
<script src="https://sdpi-components.dev/releases/v4/sdpi-components.js"></script>
⚠️ Important: Always use local references when distributing your plugin to ensure it works offline and provides a consistent experience.
2. Basic HTML structure
Create your Property Inspector HTML file:
<!doctype html>
<html>
<head lang="en">
<meta charset="utf-8" />
<script src="sdpi-components.js"></script>
</head>
<body>
<sdpi-item label="Name">
<sdpi-textfield setting="name" placeholder="Enter name"></sdpi-textfield>
</sdpi-item>
<sdpi-item label="Enabled">
<sdpi-checkbox setting="enabled"></sdpi-checkbox>
</sdpi-item>
</body>
</html>
3. Configure components with settings
Use the setting attribute to bind components to your settings:
<sdpi-item label="Favorite Color">
<sdpi-color setting="favColor"></sdpi-color>
</sdpi-item>
<sdpi-item label="Timeout (seconds)">
<sdpi-range setting="timeout" min="1" max="60" step="1" showlabels></sdpi-range>
</sdpi-item>
4. Use global settings (optional)
To persist settings globally (shared across all action instances):
<sdpi-item label="API Key">
<sdpi-textfield setting="apiKey" global></sdpi-textfield>
</sdpi-item>
5. Access Stream Deck Client (optional)
For advanced communication patterns:
<script>
const { streamDeckClient } = SDPIComponents;
// Get current settings
streamDeckClient.getSettings().then(payload => {
console.log('Current settings:', payload.settings);
});
// Listen for settings updates
streamDeckClient.didReceiveSettings.subscribe(ev => {
console.log('Settings updated:', ev.payload.settings);
});
// Set settings programmatically
streamDeckClient.setSettings({
name: "John Doe",
enabled: true
});
</script>
Available Components
The sdpi-components library provides the following web components:
Form Input Components
<sdpi-textfield>
Single-line text input.
Attributes:
setting(string): Path in settings object (supports nested paths)value(string): Current valuedefault(string): Default value if setting is undefinedplaceholder(string): Placeholder textdisabled(boolean): Whether the input is disabledrequired(boolean): Shows icon when value is emptymaxlength(number): Maximum length for the input stringpattern(string): Regular expression for validationglobal(boolean): Persist to global settings
Example:
<sdpi-item label="Name">
<sdpi-textfield
setting="name"
placeholder="Enter your name"
required>
</sdpi-textfield>
</sdpi-item>
<sdpi-textarea>
Multi-line text input.
Attributes:
setting(string): Path in settings objectvalue(string): Current valuedefault(string): Default valueplaceholder(string): Placeholder textdisabled(boolean): Whether the input is disabledrows(number): Number of visible rowsglobal(boolean): Persist to global settings
Example:
<sdpi-item label="Description">
<sdpi-textarea setting="description" rows="4"></sdpi-textarea>
</sdpi-item>
<sdpi-password>
Password input (obscured text).
Attributes:
setting(string): Path in settings objectvalue(string): Current valuedefault(string): Default valueplaceholder(string): Placeholder textdisabled(boolean): Whether the input is disabledglobal(boolean): Persist to global settings
Example:
<sdpi-item label="API Key">
<sdpi-password setting="apiKey"></sdpi-password>
</sdpi-item>
Selection Components
<sdpi-checkbox>
Single boolean checkbox.
Attributes:
setting(string): Path in settings objectvalue(boolean): Current statedefault(boolean): Default state if setting is undefinedlabel(string): Label shown next to checkboxdisabled(boolean): Whether the checkbox is disabledglobal(boolean): Persist to global settings
Example:
<sdpi-item label="Options">
<sdpi-checkbox setting="enabled" label="Enable feature"></sdpi-checkbox>
</sdpi-item>
<sdpi-checkbox-list>
Multiple checkboxes (supports data sources).
Attributes:
setting(string): Path in settings object (stores array of selected values)datasource(string): Optional remote data source event nameloading(string): Text shown while loading data sourcehot-reload(boolean): MonitorsendToPropertyInspectorfor updatesglobal(boolean): Persist to global settings
Example (static):
<sdpi-item label="Features">
<sdpi-checkbox-list setting="features">
<option value="feature1">Feature 1</option>
<option value="feature2">Feature 2</option>
<option value="feature3">Feature 3</option>
</sdpi-checkbox-list>
</sdpi-item>
Example (with data source):
<sdpi-item label="Available Devices">
<sdpi-checkbox-list
setting="devices"
datasource="getDevices"
loading="Loading devices...">
</sdpi-checkbox-list>
</sdpi-item>
<sdpi-radio>
Radio button group (single selection, supports data sources).
Attributes:
setting(string): Path in settings objectdatasource(string): Optional remote data source event nameloading(string): Text shown while loading data sourcehot-reload(boolean): MonitorsendToPropertyInspectorfor updatesglobal(boolean): Persist to global settings
Example (static):
<sdpi-item label="Mode">
<sdpi-radio setting="mode">
<option value="simple">Simple</option>
<option value="advanced">Advanced</option>
</sdpi-radio>
</sdpi-item>
<sdpi-select>
Dropdown select (single selection, supports data sources).
Attributes:
setting(string): Path in settings objectvalue(string | number | boolean): Current selected valuedefault(string): Default value if setting is undefinedvalue-type('string'|'number'|'boolean'): How to interpret the value (default:'string')placeholder(string): Placeholder text when no selectionlabel-setting(string): Optional path to persist the label of selected optiondatasource(string): Optional remote data source event nameloading(string): Text shown while loading data sourcehot-reload(boolean): MonitorsendToPropertyInspectorfor updatesdisabled(boolean): Whether the select is disabledglobal(boolean): Persist to global settings
Example (static):
<sdpi-item label="Color">
<sdpi-select setting="color" placeholder="Choose a color">
<optgroup label="Primary Colors">
<option value="#ff0000">Red</option>
<option value="#00ff00">Green</option>
<option value="#0000ff">Blue</option>
</optgroup>
<option value="#000000">Black</option>
<option value="#ffffff">White</option>
</sdpi-select>
</sdpi-item>
Example (with data source):
<sdpi-item label="Device">
<sdpi-select
setting="device"
datasource="getDevices"
loading="Loading devices..."
placeholder="Select a device">
</sdpi-select>
</sdpi-item>
Numeric Input Components
<sdpi-range>
Range slider for numeric values.
Attributes:
setting(string): Path in settings objectvalue(string): Current valuedefault(string): Default valuemin(number): Minimum valuemax(number): Maximum valuestep(number): Step intervalshowlabels(boolean): Show min/max labelsdisabled(boolean): Whether the range is disabledglobal(boolean): Persist to global settings
Example:
<sdpi-item label="Brightness">
<sdpi-range
setting="brightness"
min="0"
max="100"
step="5"
showlabels>
</sdpi-range>
</sdpi-item>
Custom labels:
<sdpi-range setting="volume" min="0" max="100" showlabels>
<span slot="label-min">Mute</span>
<span slot="label-max">Max</span>
</sdpi-range>
Date/Time Components
<sdpi-calendar>
Date, time, and datetime picker (supports multiple types).
Attributes:
type(string): One of'date','datetime-local','month','time','week'setting(string): Path in settings objectvalue(string): Current value (ISO format)default(string): Default valuemin(string): Minimum date/time (ISO format)max(string): Maximum date/time (ISO format)step(number): Step interval (especially for time)disabled(boolean): Whether the calendar is disabledglobal(boolean): Persist to global settings
Examples:
<sdpi-item label="Date">
<sdpi-calendar type="date" setting="important_date"></sdpi-calendar>
</sdpi-item>
<sdpi-item label="Time">
<sdpi-calendar type="time" setting="alarm_time" step="300"></sdpi-calendar>
</sdpi-item>
<sdpi-item label="Date and Time">
<sdpi-calendar type="datetime-local" setting="event_datetime"></sdpi-calendar>
</sdpi-item>
Special Components
<sdpi-color>
Color picker (returns hex string).
Attributes:
setting(string): Path in settings objectvalue(string): Current color (hex format, e.g.,"#ff0000")default(string): Default colordisabled(boolean): Whether the color picker is disabledglobal(boolean): Persist to global settings
Example:
<sdpi-item label="Background Color">
<sdpi-color setting="bgColor" default="#ffffff"></sdpi-color>
</sdpi-item>
<sdpi-file>
File picker input.
Attributes:
setting(string): Path in settings objectaccept(string): File type filter (e.g.,"image/*",".json")label(string): Button label textdisabled(boolean): Whether the file picker is disabledglobal(boolean): Persist to global settings
Example:
<sdpi-item label="Icon File">
<sdpi-file
setting="iconPath"
accept="image/*"
label="Choose Icon">
</sdpi-file>
</sdpi-item>
<sdpi-button>
Action button.
Attributes:
label(string): Button textdisabled(boolean): Whether the button is disabled
Example:
<sdpi-item label="Actions">
<sdpi-button label="Test Connection" onclick="testConnection()"></sdpi-button>
</sdpi-item>
<sdpi-delegate>
Custom component wrapper for plugin-invoked actions (e.g., folder picker).
Attributes:
setting(string): Path in settings object (value is set by plugin)label(string): Button label textdisabled(boolean): Whether the delegate is disabledglobal(boolean): Persist to global settings
Example:
<sdpi-item label="Folder">
<sdpi-delegate
setting="folderPath"
label="Choose Folder">
</sdpi-delegate>
</sdpi-item>
Plugin side (TypeScript example):
// Send folder picker request
streamDeck.actions.openUrl("file:///path/to/folder");
// Or use sendToPropertyInspector to set the value
streamDeck.actions.sendToPropertyInspector(context, {
event: "folderSelected",
path: "/selected/folder/path"
});
Layout Component
<sdpi-item>
Wrapper component for consistent layout (label + component).
Attributes:
label(string): Label text displayed on the leftinfo(string): Optional info text/tooltip
Example:
<sdpi-item label="Name" info="Enter your display name">
<sdpi-textfield setting="name"></sdpi-textfield>
</sdpi-item>
Data Sources
Data sources allow components to dynamically populate their options from the plugin at runtime.
Supported Components
Data sources are supported in:
<sdpi-select><sdpi-checkbox-list><sdpi-radio>
Property Inspector Setup
HTML:
<sdpi-item label="Device">
<sdpi-select
setting="device"
datasource="getDevices"
loading="Fetching devices..."
hot-reload>
</sdpi-select>
</sdpi-item>
Configuration attributes:
datasource(string): Event name that will be sent to the pluginloading(string): Optional text shown while loadinghot-reload(boolean): MonitorsendToPropertyInspectorfor real-time updates
Manual refresh:
const selectElement = document.querySelector('[setting="device"]');
selectElement.refresh(); // Manually refresh the data source
Plugin Implementation
When a component with a datasource is initialized, the plugin receives a sendToPlugin event:
Request payload:
{
"action": "com.example.myaction",
"event": "sendToPlugin",
"context": "unique-context-id",
"payload": {
"event": "getDevices",
"isRefresh": undefined | true
}
}
Plugin response (via sendToPropertyInspector):
{
"action": "com.example.myaction",
"event": "sendToPropertyInspector",
"context": "unique-context-id",
"payload": {
"event": "getDevices",
"items": [
{
"label": "Device Group",
"children": [
{
"label": "Device 1",
"value": "device1"
},
{
"label": "Device 2",
"value": "device2"
}
]
},
{
"label": "Device 3",
"value": "device3"
}
]
}
}
TypeScript type definitions:
type DataSourcePayload = {
event: string;
items: DataSourceResult;
};
type DataSourceResult = DataSourceResultItem[];
type DataSourceResultItem = Item | ItemGroup;
type Item = {
disabled?: boolean;
label?: string;
value: string;
};
type ItemGroup = {
label?: string;
children: Item[];
};
Example plugin implementation (Node.js/TypeScript):
import streamDeck, { action, type SendToPluginEvent } from "@elgato/streamdeck";
@action({ UUID: "com.example.myaction" })
class MyAction {
override onSendToPlugin(ev: SendToPluginEvent): void {
if (ev.payload.event === "getDevices") {
// Fetch devices from your source
const devices = [
{ label: "Device 1", value: "device1" },
{ label: "Device 2", value: "device2" }
];
// Send response to Property Inspector
streamDeck.actions.sendToPropertyInspector(ev.context, {
event: "getDevices",
items: devices
});
}
}
}
Stream Deck Client API
The SDPIComponents.streamDeckClient provides methods and events for advanced communication between Property Inspector and plugin.
Accessing the Client
const { streamDeckClient } = SDPIComponents;
Methods
getSettings()
Get current action-specific settings.
Returns: Promise resolving to { settings: object }
Example:
streamDeckClient.getSettings().then(payload => {
console.log('Current settings:', payload.settings);
});
setSettings(settings)
Update action-specific settings.
Parameters:
settings(object): Settings object to persist
Example:
streamDeckClient.setSettings({
name: "John Doe",
enabled: true
});
getGlobalSettings()
Get plugin-wide global settings.
Returns: Promise resolving to { settings: object }
Example:
streamDeckClient.getGlobalSettings().then(payload => {
console.log('Global settings:', payload.settings);
});
setGlobalSettings(settings)
Update plugin-wide global settings.
Parameters:
settings(object): Global settings object to persist
Example:
streamDeckClient.setGlobalSettings({
apiKey: "secret-key",
theme: "dark"
});
getConnectionInfo()
Get information about the Stream Deck environment.
Returns: Promise resolving to connection info object
Example:
streamDeckClient.getConnectionInfo().then(info => {
console.log('Plugin UUID:', info.plugin.uuid);
console.log('Action:', info.actionInfo.name);
console.log('OS:', info.applicationInfo.platform);
console.log('Language:', info.applicationInfo.language);
console.log('Devices:', info.devices);
});
send(event, payload)
Send custom events to the plugin or host environment.
Parameters:
event(string): Event name (e.g.,"sendToPlugin","openUrl")payload(object): Event payload
Example:
// Send custom message to plugin
streamDeckClient.send("sendToPlugin", {
event: "customEvent",
data: { foo: "bar" }
});
// Open URL
streamDeckClient.send("openUrl", {
url: "https://example.com"
});
Events
didReceiveSettings
Subscribe to settings updates from the plugin.
Example:
streamDeckClient.didReceiveSettings.subscribe(ev => {
console.log('Settings received:', ev.payload.settings);
// Update UI if needed
});
didReceiveGlobalSettings
Subscribe to global settings updates from the plugin.
Example:
streamDeckClient.didReceiveGlobalSettings.subscribe(ev => {
console.log('Global settings received:', ev.payload.settings);
});
sendToPropertyInspector
Subscribe to custom messages from the plugin.
Example:
streamDeckClient.sendToPropertyInspector.subscribe(ev => {
if (ev.payload.event === "deviceConnected") {
console.log('Device connected:', ev.payload.device);
}
});
Localization
Manifest Localization
Stream Deck supports localization via JSON files in your plugin directory:
File structure:
*.sdPlugin/
├── manifest.json
├── en.json # English (default)
├── fr.json # French
├── de.json # German
├── es.json # Spanish
├── ja.json # Japanese
├── ko.json # Korean
└── zh_CN.json # Chinese (Simplified)
Example en.json:
{
"Name": "My Plugin",
"Description": "A great plugin",
"Actions": {
"MyAction": {
"Name": "My Action",
"Tooltip": "Does something"
}
}
}
Example fr.json:
{
"Name": "Mon Plugin",
"Description": "Un super plugin",
"Actions": {
"MyAction": {
"Name": "Mon Action",
"Tooltip": "Fait quelque chose"
}
}
}
Property Inspector Localization
sdpi-components does not provide built-in localization for Property Inspector UI labels. To localize your Property Inspector:
- Get language from connection info:
const { streamDeckClient } = SDPIComponents;
streamDeckClient.getConnectionInfo().then(info => {
const language = info.applicationInfo.language; // e.g., "en", "fr", "de"
updateUILabels(language);
});
- Implement your own translation system:
const translations = {
en: {
name: "Name",
enabled: "Enabled"
},
fr: {
name: "Nom",
enabled: "Activé"
}
};
function updateUILabels(language) {
const t = translations[language] || translations.en;
document.querySelector('[setting="name"]').parentElement
.querySelector('sdpi-item').setAttribute('label', t.name);
}
Best Practices
Use this checklist when building Property Inspectors with sdpi-components:
-
Component selection
- Use appropriate components for each input type (don't use textfield for booleans).
- Leverage
<sdpi-item>withlabelfor consistent layout. - Use
placeholderattributes to guide users.
-
Settings management
- Use the
settingattribute on components for automatic binding. - Use nested paths (e.g.,
"user.name") for organized settings. - Use
globalattribute only when settings should be shared across actions. - Provide sensible
defaultvalues so actions work immediately.
- Use the
-
Data sources
- Use data sources for dynamic content (devices, API results, etc.).
- Implement proper error handling in plugin data source handlers.
- Use
hot-reloadfor real-time updates when appropriate. - Provide meaningful
loadingtext for better UX.
-
Performance
- Keep Property Inspector HTML/CSS/JavaScript files small.
- Avoid blocking operations in Property Inspector code.
- Use data sources efficiently (cache when appropriate).
-
Distribution
- Always use local references to
sdpi-components.jsin distributed plugins. - Test Property Inspector without an internet connection.
- Ensure all referenced assets are included in the plugin bundle.
- Always use local references to
-
User experience
- Keep interfaces simple and intuitive.
- Use clear labels and helpful tooltips (
infoattribute on<sdpi-item>). - Group related settings logically.
- Validate user input where appropriate (use
patternon textfield,min/maxon range).
-
Communication
- Use
streamDeckClientfor advanced communication patterns. - Handle cases where the plugin might not be ready.
- Implement proper error handling for communication failures.
- Use
Common Patterns
Pattern 1: Simple Settings Form
<!doctype html>
<html>
<head lang="en">
<meta charset="utf-8" />
<script src="sdpi-components.js"></script>
</head>
<body>
<sdpi-item label="Action Name">
<sdpi-textfield setting="actionName" placeholder="Enter action name"></sdpi-textfield>
</sdpi-item>
<sdpi-item label="Enabled">
<sdpi-checkbox setting="enabled"></sdpi-checkbox>
</sdpi-item>
<sdpi-item label="Timeout (seconds)">
<sdpi-range setting="timeout" min="1" max="60" step="1" showlabels></sdpi-range>
</sdpi-item>
</body>
</html>
Pattern 2: Dynamic Select with Data Source
<!doctype html>
<html>
<head lang="en">
<meta charset="utf-8" />
<script src="sdpi-components.js"></script>
</head>
<body>
<sdpi-item label="Device">
<sdpi-select
setting="device"
datasource="getDevices"
loading="Loading devices..."
placeholder="Select a device">
</sdpi-select>
</sdpi-item>
<script>
const { streamDeckClient } = SDPIComponents;
// Listen for device updates
streamDeckClient.sendToPropertyInspector.subscribe(ev => {
if (ev.payload.event === "deviceListUpdated") {
// Refresh the select
document.querySelector('[setting="device"]').refresh();
}
});
</script>
</body>
</html>
Pattern 3: Conditional UI Updates
<!doctype html>
<html>
<head lang="en">
<meta charset="utf-8" />
<script src="sdpi-components.js"></script>
</head>
<body>
<sdpi-item label="Mode">
<sdpi-select setting="mode">
<option value="simple">Simple</option>
<option value="advanced">Advanced</option>
</sdpi-select>
</sdpi-item>
<div id="advanced-settings" style="display: none;">
<sdpi-item label="Advanced Option">
<sdpi-textfield setting="advancedOption"></sdpi-textfield>
</sdpi-item>
</div>
<script>
const { streamDeckClient } = SDPIComponents;
const modeSelect = document.querySelector('[setting="mode"]');
const advancedDiv = document.getElementById('advanced-settings');
// Listen for settings changes
streamDeckClient.didReceiveSettings.subscribe(ev => {
const mode = ev.payload.settings?.mode;
if (mode === 'advanced') {
advancedDiv.style.display = 'block';
} else {
advancedDiv.style.display = 'none';
}
});
// Also handle local changes
modeSelect.addEventListener('change', (e) => {
if (e.target.value === 'advanced') {
advancedDiv.style.display = 'block';
} else {
advancedDiv.style.display = 'none';
}
});
</script>
</body>
</html>
Pattern 4: Global Settings with Action Settings
<!doctype html>
<html>
<head lang="en">
<meta charset="utf-8" />
<script src="sdpi-components.js"></script>
</head>
<body>
<!-- Global settings (shared across all actions) -->
<sdpi-item label="API Key">
<sdpi-textfield setting="apiKey" global></sdpi-textfield>
</sdpi-item>
<!-- Action-specific settings -->
<sdpi-item label="Action Name">
<sdpi-textfield setting="actionName"></sdpi-textfield>
</sdpi-item>
<sdpi-item label="Enabled">
<sdpi-checkbox setting="enabled"></sdpi-checkbox>
</sdpi-item>
</body>
</html>
Checklists
New Property Inspector with sdpi-components Checklist
-
sdpi-components.jsincluded (local for distribution, remote for development). - HTML file created in
ui/directory. -
PropertyInspectorPathadded tomanifest.json(action or plugin level). - Appropriate components selected and implemented.
-
settingattributes properly configured on components. - Components wrapped in
<sdpi-item>with labels. - Settings communication tested (PI → Plugin).
- Property Inspector visible and functional in Stream Deck app.
Data Source Implementation Checklist
- Component has
datasourceattribute set. - Plugin implements
onSendToPluginhandler for data source event. - Plugin sends response via
sendToPropertyInspectorwith correct payload structure. -
itemsarray contains validItemorItemGroupobjects. -
hot-reloadimplemented if real-time updates needed. -
loadingtext provided for better UX. - Error handling implemented in plugin.
Pre‑Release Checklist
- Local
sdpi-components.jsincluded (not remote CDN). - All settings validated before sending to plugin.
- Property Inspector tested without internet connection.
- UI is intuitive and follows Stream Deck design guidelines.
- Settings persist correctly across app restarts.
- Error handling implemented for invalid input.
- Data sources work correctly and handle errors gracefully.
- Global vs. action-specific settings properly configured.
How to Use This Skill with an Agent
When you invoke a coding agent to work with sdpi-components:
- State clearly that you are working on a Property Inspector using sdpi-components for an Elgato Stream Deck plugin.
- Ask the agent to follow this skill for:
- Selecting appropriate sdpi-components for different input types.
- Configuring components with
settingattributes. - Implementing data sources for dynamic content.
- Using Stream Deck Client API for advanced communication.
- Handling settings persistence (action-specific or global).
- Debugging Property Inspector issues related to sdpi-components.
- Provide any existing code or manifest files so the agent can:
- Avoid duplicating components or settings.
- Reuse existing settings structures.
- Maintain consistency with current plugin implementation.
This ensures a consistent, robust Property Inspector development workflow using the official sdpi-components library.