Multi-Line Controller
This example demonstrates how to create a controller that targets a primitive value, like a string. It also shows steps specific to controllers that use a native HTML form element (as opposed to a custom interface).
Imagine we want to edit multi-line text. That's not really possible with lil-gui's <input> based string controller, so we'll build a controller that uses a <textarea> instead.
import GUI from '../../dist/lil-gui.esm.js';
import './MultiLineController.js';
const gui = new GUI();
const obj = {
multiLine: 'one\ntwo\nthree',
disabled: 'one\ntwo\nthree',
};
gui.addMultiLine( obj, 'multiLine', 6 );
gui.addMultiLine( obj, 'disabled' ).disable();
To make a custom controller, we have to extend lil-gui's Controller class.
import { GUI, Controller, injectStyles } from '../../dist/lil-gui.esm.js';
class MultiLineController extends Controller {
constructor( parent, object, property, rows = 3 ) {
super( parent, object, property, 'multiline' );
this.$textarea = document.createElement( 'textarea' );
this.$textarea.setAttribute( 'rows', rows );
this.$widget.appendChild( this.$textarea );
this.$textarea.addEventListener( 'input', () => {
this.setValue( this.$textarea.value );
} );
this.$textarea.addEventListener( 'blur', () => {
this._callOnFinishChange();
} );
this.$textarea.addEventListener( 'keydown', e => {
if ( this.parent.root.captureKeys ) e.stopPropagation();
} );
this.$textarea.addEventListener( 'keyup', e => {
if ( this.parent.root.captureKeys ) e.stopPropagation();
} );
this.$disable = this.$textarea;
this.$textarea.setAttribute( 'aria-labelledby', this.$name.id );
this.updateDisplay();
}
updateDisplay() {
this.$textarea.value = this.getValue();
}
}
GUI.prototype.addMultiLine = function() {
return new MultiLineController( this, ...arguments );
};
injectStyles( `
.lil-gui .controller.multiline textarea {
/* Look at kitchen-sink for a complete list of all theme variables */
background: var(--widget-color);
color: var(--string-color);
font-family: var(--font-family);
/* Using --input-font-size for input elements will prevent zoom on iOS */
font-size: var(--input-font-size);
padding: var(--padding);
border-radius: var(--border-radius);
min-height: var(--widget-height);
resize: vertical;
/* Override some defaults */
width: 100%;
border: 0;
outline: none;
}
.lil-gui .controller.multiline textarea:hover {
background: var(--hover-color);
}
.lil-gui .controller.multiline textarea:focus {
background: var(--focus-color);
}
` );