diff --git a/addon/components/paper-button.hbs b/addon/components/paper-button.hbs index 50ce9514d..2b9f2b85f 100644 --- a/addon/components/paper-button.hbs +++ b/addon/components/paper-button.hbs @@ -19,8 +19,8 @@ target={{@target}} title={{@title}} type={{this.type}} - {{did-insert this.registerListeners}} - {{will-destroy this.unregisterListeners}} + {{did-insert this.didInsertNode}} + {{will-destroy this.willDestroyNode}} {{on 'click' this.handleClick}} ...attributes > diff --git a/addon/components/paper-button.js b/addon/components/paper-button.js index abb15c15e..0f2679a01 100644 --- a/addon/components/paper-button.js +++ b/addon/components/paper-button.js @@ -2,13 +2,86 @@ * @module ember-paper */ import Focusable from './-focusable'; +import { tracked } from '@glimmer/tracking'; import { action } from '@ember/object'; +import { assert } from '@ember/debug'; /** * @class PaperButton * @extends Focusable */ export default class PaperButton extends Focusable { + /** + * Reference to the component's DOM element + * @type {HTMLElement} + */ + @tracked element; + /** + * The parent this component is bound to. + * @type {Boolean} + */ + parent; + /** + * Marks whether the component should register itself to the supplied parent + * @type {Boolean} + */ + shouldRegister; + /** + * Marks whether the component should skip being proxied. + * @type {Boolean} + */ + skipProxy; + + constructor(owner, args) { + super(owner, args); + + this.shouldRegister = this.args.shouldRegister || false; + this.skipProxy = this.args.skipProxy || false; + if (this.shouldRegister) { + assert( + 'A parent component should be supplied to when shouldRegister=true', + this.args.parentComponent + ); + this.parent = this.args.parentComponent; + } + } + + /** + * Performs any required DOM setup. + * @param element + */ + @action didInsertNode(element) { + this.element = element; + this.registerListeners(element); + + if (this.shouldRegister) { + this.args.parentComponent.registerChild(this); + } + } + + /** + * Performs DOM updates based on tracked args. + */ + @action didUpdateNode() { + // noop + } + + /** + * Performs any required DOM teardown. + * @param element + */ + @action willDestroyNode(element) { + this.unregisterListeners(element); + } + + willDestroy() { + super.willDestroy(...arguments); + + if (this.shouldRegister) { + this.args.parentComponent.unregisterChild(this); + } + } + get tag() { if (this.args.href) { return 'a'; @@ -41,4 +114,39 @@ export default class PaperButton extends Focusable { return this.args.bubbles; } + + // Proxiable Handlers + + @action handleMouseDown(e) { + super.handleMouseDown(e); + + let parentComponent = this.parentComponent; + if (parentComponent) { + parentComponent.mouseActive = true; + setTimeout(() => { + if (parentComponent.isDestroyed) { + return; + } + parentComponent.mouseActive = false; + }, 100); + } + } + + @action handleFocusIn(e) { + super.handleFocusIn(e); + + let parentComponent = this.parent; + if (parentComponent && !parentComponent.mouseActive) { + parentComponent.focused = true; + } + } + + @action focusOut(e) { + super.focusOut(e); + + let parentComponent = this.parent; + if (parentComponent) { + parentComponent.focused = false; + } + } }