/streamdeck-formbuilder

Helps managing PI Forms and Settings

Primary LanguageCSSMIT LicenseMIT

streamdeck-formbuilder

Build/Test codecov

Helps to build forms, as described and styled in the Propertyinspector styling docs, for the propertyinspector to ease the settings handling between PI and plugin.

Installation

yarn add @rweich/streamdeck-formbuilder

Setup webpack

The styles (sdpi.css) from the official SDK (which are used in the PISamples plugin), are loaded by default.

When using webpack, it's necessary to:

  1. install the style-loader and css-loader packages:

    yarn add --dev style-loader css-loader
  2. add both of them to the rules section of your webpack config:

    {
      test: /\.css$/i,
      use: ['style-loader', 'css-loader'],
    }

Example Usage

A quick example how to use the formbuilder in the propertyinspector.

ℹ️ For a more complete implementation example, check the formbuilder-showcase streamdeck plugin.

import { FormBuilder } from '@rweich/streamdeck-formbuilder';

const initialSettings = {}; // assumes that's whatever you get from the propertyinspector on the didReceiveSettings event
const defaultSettings = { valueOne: 'a default value', valueTwo: 'another default value' };

// create a FormBuilder instance with the values it should use initially
const builder = new FormBuilder({ ...defaultSettings, ...initialSettings });

// add an input field and bind its value to the valueOne-property of the settings
// the values of the elements will (initially) be set to whatever was passed to the FormBuilder above
builder.addElement('valueOne', builder.createInput());
builder.addElement('valueTwo', builder.createInput());

// build the form and append it to the propertyinspectors body element
builder.appendTo(document.body);

// add an eventlistener to send the new settings to the propertyinspector whenever they change
builder.on('change-settings', () => {
  const newSettings = builder.getFormData(); // -> { valueOne: 'the new value', valueTwo: 'another new value' }
  // now the new settings should be sent to the propertyinspector via the setSettings event
  // ...
});

Table of Contents

FormBuilder API

FormBuilder

The main entry point is the FormBuilder class. Pass the initial data for the form as parameter.

import { FormBuilder } from '@rweich/streamdeck-formbuilder';
const builder = new FormBuilder({ valueA: 'some initial data', valueB: 'more data' });

addElement

Form elements like inputs, dropdowns (or selects) can be added using the addElement method.

addElement(name: string, element: object): void

  • name: the elements name. used as a key of the (resulting) object that holds all the form values
  • element: one of the elements, created by the create* methods (e.g. createInput)

Example:

builder.addElement('valueA', builder.createInput());

addHtml

Allows to add elements (like Details) that only show information and don't hold any form-related values.

addHtml(element: { getHtmlElement: () => HTMLElement }): void

  • element: object, that exposes a getHtmlElement function to return a HTMLElement

Example:

builder.addHtml(builder.createDetails().addParagraph('some info-text'));

addHtmlElement

Allows to directly add any HTMLElement, only used for display purposes.

addHtmlElement(element: HTMLElement): void

  • element: a plain HTMLElement, as created by document.createElement(...)

Example:

const element = document.createElement('div');
element.textContent = 'i show things';
builder.addHtmlElement(element);

createDetails

See Details API to get an overview how to use the Details object.

Creates a collapsible detail element to output informational text.

createDetails(): Details

Example:

builder.addHtml(builder.createDetails().addParagraph('example paragraph'));

createDropdown

See Dropdown API to get an overview how to use the return value.

Creates a drowpdown / select element.

createDropdown(): Details

Example:

builder.addElement('count', builder.createDropdown().addOption('One', 'one').addOption('Two', 'two'));

createInput

See Input API to get an overview how to use the return value.

Creates a text input element.

Example:

builder.addElement('username', builder.createInput());

createRange

See Range API to get an overview how to use the return value.

Creates a range-input (or slider) element.

createRange(min: number, max: number, step: number = 1): Range

  • min: The lowest value in the range of permitted values
  • max: The greatest value in the range of permitted values
  • step: The step attribute is a number that specifies the granularity that the value must adhere to. Will make the slider snap to the steps.

Example:

builder.addElement('brightness', builder.createRange(1, 10));

Details API

The Details object, returned by createDetails, can be customized using the following methods.

Example:

builder.createDetails()
  .addSummary('More Info')
  .addHeadline('a headline')
  .addParagraph('some text')
  .addHeadline('another headline')
  .addParagraph('more text');

addSummary

Adds a summary to the details, which is displayed as the title (the clickable text that still shows when the details are collapsed).

addSummary(text: string): Details


addHeadline

Adds a headline to the details.

addHeadline(text: string): Details


addParagraph

Adds a paragraph with text to the details.

addParagraph(text: string): Details


addElement

Allows to add any html element to the details.

addElement(element: HTMLElement): Details

Dropdown API

The Dropdown object, returned by createDropdown, can be customized using the following methods (including the ones from the shared API.

Example:

builder.createDropdown()
  .setLabel('choose a color')
  .addOption('the color red', 'red')
  .addOption('the color green', 'green')
  .addOption('the color blue', 'blue');

addOption

Adds one selectable option to the dropdown.

addOption(label: string, value: string): Dropdown

  • label: The text to display
  • value: The value, that will be used internally when the option was selected

Input API

The Input object, returned by createInput, can be customized using the following methods (including the ones from the shared API.

Example:

builder.createInput()
  .setLabel('a label')
  .setPlaceholder('placeholder');

setPlaceholder

Sets the placeholder that will be displayed in the field when its empty

setPlaceholder(placeholder: string): Input

Range API

The Range object, returned by createRange, can be customized using the following methods (including the ones from the shared API.

Example:

builder.createRange(0, 100, 20)
  .setLabel('choose a size')
  .enableMinMaxLabels()
  .enableTicks();

enableMinMaxLabels

Show labels displaying the min-max values in front and behind the slider.

enableMinMaxLabels(): Range


enableTicks

Shows tick marks below the slider.

enableTicks(): Range

shared Element API

Elements, added by addElement share the following functions.

setLabel

Sets the label that will be displayed alongside the form element.

setLabel(label: string): Input


showOn

Allows to show / hide the element based on another elements value. The callback gets called on every change to any of the form elements. Based on the return value of the callback the element will be shown (when true) or hidden (when false).

showOn(callback: () => boolean): Input

  • callback: a function that returns true to show or false to hide the element

Example:

builder.createInput().showOn(() => builder.getFormData().color === 'red');

Typescript

To get typings (mosty for allowed key-names) for addElement() and the return of getFormData(), add the type like this:

import { FormBuilder } from '@rweich/streamdeck-formbuilder';

type Settings = {
  valueA: string;
  valueB: 'yes' | 'no';
}

const builder = new FormBuilder<Settings>({ valueA: 'some initial data', valueB: 'yes' });

Links

Propertyinspector styling docs