diff --git a/src/core/variables/Variable.ts b/src/core/variables/Variable.ts index 6da3cde..ee5fa41 100644 --- a/src/core/variables/Variable.ts +++ b/src/core/variables/Variable.ts @@ -45,7 +45,7 @@ export interface VariableListParams extends VariableParams { * @extends Function */ export interface VariableCallback extends Function { - variable: Variable; + variable?: Variable; } /** @@ -78,7 +78,7 @@ export class Variable implements VariableParams { this.defaultValue = defaultValue; this._selectedValue = defaultValue; if (callback) { - this.callbacks.push(callback); + this._callbacks.push(callback); } this._initialized = true; } @@ -156,6 +156,14 @@ export class Variable implements VariableParams { return this._callbacks; } + /** + * Adds a callback to array of callbacks. + * @param {VariableCallback} callback The callback to add. + */ + addCallback(callback: VariableCallback): any { + this._callbacks.push(callback); + } + /** * Invokes each of the callback methods. */ @@ -170,7 +178,7 @@ export class Variable implements VariableParams { * @param {VariableCallback} callback The callback to add and execute. */ addAndExecuteCallback(callback: VariableCallback): void { - this.callbacks.push(callback); + this._callbacks.push(callback); callback(this); } diff --git a/src/ui/DOMController.tsx b/src/ui/DOMController.tsx new file mode 100644 index 0000000..89e530c --- /dev/null +++ b/src/ui/DOMController.tsx @@ -0,0 +1,100 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import * as React from "react"; +import { KeyCode, KeyEvent, CSS } from "../lib/Constants"; +import { Messaging } from "../lib/Messaging"; +import { Overlay } from "./overlay/Overlay"; +import { Variable } from "../core/variables/Variable"; + +/** + * Interface for the properties assigned to the DOMController component. + * @interface + */ +interface ControllerProps { + wrapperElement: HTMLElement; + variables: Array; + updateVariable(variable: Variable, selectedValue: any): void; +} + +/** + * Renders an MDL card-styled overlay containing a child control for each + * variable. + * @class + * @extends React.Component + */ +export class DOMController extends React.Component { + + /** @override */ + componentDidMount() { + // Register for messaging and key events. + Messaging.register(this.onMessageReceived.bind(this)); + this.addKeyListener(); + } + + /** @override */ + componentWillUnmount() { + // Unregister for messaging and key events. + Messaging.unregister(); + this.removeKeyListener(); + } + + /** + * Handles receiving of window message. + * @param {MessageEvent} event The received message event. + */ + onMessageReceived(event: MessageEvent): void { + if (event.data === Messaging.type.ToggleVisibility) { + this.toggleVisibility(); + } + } + + /** Adds a key listener. */ + addKeyListener(): void { + document.addEventListener(KeyEvent.DOWN, (e: KeyboardEvent) => { + if (e.keyCode === KeyCode.ESC) { + this.toggleVisibility(); + } + }); + } + + /** Removes a key listener. */ + removeKeyListener(): void { + document.removeEventListener(KeyEvent.DOWN); + } + + /** Toggles the Remixer overlay visibility. */ + toggleVisibility() { + this.props.wrapperElement.classList.toggle(CSS.RMX_VISIBLE); + } + + /** @override */ + render() { + return ( +
+
+

Remixer

+
+
+ +
+
+ ); + } +} diff --git a/src/ui/controls/ColorSwatchControl.tsx b/src/ui/controls/ColorSwatchControl.tsx new file mode 100644 index 0000000..2b704f9 --- /dev/null +++ b/src/ui/controls/ColorSwatchControl.tsx @@ -0,0 +1,100 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import * as React from "react"; +import { ColorControlProps } from "./controlProps"; +import { CSS, VariableType } from "../../lib/Constants"; + +/** + * A color swatch picker control consisting of a single color swatch for each + * possible value. + * @class + * @extends React.Component + */ +export class ColorSwatchControl extends React.Component { + + /** Handles the update event for this control. */ + onClick = (event: React.FormEvent): void => { + this.props.updateVariable( + this.props.variable, + (event.target as HTMLElement).dataset["value"] + ); + } + + /** @override */ + shouldComponentUpdate(nextProps: ColorControlProps) { + return nextProps.variable !== this.props.variable; + } + + /** @override */ + render() { + const { + title, + possibleValues, + selectedValue + } = this.props.variable; + + return ( +
+ + {title} + {selectedValue} + + + {possibleValues.map((value: string) => ( + + ))} + + +
+ ); + } +} + +/** + * Interface containing properties for a single color swatch. + * @interface + */ +interface ColorSwatchProps { + color: string; + isSelected: boolean; + onClick: any; +} + +/** + * Returns a single color swatch displayed within the `ColorSwatchControl`. + * @param {ColorSwatchProps} props The color swatch properties. + */ +function ColorSwatch(props: ColorSwatchProps) { + const { + color, + isSelected, + onClick, + } = props; + return ( +
+ {isSelected ? check : ""} +
+ ); +} diff --git a/src/ui/controls/DropdownControl.tsx b/src/ui/controls/DropdownControl.tsx new file mode 100644 index 0000000..4bce1af --- /dev/null +++ b/src/ui/controls/DropdownControl.tsx @@ -0,0 +1,75 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import * as React from "react"; +import { CSS } from "../../lib/Constants"; +import { StringControlProps } from "./controlProps"; + +/** + * A dropdown control. + * @class + * @extends React.Component + */ +export class DropdownControl extends React.Component { + + /** Handles the update event for this control. */ + onClick = (event: React.FormEvent): void => { + this.props.updateVariable( + this.props.variable, + (event.target as HTMLElement).dataset["value"] + ); + } + + /** @override */ + shouldComponentUpdate(nextProps: StringControlProps) { + return nextProps.variable !== this.props.variable; + } + + /** @override */ + render() { + const { + title, + key, + possibleValues, + selectedValue + } = this.props.variable; + const id = `${CSS.RMX_DROPDOWN}-${key}`; + + return ( +
+ {title} + + +
    + {possibleValues.map((value: string) => ( +
  • {value} +
  • + ))} +
+
+
+ ); + } +} diff --git a/src/ui/controls/RadioListControl.tsx b/src/ui/controls/RadioListControl.tsx new file mode 100644 index 0000000..d875218 --- /dev/null +++ b/src/ui/controls/RadioListControl.tsx @@ -0,0 +1,72 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import * as React from "react"; +import { CSS, VariableType } from "../../lib/Constants"; +import { StringControlProps } from "./controlProps"; + +/** + * A radio list control. + * @class + * @extends React.Component + */ +export class RadioListControl extends React.Component { + + /** Handles the update event for this control. */ + onChange = (event: React.FormEvent): void => { + this.props.updateVariable( + this.props.variable, + (event.target as HTMLInputElement).value + ); + } + + /** @override */ + shouldComponentUpdate(nextProps: StringControlProps) { + return nextProps.variable !== this.props.variable; + } + + /** @override */ + render() { + const { + title, + key, + possibleValues, + selectedValue + } = this.props.variable; + const id = `${CSS.RMX_RADIO_LIST_ITEM}-${key}`; + + return ( +
+ {title} + + {possibleValues.map((value: string, i: number) => ( + + ))} + +
+ ); + } +} diff --git a/src/ui/controls/SliderControl.tsx b/src/ui/controls/SliderControl.tsx new file mode 100644 index 0000000..d6ec928 --- /dev/null +++ b/src/ui/controls/SliderControl.tsx @@ -0,0 +1,72 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import * as React from "react"; +import { CSS, VariableType } from "../../lib/Constants"; +import { RangeControlProps } from "./controlProps"; + +/** + * A slider control. + * @class + * @extends React.Component + */ +export class SliderControl extends React.Component { + + /** Handles the update event for this control. */ + onChange = (event: React.FormEvent): void => { + this.props.updateVariable( + this.props.variable, + (event.target as HTMLInputElement).value + ); + } + + /** @override */ + shouldComponentUpdate(nextProps: RangeControlProps) { + return nextProps.variable !== this.props.variable; + } + + /** @override */ + render() { + const { + title, + key, + selectedValue, + minValue, + maxValue, + increment, + } = this.props.variable; + const id = `${CSS.RMX_SLIDER}-${key}`; + + return ( +
+ + {title} + {selectedValue} + + + {minValue} + + {maxValue} + + +
+ ); + } +} diff --git a/src/ui/controls/SwitchControl.tsx b/src/ui/controls/SwitchControl.tsx new file mode 100644 index 0000000..52c731b --- /dev/null +++ b/src/ui/controls/SwitchControl.tsx @@ -0,0 +1,67 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import * as React from "react"; +import { BooleanControlProps } from "./controlProps"; +import { CSS } from "../../lib/Constants"; + +/** + * A switch control. + * @class + * @extends React.Component + */ +export class SwitchControl extends React.Component { + + /** Handles the update event for this control. */ + onChange = (event: React.FormEvent): void => { + const { selectedValue } = this.props.variable; + this.props.updateVariable(this.props.variable, !selectedValue); + } + + /** @override */ + shouldComponentUpdate(nextProps: BooleanControlProps) { + return nextProps.variable !== this.props.variable; + } + + /** @override */ + render() { + const { + title, + key, + selectedValue, + } = this.props.variable; + const id = `${CSS.RMX_SWITCH}-${key}`; + + return ( +
+ {title} + + + +
+ ); + } +} diff --git a/src/ui/controls/TextFieldControl.tsx b/src/ui/controls/TextFieldControl.tsx new file mode 100644 index 0000000..429d79f --- /dev/null +++ b/src/ui/controls/TextFieldControl.tsx @@ -0,0 +1,72 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import * as React from "react"; +import { CSS, VariableType } from "../../lib/Constants"; +import { StringControlProps } from "./controlProps"; + +/** + * A textfield control. + * @class + * @extends React.Component + */ +export class TextFieldControl extends React.Component { + + /** Handles the update event for this control. */ + onChange = (event: React.FormEvent): void => { + this.props.updateVariable( + this.props.variable, + (event.target as HTMLInputElement).value + ); + } + + /** @override */ + shouldComponentUpdate(nextProps: StringControlProps) { + return nextProps.variable !== this.props.variable; + } + + /** @override */ + render() { + const { + title, + key, + dataType, + selectedValue + } = this.props.variable; + const id = `${CSS.RMX_TEXTFIELD}-${key}`; + const isNumber: boolean = dataType === VariableType.NUMBER; + const pattern = isNumber ? "-?[0-9]*(\.[0-9]+)?" : ".*"; + + return ( +
+ {title} + + + + Input is not a number! + + +
+ ); + } +} diff --git a/src/ui/controls/controlProps.tsx b/src/ui/controls/controlProps.tsx new file mode 100644 index 0000000..f724392 --- /dev/null +++ b/src/ui/controls/controlProps.tsx @@ -0,0 +1,83 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import { BooleanVariable } from "../../core/variables/BooleanVariable"; +import { ColorVariable } from "../../core/variables/ColorVariable"; +import { NumberVariable } from "../../core/variables/NumberVariable"; +import { RangeVariable } from "../../core/variables/RangeVariable"; +import { StringVariable } from "../../core/variables/StringVariable"; +import { Variable } from "../../core/variables/Variable"; + +/** + * Interface for variable controls properties and state. + * @interface + */ +export interface ControlUpdateProps { + updateVariable(variable: Variable, selectedValue: any): void; +} + +/** + * Interface for variable control properties. + * @interface + */ +interface ControlVariableProps extends ControlUpdateProps { + variable: Variable; +} + +/** + * Interface for the properties of a control that implements a Boolean variable. + * @interface + * @extends ControlInterface + */ +export interface BooleanControlProps extends ControlVariableProps { + variable: BooleanVariable; +} + +/** + * Interface for the properties of a control that implements a Color variable. + * @interface + * @extends ControlInterface + */ +export interface ColorControlProps extends ControlVariableProps { + variable: ColorVariable; +} + +/** + * Interface for the properties of a control that implements a Number variable. + * @interface + * @extends ControlInterface + */ +export interface NumberControlProps extends ControlVariableProps { + variable: NumberVariable; +} + +/** + * Interface for the properties of a control that implements a Range variable. + * @interface + * @extends ControlInterface + */ +export interface RangeControlProps extends ControlVariableProps { + variable: RangeVariable; +} + +/** + * Interface for the properties of a control that implements a String variable. + * @interface + * @extends ControlInterface + */ +export interface StringControlProps extends ControlVariableProps { + variable: StringVariable; +} diff --git a/src/ui/overlay/Overlay.tsx b/src/ui/overlay/Overlay.tsx new file mode 100644 index 0000000..28e2f23 --- /dev/null +++ b/src/ui/overlay/Overlay.tsx @@ -0,0 +1,91 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import * as React from "react"; +import { ColorSwatchControl } from "../controls/ColorSwatchControl"; +import { ControlUpdateProps } from "../controls/controlProps"; +import { CSS, VariableType } from "../../lib/Constants"; +import { DropdownControl } from "../controls/DropdownControl"; +import { RadioListControl } from "../controls/RadioListControl"; +import { SliderControl } from "../controls/SliderControl"; +import { StringVariable } from "../../core/variables/StringVariable"; +import { SwitchControl } from "../controls/SwitchControl"; +import { TextFieldControl } from "../controls/TextFieldControl"; +import { Variable } from "../../core/variables/Variable"; + +/** + * Interface for a React class that requires an array of Variables. + * @interface + * @extends ControlUpdateProps + */ +export interface OverlayVariables extends ControlUpdateProps { + variables: Array; +} + +/** + * Renders a list of remixer controls for each variable in an overlay card. + * + * @class + * @extends React.Component + */ +export class Overlay extends React.Component { + + /** + * Returns a control as determined by the variable `dataType` property. + * @param {Variable} variable The variable to provide the control for. + * @return {any} A control component. + */ + controlForVariable(variable: Variable): any { + switch (variable.dataType) { + case VariableType.BOOLEAN: + return SwitchControl; + case VariableType.RANGE: + return SliderControl; + case VariableType.STRING: + const { possibleValues } = variable as StringVariable; + if (!possibleValues) { + return TextFieldControl; + } else if (possibleValues.length === 2) { + return RadioListControl; + } else { + return DropdownControl; + } + case VariableType.NUMBER: + return TextFieldControl; + case VariableType.COLOR: + return ColorSwatchControl; + } + return null; + } + + /** @override */ + render() { + return ( +
+ {this.props.variables.map(variable => { + const Control = this.controlForVariable(variable); + return ( + + ); + })} +
+ ); + } +} diff --git a/src/ui/overlay/overlay.html b/src/ui/overlay/overlay.html new file mode 100644 index 0000000..f7fb9b6 --- /dev/null +++ b/src/ui/overlay/overlay.html @@ -0,0 +1,14 @@ + + + + + + + + + + +
+ + + diff --git a/src/ui/overlay/styles.less b/src/ui/overlay/styles.less new file mode 100644 index 0000000..d094a34 --- /dev/null +++ b/src/ui/overlay/styles.less @@ -0,0 +1,131 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +@wrapper-width: 320px; +@wrapper-padding: 10px; +@wrapper-animation-duration: 200ms; +@colorMdlBlue: #3f51b5; +@colorSwatchSize: 40px; +@colorSwatchIconSize: 24px; +@fontSize: 14px; +@fontSizeSmall: 12px; +@fontLightWeight: 200; +@fontBoldWeight: 500; + +.mdl-card { + width: @wrapper-width; + font-size: @fontSize; + overflow: visible; +} + +.mdl-list { + margin: 0; +} + +.mdl-list__item { + font-size: @fontSize; + font-weight: @fontLightWeight; +} + +.mdl-list__item--two-line { + .mdl-list__item-primary-content { height: inherit; } + .mdl-list__item-secondary-content { position: relative; margin: 10px 0 0; } +} + +#rmx-overlay-wrapper { + position: relative; + width: @wrapper-width; + float: right; + padding: @wrapper-padding; + transition: transform @wrapper-animation-duration ease-out, + opacity @wrapper-animation-duration linear; + transform: translateX(@wrapper-width / 2); + opacity: 0; +} + +#rmx-overlay-wrapper.rmx-visible { + transform: translateX(0); + opacity: 1; +} + +.rmx-selected-value { + font-weight: @fontBoldWeight; + margin-left: 5px; + color: @colorMdlBlue; +} + +.rmx-color-swatch { + .mdl-list__item-secondary-content { flex-flow: inherit; } + .rmx-color-swatch-item { + width: @colorSwatchSize; + height: @colorSwatchSize; + float: left; + margin-right: 10px; + border-radius: @colorSwatchSize / 2; + + .material-icons { + width: @colorSwatchIconSize; + height: @colorSwatchIconSize; + margin: (@colorSwatchSize - @colorSwatchIconSize) / 2; + color: white; + } + } +} + +.rmx-radio-list { + .mdl-list__item-secondary-content { flex-flow: inherit; } + .rmx-radio-list-item { + width: inherit; + font-size: @fontSize; + font-weight: @fontBoldWeight; + margin-left: 20px; + } +} + +.rmx-dropdown button { + margin-right: -20px; + text-transform: inherit; +} + +.rmx-textfield { + .mdl-textfield { + width: 100%; + padding: 0; + font-size: @fontSize; + .mdl-textfield__input { padding: 0; margin-top:-5px; } + .mdl-textfield__label { top: -5px; } + } +} + +.mdl-switch.is-upgraded { + padding-left: 38px; +} + +.mdl-menu__container { + right: 20px !important; +} + +.rmx-slider{ + .mdl-slider__container { width: 100%; } + .rmx-slider-min-value { left: 0; } + .rmx-slider-max-value { right: 0; } + .rmx-slider-min-value, .rmx-slider-max-value { + position: absolute; + top: 0; + font-weight: @fontBoldWeight; + font-size: @fontSizeSmall; + } +} diff --git a/src/ui/render.tsx b/src/ui/render.tsx new file mode 100644 index 0000000..59fdf6e --- /dev/null +++ b/src/ui/render.tsx @@ -0,0 +1,65 @@ +/** @license + * Copyright 2016 Google Inc. All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy + * of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + */ + +import "./overlay/styles.less"; +import * as React from "react"; +import * as ReactDOM from "react-dom"; +import { CSS } from "../lib/Constants"; +import { Variable } from "../core/variables/Variable"; +import { DOMController } from "./DOMController"; +import { remixer } from "../core/Remixer"; + +// Get remixer variables from the current instance of remixer. +let variables = remixer.attachedInstance.variablesArray; + +/** + * Handles all control updates by setting a new selected value for the + * variable. + * + * To maintain immutability for React, lets first clone the variable, + * update its selected value, then set it back to the variables array. + * Doing so allows each control to handle its own `shouldComponentUpdate` + * method to determine if it should be re-rendered. + * + * @param {Variable} variable The variable to update. + * @param {any} selectedValue The new selected value. + */ +function updateVariable(variable: Variable, selectedValue: any): void { + const index = variables.indexOf(variable); + let clonedVariable = variable.clone(); + clonedVariable.selectedValue = selectedValue; + variables[index] = clonedVariable; +} + +// Renders the DOMController component to the overlay wrapper element. +const overlayWrapper = document.getElementById(CSS.RMX_OVERLAY_WRAPPER); +function redraw(): void { + ReactDOM.render( + , + overlayWrapper + ); +} + +// Add `redraw()` as a callback when selected value changes on a variable. +variables.forEach(variable => { + variable.addCallback(redraw); +}); + +redraw(); diff --git a/webpack.config.js b/webpack.config.js index 814bc1d..48d46a3 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -1,7 +1,7 @@ module.exports = { entry: { remixer: './src/core/Remixer.ts', - overlay: './src/ui/DOMController.tsx' + overlay: './src/ui/render.tsx' }, output: {