From 27b24d44b7765edc351ff73fcf398615bcd39bff Mon Sep 17 00:00:00 2001 From: Miguel Andrade Date: Fri, 7 Feb 2020 19:25:54 +0000 Subject: [PATCH] update paper-slider to "pseudo-octane" --- addon/components/paper-slider.js | 212 ------------------- addon/components/paper-slider/component.js | 222 ++++++++++++++++++++ addon/components/paper-slider/template.hbs | 37 ++++ addon/templates/components/paper-slider.hbs | 18 -- app/components/paper-slider.js | 4 +- 5 files changed, 260 insertions(+), 233 deletions(-) delete mode 100644 addon/components/paper-slider.js create mode 100644 addon/components/paper-slider/component.js create mode 100644 addon/components/paper-slider/template.hbs delete mode 100644 addon/templates/components/paper-slider.hbs diff --git a/addon/components/paper-slider.js b/addon/components/paper-slider.js deleted file mode 100644 index 047407292..000000000 --- a/addon/components/paper-slider.js +++ /dev/null @@ -1,212 +0,0 @@ -/** - * @module ember-paper - */ -import { inject as service } from '@ember/service'; - -import { not } from '@ember/object/computed'; -import Component from '@ember/component'; -import { computed } from '@ember/object'; -import { run } from '@ember/runloop'; -import { htmlSafe } from '@ember/string'; -import layout from '../templates/components/paper-slider'; -import FocusableMixin from 'ember-paper/mixins/focusable-mixin'; -import ColorMixin from 'ember-paper/mixins/color-mixin'; -import clamp from 'ember-paper/utils/clamp'; -import { invokeAction } from 'ember-invoke-action'; - -/* global Hammer */ - -/** - * @class PaperSlider - * @extends Ember.Component - * @uses FocusableMixin - * @uses ColorMixin - */ -export default Component.extend(FocusableMixin, ColorMixin, { - layout, - tagName: 'md-slider', - - attributeBindings: ['min', 'max', 'step', 'discrete:md-discrete', 'tabindex'], - - classNames: ['md-default-theme'], - classNameBindings: ['isMinimum:md-min', 'active:md-active', 'dragging:md-dragging'], - - constants: service(), - - min: 0, - max: 100, - step: 1, - tabindex: 0, - - activeTrackStyle: computed('percent', function() { - let percent = this.get('percent') || 0; - return htmlSafe(`width: ${percent * 100}%`); - }), - - thumbContainerStyle: computed('percent', function() { - let percent = this.get('percent') || 0; - return htmlSafe(`left: ${percent * 100}%`); - }), - - isMinimum: computed('percent', 'min', function() { - return this.get('percent') === this.get('min'); - }), - - percent: computed('value', 'min', 'max', function() { - let min = parseFloat(this.get('min'), 10); - let max = parseFloat(this.get('max'), 10); - - return clamp((this.get('value') - min) / (max - min), 0, 1); - }), - - didInsertElement() { - this._super(...arguments); - if (!this.get('disabled')) { - this._setupHammer(); - } - }, - - didUpdateAttrs() { - this._super(...arguments); - - if (!this.get('disabled') && !this._hammer) { - // if it is enabled and we didn't init hammer yet - this._setupHammer(); - } else if (this.get('disabled') && this._hammer) { - // if it is disabled and we did init hammer already - this._teardownHammer(); - } - }, - - willDestroyElement() { - this._super(...arguments); - if (this._hammer) { - this._teardownHammer(); - } - }, - - _setupHammer() { - // Enable dragging the slider - let containerManager = new Hammer.Manager(this.element); - let pan = new Hammer.Pan({ direction: Hammer.DIRECTION_HORIZONTAL, threshold: 10 }); - containerManager.add(pan); - let tap = new Hammer.Tap(); - containerManager.add(tap); - - containerManager.on('panstart', run.bind(this, this.dragStart)) - .on('panmove', run.bind(this, this.drag)) - .on('panend', run.bind(this, this.dragEnd)) - .on('tap', run.bind(this, this.tap)); - - this._hammer = containerManager; - }, - - _teardownHammer() { - this._hammer.destroy(); - delete this._hammer; - }, - - positionToPercent(x) { - let { left, width } = this.sliderDimensions(); - return Math.max(0, Math.min(1, (x - left) / width)); - }, - - percentToValue(x) { - let min = parseFloat(this.get('min'), 10); - let max = parseFloat(this.get('max'), 10); - return (min + x * (max - min)); - }, - - minMaxValidator(value) { - let min = parseFloat(this.get('min'), 10); - let max = parseFloat(this.get('max'), 10); - return Math.max(min, Math.min(max, value)); - }, - - stepValidator(value) { - let step = parseFloat(this.get('step'), 10); - return Math.round(value / step) * step; - }, - - active: false, - dragging: false, - enabled: not('disabled'), - - sliderDimensions() { - return this.element.querySelector('.md-track-container').getBoundingClientRect(); - }, - - setValueFromEvent(value) { - let exactVal = this.percentToValue(this.positionToPercent(value)); - let closestVal = this.minMaxValidator(this.stepValidator(exactVal)); - - invokeAction(this, 'onChange', closestVal); - }, - - tap(event) { - if (this.get('disabled')) { - return; - } - - this.setValueFromEvent(event.center.x); - }, - - dragStart(event) { - if (this.get('disabled')) { - return; - } - - this.set('active', true); - this.set('dragging', true); - this.element.focus(); - - this.setValueFromEvent(event.center.x); - }, - - drag(event) { - if (this.get('disabled') || !this.get('dragging')) { - return; - } - - this.setValueFromEvent(event.center.x); - }, - - dragEnd() { - if (this.get('disabled')) { - return; - } - - this.setProperties({ - active: false, - dragging: false - }); - }, - - keyDown(event) { - if (this.get('disabled')) { - return; - } - - let changeAmount, newValue; - - if (event.keyCode === this.get('constants.KEYCODE.LEFT_ARROW')) { - changeAmount = parseFloat(this.get('step')) * -1; - } else if (event.keyCode === this.get('constants.KEYCODE.RIGHT_ARROW')) { - changeAmount = parseFloat(this.get('step')); - } - - if (changeAmount) { - if (event.metaKey || event.ctrlKey || event.altKey) { - changeAmount *= 4; - } - - newValue = this.get('value') + changeAmount; - - invokeAction(this, 'onChange', this.minMaxValidator(newValue)); - - event.preventDefault(); - event.stopPropagation(); - } - } - -}); diff --git a/addon/components/paper-slider/component.js b/addon/components/paper-slider/component.js new file mode 100644 index 000000000..05e1dbaac --- /dev/null +++ b/addon/components/paper-slider/component.js @@ -0,0 +1,222 @@ +/** + * @module ember-paper + */ +import Component from '@ember/component'; +import { computed, action } from '@ember/object'; +import { bind } from '@ember/runloop'; +import { htmlSafe } from '@ember/string'; +import template from './template'; +import clamp from 'ember-paper/utils/clamp'; +import { tagName, layout } from '@ember-decorators/component'; + +/* global Hammer */ + +/** + * @class PaperSlider + * @extends Ember.Component + */ +@tagName('') +@layout(template) +class PaperSlider extends Component { + + min = 0; + max = 100; + step = 1; + tabindex = 0; + + active = false; + dragging = false; + focused = false; + + element = null; + + @computed('value', 'min', 'max') + get percent() { + let min = parseFloat(this.min, 10); + let max = parseFloat(this.max, 10); + + return clamp((this.value - min) / (max - min), 0, 1); + } + + @computed('percent') + get activeTrackStyle() { + let percent = this.percent || 0; + return htmlSafe(`width: ${percent * 100}%`); + } + + @computed('percent') + get thumbContainerStyle() { + let percent = this.percent || 0; + return htmlSafe(`left: ${percent * 100}%`); + } + + @computed('percent', 'min') + get isMinimum() { + return this.percent === this.min; + } + + @action + onDidInsert(element) { + this.element = element; + if (!this.disabled) { + this._setupHammer(); + } + } + + @action + onDidUpdate() { + if (!this.disabled && !this._hammer) { + // if it is enabled and we didn't init hammer yet + this._setupHammer(); + } else if (this.disabled && this._hammer) { + // if it is disabled and we did init hammer already + this._teardownHammer(); + } + } + + @action + onWillDestroy() { + if (this._hammer) { + this._teardownHammer(); + } + } + + _setupHammer() { + // Enable dragging the slider + let containerManager = new Hammer.Manager(this.element); + let pan = new Hammer.Pan({ direction: Hammer.DIRECTION_HORIZONTAL, threshold: 10 }); + containerManager.add(pan); + let tap = new Hammer.Tap(); + containerManager.add(tap); + + containerManager + .on('panstart', bind(this, this.onDragStart)) + .on('panmove', bind(this, this.onDrag)) + .on('panend', bind(this, this.onDragEnd)) + .on('tap', bind(this, this.onTap)); + + this._hammer = containerManager; + } + + _teardownHammer() { + this._hammer.destroy(); + delete this._hammer; + } + + positionToPercent(x) { + let { left, width } = this.sliderDimensions(); + return Math.max(0, Math.min(1, (x - left) / width)); + } + + percentToValue(x) { + let min = parseFloat(this.min, 10); + let max = parseFloat(this.max, 10); + return (min + x * (max - min)); + } + + minMaxValidator(value) { + let min = parseFloat(this.min, 10); + let max = parseFloat(this.max, 10); + return Math.max(min, Math.min(max, value)); + } + + stepValidator(value) { + let step = parseFloat(this.step, 10); + return Math.round(value / step) * step; + } + + sliderDimensions() { + return this.element.querySelector('.md-track-container').getBoundingClientRect(); + } + + setValueFromEvent(value) { + let exactVal = this.percentToValue(this.positionToPercent(value)); + let closestVal = this.minMaxValidator(this.stepValidator(exactVal)); + + if (this.onChange) { + this.onChange(closestVal); + } + } + + onTap(event) { + if (this.disabled) { + return; + } + + this.setValueFromEvent(event.center.x); + } + + onDragStart(event) { + if (this.disabled) { + return; + } + + this.set('active', true); + this.set('dragging', true); + this.element.focus(); + + this.setValueFromEvent(event.center.x); + } + + onDrag(event) { + if (this.disabled || !this.dragging) { + return; + } + + this.setValueFromEvent(event.center.x); + } + + onDragEnd() { + if (this.disabled) { + return; + } + + this.set('active', false); + this.set('dragging', false); + } + + @action + handleKeyDown(event) { + if (this.disabled) { + return; + } + + let changeAmount, newValue; + + if (['ArrowLeft', 'Left'].includes(event.key)) { + changeAmount = parseFloat(this.step) * -1; + } else if (['ArrowRight', 'Right'].includes(event.key)) { + changeAmount = parseFloat(this.step); + } + + if (changeAmount) { + if (event.metaKey || event.ctrlKey || event.altKey) { + changeAmount *= 4; + } + + newValue = this.value + changeAmount; + + if (this.onChange) { + this.onChange(this.minMaxValidator(newValue)); + } + + event.preventDefault(); + event.stopPropagation(); + } + } + + @action + handleFocusIn() { + if (!this.disabled) { + this.set('focused', true); + } + } + + @action + handleFocusOut() { + this.set('focused', false); + } + +} + +export default PaperSlider; diff --git a/addon/components/paper-slider/template.hbs b/addon/components/paper-slider/template.hbs new file mode 100644 index 000000000..d2a2ad906 --- /dev/null +++ b/addon/components/paper-slider/template.hbs @@ -0,0 +1,37 @@ + +
+
+
+
+
+
+
+
+
+
+
+
+ {{@value}} +
+
+
+
+
+
\ No newline at end of file diff --git a/addon/templates/components/paper-slider.hbs b/addon/templates/components/paper-slider.hbs deleted file mode 100644 index 09f2f09be..000000000 --- a/addon/templates/components/paper-slider.hbs +++ /dev/null @@ -1,18 +0,0 @@ -
-
-
-
-
-
-
-
-
-
-
-
- {{value}} -
-
-
-
-
diff --git a/app/components/paper-slider.js b/app/components/paper-slider.js index 78da5ace0..2a9eae07e 100644 --- a/app/components/paper-slider.js +++ b/app/components/paper-slider.js @@ -1,3 +1 @@ -import paperSlider from 'ember-paper/components/paper-slider'; - -export default paperSlider; +export { default } from 'ember-paper/components/paper-slider/component';