UNPKG

ember-text-resize

Version:
160 lines (135 loc) 4.27 kB
import Ember from 'ember'; import layout from '../templates/components/text-resize'; const { get, getProperties, set, $, run:{next, scheduleOnce}, isPresent, typeOf, assert, RSVP:{Promise}, copy } = Ember; export default Ember.Component.extend({ layout, /* Element settings */ tagName: 'div', classNames: ['text-resize-container'], classNameBindings: ['_visible:visible'], /* Public properties */ text: undefined, fontSize: undefined, minFontSize: undefined, maxFontSize: undefined, step: -2, alwaysVisible: false, /* Private properties */ _fontSize: undefined, _visible: false, _activeDidRender: true, /* Private methods */ /** * Active the solution */ _active() { set(this, '_activeDidRender', false); set(this, '_fontSize', copy(get(this, 'fontSize'))); this._validateParams(); scheduleOnce('afterRender', () => { this._resizeText().then(() => { scheduleOnce('afterRender', () => set(this, '_activeDidRender', true)); }); }); }, /** * Validate the params received */ _validateParams() { let {fontSize, minFontSize, maxFontSize} = getProperties(this, ['fontSize', 'minFontSize', 'maxFontSize']), step = get(this, 'step'), alwaysVisible = get(this, 'alwaysVisible'), validNumber = (n) => n && parseFloat(n) && !isNaN(parseFloat(n)) || false, validFontSize = isPresent(fontSize) ? validNumber(fontSize) : true, validMinFontSize = isPresent(minFontSize) ? validNumber(minFontSize) : true, validMaxFontSize = isPresent(maxFontSize) ? validNumber(maxFontSize) : true, validStep = validNumber(step), validAlwaysVisible = typeOf(alwaysVisible) === 'boolean'; assert(`Invalid 'fontSize'. It must be a number.`, validFontSize); assert(`Invalid 'minFontSize'. It must be a number.`, validMinFontSize); assert(`Invalid 'maxFontSize'. It must be a number.`, validMaxFontSize); assert(`Invalid 'step'. It must be a number.`, validStep); assert(`Invalid 'alwaysVisible'. It must be boolean.`, validAlwaysVisible); }, /** * Resize the text size */ _resizeText() { return new Promise((resolve, reject) => { let $element = $(`#${this.elementId}`), $parent = $element.parent(), fontSize = parseFloat(get(this, '_fontSize') || 0) || parseFloat($element.css('font-size')), {minFontSize, maxFontSize} = getProperties(this, ['minFontSize', 'maxFontSize']), step = parseFloat(get(this, 'step')), alwaysVisible = get(this, 'alwaysVisible'); if ($element.width() <= 0) { resolve(); return; } const finish = () => { set(this, '_visible', true); resolve(); }; const maximize = () => { if ($element.width() < $parent.width()) { if (maxFontSize && fontSize === maxFontSize) { finish(); return; } fontSize += step; if (maxFontSize && fontSize > maxFontSize) { fontSize = maxFontSize; } resize(); } else { step *= -1; minimize(); } }; const minimize = () => { if ($element.width() > $parent.width()) { if (minFontSize && fontSize === minFontSize) { finish(); return; } fontSize += step; if (minFontSize && fontSize < minFontSize) { fontSize = minFontSize; } resize(); } else { finish(); } }; const resize = () => { let valid = fontSize > 0 , action = step > 0 ? maximize : minimize; set(this, '_fontSize', fontSize); if (valid) { next(() => action()); } }; set(this, '_visible', alwaysVisible); resize(); }); }, /* Life cycle */ didReceiveAttrs() { this._super(...arguments); this._active(); }, didRender() { this._super(...arguments); get(this, '_activeDidRender') && this._active(); }, });