import { Subject } from 'rxjs/Subject'; import 'rxjs/Subscription'; import { Renderer2, Directive, ElementRef, HostBinding, Component, ViewChild, HostListener, Input, EventEmitter, Output, ContentChild, ChangeDetectorRef, forwardRef, NgZone, NgModule } from '@angular/core'; import { throttleTime, tap, distinctUntilChanged, filter } from 'rxjs/operators'; import detectPassiveEvents from 'detect-passive-events'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { CommonModule } from '@angular/common'; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** @enum {number} */ const PointerType = { /** Low pointer */ Min: 0, /** High pointer */ Max: 1, }; PointerType[PointerType.Min] = "Min"; PointerType[PointerType.Max] = "Max"; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** @enum {number} */ const LabelType = { /** Label above low pointer */ Low: 0, /** Label above high pointer */ High: 1, /** Label for minimum slider value */ Floor: 2, /** Label for maximum slider value */ Ceil: 3, /** Label below legend tick */ TickValue: 4, }; LabelType[LabelType.Low] = "Low"; LabelType[LabelType.High] = "High"; LabelType[LabelType.Floor] = "Floor"; LabelType[LabelType.Ceil] = "Ceil"; LabelType[LabelType.TickValue] = "TickValue"; /** * Custom step definition * * This can be used to specify custom values and legend values for slider ticks * @record */ /** * Slider options */ class Options { constructor() { /** * Minimum value for a slider. * Not applicable when using stepsArray. */ this.floor = 0; /** * Maximum value for a slider. * Not applicable when using stepsArray. */ this.ceil = null; /** * Step between each value. * Not applicable when using stepsArray. */ this.step = 1; /** * The minimum range authorized on the slider. * Applies to range slider only. * When using stepsArray, expressed as index into stepsArray. */ this.minRange = null; /** * The maximum range authorized on the slider. * Applies to range slider only. * When using stepsArray, expressed as index into stepsArray. */ this.maxRange = null; /** * Set to true to have a push behavior. When the min handle goes above the max, * the max is moved as well (and vice-versa). The range between min and max is * defined by the step option (defaults to 1) and can also be overriden by * the minRange option. Applies to range slider only. */ this.pushRange = false; /** * The minimum value authorized on the slider. * When using stepsArray, expressed as index into stepsArray. */ this.minLimit = null; /** * The maximum value authorized on the slider. * When using stepsArray, expressed as index into stepsArray. */ this.maxLimit = null; /** * Custom translate function. Use this if you want to translate values displayed * on the slider. */ this.translate = null; /** * Custom function for combining overlapping labels in range slider. * It takes the min and max values (already translated with translate fuction) * and should return how these two values should be combined. * If not provided, the default function will join the two values with * ' - ' as separator. */ this.combineLabels = null; /** * Use to display legend under ticks (thus, it needs to be used along with * showTicks or showTicksValues). The function will be called with each tick * value and returned content will be displayed under the tick as a legend. * If the returned value is null, then no legend is displayed under * the corresponding tick.You can also directly provide the legend values * in the stepsArray option. */ this.getLegend = null; /** * If you want to display a slider with non linear/number steps. * Just pass an array with each slider value and that's it; the floor, ceil and step settings * of the slider will be computed automatically. * By default, the value model and valueHigh model values will be the value of the selected item * in the stepsArray. * They can also be bound to the index of the selected item by setting the bindIndexForStepsArray * option to true. */ this.stepsArray = null; /** * Set to true to bind the index of the selected item to value model and valueHigh model. */ this.bindIndexForStepsArray = false; /** * When set to true and using a range slider, the range can be dragged by the selection bar. * Applies to range slider only. */ this.draggableRange = false; /** * Same as draggableRange but the slider range can't be changed. * Applies to range slider only. */ this.draggableRangeOnly = false; /** * Set to true to always show the selection bar before the slider handle. */ this.showSelectionBar = false; /** * Set to true to always show the selection bar after the slider handle. */ this.showSelectionBarEnd = false; /** * Set a number to draw the selection bar between this value and the slider handle. * When using stepsArray, expressed as index into stepsArray. */ this.showSelectionBarFromValue = null; /** * Only for range slider. Set to true to visualize in different colour the areas * on the left/right (top/bottom for vertical range slider) of selection bar between the handles. */ this.showOuterSelectionBars = false; /** * Set to true to hide pointer labels */ this.hidePointerLabels = false; /** * Set to true to hide min / max labels */ this.hideLimitLabels = false; /** * Set to false to disable the auto-hiding behavior of the limit labels. */ this.autoHideLimitLabels = true; /** * Set to true to make the slider read-only. */ this.readOnly = false; /** * Set to true to disable the slider. */ this.disabled = false; /** * Throttle interval for mouse events in milliseconds. * This is provided to avoid a flood of events when moving the slider with mouse. */ this.mouseEventsInterval = 50; /** * Throttle interval for touch events in milliseconds. * This is provided to avoid a flood of events when moving the slider with touch gesture. */ this.touchEventsInterval = 50; /** * Throttle interval for input changes (changes to bindings or reactive form inputs) * This is provided to avoid a flood of events on frequent input binding changes affecting performance. */ this.inputEventsInterval = 100; /** * Throttle interval for output changes (signalling changes to output bindings and user callbacks) * This is provided to avoid a flood of outgoing events affecting Angular app performance. */ this.outputEventsInterval = 100; /** * Set to true to display a tick for each step of the slider. */ this.showTicks = false; /** * Set to true to display a tick and the step value for each step of the slider.. */ this.showTicksValues = false; /* The step between each tick to display. If not set, the step value is used. Not used when ticksArray is specified. */ this.tickStep = null; /* The step between displaying each tick step value. */ this.tickValueStep = 1; /** * Use to display ticks at specific positions. * The array contains the index of the ticks that should be displayed. * For example, [0, 1, 5] will display a tick for the first, second and sixth values. */ this.ticksArray = null; /** * Used to display a tooltip when a tick is hovered. * Set to a function that returns the tooltip content for a given value. */ this.ticksTooltip = null; /** * Same as ticksTooltip but for ticks values. */ this.ticksValuesTooltip = null; /** * Set to true to display the slider vertically. * The slider will take the full height of its parent. * Changing this value at runtime is not currently supported. */ this.vertical = false; /** * Function that returns the current color of the selection bar. * If your color won't change, don't use this option but set it through CSS. * If the returned color depends on a model value (either value or valueHigh), * you should use the argument passed to the function. * Indeed, when the function is called, there is no certainty that the model * has already been updated. */ this.getSelectionBarColor = null; /** * Function that returns the color of a tick. showTicks must be enabled. */ this.getTickColor = null; /** * Function that returns the current color of a pointer. * If your color won't change, don't use this option but set it through CSS. * If the returned color depends on a model value (either value or valueHigh), * you should use the argument passed to the function. * Indeed, when the function is called, there is no certainty that the model has already been updated. * To handle range slider pointers independently, you should evaluate pointerType within the given * function where "min" stands for value model and "max" for valueHigh model values. */ this.getPointerColor = null; /** * Handles are focusable (on click or with tab) and can be modified using the following keyboard controls: * Left/bottom arrows: -1 * Right/top arrows: +1 * Page-down: -10% * Page-up: +10% * Home: minimum value * End: maximum value */ this.keyboardSupport = true; /** * If you display the slider in an element that uses transform: scale(0.5), set the scale value to 2 * so that the slider is rendered properly and the events are handled correctly. */ this.scale = 1; /** * Set to true to force the value to be rounded to the step, even when modified from the outside. * When set to false, if the model values are modified from outside the slider, they are not rounded * and can be between two steps. */ this.enforceStep = true; /** * Set to true to force the value to be normalised to allowed range (floor to ceil), even when modified from the outside. * When set to false, if the model values are modified from outside the slider, and they are outside allowed range, * the slider may be rendered incorrectly. However, setting this to false may be useful if you want to perform custom normalisation. */ this.enforceRange = true; /** * Set to true to prevent to user from switching the min and max handles. Applies to range slider only. */ this.noSwitching = false; /** * Set to true to only bind events on slider handles. */ this.onlyBindHandles = false; /** * Set to true to show graphs right to left. * If vertical is true it will be from top to bottom and left / right arrow functions reversed. */ this.rightToLeft = false; /** * Set to true to reverse keyboard navigation: * Right/top arrows: -1 * Left/bottom arrows: +1 * Page-up: -10% * Page-down: +10% * End: minimum value * Home: maximum value */ this.reversedControls = false; /** * Set to true to keep the slider labels inside the slider bounds. */ this.boundPointerLabels = true; /** * Set to true to use a logarithmic scale to display the slider. */ this.logScale = false; /** * Function that returns the position on the slider for a given value. * The position must be a percentage between 0 and 1. * The function should be monotonically increasing or decreasing; otherwise the slider may behave incorrectly. */ this.customValueToPosition = null; /** * Function that returns the value for a given position on the slider. * The position is a percentage between 0 and 1. * The function should be monotonically increasing or decreasing; otherwise the slider may behave incorrectly. */ this.customPositionToValue = null; /** * Precision limit for calculated values. * Values used in calculations will be rounded to this number of significant digits * to prevent accumulating small floating-point errors. */ this.precisionLimit = 12; /** * Use to display the selection bar as a gradient. * The given object must contain from and to properties which are colors. */ this.selectionBarGradient = null; /** * Use to add a label directly to the slider for accessibility. Adds the aria-label attribute. */ this.ariaLabel = null; /** * Use instead of ariaLabel to reference the id of an element which will be used to label the slider. * Adds the aria-labelledby attribute. */ this.ariaLabelledBy = null; /** * Use to add a label directly to the slider range for accessibility. Adds the aria-label attribute. */ this.ariaLabelHigh = null; /** * Use instead of ariaLabelHigh to reference the id of an element which will be used to label the slider range. * Adds the aria-labelledby attribute. */ this.ariaLabelledByHigh = null; /** * Use to increase rendering performance. If the value is not provided, the slider calculates the with/height of the handle */ this.handleDimension = null; /** * Use to increase rendering performance. If the value is not provided, the slider calculates the with/height of the bar */ this.barDimension = null; /** * Enable/disable CSS animations */ this.animate = true; } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class ChangeContext { } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Collection of functions to handle conversions/lookups of values */ class ValueHelper { /** * @param {?} value * @return {?} */ static isNullOrUndefined(value) { return value === undefined || value === null; } /** * @param {?} val * @param {?} minVal * @param {?} maxVal * @return {?} */ static linearValueToPosition(val, minVal, maxVal) { const /** @type {?} */ range = maxVal - minVal; return (val - minVal) / range; } /** * @param {?} val * @param {?} minVal * @param {?} maxVal * @return {?} */ static logValueToPosition(val, minVal, maxVal) { val = Math.log(val); minVal = Math.log(minVal); maxVal = Math.log(maxVal); const /** @type {?} */ range = maxVal - minVal; return (val - minVal) / range; } /** * @param {?} percent * @param {?} minVal * @param {?} maxVal * @return {?} */ static linearPositionToValue(percent, minVal, maxVal) { return percent * (maxVal - minVal) + minVal; } /** * @param {?} percent * @param {?} minVal * @param {?} maxVal * @return {?} */ static logPositionToValue(percent, minVal, maxVal) { minVal = Math.log(minVal); maxVal = Math.log(maxVal); const /** @type {?} */ value = percent * (maxVal - minVal) + minVal; return Math.exp(value); } /** * @param {?} modelValue * @param {?} stepsArray * @return {?} */ static findStepIndex(modelValue, stepsArray) { const /** @type {?} */ differences = stepsArray.map((step) => Math.abs(modelValue - step.value)); let /** @type {?} */ minDifferenceIndex = 0; for (let /** @type {?} */ index = 0; index < stepsArray.length; index++) { if (differences[index] !== differences[minDifferenceIndex] && differences[index] < differences[minDifferenceIndex]) { minDifferenceIndex = index; } } return minDifferenceIndex; } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Helper with compatibility functions to support different browsers */ class CompatibilityHelper { /** * Workaround for TouchEvent constructor sadly not being available on all browsers (e.g. Firefox, Safari) * @param {?} event * @return {?} */ static isTouchEvent(event) { if ((/** @type {?} */ (window)).TouchEvent !== undefined) { return event instanceof TouchEvent; } return event.touches !== undefined; } /** * Detect presence of ResizeObserver API * @return {?} */ static isResizeObserverAvailable() { return (/** @type {?} */ (window)).ResizeObserver !== undefined; } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Helper with mathematical functions */ class MathHelper { /** * @param {?} value * @param {?} precisionLimit * @return {?} */ static roundToPrecisionLimit(value, precisionLimit) { return +(value.toPrecision(precisionLimit)); } /** * @param {?} value * @param {?} floor * @param {?} ceil * @return {?} */ static clampToRange(value, floor, ceil) { return Math.min(Math.max(value, floor), ceil); } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class EventListener { constructor() { this.eventName = null; this.events = null; this.eventsSubscription = null; this.teardownCallback = null; } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Helper class to attach event listeners to DOM elements with debounce support using rxjs */ class EventListenerHelper { /** * @param {?} renderer */ constructor(renderer) { this.renderer = renderer; } /** * @param {?} nativeElement * @param {?} eventName * @param {?} callback * @param {?=} throttleInterval * @return {?} */ attachPassiveEventListener(nativeElement, eventName, callback, throttleInterval) { // Only use passive event listeners if the browser supports it if (detectPassiveEvents.hasSupport !== true) { return this.attachEventListener(nativeElement, eventName, callback, throttleInterval); } // Angular doesn't support passive event handlers (yet), so we need to roll our own code using native functions const /** @type {?} */ listener = new EventListener(); listener.eventName = eventName; listener.events = new Subject(); const /** @type {?} */ observerCallback = (event) => { listener.events.next(event); }; nativeElement.addEventListener(eventName, observerCallback, { passive: true, capture: false }); listener.teardownCallback = () => { nativeElement.removeEventListener(eventName, observerCallback, { passive: true, capture: false }); }; listener.eventsSubscription = listener.events .pipe((!ValueHelper.isNullOrUndefined(throttleInterval)) ? throttleTime(throttleInterval, undefined, { leading: true, trailing: true }) : tap(() => { }) // no-op ) .subscribe((event) => { callback(event); }); return listener; } /** * @param {?} eventListener * @return {?} */ detachEventListener(eventListener) { if (!ValueHelper.isNullOrUndefined(eventListener.eventsSubscription)) { eventListener.eventsSubscription.unsubscribe(); eventListener.eventsSubscription = null; } if (!ValueHelper.isNullOrUndefined(eventListener.events)) { eventListener.events.complete(); eventListener.events = null; } if (!ValueHelper.isNullOrUndefined(eventListener.teardownCallback)) { eventListener.teardownCallback(); eventListener.teardownCallback = null; } } /** * @param {?} nativeElement * @param {?} eventName * @param {?} callback * @param {?=} throttleInterval * @return {?} */ attachEventListener(nativeElement, eventName, callback, throttleInterval) { const /** @type {?} */ listener = new EventListener(); listener.eventName = eventName; listener.events = new Subject(); const /** @type {?} */ observerCallback = (event) => { listener.events.next(event); }; listener.teardownCallback = this.renderer.listen(nativeElement, eventName, observerCallback); listener.eventsSubscription = listener.events .pipe((!ValueHelper.isNullOrUndefined(throttleInterval)) ? throttleTime(throttleInterval, undefined, { leading: true, trailing: true }) : tap(() => { }) // no-op ) .subscribe((event) => { callback(event); }); return listener; } } /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class SliderElementDirective { /** * @param {?} elemRef * @param {?} renderer */ constructor(elemRef, renderer) { this.elemRef = elemRef; this.renderer = renderer; this._position = 0; this._dimension = 0; this._alwaysHide = false; this._vertical = false; this._scale = 1; this.opacity = 1; this.visibility = 'visible'; this.left = ''; this.bottom = ''; this.height = ''; this.width = ''; this.eventListeners = []; this.eventListenerHelper = new EventListenerHelper(this.renderer); } /** * @return {?} */ get position() { return this._position; } /** * @return {?} */ get dimension() { return this._dimension; } /** * @return {?} */ get alwaysHide() { return this._alwaysHide; } /** * @return {?} */ get vertical() { return this._vertical; } /** * @return {?} */ get scale() { return this._scale; } /** * @param {?} hide * @return {?} */ setAlwaysHide(hide) { this._alwaysHide = hide; if (hide) { this.visibility = 'hidden'; } else { this.visibility = 'visible'; } } /** * @return {?} */ hide() { this.opacity = 0; } /** * @return {?} */ show() { if (this.alwaysHide) { return; } this.opacity = 1; } /** * @return {?} */ isVisible() { if (this.alwaysHide) { return false; } return this.opacity !== 0; } /** * @param {?} vertical * @return {?} */ setVertical(vertical) { this._vertical = vertical; if (this._vertical) { this.left = ''; this.width = ''; } else { this.bottom = ''; this.height = ''; } } /** * @param {?} scale * @return {?} */ setScale(scale) { this._scale = scale; } /** * @param {?} pos * @return {?} */ setPosition(pos) { this._position = pos; if (this._vertical) { this.bottom = Math.round(pos) + 'px'; } else { this.left = Math.round(pos) + 'px'; } } /** * @return {?} */ calculateDimension() { const /** @type {?} */ val = this.getBoundingClientRect(); if (this.vertical) { this._dimension = (val.bottom - val.top) * this.scale; } else { this._dimension = (val.right - val.left) * this.scale; } } /** * @param {?} dim * @return {?} */ setDimension(dim) { this._dimension = dim; if (this._vertical) { this.height = Math.round(dim) + 'px'; } else { this.width = Math.round(dim) + 'px'; } } /** * @return {?} */ getBoundingClientRect() { return this.elemRef.nativeElement.getBoundingClientRect(); } /** * @param {?} eventName * @param {?} callback * @param {?=} debounceInterval * @return {?} */ on(eventName, callback, debounceInterval) { const /** @type {?} */ listener = this.eventListenerHelper.attachEventListener(this.elemRef.nativeElement, eventName, callback, debounceInterval); this.eventListeners.push(listener); } /** * @param {?} eventName * @param {?} callback * @param {?=} debounceInterval * @return {?} */ onPassive(eventName, callback, debounceInterval) { const /** @type {?} */ listener = this.eventListenerHelper.attachPassiveEventListener(this.elemRef.nativeElement, eventName, callback, debounceInterval); this.eventListeners.push(listener); } /** * @param {?=} eventName * @return {?} */ off(eventName) { let /** @type {?} */ listenersToKeep; let /** @type {?} */ listenersToRemove; if (!ValueHelper.isNullOrUndefined(eventName)) { listenersToKeep = this.eventListeners.filter((event) => event.eventName !== eventName); listenersToRemove = this.eventListeners.filter((event) => event.eventName === eventName); } else { listenersToKeep = []; listenersToRemove = this.eventListeners; } for (const /** @type {?} */ listener of listenersToRemove) { this.eventListenerHelper.detachEventListener(listener); } this.eventListeners = listenersToKeep; } } SliderElementDirective.decorators = [ { type: Directive, args: [{ selector: '[ng5SliderElement]' },] }, ]; /** @nocollapse */ SliderElementDirective.ctorParameters = () => [ { type: ElementRef, }, { type: Renderer2, }, ]; SliderElementDirective.propDecorators = { "opacity": [{ type: HostBinding, args: ['style.opacity',] },], "visibility": [{ type: HostBinding, args: ['style.visibility',] },], "left": [{ type: HostBinding, args: ['style.left',] },], "bottom": [{ type: HostBinding, args: ['style.bottom',] },], "height": [{ type: HostBinding, args: ['style.height',] },], "width": [{ type: HostBinding, args: ['style.width',] },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class SliderHandleDirective extends SliderElementDirective { /** * @param {?} elemRef * @param {?} renderer */ constructor(elemRef, renderer) { super(elemRef, renderer); this.active = false; this.role = ''; this.tabindex = ''; this.ariaOrientation = ''; this.ariaLabel = ''; this.ariaLabelledBy = ''; this.ariaValueNow = ''; this.ariaValueText = ''; this.ariaValueMin = ''; this.ariaValueMax = ''; } /** * @return {?} */ focus() { this.elemRef.nativeElement.focus(); } } SliderHandleDirective.decorators = [ { type: Directive, args: [{ selector: '[ng5SliderHandle]' },] }, ]; /** @nocollapse */ SliderHandleDirective.ctorParameters = () => [ { type: ElementRef, }, { type: Renderer2, }, ]; SliderHandleDirective.propDecorators = { "active": [{ type: HostBinding, args: ['class.ng5-slider-active',] },], "role": [{ type: HostBinding, args: ['attr.role',] },], "tabindex": [{ type: HostBinding, args: ['attr.tabindex',] },], "ariaOrientation": [{ type: HostBinding, args: ['attr.aria-orientation',] },], "ariaLabel": [{ type: HostBinding, args: ['attr.aria-label',] },], "ariaLabelledBy": [{ type: HostBinding, args: ['attr.aria-labelledby',] },], "ariaValueNow": [{ type: HostBinding, args: ['attr.aria-valuenow',] },], "ariaValueText": [{ type: HostBinding, args: ['attr.aria-valuetext',] },], "ariaValueMin": [{ type: HostBinding, args: ['attr.aria-valuemin',] },], "ariaValueMax": [{ type: HostBinding, args: ['attr.aria-valuemax',] },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class SliderLabelDirective extends SliderElementDirective { /** * @param {?} elemRef * @param {?} renderer */ constructor(elemRef, renderer) { super(elemRef, renderer); this._value = null; } /** * @return {?} */ get value() { return this._value; } /** * @param {?} value * @return {?} */ setValue(value) { let /** @type {?} */ recalculateDimension = false; if (!this.alwaysHide && (ValueHelper.isNullOrUndefined(this.value) || this.value.length !== value.length || (this.value.length > 0 && this.dimension === 0))) { recalculateDimension = true; } this._value = value; this.elemRef.nativeElement.innerHTML = value; // Update dimension only when length of the label have changed if (recalculateDimension) { this.calculateDimension(); } } } SliderLabelDirective.decorators = [ { type: Directive, args: [{ selector: '[ng5SliderLabel]' },] }, ]; /** @nocollapse */ SliderLabelDirective.ctorParameters = () => [ { type: ElementRef, }, { type: Renderer2, }, ]; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class Tick { constructor() { this.selected = false; this.style = {}; this.tooltip = null; this.tooltipPlacement = null; this.value = null; this.valueTooltip = null; this.valueTooltipPlacement = null; this.legend = null; } } class Dragging { constructor() { this.active = false; this.value = 0; this.difference = 0; this.position = 0; this.lowLimit = 0; this.highLimit = 0; } } class ModelValues { /** * @param {?=} x * @param {?=} y * @return {?} */ static compare(x, y) { if (ValueHelper.isNullOrUndefined(x) && ValueHelper.isNullOrUndefined(y)) { return false; } if (ValueHelper.isNullOrUndefined(x) !== ValueHelper.isNullOrUndefined(y)) { return false; } return x.value === y.value && x.highValue === y.highValue; } } class ModelChange extends ModelValues { /** * @param {?=} x * @param {?=} y * @return {?} */ static compare(x, y) { if (ValueHelper.isNullOrUndefined(x) && ValueHelper.isNullOrUndefined(y)) { return false; } if (ValueHelper.isNullOrUndefined(x) !== ValueHelper.isNullOrUndefined(y)) { return false; } return x.value === y.value && x.highValue === y.highValue && x.forceChange === y.forceChange; } } const NG5_SLIDER_CONTROL_VALUE_ACCESSOR = { provide: NG_VALUE_ACCESSOR, /* tslint:disable-next-line: no-use-before-declare */ useExisting: forwardRef(() => SliderComponent), multi: true, }; class SliderComponent { /** * @param {?} renderer * @param {?} elementRef * @param {?} changeDetectionRef * @param {?} zone */ constructor(renderer, elementRef, changeDetectionRef, zone) { this.renderer = renderer; this.elementRef = elementRef; this.changeDetectionRef = changeDetectionRef; this.zone = zone; // Model for low value of slider. For simple slider, this is the only input. For range slider, this is the low value. this.value = null; // Output for low value slider to support two-way bindings this.valueChange = new EventEmitter(); // Model for high value of slider. Not used in simple slider. For range slider, this is the high value. this.highValue = null; // Output for high value slider to support two-way bindings this.highValueChange = new EventEmitter(); // An object with all the other options of the slider. // Each option can be updated at runtime and the slider will automatically be re-rendered. this.options = new Options(); // Event emitted when user starts interaction with the slider this.userChangeStart = new EventEmitter(); // Event emitted on each change coming from user interaction this.userChange = new EventEmitter(); // Event emitted when user finishes interaction with the slider this.userChangeEnd = new EventEmitter(); this.initHasRun = false; this.inputModelChangeSubject = new Subject(); this.inputModelChangeSubscription = null; this.outputModelChangeSubject = new Subject(); this.outputModelChangeSubscription = null; this.viewLowValue = null; this.viewHighValue = null; this.viewOptions = new Options(); this.handleHalfDimension = 0; this.maxHandlePosition = 0; this.currentTrackingPointer = null; this.currentFocusPointer = null; this.firstKeyDown = false; this.touchId = null; this.dragging = new Dragging(); // Host element class bindings this.sliderElementVerticalClass = false; this.sliderElementAnimateClass = false; this.sliderElementDisabledAttr = null; this.barStyle = {}; this.minPointerStyle = {}; this.maxPointerStyle = {}; this.fullBarTransparentClass = false; this.selectionBarDraggableClass = false; this.ticksUnderValuesClass = false; this.intermediateTicks = false; this.ticks = []; this.eventListenerHelper = null; this.onMoveEventListener = null; this.onEndEventListener = null; this.resizeObserver = null; this.onTouchedCallback = null; this.onChangeCallback = null; this.eventListenerHelper = new EventListenerHelper(this.renderer); } /** * @param {?} manualRefresh * @return {?} */ set manualRefresh(manualRefresh) { this.unsubscribeManualRefresh(); this.manualRefreshSubscription = manualRefresh.subscribe(() => { setTimeout(() => this.calculateViewDimensionsAndDetectChanges()); }); } /** * @param {?} triggerFocus * @return {?} */ set triggerFocus(triggerFocus) { this.unsubscribeTriggerFocus(); this.triggerFocusSubscription = triggerFocus.subscribe((pointerType) => { this.focusPointer(pointerType); }); } /** * @return {?} */ get range() { return !ValueHelper.isNullOrUndefined(this.value) && !ValueHelper.isNullOrUndefined(this.highValue); } /** * @return {?} */ get showTicks() { return this.viewOptions.showTicks; } /** * @return {?} */ ngOnInit() { this.viewOptions = new Options(); Object.assign(this.viewOptions, this.options); // We need to run these two things first, before the rest of the init in ngAfterViewInit(), // because these two settings are set through @HostBinding and Angular change detection // mechanism doesn't like them changing in ngAfterViewInit() this.updateDisabledState(); this.updateVerticalState(); } /** * @return {?} */ ngAfterViewInit() { this.applyOptions(); this.subscribeInputModelChangeSubject(this.viewOptions.inputEventsInterval); this.subscribeOutputModelChangeSubject(this.viewOptions.outputEventsInterval); // Once we apply options, we need to normalise model values for the first time this.renormaliseModelValues(); this.viewLowValue = this.modelValueToViewValue(this.value); if (this.range) { this.viewHighValue = this.modelValueToViewValue(this.highValue); } else { this.viewHighValue = null; } this.updateVerticalState(); // need to run this again to cover changes to slider elements this.manageElementsStyle(); this.updateDisabledState(); this.calculateViewDimensions(); this.addAccessibility(); this.updateCeilLabel(); this.updateFloorLabel(); this.initHandles(); this.manageEventsBindings(); this.subscribeResizeObserver(); this.initHasRun = true; // Run change detection manually to resolve some issues when init procedure changes values used in the view this.changeDetectionRef.detectChanges(); } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { // Always apply options first if (!ValueHelper.isNullOrUndefined(changes["options"])) { this.onChangeOptions(); } // Then value changes if (!ValueHelper.isNullOrUndefined(changes["value"]) || !ValueHelper.isNullOrUndefined(changes["highValue"])) { this.inputModelChangeSubject.next({ value: this.value, highValue: this.highValue, forceChange: false, internalChange: false }); } } /** * @return {?} */ ngOnDestroy() { this.unbindEvents(); this.unsubscribeResizeObserver(); this.unsubscribeInputModelChangeSubject(); this.unsubscribeOutputModelChangeSubject(); this.unsubscribeManualRefresh(); this.unsubscribeTriggerFocus(); } /** * @param {?} obj * @return {?} */ writeValue(obj) { if (obj instanceof Array) { this.value = obj[0]; this.highValue = obj[1]; } else { this.value = obj; } // ngOnChanges() is not called in this instance, so we need to communicate the change manually this.inputModelChangeSubject.next({ value: this.value, highValue: this.highValue, forceChange: false, internalChange: false }); } /** * @param {?} onChangeCallback * @return {?} */ registerOnChange(onChangeCallback) { this.onChangeCallback = onChangeCallback; } /** * @param {?} onTouchedCallback * @return {?} */ registerOnTouched(onTouchedCallback) { this.onTouchedCallback = onTouchedCallback; } /** * @param {?} isDisabled * @return {?} */ setDisabledState(isDisabled) { this.viewOptions.disabled = isDisabled; this.updateDisabledState(); } /** * @param {?} event * @return {?} */ onResize(event) { this.calculateViewDimensionsAndDetectChanges(); } /** * @param {?=} interval * @return {?} */ subscribeInputModelChangeSubject(interval) { this.inputModelChangeSubscription = this.inputModelChangeSubject .pipe(distinctUntilChanged(ModelChange.compare), // Hack to reset the status of the distinctUntilChanged() - if a "fake" event comes through with forceChange=true, // we forcefully by-pass distinctUntilChanged(), but otherwise drop the event filter((modelChange) => !modelChange.forceChange && !modelChange.internalChange), (!ValueHelper.isNullOrUndefined(interval)) ? throttleTime(interval, undefined, { leading: true, trailing: true }) : tap(() => { }) // no-op ) .subscribe((modelChange) => this.applyInputModelChange(modelChange)); } /** * @param {?=} interval * @return {?} */ subscribeOutputModelChangeSubject(interval) { this.outputModelChangeSubscription = this.outputModelChangeSubject .pipe(distinctUntilChanged(ModelChange.compare), (!ValueHelper.isNullOrUndefined(interval)) ? throttleTime(interval, undefined, { leading: true, trailing: true }) : tap(() => { }) // no-op ) .subscribe((modelChange) => this.publishOutputModelChange(modelChange)); } /** * @return {?} */ subscribeResizeObserver() { if (CompatibilityHelper.isResizeObserverAvailable()) { this.resizeObserver = new ResizeObserver(() => this.calculateViewDimensionsAndDetectChanges()); this.resizeObserver.observe(this.elementRef.nativeElement); } } /** * @return {?} */ unsubscribeResizeObserver() { if (CompatibilityHelper.isResizeObserverAvailable() && this.resizeObserver !== null) { this.resizeObserver.disconnect(); this.resizeObserver = null; } } /** * @return {?} */ unsubscribeOnMove() { if (!ValueHelper.isNullOrUndefined(this.onMoveEventListener)) { this.eventListenerHelper.detachEventListener(this.onMoveEventListener); this.onMoveEventListener = null; } } /** * @return {?} */ unsubscribeOnEnd() { if (!ValueHelper.isNullOrUndefined(this.onEndEventListener)) { this.eventListenerHelper.detachEventListener(this.onEndEventListener); this.onEndEventListener = null; } } /** * @return {?} */ unsubscribeInputModelChangeSubject() { if (!ValueHelper.isNullOrUndefined(this.inputModelChangeSubscription)) { this.inputModelChangeSubscription.unsubscribe(); this.inputModelChangeSubscription = null; } } /** * @return {?} */ unsubscribeOutputModelChangeSubject() { if (!ValueHelper.isNullOrUndefined(this.outputModelChangeSubscription)) { this.outputModelChangeSubscription.unsubscribe(); this.outputModelChangeSubscription = null; } } /** * @return {?} */ unsubscribeManualRefresh() { if (!ValueHelper.isNullOrUndefined(this.manualRefreshSubscription)) { this.manualRefreshSubscription.unsubscribe(); this.manualRefreshSubscription = null; } } /** * @return {?} */ unsubscribeTriggerFocus() { if (!ValueHelper.isNullOrUndefined(this.triggerFocusSubscription)) { this.triggerFocusSubscription.unsubscribe(); this.triggerFocusSubscription = null; } } /** * @param {?} pointerType * @return {?} */ getPointerElement(pointerType) { if (pointerType === PointerType.Min) { return this.minHandleElement; } else if (pointerType === PointerType.Max) { return this.maxHandleElement; } return null; } /** * @return {?} */ getCurrentTrackingValue() { if (this.currentTrackingPointer === PointerType.Min) { return this.viewLowValue; } else if (this.currentTrackingPointer === PointerType.Max) { return this.viewHighValue; } return null; } /** * @param {?} modelValue * @return {?} */ modelValueToViewValue(modelValue) { if (ValueHelper.isNullOrUndefined(modelValue)) { return NaN; } if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray) && !this.viewOptions.bindIndexForStepsArray) { return ValueHelper.findStepIndex(+modelValue, this.viewOptions.stepsArray); } return +modelValue; } /** * @param {?} viewValue * @return {?} */ viewValueToModelValue(viewValue) { if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray) && !this.viewOptions.bindIndexForStepsArray) { return this.getStepValue(viewValue); } return viewValue; } /** * @param {?} sliderValue * @return {?} */ getStepValue(sliderValue) { const /** @type {?} */ step = this.viewOptions.stepsArray[sliderValue]; return (!ValueHelper.isNullOrUndefined(step)) ? step.value : NaN; } /** * @return {?} */ applyViewChange() { this.value = this.viewValueToModelValue(this.viewLowValue); if (this.range) { this.highValue = this.viewValueToModelValue(this.viewHighValue); } this.outputModelChangeSubject.next({ value: this.value, highValue: this.highValue, userEventInitiated: true, forceChange: false }); // At this point all changes are applied and outputs are emitted, so we should be done. // However, input changes are communicated in different stream and we need to be ready to // act on the next input change even if it is exactly the same as last input change. // Therefore, we send a special event to reset the stream. this.inputModelChangeSubject.next({ value: this.value, highValue: this.highValue, forceChange: false, internalChange: true }); } /** * @param {?} modelChange * @return {?} */ applyInputModelChange(modelChange) { const /** @type {?} */ normalisedModelChange = this.normaliseModelValues(modelChange); // If normalised model change is different, apply the change to the model values const /** @type {?} */ normalisationChange = !ModelValues.compare(modelChange, normalisedModelChange); if (normalisationChange) { this.value = normalisedModelChange.value; this.highValue = normalisedModelChange.highValue; } this.viewLowValue = this.modelValueToViewValue(normalisedModelChange.value); if (this.range) { this.viewHighValue = this.modelValueToViewValue(normalisedModelChange.highValue); } else { this.viewHighValue = null; } this.updateLowHandle(this.valueToPosition(this.viewLowValue)); if (this.range) { this.updateHighHandle(this.valueToPosition(this.viewHighValue)); } this.updateSelectionBar(); this.updateTicksScale(); this.updateAriaAttributes(); if (this.range) { this.updateCombinedLabel(); } // At the end, we need to communicate the model change to the outputs as well // Normalisation changes are also always forced out to ensure that subscribers always end up in correct state this.outputModelChangeSubject.next({ value: normalisedModelChange.value, highValue: normalisedModelChange.highValue, forceChange: normalisationChange, userEventInitiated: false }); } /** * @param {?} modelChange * @return {?} */ publishOutputModelChange(modelChange) { const /** @type {?} */ emitOutputs = () => { this.valueChange.emit(modelChange.value); if (this.range) { this.highValueChange.emit(modelChange.highValue); } if (!ValueHelper.isNullOrUndefined(this.onChangeCallback)) { if (this.range) { this.onChangeCallback([modelChange.value, modelChange.highValue]); } else { this.onChangeCallback(modelChange.value); } } if (!ValueHelper.isNullOrUndefined(this.onTouchedCallback)) { if (this.range) { this.onTouchedCallback([modelChange.value, modelChange.highValue]); } else { this.onTouchedCallback(modelChange.value); } } }; if (modelChange.userEventInitiated) { // If this change was initiated by a user event, we can emit outputs in the same tick emitOutputs(); this.userChange.emit(this.getChangeContext()); } else { // But, if the change was initated by something else like a change in input bindings, // we need to wait until next tick to emit the outputs to keep Angular change detection happy setTimeout(() => { emitOutputs(); }); } } /** * @param {?} input * @return {?} */ normaliseModelValues(input) { const /** @type {?} */ normalisedInput = new ModelValues(); normalisedInput.value = input.value; normalisedInput.highValue = input.highValue; if (this.viewOptions.enforceStep) { normalisedInput.value = this.roundStep(normalisedInput.value); if (this.range) { normalisedInput.highValue = this.roundStep(normalisedInput.highValue); } } // Don't attempt to normalise further when using steps array (steps may be out of order and that is perfectly fine) if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray) || !this.viewOptions.enforceRange) { return normalisedInput; } normalisedInput.value = MathHelper.clampToRange(normalisedInput.value, this.viewOptions.floor, this.viewOptions.ceil); if (this.range) { normalisedInput.highValue = MathHelper.clampToRange(normalisedInput.highValue, this.viewOptions.floor, this.viewOptions.ceil); } // Make sure that range slider invariant (value <= highValue) is always satisfied if (this.range && input.value > input.highValue) { // We know that both values are now clamped correctly, they may just be in the wrong order // So the easy solution is to swap them... except swapping is sometimes disabled in options, so we make the two values the same if (this.viewOptions.noSwitching) { normalisedInput.value = normalisedInput.highValue; } else { const /** @type {?} */ tempValue = input.value; normalisedInput.value = input.highValue; normalisedInput.highValue = tempValue; } } return normalisedInput; } /** * @return {?} */ renormaliseModelValues() { const /** @type {?} */ previousModelValues = { value: this.value, highValue: this.highValue }; const /** @type {?} */ normalisedModelValues = this.normaliseModelValues(previousModelValues); if (!ModelValues.compare(normalisedModelValues, previousModelValues)) { this.value = normalisedModelValues.value; this.highValue = normalisedModelValues.highValue; this.outputModelChangeSubject.next({ value: this.value, highValue: this.highValue, forceChange: true, userEventInitiated: false }); } } /** * @return {?} */ onChangeOptions() { if (!this.initHasRun) { return; } const /** @type {?} */ previousInputEventsInterval = this.viewOptions.inputEventsInterval; const /** @type {?} */ previousOutputEventsInterval = this.viewOptions.outputEventsInterval; this.applyOptions(); if (previousInputEventsInterval !== this.viewOptions.inputEventsInterval) { this.unsubscribeInputModelChangeSubject(); this.subscribeInputModelChangeSubject(this.viewOptions.inputEventsInterval); } if (previousOutputEventsInterval !== this.viewOptions.outputEventsInterval) { this.unsubscribeInputModelChangeSubject(); this.subscribeInputModelChangeSubject(this.viewOptions.outputEventsInterval); } // With new options, we need to re-normalise model values if necessary this.renormaliseModelValues(); this.viewLowValue = this.modelValueToViewValue(this.value); if (this.range) { this.viewHighValue = this.modelValueToViewValue(this.highValue); } else { this.viewHighValue = null; } this.resetSlider(); } /** * @return {?} */ applyOptions() { this.viewOptions = new Options(); Object.assign(this.viewOptions, this.options); this.viewOptions.draggableRange = this.range && this.viewOptions.draggableRange; this.viewOptions.draggableRangeOnly = this.range && this.viewOptions.draggableRangeOnly; if (this.viewOptions.draggableRangeOnly) { this.viewOptions.draggableRange = true; } this.viewOptions.showTicks = this.viewOptions.showTicks || this.viewOptions.showTicksValues || !ValueHelper.isNullOrUndefined(this.viewOptions.ticksArray); if (this.viewOptions.showTicks && (!ValueHelper.isNullOrUndefined(this.viewOptions.tickStep) || !ValueHelper.isNullOrUndefined(this.viewOptions.ticksArray))) { this.intermediateTicks = true; } this.viewOptions.showSelectionBar = this.viewOptions.showSelectionBar || this.viewOptions.showSelectionBarEnd || !ValueHelper.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue); if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray)) { this.applyStepsArrayOptions(); } else { this.applyFloorCeilOptions(); } if (ValueHelper.isNullOrUndefined(this.viewOptions.combineLabels)) { this.viewOptions.combineLabels = (minValue, maxValue) => { return minValue + ' - ' + maxValue; }; } if (this.viewOptions.logScale && this.viewOptions.floor === 0) { throw Error('Can\'t use floor=0 with logarithmic scale'); } } /** * @return {?} */ applyStepsArrayOptions() { this.viewOptions.floor = 0; this.viewOptions.ceil = this.viewOptions.stepsArray.length - 1; this.viewOptions.step = 1; if (ValueHelper.isNullOrUndefined(this.viewOptions.translate)) { this.viewOptions.translate = (modelValue) => { if (this.viewOptions.bindIndexForStepsArray) { return String(this.getStepValue(modelValue)); } return String(modelValue); }; } this.viewOptions.getLegend = (index) => { const /** @type {?} */ step = this.viewOptions.stepsArray[index]; return step.legend; }; } /** * @return {?} */ applyFloorCeilOptions() { if (ValueHelper.isNullOrUndefined(this.viewOptions.step)) { this.viewOptions.step = 1; } else { this.viewOptions.step = +this.viewOptions.step; if (this.viewOptions.step <= 0) { this.viewOptions.step = 1; } } if (ValueHelper.isNullOrUndefined(this.viewOptions.ceil) || ValueHelper.isNullOrUndefined(this.viewOptions.floor)) { throw Error('floor and ceil options must be supplied'); } this.viewOptions.ceil = +this.viewOptions.ceil; this.viewOptions.floor = +this.viewOptions.floor; if (ValueHelper.isNullOrUndefined(this.viewOptions.translate)) { this.viewOptions.translate = (value) => String(value); } } /** * @return {?} */ resetSlider() { this.manageElementsStyle(); this.addAccessibility(); this.updateCeilLabel(); this.updateFloorLabel(); this.unbindEvents(); this.manageEventsBindings(); this.updateDisabledState(); this.calculateViewDimensions(); this.refocusPointerIfNeeded(); } /** * @param {?} pointerType * @return {?} */ focusPointer(pointerType) { // If not supplied, use min pointer as default if (pointerType !== PointerType.Min && pointerType !== PointerType.Max) { pointerType = PointerType.Min; } if (pointerType === PointerType.Min) { this.minHandleElement.focus(); } else if (this.range && pointerType === PointerType.Max) { this.maxHandleElement.focus(); } } /** * @return {?} */ refocusPointerIfNeeded() { if (!ValueHelper.isNullOrUndefined(this.currentFocusPointer)) { this.onPointerFocus(this.currentFocusPointer); const /** @type {?} */ element = this.getPointerElement(this.currentFocusPointer); element.focus(); } } /** * @return {?} */ manageElementsStyle() { this.updateScale(); this.floorLabelElement.setAlwaysHide(this.viewOptions.showTicksValues || this.viewOptions.hideLimitLabels); this.ceilLabelElement.setAlwaysHide(this.viewOptions.showTicksValues || this.viewOptions.hideLimitLabels); const /** @type {?} */ hideLabelsForTicks = this.viewOptions.showTicksValues && !this.intermediateTicks; this.minHandleLabelElement.setAlwaysHide(hideLabelsForTicks || this.viewOptions.hidePointerLabels); this.maxHandleLabelElement.setAlwaysHide(hideLabelsForTicks || !this.range || this.viewOptions.hidePointerLabels); this.combinedLabelElement.setAlwaysHide(hideLabelsForTicks || !this.range || this.viewOptions.hidePointerLabels); this.selectionBarElement.setAlwaysHide(!this.range && !this.viewOptions.showSelectionBar); this.leftOuterSelectionBarElement.setAlwaysHide(!this.range || !this.viewOptions.showOuterSelectionBars); this.rightOuterSelectionBarElement.setAlwaysHide(!this.range || !this.viewOptions.showOuterSelectionBars); this.fullBarTransparentClass = this.range && this.viewOptions.showOuterSelectionBars; this.selectionBarDraggableClass = this.viewOptions.draggableRange && !this.viewOptions.onlyBindHandles; this.ticksUnderValuesClass = this.intermediateTicks && this.options.showTicksValues; if (this.sliderElementVerticalClass !== this.viewOptions.vertical) { this.updateVerticalState(); // The above change in host component class will not be applied until the end of this cycle // However, functions calculating the slider position expect the slider to be already styled as vertical // So as a workaround, we need to reset the slider once again to compute the correct values setTimeout(() => { this.resetSlider(); }); } // Changing animate class may interfere with slider reset/initialisation, so we should set it separately, // after all is properly set up if (this.sliderElementAnimateClass !== this.viewOptions.animate) { setTimeout(() => { this.sliderElementAnimateClass = this.viewOptions.animate; }); } } /** * @return {?} */ manageEventsBindings() { if (this.viewOptions.disabled || this.viewOptions.readOnly) { this.unbindEvents(); } else { this.bindEvents(); } } /** * @return {?} */ updateDisabledState() { this.sliderElementDisabledAttr = this.viewOptions.disabled ? 'disabled' : null; } /** * @return {?} */ updateVerticalState() { this.sliderElementVerticalClass = this.viewOptions.vertical; for (const /** @type {?} */ element of this.getAllSliderElements()) { // This is also called before ngAfterInit, so need to check that view child bindings work if (!ValueHelper.isNullOrUndefined(element)) { element.setVertical(this.viewOptions.vertical); } } } /** * @return {?} */ updateScale() { for (const /** @type {?} */ element of this.getAllSliderElements()) { element.setScale(this.viewOptions.scale); } } /** * @return {?} */ getAllSliderElements() { return [this.leftOuterSelectionBarElement, this.rightOuterSelectionBarElement, this.fullBarElement, this.selectionBarElement, this.minHandleElement, this.maxHandleElement, this.floorLabelElement, this.ceilLabelElement, this.minHandleLabelElement, this.maxHandleLabelElement, this.combinedLabelElement, this.ticksElement ]; } /** * @return {?} */ initHandles() { this.updateLowHandle(this.valueToPosition(this.viewLowValue)); /* the order here is important since the selection bar should be updated after the high handle but before the combined label */ if (this.range) { this.updateHighHandle(this.valueToPosition(this.viewHighValue)); } this.updateSelectionBar(); if (this.range) { this.updateCombinedLabel(); } this.updateTicksScale(); } /** * @return {?} */ addAccessibility() { this.updateAriaAttributes(); this.minHandleElement.role = 'slider'; if (this.viewOptions.keyboardSupport && !(this.viewOptions.readOnly || this.viewOptions.disabled)) { this.minHandleElement.tabindex = '0'; } else { this.minHandleElement.tabindex = ''; } if (this.viewOptions.vertical) { this.minHandleElement.ariaOrientation = 'vertical'; } if (!ValueHelper.isNullOrUndefined(this.viewOptions.ariaLabel)) { this.minHandleElement.ariaLabel = this.viewOptions.ariaLabel; } else if (!ValueHelper.isNullOrUndefined(this.viewOptions.ariaLabelledBy)) { this.minHandleElement.ariaLabelledBy = this.viewOptions.ariaLabelledBy; } if (this.range) { this.maxHandleElement.role = 'slider'; if (this.viewOptions.keyboardSupport && !(this.viewOptions.readOnly || this.viewOptions.disabled)) { this.maxHandleElement.tabindex = '0'; } else { this.maxHandleElement.tabindex = ''; } this.maxHandleElement.ariaOrientation = this.viewOptions.vertical ? 'vertical' : 'horizontal'; if (!ValueHelper.isNullOrUndefined(this.viewOptions.ariaLabelHigh)) { this.maxHandleElement.ariaLabel = this.viewOptions.ariaLabelHigh; } else if (!ValueHelper.isNullOrUndefined(this.viewOptions.ariaLabelledByHigh)) { this.maxHandleElement.ariaLabelledBy = this.viewOptions.ariaLabelledByHigh; } } } /** * @return {?} */ updateAriaAttributes() { this.minHandleElement.ariaValueNow = (+this.value).toString(); this.minHandleElement.ariaValueText = this.viewOptions.translate(+this.value, LabelType.Low); this.minHandleElement.ariaValueMin = this.viewOptions.floor.toString(); this.minHandleElement.ariaValueMax = this.viewOptions.ceil.toString(); if (this.range) { this.maxHandleElement.ariaValueNow = (+this.highValue).toString(); this.maxHandleElement.ariaValueText = this.viewOptions.translate(+this.highValue, LabelType.High); this.maxHandleElement.ariaValueMin = this.viewOptions.floor.toString(); this.maxHandleElement.ariaValueMax = this.viewOptions.ceil.toString(); } } /** * @return {?} */ calculateViewDimensions() { if (!ValueHelper.isNullOrUndefined(this.viewOptions.handleDimension)) { this.minHandleElement.setDimension(this.viewOptions.handleDimension); } else { this.minHandleElement.calculateDimension(); } const /** @type {?} */ handleWidth = this.minHandleElement.dimension; this.handleHalfDimension = handleWidth / 2; if (!ValueHelper.isNullOrUndefined(this.viewOptions.barDimension)) { this.fullBarElement.setDimension(this.viewOptions.barDimension); } else { this.fullBarElement.calculateDimension(); } this.maxHandlePosition = this.fullBarElement.dimension - handleWidth; if (this.initHasRun) { this.updateFloorLabel(); this.updateCeilLabel(); this.initHandles(); } } /** * @return {?} */ calculateViewDimensionsAndDetectChanges() { this.calculateViewDimensions(); this.changeDetectionRef.detectChanges(); } /** * @return {?} */ updateTicksScale() { if (!this.viewOptions.showTicks) { return; } const /** @type {?} */ ticksArray = !ValueHelper.isNullOrUndefined(this.viewOptions.ticksArray) ? this.viewOptions.ticksArray : this.getTicksArray(); const /** @type {?} */ translate = this.viewOptions.vertical ? 'translateY' : 'translateX'; if (this.viewOptions.rightToLeft) { ticksArray.reverse(); } const /** @type {?} */ newTicks = ticksArray.map((value) => { let /** @type {?} */ position = this.valueToPosition(value); if (this.viewOptions.vertical) { position = this.maxHandlePosition - position; } const /** @type {?} */ translation = translate + '(' + Math.round(position) + 'px)'; const /** @type {?} */ tick = new Tick(); tick.selected = this.isTickSelected(value); tick.style = { '-webkit-transform': translation, '-moz-transform': translation, '-o-transform': translation, '-ms-transform': translation, transform: translation, }; if (tick.selected && !ValueHelper.isNullOrUndefined(this.viewOptions.getSelectionBarColor)) { tick.style['background-color'] = this.getSelectionBarColor(); } if (!tick.selected && !ValueHelper.isNullOrUndefined(this.viewOptions.getTickColor)) { tick.style['background-color'] = this.getTickColor(value); } if (!ValueHelper.isNullOrUndefined(this.viewOptions.ticksTooltip)) { tick.tooltip = this.viewOptions.ticksTooltip(value); tick.tooltipPlacement = this.viewOptions.vertical ? 'right' : 'top'; } if (this.viewOptions.showTicksValues && (value % this.viewOptions.tickValueStep === 0)) { tick.value = this.getDisplayValue(value, LabelType.TickValue); if (!ValueHelper.isNullOrUndefined(this.viewOptions.ticksValuesTooltip)) { tick.valueTooltip = this.viewOptions.ticksValuesTooltip(value); tick.valueTooltipPlacement = this.viewOptions.vertical ? 'right' : 'top'; } } if (!ValueHelper.isNullOrUndefined(this.viewOptions.getLegend)) { const /** @type {?} */ legend = this.viewOptions.getLegend(value); if (!ValueHelper.isNullOrUndefined(legend)) { tick.legend = legend; } } return tick; }); // We should avoid re-creating the ticks array if possible // This both improves performance and makes CSS animations work correctly if (!ValueHelper.isNullOrUndefined(this.ticks) && this.ticks.length === newTicks.length) { for (let /** @type {?} */ i = 0; i < newTicks.length; ++i) { Object.assign(this.ticks[i], newTicks[i]); } } else { this.ticks = newTicks; } this.changeDetectionRef.detectChanges(); } /** * @return {?} */ getTicksArray() { const /** @type {?} */ step = (!ValueHelper.isNullOrUndefined(this.viewOptions.tickStep)) ? this.viewOptions.tickStep : this.viewOptions.step; const /** @type {?} */ ticksArray = []; for (let /** @type {?} */ value = this.viewOptions.floor; value <= this.viewOptions.ceil; value += step) { ticksArray.push(value); } return ticksArray; } /** * @param {?} value * @return {?} */ isTickSelected(value) { if (!this.range) { if (!ValueHelper.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue)) { const /** @type {?} */ center = this.viewOptions.showSelectionBarFromValue; if (this.viewLowValue > center && value >= center && value <= this.viewLowValue) { return true; } else if (this.viewLowValue < center && value <= center && value >= this.viewLowValue) { return true; } } else if (this.viewOptions.showSelectionBarEnd) { if (value >= this.viewLowValue) { return true; } } else if (this.viewOptions.showSelectionBar && value <= this.viewLowValue) { return true; } } if (this.range && value >= this.viewLowValue && value <= this.viewHighValue) { return true; } return false; } /** * @return {?} */ updateFloorLabel() { if (!this.floorLabelElement.alwaysHide) { this.floorLabelElement.setValue(this.getDisplayValue(this.viewOptions.floor, LabelType.Floor)); this.floorLabelElement.calculateDimension(); const /** @type {?} */ position = this.viewOptions.rightToLeft ? this.fullBarElement.dimension - this.floorLabelElement.dimension : 0; this.floorLabelElement.setPosition(position); } } /** * @return {?} */ updateCeilLabel() { if (!this.ceilLabelElement.alwaysHide) { this.ceilLabelElement.setValue(this.getDisplayValue(this.viewOptions.ceil, LabelType.Ceil)); this.ceilLabelElement.calculateDimension(); const /** @type {?} */ position = this.viewOptions.rightToLeft ? 0 : this.fullBarElement.dimension - this.ceilLabelElement.dimension; this.ceilLabelElement.setPosition(position); } } /** * @param {?} which * @param {?} newPos * @return {?} */ updateHandles(which, newPos) { if (which === PointerType.Min) { this.updateLowHandle(newPos); } else if (which === PointerType.Max) { this.updateHighHandle(newPos); } this.updateSelectionBar(); this.updateTicksScale(); if (this.range) { this.updateCombinedLabel(); } } /** * @param {?} labelType * @param {?} newPos * @return {?} */ getHandleLabelPos(labelType, newPos) { const /** @type {?} */ labelDimension = (labelType === PointerType.Min) ? this.minHandleLabelElement.dimension : this.maxHandleLabelElement.dimension; const /** @type {?} */ nearHandlePos = newPos - labelDimension / 2 + this.handleHalfDimension; const /** @type {?} */ endOfBarPos = this.fullBarElement.dimension - labelDimension; if (!this.viewOptions.boundPointerLabels) { return nearHandlePos; } if ((this.viewOptions.rightToLeft && labelType === PointerType.Min) || (!this.viewOptions.rightToLeft && labelType === PointerType.Max)) { return Math.min(nearHandlePos, endOfBarPos); } else { return Math.min(Math.max(nearHandlePos, 0), endOfBarPos); } } /** * @param {?} newPos * @return {?} */ updateLowHandle(newPos) { this.minHandleElement.setPosition(newPos); this.minHandleLabelElement.setValue(this.getDisplayValue(this.viewLowValue, LabelType.Low)); this.minHandleLabelElement.setPosition(this.getHandleLabelPos(PointerType.Min, newPos)); if (!ValueHelper.isNullOrUndefined(this.viewOptions.getPointerColor)) { this.minPointerStyle = { backgroundColor: this.getPointerColor(PointerType.Min), }; } if (this.viewOptions.autoHideLimitLabels) { this.updateFloorAndCeilLabelsVisibility(); } } /** * @param {?} newPos * @return {?} */ updateHighHandle(newPos) { this.maxHandleElement.setPosition(newPos); this.maxHandleLabelElement.setValue(this.getDisplayValue(this.viewHighValue, LabelType.High)); this.maxHandleLabelElement.setPosition(this.getHandleLabelPos(PointerType.Max, newPos)); if (!ValueHelper.isNullOrUndefined(this.viewOptions.getPointerColor)) { this.maxPointerStyle = { backgroundColor: this.getPointerColor(PointerType.Max), }; } if (this.viewOptions.autoHideLimitLabels) { this.updateFloorAndCeilLabelsVisibility(); } } /** * @return {?} */ updateFloorAndCeilLabelsVisibility() { // Show based only on hideLimitLabels if pointer labels are hidden if (this.viewOptions.hidePointerLabels) { return; } let /** @type {?} */ floorLabelHidden = false; let /** @type {?} */ ceilLabelHidden = false; const /** @type {?} */ isMinLabelAtFloor = this.isLabelBelowFloorLabel(this.minHandleLabelElement); const /** @type {?} */ isMinLabelAtCeil = this.isLabelAboveCeilLabel(this.minHandleLabelElement); const /** @type {?} */ isMaxLabelAtCeil = this.isLabelAboveCeilLabel(this.maxHandleLabelElement); const /** @type {?} */ isCombinedLabelAtFloor = this.isLabelBelowFloorLabel(this.combinedLabelElement); const /** @type {?} */ isCombinedLabelAtCeil = this.isLabelAboveCeilLabel(this.combinedLabelElement); if (isMinLabelAtFloor) { floorLabelHidden = true; this.floorLabelElement.hide(); } else { floorLabelHidden = false; this.floorLabelElement.show(); } if (isMinLabelAtCeil) { ceilLabelHidden = true; this.ceilLabelElement.hide(); } else { ceilLabelHidden = false; this.ceilLabelElement.show(); } if (this.range) { const /** @type {?} */ hideCeil = this.combinedLabelElement.isVisible() ? isCombinedLabelAtCeil : isMaxLabelAtCeil; const /** @type {?} */ hideFloor = this.combinedLabelElement.isVisible() ? isCombinedLabelAtFloor : isMinLabelAtFloor; if (hideCeil) { this.ceilLabelElement.hide(); } else if (!ceilLabelHidden) { this.ceilLabelElement.show(); } // Hide or show floor label if (hideFloor) { this.floorLabelElement.hide(); } else if (!floorLabelHidden) { this.floorLabelElement.show(); } } } /** * @param {?} label * @return {?} */ isLabelBelowFloorLabel(label) { const /** @type {?} */ pos = label.position; const /** @type {?} */ dim = label.dimension; const /** @type {?} */ floorPos = this.floorLabelElement.position; const /** @type {?} */ floorDim = this.floorLabelElement.dimension; return this.viewOptions.rightToLeft ? pos + dim >= floorPos - 2 : pos <= floorPos + floorDim + 2; } /** * @param {?} label * @return {?} */ isLabelAboveCeilLabel(label) { const /** @type {?} */ pos = label.position; const /** @type {?} */ dim = label.dimension; const /** @type {?} */ ceilPos = this.ceilLabelElement.position; const /** @type {?} */ ceilDim = this.ceilLabelElement.dimension; return this.viewOptions.rightToLeft ? pos <= ceilPos + ceilDim + 2 : pos + dim >= ceilPos - 2; } /** * @return {?} */ updateSelectionBar() { let /** @type {?} */ position = 0; let /** @type {?} */ dimension = 0; const /** @type {?} */ isSelectionBarFromRight = this.viewOptions.rightToLeft ? !this.viewOptions.showSelectionBarEnd : this.viewOptions.showSelectionBarEnd; const /** @type {?} */ positionForRange = this.viewOptions.rightToLeft ? this.maxHandleElement.position + this.handleHalfDimension : this.minHandleElement.position + this.handleHalfDimension; if (this.range) { dimension = Math.abs(this.maxHandleElement.position - this.minHandleElement.position); position = positionForRange; } else { if (!ValueHelper.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue)) { const /** @type {?} */ center = this.viewOptions.showSelectionBarFromValue; const /** @type {?} */ centerPosition = this.valueToPosition(center); const /** @type {?} */ isModelGreaterThanCenter = this.viewOptions.rightToLeft ? this.viewLowValue <= center : this.viewLowValue > center; if (isModelGreaterThanCenter) { dimension = this.minHandleElement.position - centerPosition; position = centerPosition + this.handleHalfDimension; } else { dimension = centerPosition - this.minHandleElement.position; position = this.minHandleElement.position + this.handleHalfDimension; } } else if (isSelectionBarFromRight) { dimension = Math.ceil(Math.abs(this.maxHandlePosition - this.minHandleElement.position) + this.handleHalfDimension); position = Math.floor(this.minHandleElement.position + this.handleHalfDimension); } else { dimension = this.minHandleElement.position + this.handleHalfDimension; position = 0; } } this.selectionBarElement.setDimension(dimension); this.selectionBarElement.setPosition(position); if (this.range && this.viewOptions.showOuterSelectionBars) { if (this.viewOptions.rightToLeft) { this.rightOuterSelectionBarElement.setDimension(position); this.rightOuterSelectionBarElement.setPosition(0); this.fullBarElement.calculateDimension(); this.leftOuterSelectionBarElement.setDimension(this.fullBarElement.dimension - (position + dimension)); this.leftOuterSelectionBarElement.setPosition(position + dimension); } else { this.leftOuterSelectionBarElement.setDimension(position); this.leftOuterSelectionBarElement.setPosition(0); this.fullBarElement.calculateDimension(); this.rightOuterSelectionBarElement.setDimension(this.fullBarElement.dimension - (position + dimension)); this.rightOuterSelectionBarElement.setPosition(position + dimension); } } if (!ValueHelper.isNullOrUndefined(this.viewOptions.getSelectionBarColor)) { const /** @type {?} */ color = this.getSelectionBarColor(); this.barStyle = { backgroundColor: color, }; } else if (!ValueHelper.isNullOrUndefined(this.viewOptions.selectionBarGradient)) { const /** @type {?} */ offset = (!ValueHelper.isNullOrUndefined(this.viewOptions.showSelectionBarFromValue)) ? this.valueToPosition(this.viewOptions.showSelectionBarFromValue) : 0; const /** @type {?} */ reversed = (offset - position > 0 && !isSelectionBarFromRight) || (offset - position <= 0 && isSelectionBarFromRight); const /** @type {?} */ direction = this.viewOptions.vertical ? reversed ? 'bottom' : 'top' : reversed ? 'left' : 'right'; this.barStyle = { backgroundImage: 'linear-gradient(to ' + direction + ', ' + this.viewOptions.selectionBarGradient.from + ' 0%,' + this.viewOptions.selectionBarGradient.to + ' 100%)', }; if (this.viewOptions.vertical) { this.barStyle.backgroundPosition = 'center ' + (offset + dimension + position + (reversed ? -this.handleHalfDimension : 0)) + 'px'; this.barStyle.backgroundSize = '100% ' + (this.fullBarElement.dimension - this.handleHalfDimension) + 'px'; } else { this.barStyle.backgroundPosition = offset - position + (reversed ? this.handleHalfDimension : 0) + 'px center'; this.barStyle.backgroundSize = this.fullBarElement.dimension - this.handleHalfDimension + 'px 100%'; } } } /** * @return {?} */ getSelectionBarColor() { if (this.range) { return this.viewOptions.getSelectionBarColor(this.value, this.highValue); } return this.viewOptions.getSelectionBarColor(this.value); } /** * @param {?} pointerType * @return {?} */ getPointerColor(pointerType) { if (pointerType === PointerType.Max) { return this.viewOptions.getPointerColor(this.highValue, pointerType); } return this.viewOptions.getPointerColor(this.value, pointerType); } /** * @param {?} value * @return {?} */ getTickColor(value) { return this.viewOptions.getTickColor(value); } /** * @return {?} */ updateCombinedLabel() { let /** @type {?} */ isLabelOverlap = null; if (this.viewOptions.rightToLeft) { isLabelOverlap = this.minHandleLabelElement.position - this.minHandleLabelElement.dimension - 10 <= this.maxHandleLabelElement.position; } else { isLabelOverlap = this.minHandleLabelElement.position + this.minHandleLabelElement.dimension + 10 >= this.maxHandleLabelElement.position; } if (isLabelOverlap) { const /** @type {?} */ lowDisplayValue = this.getDisplayValue(this.viewLowValue, LabelType.Low); const /** @type {?} */ highDisplayValue = this.getDisplayValue(this.viewHighValue, LabelType.High); const /** @type {?} */ combinedLabelValue = this.viewOptions.rightToLeft ? this.viewOptions.combineLabels(highDisplayValue, lowDisplayValue) : this.viewOptions.combineLabels(lowDisplayValue, highDisplayValue); this.combinedLabelElement.setValue(combinedLabelValue); const /** @type {?} */ pos = this.viewOptions.boundPointerLabels ? Math.min(Math.max(this.selectionBarElement.position + this.selectionBarElement.dimension / 2 - this.combinedLabelElement.dimension / 2, 0), this.fullBarElement.dimension - this.combinedLabelElement.dimension) : this.selectionBarElement.position + this.selectionBarElement.dimension / 2 - this.combinedLabelElement.dimension / 2; this.combinedLabelElement.setPosition(pos); this.minHandleLabelElement.hide(); this.maxHandleLabelElement.hide(); this.combinedLabelElement.show(); } else { this.updateHighHandle(this.valueToPosition(this.viewHighValue)); this.updateLowHandle(this.valueToPosition(this.viewLowValue)); this.maxHandleLabelElement.show(); this.minHandleLabelElement.show(); this.combinedLabelElement.hide(); } if (this.viewOptions.autoHideLimitLabels) { this.updateFloorAndCeilLabelsVisibility(); } } /** * @param {?} value * @param {?} which * @return {?} */ getDisplayValue(value, which) { if (!ValueHelper.isNullOrUndefined(this.viewOptions.stepsArray) && !this.viewOptions.bindIndexForStepsArray) { value = this.getStepValue(value); } return this.viewOptions.translate(value, which); } /** * @param {?} value * @param {?=} customStep * @return {?} */ roundStep(value, customStep) { const /** @type {?} */ step = !ValueHelper.isNullOrUndefined(customStep) ? customStep : this.viewOptions.step; let /** @type {?} */ steppedDifference = MathHelper.roundToPrecisionLimit((value - this.viewOptions.floor) / step, this.viewOptions.precisionLimit); steppedDifference = Math.round(steppedDifference) * step; return MathHelper.roundToPrecisionLimit(this.viewOptions.floor + steppedDifference, this.viewOptions.precisionLimit); } /** * @param {?} val * @return {?} */ valueToPosition(val) { let /** @type {?} */ fn = ValueHelper.linearValueToPosition; if (!ValueHelper.isNullOrUndefined(this.viewOptions.customValueToPosition)) { fn = this.viewOptions.customValueToPosition; } else if (this.viewOptions.logScale) { fn = ValueHelper.logValueToPosition; } val = MathHelper.clampToRange(val, this.viewOptions.floor, this.viewOptions.ceil); let /** @type {?} */ percent = fn(val, this.viewOptions.floor, this.viewOptions.ceil); if (ValueHelper.isNullOrUndefined(percent)) { percent = 0; } if (this.viewOptions.rightToLeft) { percent = 1 - percent; } return percent * this.maxHandlePosition; } /** * @param {?} position * @return {?} */ positionToValue(position) { let /** @type {?} */ percent = position / this.maxHandlePosition; if (this.viewOptions.rightToLeft) { percent = 1 - percent; } let /** @type {?} */ fn = ValueHelper.linearPositionToValue; if (!ValueHelper.isNullOrUndefined(this.viewOptions.customPositionToValue)) { fn = this.viewOptions.customPositionToValue; } else if (this.viewOptions.logScale) { fn = ValueHelper.logPositionToValue; } const /** @type {?} */ value = fn(percent, this.viewOptions.floor, this.viewOptions.ceil); return !ValueHelper.isNullOrUndefined(value) ? value : 0; } /** * @param {?} event * @param {?=} targetTouchId * @return {?} */ getEventXY(event, targetTouchId) { if (event instanceof MouseEvent) { return this.viewOptions.vertical ? event.clientY : event.clientX; } let /** @type {?} */ touchIndex = 0; const /** @type {?} */ touches = event.touches; if (!ValueHelper.isNullOrUndefined(targetTouchId)) { for (let /** @type {?} */ i = 0; i < touches.length; i++) { if (touches[i].identifier === targetTouchId) { touchIndex = i; break; } } } // Return the target touch or if the target touch was not found in the event // returns the coordinates of the first touch return this.viewOptions.vertical ? touches[touchIndex].clientY : touches[touchIndex].clientX; } /** * @param {?} event * @param {?=} targetTouchId * @return {?} */ getEventPosition(event, targetTouchId) { const /** @type {?} */ sliderElementBoundingRect = this.elementRef.nativeElement.getBoundingClientRect(); const /** @type {?} */ sliderPos = this.viewOptions.vertical ? sliderElementBoundingRect.bottom : sliderElementBoundingRect.left; let /** @type {?} */ eventPos = 0; if (this.viewOptions.vertical) { eventPos = -this.getEventXY(event, targetTouchId) + sliderPos; } else { eventPos = this.getEventXY(event, targetTouchId) - sliderPos; } return eventPos * this.viewOptions.scale - this.handleHalfDimension; } /** * @param {?} event * @return {?} */ getNearestHandle(event) { if (!this.range) { return PointerType.Min; } const /** @type {?} */ position = this.getEventPosition(event); const /** @type {?} */ distanceMin = Math.abs(position - this.minHandleElement.position); const /** @type {?} */ distanceMax = Math.abs(position - this.maxHandleElement.position); if (distanceMin < distanceMax) { return PointerType.Min; } else if (distanceMin > distanceMax) { return PointerType.Max; } else if (!this.viewOptions.rightToLeft) { // if event is at the same distance from min/max then if it's at left of minH, we return minH else maxH return position < this.minHandleElement.position ? PointerType.Min : PointerType.Max; } // reverse in rtl return position > this.minHandleElement.position ? PointerType.Min : PointerType.Max; } /** * @return {?} */ bindEvents() { const /** @type {?} */ draggableRange = this.viewOptions.draggableRange; if (!this.viewOptions.onlyBindHandles) { this.selectionBarElement.on('mousedown', (event) => this.onBarStart(null, draggableRange, event, true, true, true)); } if (this.viewOptions.draggableRangeOnly) { this.minHandleElement.on('mousedown', (event) => this.onBarStart(PointerType.Min, draggableRange, event, true, true)); this.maxHandleElement.on('mousedown', (event) => this.onBarStart(PointerType.Max, draggableRange, event, true, true)); } else { this.minHandleElement.on('mousedown', (event) => this.onStart(PointerType.Min, event, true, true)); if (this.range) { this.maxHandleElement.on('mousedown', (event) => this.onStart(PointerType.Max, event, true, true)); } if (!this.viewOptions.onlyBindHandles) { this.fullBarElement.on('mousedown', (event) => this.onStart(null, event, true, true, true)); this.ticksElement.on('mousedown', (event) => this.onStart(null, event, true, true, true, true)); } } if (!this.viewOptions.onlyBindHandles) { this.selectionBarElement.onPassive('touchstart', (event) => this.onBarStart(null, draggableRange, event, true, true, true)); } if (this.viewOptions.draggableRangeOnly) { this.minHandleElement.onPassive('touchstart', (event) => this.onBarStart(PointerType.Min, draggableRange, event, true, true)); this.maxHandleElement.onPassive('touchstart', (event) => this.onBarStart(PointerType.Max, draggableRange, event, true, true)); } else { this.minHandleElement.onPassive('touchstart', (event) => this.onStart(PointerType.Min, event, true, true)); if (this.range) { this.maxHandleElement.onPassive('touchstart', (event) => this.onStart(PointerType.Max, event, true, true)); } if (!this.viewOptions.onlyBindHandles) { this.fullBarElement.onPassive('touchstart', (event) => this.onStart(null, event, true, true, true)); this.ticksElement.onPassive('touchstart', (event) => this.onStart(null, event, false, false, true, true)); } } if (this.viewOptions.keyboardSupport) { this.minHandleElement.on('focus', () => this.onPointerFocus(PointerType.Min)); if (this.range) { this.maxHandleElement.on('focus', () => this.onPointerFocus(PointerType.Max)); } } } /** * @return {?} */ unbindEvents() { this.unsubscribeOnMove(); this.unsubscribeOnEnd(); for (const /** @type {?} */ element of this.getAllSliderElements()) { element.off(); } } /** * @param {?} pointerType * @param {?} draggableRange * @param {?} event * @param {?} bindMove * @param {?} bindEnd * @param {?=} simulateImmediateMove * @param {?=} simulateImmediateEnd * @return {?} */ onBarStart(pointerType, draggableRange, event, bindMove, bindEnd, simulateImmediateMove, simulateImmediateEnd) { if (draggableRange) { this.onDragStart(pointerType, event, bindMove, bindEnd); } else { this.onStart(pointerType, event, bindMove, bindEnd, simulateImmediateMove, simulateImmediateEnd); } } /** * @param {?} pointerType * @param {?} event * @param {?} bindMove * @param {?} bindEnd * @param {?=} simulateImmediateMove * @param {?=} simulateImmediateEnd * @return {?} */ onStart(pointerType, event, bindMove, bindEnd, simulateImmediateMove, simulateImmediateEnd) { event.stopPropagation(); // Only call preventDefault() when handling non-passive events (passive events don't need it) if (!CompatibilityHelper.isTouchEvent(event) || !detectPassiveEvents.hasSupport) { event.preventDefault(); } // We have to do this in case the HTML where the sliders are on // have been animated into view. this.calculateViewDimensions(); if (ValueHelper.isNullOrUndefined(pointerType)) { pointerType = this.getNearestHandle(event); } this.currentTrackingPointer = pointerType; const /** @type {?} */ pointerElement = this.getPointerElement(pointerType); pointerElement.active = true; if (this.viewOptions.keyboardSupport) { pointerElement.focus(); } if (bindMove) { this.unsubscribeOnMove(); const /** @type {?} */ onMoveCallback = (e) => this.dragging.active ? this.onDragMove(e) : this.onMove(e); if (CompatibilityHelper.isTouchEvent(event)) { this.onMoveEventListener = this.eventListenerHelper.attachPassiveEventListener(document, 'touchmove', onMoveCallback, this.viewOptions.touchEventsInterval); } else { this.onMoveEventListener = this.eventListenerHelper.attachEventListener(document, 'mousemove', onMoveCallback, this.viewOptions.mouseEventsInterval); } } if (bindEnd) { this.unsubscribeOnEnd(); const /** @type {?} */ onEndCallback = (e) => this.onEnd(e); if (CompatibilityHelper.isTouchEvent(event)) { this.onEndEventListener = this.eventListenerHelper.attachPassiveEventListener(document, 'touchend', onEndCallback); } else { this.onEndEventListener = this.eventListenerHelper.attachEventListener(document, 'mouseup', onEndCallback); } } this.userChangeStart.emit(this.getChangeContext()); if (CompatibilityHelper.isTouchEvent(event) && !ValueHelper.isNullOrUndefined((/** @type {?} */ (event)).changedTouches)) { // Store the touch identifier if (ValueHelper.isNullOrUndefined(this.touchId)) { this.touchId = (/** @type {?} */ (event)).changedTouches[0].identifier; } } // Click events, either with mouse or touch gesture are weird. Sometimes they result in full // start, move, end sequence, and sometimes, they don't - they only invoke mousedown // As a workaround, we simulate the first move event and the end event if it's necessary if (simulateImmediateMove) { this.onMove(event, true); } if (simulateImmediateEnd) { this.onEnd(event); } } /** * @param {?} event * @param {?=} fromTick * @return {?} */ onMove(event, fromTick) { let /** @type {?} */ touchForThisSlider = null; if (CompatibilityHelper.isTouchEvent(event)) { const /** @type {?} */ changedTouches = (/** @type {?} */ (event)).changedTouches; for (let /** @type {?} */ i = 0; i < changedTouches.length; i++) { if (changedTouches[i].identifier === this.touchId) { touchForThisSlider = changedTouches[i]; break; } } if (ValueHelper.isNullOrUndefined(touchForThisSlider)) { return; } } const /** @type {?} */ newPos = !ValueHelper.isNullOrUndefined(touchForThisSlider) ? this.getEventPosition(event, touchForThisSlider.identifier) : this.getEventPosition(event); let /** @type {?} */ newValue; const /** @type {?} */ ceilValue = this.viewOptions.rightToLeft ? this.viewOptions.floor : this.viewOptions.ceil; const /** @type {?} */ floorValue = this.viewOptions.rightToLeft ? this.viewOptions.ceil : this.viewOptions.floor; if (newPos <= 0) { newValue = floorValue; } else if (newPos >= this.maxHandlePosition) { newValue = ceilValue; } else { newValue = this.positionToValue(newPos); if (fromTick && !ValueHelper.isNullOrUndefined(this.viewOptions.tickStep)) { newValue = this.roundStep(newValue, this.viewOptions.tickStep); } else { newValue = this.roundStep(newValue); } } this.positionTrackingHandle(newValue); } /** * @param {?} event * @return {?} */ onEnd(event) { if (CompatibilityHelper.isTouchEvent(event)) { const /** @type {?} */ changedTouches = (/** @type {?} */ (event)).changedTouches; if (changedTouches[0].identifier !== this.touchId) { return; } } this.touchId = null; if (!this.viewOptions.keyboardSupport) { this.minHandleElement.active = false; this.maxHandleElement.active = false; this.currentTrackingPointer = null; } this.dragging.active = false; this.unsubscribeOnMove(); this.unsubscribeOnEnd(); this.userChangeEnd.emit(this.getChangeContext()); } /** * @param {?} pointerType * @return {?} */ onPointerFocus(pointerType) { const /** @type {?} */ pointerElement = this.getPointerElement(pointerType); pointerElement.on('blur', () => this.onPointerBlur(pointerElement)); pointerElement.on('keydown', (event) => this.onKeyboardEvent(event)); pointerElement.on('keyup', () => this.onKeyUp()); pointerElement.active = true; this.currentTrackingPointer = pointerType; this.currentFocusPointer = pointerType; this.firstKeyDown = true; } /** * @return {?} */ onKeyUp() { this.firstKeyDown = true; this.userChangeEnd.emit(this.getChangeContext()); } /** * @param {?} pointer * @return {?} */ onPointerBlur(pointer) { pointer.off('blur'); pointer.off('keydown'); pointer.off('keyup'); pointer.active = false; if (ValueHelper.isNullOrUndefined(this.touchId)) { this.currentTrackingPointer = null; this.currentFocusPointer = null; } } /** * @param {?} currentValue * @return {?} */ getKeyActions(currentValue) { const /** @type {?} */ valueRange = this.viewOptions.ceil - this.viewOptions.floor; let /** @type {?} */ increaseStep = currentValue + this.viewOptions.step; let /** @type {?} */ decreaseStep = currentValue - this.viewOptions.step; let /** @type {?} */ increasePage = currentValue + valueRange / 10; let /** @type {?} */ decreasePage = currentValue - valueRange / 10; if (this.viewOptions.reversedControls) { increaseStep = currentValue - this.viewOptions.step; decreaseStep = currentValue + this.viewOptions.step; increasePage = currentValue - valueRange / 10; decreasePage = currentValue + valueRange / 10; } // Left to right default actions const /** @type {?} */ actions = { UP: increaseStep, DOWN: decreaseStep, LEFT: decreaseStep, RIGHT: increaseStep, PAGEUP: increasePage, PAGEDOWN: decreasePage, HOME: this.viewOptions.reversedControls ? this.viewOptions.ceil : this.viewOptions.floor, END: this.viewOptions.reversedControls ? this.viewOptions.floor : this.viewOptions.ceil, }; // right to left means swapping right and left arrows if (this.viewOptions.rightToLeft) { actions["LEFT"] = increaseStep; actions["RIGHT"] = decreaseStep; // right to left and vertical means we also swap up and down if (this.viewOptions.vertical) { actions["UP"] = decreaseStep; actions["DOWN"] = increaseStep; } } return actions; } /** * @param {?} event * @return {?} */ onKeyboardEvent(event) { const /** @type {?} */ currentValue = this.getCurrentTrackingValue(); const /** @type {?} */ keyCode = !ValueHelper.isNullOrUndefined(event.keyCode) ? event.keyCode : event.which; const /** @type {?} */ keys = { 38: 'UP', 40: 'DOWN', 37: 'LEFT', 39: 'RIGHT', 33: 'PAGEUP', 34: 'PAGEDOWN', 36: 'HOME', 35: 'END', }; const /** @type {?} */ actions = this.getKeyActions(currentValue); const /** @type {?} */ key = keys[keyCode]; const /** @type {?} */ action = actions[key]; if (ValueHelper.isNullOrUndefined(action) || ValueHelper.isNullOrUndefined(this.currentTrackingPointer)) { return; } event.preventDefault(); if (this.firstKeyDown) { this.firstKeyDown = false; this.userChangeStart.emit(this.getChangeContext()); } const /** @type {?} */ actionValue = MathHelper.clampToRange(action, this.viewOptions.floor, this.viewOptions.ceil); const /** @type {?} */ newValue = this.roundStep(actionValue); if (!this.viewOptions.draggableRangeOnly) { this.positionTrackingHandle(newValue); } else { const /** @type {?} */ difference = this.viewHighValue - this.viewLowValue; let /** @type {?} */ newMinValue; let /** @type {?} */ newMaxValue; if (this.currentTrackingPointer === PointerType.Min) { newMinValue = newValue; newMaxValue = newValue + difference; if (newMaxValue > this.viewOptions.ceil) { newMaxValue = this.viewOptions.ceil; newMinValue = newMaxValue - difference; } } else if (this.currentTrackingPointer === PointerType.Max) { newMaxValue = newValue; newMinValue = newValue - difference; if (newMinValue < this.viewOptions.floor) { newMinValue = this.viewOptions.floor; newMaxValue = newMinValue + difference; } } this.positionTrackingBar(newMinValue, newMaxValue); } } /** * @param {?} pointerType * @param {?} event * @param {?} bindMove * @param {?} bindEnd * @return {?} */ onDragStart(pointerType, event, bindMove, bindEnd) { const /** @type {?} */ position = this.getEventPosition(event); this.dragging = new Dragging(); this.dragging.active = true; this.dragging.value = this.positionToValue(position); this.dragging.difference = this.viewHighValue - this.viewLowValue; this.dragging.lowLimit = this.viewOptions.rightToLeft ? this.minHandleElement.position - position : position - this.minHandleElement.position; this.dragging.highLimit = this.viewOptions.rightToLeft ? position - this.maxHandleElement.position : this.maxHandleElement.position - position; this.onStart(pointerType, event, bindMove, bindEnd); } /** * Get min value depending on whether the newPos is outOfBounds above or below the bar and rightToLeft * @param {?} newPos * @param {?} outOfBounds * @param {?} isAbove * @return {?} */ getMinValue(newPos, outOfBounds, isAbove) { const /** @type {?} */ isRTL = this.viewOptions.rightToLeft; let /** @type {?} */ value = null; if (outOfBounds) { if (isAbove) { value = isRTL ? this.viewOptions.floor : this.viewOptions.ceil - this.dragging.difference; } else { value = isRTL ? this.viewOptions.ceil - this.dragging.difference : this.viewOptions.floor; } } else { value = isRTL ? this.positionToValue(newPos + this.dragging.lowLimit) : this.positionToValue(newPos - this.dragging.lowLimit); } return this.roundStep(value); } /** * Get max value depending on whether the newPos is outOfBounds above or below the bar and rightToLeft * @param {?} newPos * @param {?} outOfBounds * @param {?} isAbove * @return {?} */ getMaxValue(newPos, outOfBounds, isAbove) { const /** @type {?} */ isRTL = this.viewOptions.rightToLeft; let /** @type {?} */ value = null; if (outOfBounds) { if (isAbove) { value = isRTL ? this.viewOptions.floor + this.dragging.difference : this.viewOptions.ceil; } else { value = isRTL ? this.viewOptions.ceil : this.viewOptions.floor + this.dragging.difference; } } else { if (isRTL) { value = this.positionToValue(newPos + this.dragging.lowLimit) + this.dragging.difference; } else { value = this.positionToValue(newPos - this.dragging.lowLimit) + this.dragging.difference; } } return this.roundStep(value); } /** * @param {?=} event * @return {?} */ onDragMove(event) { const /** @type {?} */ newPos = this.getEventPosition(event); let /** @type {?} */ ceilLimit, /** @type {?} */ floorLimit, /** @type {?} */ floorHandleElement, /** @type {?} */ ceilHandleElement; if (this.viewOptions.rightToLeft) { ceilLimit = this.dragging.lowLimit; floorLimit = this.dragging.highLimit; floorHandleElement = this.maxHandleElement; ceilHandleElement = this.minHandleElement; } else { ceilLimit = this.dragging.highLimit; floorLimit = this.dragging.lowLimit; floorHandleElement = this.minHandleElement; ceilHandleElement = this.maxHandleElement; } const /** @type {?} */ isUnderFloorLimit = (newPos <= floorLimit); const /** @type {?} */ isOverCeilLimit = (newPos >= this.maxHandlePosition - ceilLimit); let /** @type {?} */ newMinValue; let /** @type {?} */ newMaxValue; if (isUnderFloorLimit) { if (floorHandleElement.position === 0) { return; } newMinValue = this.getMinValue(newPos, true, false); newMaxValue = this.getMaxValue(newPos, true, false); } else if (isOverCeilLimit) { if (ceilHandleElement.position === this.maxHandlePosition) { return; } newMaxValue = this.getMaxValue(newPos, true, true); newMinValue = this.getMinValue(newPos, true, true); } else { newMinValue = this.getMinValue(newPos, false, false); newMaxValue = this.getMaxValue(newPos, false, false); } this.positionTrackingBar(newMinValue, newMaxValue); } /** * @param {?} newMinValue * @param {?} newMaxValue * @return {?} */ positionTrackingBar(newMinValue, newMaxValue) { if (!ValueHelper.isNullOrUndefined(this.viewOptions.minLimit) && newMinValue < this.viewOptions.minLimit) { newMinValue = this.viewOptions.minLimit; newMaxValue = MathHelper.roundToPrecisionLimit(newMinValue + this.dragging.difference, this.viewOptions.precisionLimit); } if (!ValueHelper.isNullOrUndefined(this.viewOptions.maxLimit) && newMaxValue > this.viewOptions.maxLimit) { newMaxValue = this.viewOptions.maxLimit; newMinValue = MathHelper.roundToPrecisionLimit(newMaxValue - this.dragging.difference, this.viewOptions.precisionLimit); } this.viewLowValue = newMinValue; this.viewHighValue = newMaxValue; this.applyViewChange(); this.updateHandles(PointerType.Min, this.valueToPosition(newMinValue)); this.updateHandles(PointerType.Max, this.valueToPosition(newMaxValue)); } /** * @param {?} newValue * @return {?} */ positionTrackingHandle(newValue) { newValue = this.applyMinMaxLimit(newValue); if (this.range) { if (this.viewOptions.pushRange) { newValue = this.applyPushRange(newValue); } else { if (this.viewOptions.noSwitching) { if (this.currentTrackingPointer === PointerType.Min && newValue > this.viewHighValue) { newValue = this.applyMinMaxRange(this.viewHighValue); } else if (this.currentTrackingPointer === PointerType.Max && newValue < this.viewLowValue) { newValue = this.applyMinMaxRange(this.viewLowValue); } } newValue = this.applyMinMaxRange(newValue); /* This is to check if we need to switch the min and max handles */ if (this.currentTrackingPointer === PointerType.Min && newValue > this.viewHighValue) { this.viewLowValue = this.viewHighValue; this.applyViewChange(); this.updateHandles(PointerType.Min, this.maxHandleElement.position); this.updateAriaAttributes(); this.currentTrackingPointer = PointerType.Max; this.minHandleElement.active = false; this.maxHandleElement.active = true; if (this.viewOptions.keyboardSupport) { this.maxHandleElement.focus(); } } else if (this.currentTrackingPointer === PointerType.Max && newValue < this.viewLowValue) { this.viewHighValue = this.viewLowValue; this.applyViewChange(); this.updateHandles(PointerType.Max, this.minHandleElement.position); this.updateAriaAttributes(); this.currentTrackingPointer = PointerType.Min; this.maxHandleElement.active = false; this.minHandleElement.active = true; if (this.viewOptions.keyboardSupport) { this.minHandleElement.focus(); } } } } if (this.getCurrentTrackingValue() !== newValue) { if (this.currentTrackingPointer === PointerType.Min) { this.viewLowValue = newValue; this.applyViewChange(); } else if (this.currentTrackingPointer === PointerType.Max) { this.viewHighValue = newValue; this.applyViewChange(); } this.updateHandles(this.currentTrackingPointer, this.valueToPosition(newValue)); this.updateAriaAttributes(); } } /** * @param {?} newValue * @return {?} */ applyMinMaxLimit(newValue) { if (!ValueHelper.isNullOrUndefined(this.viewOptions.minLimit) && newValue < this.viewOptions.minLimit) { return this.viewOptions.minLimit; } if (!ValueHelper.isNullOrUndefined(this.viewOptions.maxLimit) && newValue > this.viewOptions.maxLimit) { return this.viewOptions.maxLimit; } return newValue; } /** * @param {?} newValue * @return {?} */ applyMinMaxRange(newValue) { const /** @type {?} */ oppositeValue = (this.currentTrackingPointer === PointerType.Min) ? this.viewHighValue : this.viewLowValue; const /** @type {?} */ difference = Math.abs(newValue - oppositeValue); if (!ValueHelper.isNullOrUndefined(this.viewOptions.minRange)) { if (difference < this.viewOptions.minRange) { if (this.currentTrackingPointer === PointerType.Min) { return MathHelper.roundToPrecisionLimit(this.viewHighValue - this.viewOptions.minRange, this.viewOptions.precisionLimit); } else if (this.currentTrackingPointer === PointerType.Max) { return MathHelper.roundToPrecisionLimit(this.viewLowValue + this.viewOptions.minRange, this.viewOptions.precisionLimit); } } } if (!ValueHelper.isNullOrUndefined(this.viewOptions.maxRange)) { if (difference > this.viewOptions.maxRange) { if (this.currentTrackingPointer === PointerType.Min) { return MathHelper.roundToPrecisionLimit(this.viewHighValue - this.viewOptions.maxRange, this.viewOptions.precisionLimit); } else if (this.currentTrackingPointer === PointerType.Max) { return MathHelper.roundToPrecisionLimit(this.viewLowValue + this.viewOptions.maxRange, this.viewOptions.precisionLimit); } } } return newValue; } /** * @param {?} newValue * @return {?} */ applyPushRange(newValue) { const /** @type {?} */ difference = (this.currentTrackingPointer === PointerType.Min) ? this.viewHighValue - newValue : newValue - this.viewLowValue; const /** @type {?} */ minRange = (!ValueHelper.isNullOrUndefined(this.viewOptions.minRange)) ? this.viewOptions.minRange : this.viewOptions.step; const /** @type {?} */ maxRange = this.viewOptions.maxRange; // if smaller than minRange if (difference < minRange) { if (this.currentTrackingPointer === PointerType.Min) { this.viewHighValue = MathHelper.roundToPrecisionLimit(Math.min(newValue + minRange, this.viewOptions.ceil), this.viewOptions.precisionLimit); newValue = MathHelper.roundToPrecisionLimit(this.viewHighValue - minRange, this.viewOptions.precisionLimit); this.applyViewChange(); this.updateHandles(PointerType.Max, this.valueToPosition(this.viewHighValue)); } else if (this.currentTrackingPointer === PointerType.Max) { this.viewLowValue = MathHelper.roundToPrecisionLimit(Math.max(newValue - minRange, this.viewOptions.floor), this.viewOptions.precisionLimit); newValue = MathHelper.roundToPrecisionLimit(this.viewLowValue + minRange, this.viewOptions.precisionLimit); this.applyViewChange(); this.updateHandles(PointerType.Min, this.valueToPosition(this.viewLowValue)); } this.updateAriaAttributes(); } else if (!ValueHelper.isNullOrUndefined(maxRange) && difference > maxRange) { // if greater than maxRange if (this.currentTrackingPointer === PointerType.Min) { this.viewHighValue = MathHelper.roundToPrecisionLimit(newValue + maxRange, this.viewOptions.precisionLimit); this.applyViewChange(); this.updateHandles(PointerType.Max, this.valueToPosition(this.viewHighValue)); } else if (this.currentTrackingPointer === PointerType.Max) { this.viewLowValue = MathHelper.roundToPrecisionLimit(newValue - maxRange, this.viewOptions.precisionLimit); this.applyViewChange(); this.updateHandles(PointerType.Min, this.valueToPosition(this.viewLowValue)); } this.updateAriaAttributes(); } return newValue; } /** * @return {?} */ getChangeContext() { const /** @type {?} */ changeContext = new ChangeContext(); changeContext.pointerType = this.currentTrackingPointer; changeContext.value = +this.value; if (this.range) { changeContext.highValue = +this.highValue; } return changeContext; } } SliderComponent.decorators = [ { type: Component, args: [{ selector: 'ng5-slider', template: ` `, styles: [`::ng-deep .ng5-slider{display:inline-block;position:relative;height:4px;width:100%;margin:35px 0 15px;vertical-align:middle;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;-ms-touch-action:pan-y;touch-action:pan-y}::ng-deep .ng5-slider.with-legend{margin-bottom:40px}::ng-deep .ng5-slider[disabled]{cursor:not-allowed}::ng-deep .ng5-slider[disabled] .ng5-slider-pointer{cursor:not-allowed;background-color:#d8e0f3}::ng-deep .ng5-slider[disabled] .ng5-slider-draggable{cursor:not-allowed}::ng-deep .ng5-slider[disabled] .ng5-slider-selection{background:#8b91a2}::ng-deep .ng5-slider[disabled] .ng5-slider-tick{cursor:not-allowed}::ng-deep .ng5-slider[disabled] .ng5-slider-tick.ng5-slider-selected{background:#8b91a2}::ng-deep .ng5-slider .ng5-slider-span{white-space:nowrap;position:absolute;display:inline-block}::ng-deep .ng5-slider .ng5-slider-base{width:100%;height:100%;padding:0}::ng-deep .ng5-slider .ng5-slider-bar-wrapper{left:0;-webkit-box-sizing:border-box;box-sizing:border-box;margin-top:-16px;padding-top:16px;width:100%;height:32px;z-index:1}::ng-deep .ng5-slider .ng5-slider-draggable{cursor:move}::ng-deep .ng5-slider .ng5-slider-bar{left:0;width:100%;height:4px;z-index:1;background:#d8e0f3;border-radius:2px}::ng-deep .ng5-slider .ng5-slider-bar-wrapper.ng5-slider-transparent .ng5-slider-bar{background:0 0}::ng-deep .ng5-slider .ng5-slider-bar-wrapper.ng5-slider-left-out-selection .ng5-slider-bar{background:#df002d}::ng-deep .ng5-slider .ng5-slider-bar-wrapper.ng5-slider-right-out-selection .ng5-slider-bar{background:#03a688}::ng-deep .ng5-slider .ng5-slider-selection{z-index:2;background:#0db9f0;border-radius:2px}::ng-deep .ng5-slider .ng5-slider-pointer{cursor:pointer;width:32px;height:32px;top:-14px;background-color:#0db9f0;z-index:3;border-radius:16px}::ng-deep .ng5-slider .ng5-slider-pointer:after{content:'';width:8px;height:8px;position:absolute;top:12px;left:12px;border-radius:4px;background:#fff}::ng-deep .ng5-slider .ng5-slider-pointer:hover:after{background-color:#fff}::ng-deep .ng5-slider .ng5-slider-pointer.ng5-slider-active{z-index:4}::ng-deep .ng5-slider .ng5-slider-pointer.ng5-slider-active:after{background-color:#451aff}::ng-deep .ng5-slider .ng5-slider-bubble{cursor:default;bottom:16px;padding:1px 3px;color:#55637d;font-size:16px}::ng-deep .ng5-slider .ng5-slider-bubble.ng5-slider-limit{color:#55637d}::ng-deep .ng5-slider .ng5-slider-ticks{-webkit-box-sizing:border-box;box-sizing:border-box;width:100%;height:0;position:absolute;left:0;top:-3px;margin:0;z-index:1;list-style:none}::ng-deep .ng5-slider .ng5-slider-ticks-values-under .ng5-slider-tick-value{top:auto;bottom:-36px}::ng-deep .ng5-slider .ng5-slider-tick{text-align:center;cursor:pointer;width:10px;height:10px;background:#d8e0f3;border-radius:50%;position:absolute;top:0;left:0;margin-left:11px}::ng-deep .ng5-slider .ng5-slider-tick.ng5-slider-selected{background:#0db9f0}::ng-deep .ng5-slider .ng5-slider-tick-value{position:absolute;top:-34px;-webkit-transform:translate(-50%,0);transform:translate(-50%,0)}::ng-deep .ng5-slider .ng5-slider-tick-legend{position:absolute;top:24px;-webkit-transform:translate(-50%,0);transform:translate(-50%,0);max-width:50px;white-space:normal}::ng-deep .ng5-slider.vertical{position:relative;width:4px;height:100%;margin:0 20px;padding:0;vertical-align:baseline;-ms-touch-action:pan-x;touch-action:pan-x}::ng-deep .ng5-slider.vertical .ng5-slider-base{width:100%;height:100%;padding:0}::ng-deep .ng5-slider.vertical .ng5-slider-bar-wrapper{top:auto;left:0;margin:0 0 0 -16px;padding:0 0 0 16px;height:100%;width:32px}::ng-deep .ng5-slider.vertical .ng5-slider-bar{bottom:0;left:auto;width:4px;height:100%}::ng-deep .ng5-slider.vertical .ng5-slider-pointer{left:-14px!important;top:auto;bottom:0}::ng-deep .ng5-slider.vertical .ng5-slider-bubble{left:16px!important;bottom:0}::ng-deep .ng5-slider.vertical .ng5-slider-ticks{height:100%;width:0;left:-3px;top:0;z-index:1}::ng-deep .ng5-slider.vertical .ng5-slider-tick{vertical-align:middle;margin-left:auto;margin-top:11px}::ng-deep .ng5-slider.vertical .ng5-slider-tick-value{left:24px;top:auto;-webkit-transform:translate(0,-28%);transform:translate(0,-28%)}::ng-deep .ng5-slider.vertical .ng5-slider-tick-legend{top:auto;right:24px;-webkit-transform:translate(0,-28%);transform:translate(0,-28%);max-width:none;white-space:nowrap}::ng-deep .ng5-slider.vertical .ng5-slider-ticks-values-under .ng5-slider-tick-value{bottom:auto;left:auto;right:24px}::ng-deep .ng5-slider *{-webkit-transition:none;transition:none}::ng-deep .ng5-slider.animate .ng5-slider-bar-wrapper{-webkit-transition:all linear .3s;transition:all linear .3s}::ng-deep .ng5-slider.animate .ng5-slider-selection{-webkit-transition:background-color linear .3s;transition:background-color linear .3s}::ng-deep .ng5-slider.animate .ng5-slider-pointer{-webkit-transition:all linear .3s;transition:all linear .3s}::ng-deep .ng5-slider.animate .ng5-slider-bubble{-webkit-transition:all linear .3s;transition:all linear .3s}::ng-deep .ng5-slider.animate .ng5-slider-bubble.ng5-slider-limit{-webkit-transition:opacity linear .3s;transition:opacity linear .3s}::ng-deep .ng5-slider.animate .ng5-slider-bubble.ng5-slider-combined{-webkit-transition:opacity linear .3s;transition:opacity linear .3s}::ng-deep .ng5-slider.animate .ng5-slider-tick{-webkit-transition:background-color linear .3s;transition:background-color linear .3s}`], host: { class: 'ng5-slider' }, providers: [NG5_SLIDER_CONTROL_VALUE_ACCESSOR] },] }, ]; /** @nocollapse */ SliderComponent.ctorParameters = () => [ { type: Renderer2, }, { type: ElementRef, }, { type: ChangeDetectorRef, }, { type: NgZone, }, ]; SliderComponent.propDecorators = { "value": [{ type: Input },], "valueChange": [{ type: Output },], "highValue": [{ type: Input },], "highValueChange": [{ type: Output },], "options": [{ type: Input },], "userChangeStart": [{ type: Output },], "userChange": [{ type: Output },], "userChangeEnd": [{ type: Output },], "manualRefresh": [{ type: Input },], "triggerFocus": [{ type: Input },], "leftOuterSelectionBarElement": [{ type: ViewChild, args: ['leftOuterSelectionBar', { read: SliderElementDirective },] },], "rightOuterSelectionBarElement": [{ type: ViewChild, args: ['rightOuterSelectionBar', { read: SliderElementDirective },] },], "fullBarElement": [{ type: ViewChild, args: ['fullBar', { read: SliderElementDirective },] },], "selectionBarElement": [{ type: ViewChild, args: ['selectionBar', { read: SliderElementDirective },] },], "minHandleElement": [{ type: ViewChild, args: ['minHandle', { read: SliderHandleDirective },] },], "maxHandleElement": [{ type: ViewChild, args: ['maxHandle', { read: SliderHandleDirective },] },], "floorLabelElement": [{ type: ViewChild, args: ['floorLabel', { read: SliderLabelDirective },] },], "ceilLabelElement": [{ type: ViewChild, args: ['ceilLabel', { read: SliderLabelDirective },] },], "minHandleLabelElement": [{ type: ViewChild, args: ['minHandleLabel', { read: SliderLabelDirective },] },], "maxHandleLabelElement": [{ type: ViewChild, args: ['maxHandleLabel', { read: SliderLabelDirective },] },], "combinedLabelElement": [{ type: ViewChild, args: ['combinedLabel', { read: SliderLabelDirective },] },], "ticksElement": [{ type: ViewChild, args: ['ticksElement', { read: SliderElementDirective },] },], "tooltipTemplate": [{ type: ContentChild, args: ['tooltipTemplate',] },], "sliderElementVerticalClass": [{ type: HostBinding, args: ['class.vertical',] },], "sliderElementAnimateClass": [{ type: HostBinding, args: ['class.animate',] },], "sliderElementDisabledAttr": [{ type: HostBinding, args: ['attr.disabled',] },], "onResize": [{ type: HostListener, args: ['window:resize', ['$event'],] },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ class TooltipWrapperComponent { } TooltipWrapperComponent.decorators = [ { type: Component, args: [{ selector: 'ng5-slider-tooltip-wrapper', template: `
{{content}}
`, styles: [`.ng5-slider-inner-tooltip{height:100%}`] },] }, ]; /** @nocollapse */ TooltipWrapperComponent.ctorParameters = () => []; TooltipWrapperComponent.propDecorators = { "template": [{ type: Input },], "tooltip": [{ type: Input },], "placement": [{ type: Input },], "content": [{ type: Input },], }; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Ng5Slider module * * The module exports the slider component */ class Ng5SliderModule { } Ng5SliderModule.decorators = [ { type: NgModule, args: [{ imports: [ CommonModule ], declarations: [ SliderComponent, SliderElementDirective, SliderHandleDirective, SliderLabelDirective, TooltipWrapperComponent ], exports: [ SliderComponent ] },] }, ]; /** @nocollapse */ Ng5SliderModule.ctorParameters = () => []; /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * @fileoverview added by tsickle * @suppress {checkTypes} checked by tsc */ /** * Generated bundle index. Do not edit. */ export { Ng5SliderModule, ChangeContext, PointerType, LabelType, Options, SliderElementDirective as ɵb, SliderHandleDirective as ɵc, SliderLabelDirective as ɵd, SliderComponent as ɵa, TooltipWrapperComponent as ɵe }; //# sourceMappingURL=ng5-slider.js.map