ES modules

Tweakpane has been migrated to ES modules from v4.

<!-- v3 -->
<script src="./path/to/tweakpane.js"></script>
<script>
  const pane = new Tweakpane.Pane();
  // ...
</script>
<!-- v4 -->
<script type="module">
  import {Pane} from './path/to/tweakpane.js';

  const pane = new Pane();
  // ...
</script>

If you want to keep existing code, you can export the ES module as a global variable.

<script type="module">
  // Import ES module
  import * as Tweakpane from './path/to/tweakpane.js';

  // Export it as a global variable
  window.Tweakpane = Tweakpane;
</script>
<script>
  const pane = new Tweakpane.Pane();
  // ...
</script>

Bindings

addInput() is now addBinding(). The new name more accurately describes its functionality.

// v3
pane.addInput(PARAMS, 'size');
// v4
pane.addBinding(PARAMS, 'size');

addMonitor() is merged into addBinding(), and needs an additional option {readonly: true}.

// v3
pane.addMonitor(PARAMS, 'total');
// v4
pane.addBinding(PARAMS, 'total', {
  readonly: true,
});

Event handling

If you uses presetKey of the event object, replace it with target.key.

// v3
const b = pane.addInput(PARAMS, 'strength');

b.on('change', (ev) => {
  console.log(ev.presetKey);  // 'strength'
});
// v4
const b = pane.addBinding(PARAMS, 'strength');

b.on('change', (ev) => {
  console.log(ev.target.key);  // 'strength'
});

For monitor bindings, use the event name change instead of update.

// v3
const b = pane.addMonitor(PARAMS, 'total');

b.on('update', (ev) => {
  // ...
});
// v4
const b = pane.addBinding(PARAMS, 'total', {readonly: true});

b.on('change', (ev) => {
  // ...
});

Importing/Exporting a preset

v4 omits the preset functionality importPreset(), exportPreset(), and added importState(), exportState() instead. Exported state has more information about blades.

// v3
console.log(pane.exportPreset());
// v4
console.log(pane.exportState());

Do you prefer the classic preset style? You can convert a blade state into a preset with a small utility function. Refer preset.ts to see the whole code written in TypeScript.

function stateToPreset(state) {
  if ('children' in state) {
    return state.children.reduce((tmp, s) => {
      return {...tmp, ...stateToPreset(s)};
    }, {});
  }
  const binding = state.binding ?? {};
  if ('key' in binding && 'value' in binding) {
    return {[binding.key]: binding.value};
  }
  return {};
}
.js

If you want to handle binding key collisions, generic tag option would be useful to identify each key.

pane.addBinding(PARAMS, 'speed', {
  tag: 'speed2',
});

Separators

addSeparator() is removed in v4. Use addBlade() instead to add a separator.

// v3
pane.addSeparator();
// v4
pane.addBlade({view: 'separator'});

Blade API changes

All blade APIs are renamed.

// v3
const b = pane.addBlade({
  view: 'slider',
  label: 'brightness',
  min: 0,
  max: 1,
  value: 0.5,
}) as SliderApi;
// v4
const b = pane.addBlade({
  view: 'slider',
  label: 'brightness',
  min: 0,
  max: 1,
  value: 0.5,
}) as SliderBladeApi;

Here is the list of the renamed blade APIs:

v3 v4
ListApi ListBladeApi
SliderApi SliderBladeApi
TextApi TextBladeApi

Additionally, minValue, maxValue of the slider blade API is now min and max.

// v3
const b = pane.addBlade({
  view: 'slider',
  label: 'brightness',
  min: 0,
  max: 1,
  value: 0.5,
}) as SliderApi;

console.log(b.minValue, b.maxValue);
// v4
const b = pane.addBlade({
  view: 'slider',
  label: 'brightness',
  min: 0,
  max: 1,
  value: 0.5,
}) as SliderBladeApi;

console.log(b.min, b.max);