Save Containers

Wrap components inside a save container to halt hardware writes until a user presses 'Save'.

Background

Sometimes you don't want your settings going straight to the embedded device. A few examples include control systems tuning, manipulating multiple settings for lighting setups, or just being more explicit about when a variable should be written.

Electric UI's solution to this UX requirement is save containers.

A save container is a logical block which can contain a series of components. Any variable which is modified inside the save container is cached and waits until a master "Save" button has been pressed.

As this design pattern is most likely used with more complex configurations, we offer additional helper functionality to:

  • Reset the variable(s) to their current values on the embedded device.
  • Provide a callback to the embedded device after transmission, to bootstrap a non-volatile write operation.
  • Coming soon: Undo/Redo functionality
  • Coming soon: Save settings to file and restore them at a later date.

Usage

There are no changes required for use on the microcontroller, though implementing variable storage is left as to the firmware (see the Arduino persistence-eeprom example for a very basic demo).

On the UI side, simply import the save container, wrap your existing UI elements with <SaveContainer> tags and insert a <SaveButton> as demonstrated below:

import { SaveContainer } from '@electricui/components-core'
import {
SaveButton,
ResetButton,
} from '@electricui/components-desktop-blueprint'
<SaveContainer>
<Button
writer={{
bright: 255,
}}
>
Set brightness to 255
</Button>
// Slider, Checkbox, TextInput, etc
<SaveButton>Save</SaveButton>
<ResetButton>Revert</ResetButton> // optional
</SaveContainer>

Try it with any interactive components like sliders, checkboxes or text inputs.

With hooks

Returns an object containing a save function to write the contained state to hardware, a reset method to reset the contained state, and a dirty boolean indicating if the internal state differs from the current hardware state.

import { SaveContainer } from '@electricui/components-core'
function SaveContainerControls() {
const { save, reset, dirty } = useSaveContainer()
return (
<div>
<button onClick={save} disabled={!dirty}>
Save
</button>
<button onClick={reset} disabled={!dirty}>
Reset
</button>
</div>
)
}