+ `);
+ }
+
+ on_ready ({ listen }) {
+ for ( const child of this.get('children') ) {
+ child.setAttribute('slot', 'inside');
+ child.attach(this);
+ $(child).hide();
+ }
+
+ // show the first child
+ $(this.children[0]).show();
+
+ // listen for changes to the current step
+ listen('position', position => {
+ // hide all children
+ for ( const child of this.children ) {
+ $(child).hide();
+ }
+
+ // show the child at the current position
+ $(this.children[position]).show();
+ });
+
+ // now that we're ready, show the wrapper
+ $(this.dom_).find('#wrapper').show();
+ }
+
+ back () {
+ if ( this.get('position') === 0 ) return;
+ this.set('position', this.get('position') - 1);
+ }
+
+ next () {
+ if ( this.get('position') === this.children.length - 1 ) {
+ this.set('done', true);
+ return;
+ }
+ this.set('position', this.get('position') + 1);
+ }
+}
+
+// TODO: This is necessary because files can be loaded from
+// both `/src/UI` and `/UI` in the URL; we need to fix that
+if ( ! window.__component_stepView ) {
+ window.__component_stepView = true;
+
+ customElements.define('c-step-view', StepView);
+}
diff --git a/src/UI/Components/TestView.js b/src/UI/Components/TestView.js
new file mode 100644
index 00000000..b6b7dae9
--- /dev/null
+++ b/src/UI/Components/TestView.js
@@ -0,0 +1,28 @@
+import { Component } from "../../util/Component.js";
+
+/**
+ * A simple component when you just need to test something.
+ */
+export default class TestView extends Component {
+ static CSS = `
+ div {
+ background-color: lightblue;
+ padding: 1em;
+ border-radius: 0.5em;
+ }
+ `;
+
+ create_template ({ template }) {
+ $(template).html(`
+
I am a test view
+ `);
+ }
+}
+
+// TODO: This is necessary because files can be loaded from
+// both `/src/UI` and `/UI` in the URL; we need to fix that
+if ( ! window.__component_testView ) {
+ window.__component_testView = true;
+
+ customElements.define('c-test-view', TestView);
+}
diff --git a/src/UI/UIWindow2FASetup.js b/src/UI/UIWindow2FASetup.js
index 45286b22..882f391e 100644
--- a/src/UI/UIWindow2FASetup.js
+++ b/src/UI/UIWindow2FASetup.js
@@ -22,6 +22,8 @@
import CodeEntryView from "./Components/CodeEntryView.js";
import Flexer from "./Components/Flexer.js";
import QRCodeView from "./Components/QRCode.js";
+import StepView from "./Components/StepView.js";
+import TestView from "./Components/TestView.js";
import UIComponentWindow from "./UIComponentWindow.js";
const UIWindow2FASetup = async function UIWindow2FASetup () {
@@ -35,18 +37,29 @@ const UIWindow2FASetup = async function UIWindow2FASetup () {
});
const data = await resp.json();
- const component = new Flexer({
- children: [
- new QRCodeView({
- value: data.url,
- }),
- new CodeEntryView({
- on_update () {
- // NEXT
- }
- }),
- ]
- });
+ let stepper;
+ const component =
+ new StepView({
+ _ref: me => stepper = me,
+ children: [
+ new Flexer({
+ children: [
+ new QRCodeView({
+ value: data.url,
+ }),
+ new CodeEntryView({
+ [`property.value`] (value) {
+ console.log('value? ', value)
+ stepper.next();
+ }
+ }),
+ new TestView(),
+ ]
+ }),
+ new TestView(),
+ ]
+ })
+ ;
UIComponentWindow({
component,
diff --git a/src/util/Component.js b/src/util/Component.js
index 77579610..3e9e6d28 100644
--- a/src/util/Component.js
+++ b/src/util/Component.js
@@ -24,8 +24,20 @@ export class Component extends HTMLElement {
let initial_value;
if ( property_values && key in property_values ) {
initial_value = property_values[key];
+ } else if ( this.constructor.PROPERTIES[key].value !== undefined ) {
+ initial_value = this.constructor.PROPERTIES[key].value;
}
this.values_[key] = ValueHolder.adapt(initial_value);
+
+ const listener_key = `property.${key}`;
+ if ( property_values[listener_key] ) {
+ this.values_[key].sub(property_values[listener_key]);
+ }
+ }
+
+ // Convenience for setting a property while composing components
+ if ( property_values && property_values.hasOwnProperty('_ref') ) {
+ property_values._ref(this);
}
}