igniteui-angular
Version:
Ignite UI for Angular is a dependency-free Angular toolkit for building modern web apps
1,297 lines (1,291 loc) • 83.3 kB
JavaScript
import * as i0 from '@angular/core';
import { Directive, inject, ElementRef, booleanAttribute, HostBinding, Input, Component, EventEmitter, HostListener, Output, Pipe, Renderer2, ChangeDetectorRef, NgZone, QueryList, TemplateRef, ViewChildren, ViewChild, ContentChild, NgModule } from '@angular/core';
import { NG_VALUE_ACCESSOR } from '@angular/forms';
import { Subject, noop, fromEvent, interval, animationFrameScheduler, timer, merge } from 'rxjs';
import { takeUntil, throttleTime, throttle } from 'rxjs/operators';
import { ɵIgxDirectionality as _IgxDirectionality, resizeObservable } from 'igniteui-angular/core';
import { NgClass, NgTemplateOutlet } from '@angular/common';
/**
* Template directive that allows you to set a custom template representing the lower label value of the {@link IgxSliderComponent}
*
* ```html
* <igx-slider>
* <ng-template igxSliderThumbFrom let-value let-labels>{{value}}</ng-template>
* </igx-slider>
* ```
*
* @context {@link IgxSliderComponent.context}
*/
class IgxThumbFromTemplateDirective {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxThumbFromTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxThumbFromTemplateDirective, isStandalone: true, selector: "[igxSliderThumbFrom]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxThumbFromTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[igxSliderThumbFrom]',
standalone: true
}]
}] });
/**
* Template directive that allows you to set a custom template representing the upper label value of the {@link IgxSliderComponent}
*
* ```html
* <igx-slider>
* <ng-template igxSliderThumbTo let-value let-labels>{{value}}</ng-template>
* </igx-slider>
* ```
*
* @context {@link IgxSliderComponent.context}
*/
class IgxThumbToTemplateDirective {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxThumbToTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxThumbToTemplateDirective, isStandalone: true, selector: "[igxSliderThumbTo]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxThumbToTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[igxSliderThumbTo]',
standalone: true
}]
}] });
/**
* Template directive that allows you to set a custom template, represeting primary/secondary tick labels of the {@link IgxSliderComponent}
*
* @context {@link IgxTicksComponent.context}
*/
class IgxTickLabelTemplateDirective {
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxTickLabelTemplateDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "21.0.2", type: IgxTickLabelTemplateDirective, isStandalone: true, selector: "[igxSliderTickLabel]", ngImport: i0 }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxTickLabelTemplateDirective, decorators: [{
type: Directive,
args: [{
selector: '[igxSliderTickLabel]',
standalone: true
}]
}] });
const IgxSliderType = {
/**
* Slider with single thumb.
*/
SLIDER: 'slider',
/**
* Range slider with multiple thumbs, that can mark the range.
*/
RANGE: 'range'
};
const SliderHandle = {
FROM: 'from',
TO: 'to'
};
/**
* Slider Tick labels Orientation
*/
const TickLabelsOrientation = {
Horizontal: 'horizontal',
TopToBottom: 'toptobottom',
BottomToTop: 'bottomtotop'
};
/**
* Slider Ticks orientation
*/
const TicksOrientation = {
Top: 'top',
Bottom: 'bottom',
Mirror: 'mirror'
};
/**
* @hidden
*/
class IgxThumbLabelComponent {
constructor() {
this._elementRef = inject(ElementRef);
}
get thumbFromClass() {
return this.type === SliderHandle.FROM;
}
get thumbToClass() {
return this.type === SliderHandle.TO;
}
get thumbFromActiveClass() {
return this.type === SliderHandle.FROM && this.active;
}
get thumbToActiveClass() {
return this.type === SliderHandle.TO && this.active;
}
get labelFromPressedClass() {
return this.thumb?.thumbFromPressedClass;
}
get labelToPressedClass() {
return this.thumb?.thumbToPressedClass;
}
get getLabelClass() {
return {
'igx-slider-thumb-label-from__container': this.type === SliderHandle.FROM,
'igx-slider-thumb-label-to__container': this.type === SliderHandle.TO
};
}
get nativeElement() {
return this._elementRef.nativeElement;
}
get active() {
return this._active;
}
set active(val) {
if (this.continuous || this.deactiveState) {
this._active = false;
}
else {
this._active = val;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxThumbLabelComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.0.2", type: IgxThumbLabelComponent, isStandalone: true, selector: "igx-thumb-label", inputs: { value: "value", templateRef: "templateRef", context: "context", type: "type", continuous: ["continuous", "continuous", booleanAttribute], deactiveState: ["deactiveState", "deactiveState", booleanAttribute], thumb: "thumb" }, host: { properties: { "class.igx-slider-thumb-label-from": "this.thumbFromClass", "class.igx-slider-thumb-label-to": "this.thumbToClass", "class.igx-slider-thumb-label-from--active": "this.thumbFromActiveClass", "class.igx-slider-thumb-label-to--active": "this.thumbToActiveClass", "class.igx-slider-thumb-label-from--pressed": "this.labelFromPressedClass", "class.igx-slider-thumb-label-to--pressed": "this.labelToPressedClass" } }, ngImport: i0, template: "<div [ngClass]=\"getLabelClass\">\n <ng-container *ngTemplateOutlet=\"templateRef ? templateRef : thumbFromDefaultTemplate; context: context\"></ng-container>\n</div>\n\n<ng-template #thumbFromDefaultTemplate>\n {{ value }}\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxThumbLabelComponent, decorators: [{
type: Component,
args: [{ selector: 'igx-thumb-label', imports: [NgClass, NgTemplateOutlet], template: "<div [ngClass]=\"getLabelClass\">\n <ng-container *ngTemplateOutlet=\"templateRef ? templateRef : thumbFromDefaultTemplate; context: context\"></ng-container>\n</div>\n\n<ng-template #thumbFromDefaultTemplate>\n {{ value }}\n</ng-template>\n" }]
}], propDecorators: { value: [{
type: Input
}], templateRef: [{
type: Input
}], context: [{
type: Input
}], type: [{
type: Input
}], continuous: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], deactiveState: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], thumb: [{
type: Input
}], thumbFromClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-label-from']
}], thumbToClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-label-to']
}], thumbFromActiveClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-label-from--active']
}], thumbToActiveClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-label-to--active']
}], labelFromPressedClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-label-from--pressed']
}], labelToPressedClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-label-to--pressed']
}] } });
/**
* @hidden
*/
class IgxSliderThumbComponent {
constructor() {
this._elementRef = inject(ElementRef);
this._dir = inject(_IgxDirectionality);
this.thumbValueChange = new EventEmitter();
this.thumbChange = new EventEmitter();
this.thumbBlur = new EventEmitter();
this.hoverChange = new EventEmitter();
this.tabindex = 0;
this.role = 'slider';
this.ariaOrientation = 'horizontal';
this.zIndex = 0;
this.focused = false;
this.isActive = false;
this._isActive = false;
this._isPressed = false;
this._destroy$ = new Subject();
}
get ariaValueNow() {
return this.value;
}
get ariaValueMin() {
return this.min;
}
get ariaValueMax() {
return this.max;
}
get ariaValueText() {
if (this.labels && this.labels[this.value] !== undefined) {
return this.labels[this.value];
}
return this.value;
}
get ariaLabelAttr() {
return `Slider thumb ${this.type}`;
}
get ariaDisabled() {
return this.disabled;
}
get thumbFromClass() {
return this.type === SliderHandle.FROM;
}
get thumbToClass() {
return this.type === SliderHandle.TO;
}
get thumbFromActiveClass() {
return this.type === SliderHandle.FROM && this._isActive;
}
get thumbToActiveClass() {
return this.type === SliderHandle.TO && this._isActive;
}
get thumbFromDisabledClass() {
return this.type === SliderHandle.FROM && this.disabled;
}
get thumbToDisabledClass() {
return this.type === SliderHandle.TO && this.disabled;
}
get thumbFromPressedClass() {
return this.type === SliderHandle.FROM && this.isActive && this._isPressed;
}
get thumbToPressedClass() {
return this.type === SliderHandle.TO && this.isActive && this._isPressed;
}
get getDotClass() {
return {
'igx-slider-thumb-from__dot': this.type === SliderHandle.FROM,
'igx-slider-thumb-to__dot': this.type === SliderHandle.TO
};
}
get nativeElement() {
return this._elementRef.nativeElement;
}
get destroy() {
return this._destroy$;
}
get thumbPositionX() {
const thumbBounderies = this.nativeElement.getBoundingClientRect();
const thumbCenter = (thumbBounderies.right - thumbBounderies.left) / 2;
return thumbBounderies.left + thumbCenter;
}
onPointerEnter() {
this.focused = false;
this.hoverChange.emit(true);
}
onPointerLeave() {
this.hoverChange.emit(false);
}
onKeyUp(event) {
event.stopPropagation();
this.focused = true;
}
onKeyDown(event) {
if (this.disabled) {
return;
}
let increment = 0;
const stepWithDir = (rtl) => rtl ? this.step * -1 : this.step;
if (event.key.endsWith('Left')) {
increment = stepWithDir(!this._dir.rtl);
}
else if (event.key.endsWith('Right')) {
increment = stepWithDir(this._dir.rtl);
}
else {
return;
}
this.thumbChange.emit();
this.thumbValueChange.emit(increment);
}
onBlur() {
this.isActive = false;
this.zIndex = 0;
this.focused = false;
this.thumbBlur.emit();
}
onFocusListener() {
this.isActive = true;
this.zIndex = 1;
}
/**
* @hidden
*/
ngOnInit() {
this.onPan
.pipe(takeUntil(this._destroy$))
.subscribe(mouseX => this.updateThumbValue(mouseX));
}
/**
* @hidden
*/
ngOnDestroy() {
this._destroy$.next(true);
this._destroy$.complete();
}
/**
* Show thumb label and ripple.
*/
showThumbIndicators() {
this.toggleThumbIndicators(true);
}
/**
* Hide thumb label and ripple.
*/
hideThumbIndicators() {
this.toggleThumbIndicators(false);
}
updateThumbValue(mouseX) {
const updateValue = this.calculateTrackUpdate(mouseX);
if (this.isActive && updateValue !== 0) {
this.thumbValueChange.emit(updateValue);
}
}
calculateTrackUpdate(mouseX) {
const scaleX = this._dir.rtl ? this.thumbPositionX - mouseX : mouseX - this.thumbPositionX;
const stepDistanceCenter = this.stepDistance / 2;
// If the thumb scale range (slider update) is less thàn a half step,
// the position stays the same.
const scaleXPositive = Math.abs(scaleX);
if (scaleXPositive < stepDistanceCenter) {
return 0;
}
return this.stepToProceed(scaleX, this.stepDistance);
}
stepToProceed(scaleX, stepDist) {
return Math.round(scaleX / stepDist) * this.step;
}
toggleThumbIndicators(visible) {
this._isPressed = visible;
if (this.continuous || this.deactiveState) {
this._isActive = false;
}
else {
this._isActive = visible;
}
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxSliderThumbComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "16.1.0", version: "21.0.2", type: IgxSliderThumbComponent, isStandalone: true, selector: "igx-thumb", inputs: { value: "value", continuous: ["continuous", "continuous", booleanAttribute], thumbLabelVisibilityDuration: "thumbLabelVisibilityDuration", disabled: ["disabled", "disabled", booleanAttribute], onPan: "onPan", stepDistance: "stepDistance", step: "step", templateRef: "templateRef", context: "context", type: "type", deactiveState: ["deactiveState", "deactiveState", booleanAttribute], min: "min", max: "max", labels: "labels" }, outputs: { thumbValueChange: "thumbValueChange", thumbChange: "thumbChange", thumbBlur: "thumbBlur", hoverChange: "hoverChange" }, host: { listeners: { "pointerenter": "onPointerEnter()", "pointerleave": "onPointerLeave()", "keyup": "onKeyUp($event)", "keydown": "onKeyDown($event)", "blur": "onBlur()", "focus": "onFocusListener()" }, properties: { "attr.tabindex": "this.tabindex", "attr.role": "this.role", "attr.aria-valuenow": "this.ariaValueNow", "attr.aria-valuemin": "this.ariaValueMin", "attr.aria-valuemax": "this.ariaValueMax", "attr.aria-valuetext": "this.ariaValueText", "attr.aria-label": "this.ariaLabelAttr", "attr.aria-orientation": "this.ariaOrientation", "attr.aria-disabled": "this.ariaDisabled", "attr.z-index": "this.zIndex", "class.igx-slider-thumb-to--focused": "this.focused", "class.igx-slider-thumb-from": "this.thumbFromClass", "class.igx-slider-thumb-to": "this.thumbToClass", "class.igx-slider-thumb-from--active": "this.thumbFromActiveClass", "class.igx-slider-thumb-to--active": "this.thumbToActiveClass", "class.igx-slider-thumb-from--disabled": "this.thumbFromDisabledClass", "class.igx-slider-thumb-to--disabled": "this.thumbToDisabledClass", "class.igx-slider-thumb-from--pressed": "this.thumbFromPressedClass", "class.igx-slider-thumb-to--pressed": "this.thumbToPressedClass" } }, ngImport: i0, template: "<div [ngClass]=\"getDotClass\"></div>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxSliderThumbComponent, decorators: [{
type: Component,
args: [{ selector: 'igx-thumb', imports: [NgClass], template: "<div [ngClass]=\"getDotClass\"></div>\n" }]
}], propDecorators: { value: [{
type: Input
}], continuous: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], thumbLabelVisibilityDuration: [{
type: Input
}], disabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], onPan: [{
type: Input
}], stepDistance: [{
type: Input
}], step: [{
type: Input
}], templateRef: [{
type: Input
}], context: [{
type: Input
}], type: [{
type: Input
}], deactiveState: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], min: [{
type: Input
}], max: [{
type: Input
}], labels: [{
type: Input
}], thumbValueChange: [{
type: Output
}], thumbChange: [{
type: Output
}], thumbBlur: [{
type: Output
}], hoverChange: [{
type: Output
}], tabindex: [{
type: HostBinding,
args: ['attr.tabindex']
}], role: [{
type: HostBinding,
args: ['attr.role']
}], ariaValueNow: [{
type: HostBinding,
args: ['attr.aria-valuenow']
}], ariaValueMin: [{
type: HostBinding,
args: ['attr.aria-valuemin']
}], ariaValueMax: [{
type: HostBinding,
args: ['attr.aria-valuemax']
}], ariaValueText: [{
type: HostBinding,
args: ['attr.aria-valuetext']
}], ariaLabelAttr: [{
type: HostBinding,
args: ['attr.aria-label']
}], ariaOrientation: [{
type: HostBinding,
args: ['attr.aria-orientation']
}], ariaDisabled: [{
type: HostBinding,
args: [`attr.aria-disabled`]
}], zIndex: [{
type: HostBinding,
args: ['attr.z-index']
}], focused: [{
type: HostBinding,
args: ['class.igx-slider-thumb-to--focused']
}], thumbFromClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-from']
}], thumbToClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-to']
}], thumbFromActiveClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-from--active']
}], thumbToActiveClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-to--active']
}], thumbFromDisabledClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-from--disabled']
}], thumbToDisabledClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-to--disabled']
}], thumbFromPressedClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-from--pressed']
}], thumbToPressedClass: [{
type: HostBinding,
args: ['class.igx-slider-thumb-to--pressed']
}], onPointerEnter: [{
type: HostListener,
args: ['pointerenter']
}], onPointerLeave: [{
type: HostListener,
args: ['pointerleave']
}], onKeyUp: [{
type: HostListener,
args: ['keyup', ['$event']]
}], onKeyDown: [{
type: HostListener,
args: ['keydown', ['$event']]
}], onBlur: [{
type: HostListener,
args: ['blur']
}], onFocusListener: [{
type: HostListener,
args: ['focus']
}] } });
/**
* @hidden
*/
class IgxTickLabelsPipe {
transform(labels, secondaryTicks) {
if (!labels) {
return;
}
const result = [];
labels.forEach(item => {
result.push(item);
for (let i = 0; i < secondaryTicks; i++) {
result.push('');
}
});
return result;
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxTickLabelsPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe }); }
static { this.ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "21.0.2", ngImport: i0, type: IgxTickLabelsPipe, isStandalone: true, name: "spreadTickLabels" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxTickLabelsPipe, decorators: [{
type: Pipe,
args: [{
name: 'spreadTickLabels',
standalone: true
}]
}] });
/**
* @hidden
*/
class IgxTicksComponent {
constructor() {
/**
* @hidden
*/
this.ticksClass = true;
}
/**
* @hidden
*/
get ticksTopClass() {
return this.ticksOrientation === TicksOrientation.Top;
}
/**
* @hidden
*/
get hasPrimaryClass() {
return this.primaryTicks > 0;
}
/**
* @hidden
*/
get labelsTopToBottomClass() {
return this.tickLabelsOrientation === TickLabelsOrientation.TopToBottom;
}
/**
* @hidden
*/
get labelsBottomToTopClass() {
return this.tickLabelsOrientation === TickLabelsOrientation.BottomToTop;
}
/**
* Returns the template context corresponding to
* {@link IgxTickLabelTemplateDirective}
*
* ```typescript
* return {
* $implicit //returns the value per each tick label.
* isPrimery //returns if the tick is primary.
* labels // returns the {@link labels} collection.
* index // returns the index per each tick of the whole sequence.
* }
* ```
*
* @param idx the index per each tick label.
*/
context(idx) {
return {
$implicit: this.tickLabel(idx),
isPrimary: this.isPrimary(idx),
labels: this.labels,
index: idx
};
}
/**
* @hidden
*/
get ticksLength() {
return this.primaryTicks > 0 ?
((this.primaryTicks - 1) * this.secondaryTicks) + this.primaryTicks :
this.secondaryTicks > 0 ? this.secondaryTicks : 0;
}
hiddenTickLabels(idx) {
return this.isPrimary(idx) ? this.primaryTickLabels : this.secondaryTickLabels;
}
/**
* @hidden
*/
isPrimary(idx) {
return this.primaryTicks <= 0 ? false :
idx % (this.secondaryTicks + 1) === 0;
}
/**
* @hidden
*/
tickLabel(idx) {
if (this.labelsViewEnabled) {
return this.labels[idx];
}
const labelStep = (Math.max(this.minValue, this.maxValue) - Math.min(this.minValue, this.maxValue)) / (this.ticksLength - 1);
const labelVal = labelStep * idx;
return (this.minValue + labelVal).toFixed(2);
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxTicksComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.2", type: IgxTicksComponent, isStandalone: true, selector: "igx-ticks", inputs: { primaryTicks: "primaryTicks", secondaryTicks: "secondaryTicks", primaryTickLabels: ["primaryTickLabels", "primaryTickLabels", booleanAttribute], secondaryTickLabels: ["secondaryTickLabels", "secondaryTickLabels", booleanAttribute], ticksOrientation: "ticksOrientation", tickLabelsOrientation: "tickLabelsOrientation", maxValue: "maxValue", minValue: "minValue", labelsViewEnabled: ["labelsViewEnabled", "labelsViewEnabled", booleanAttribute], labels: "labels", tickLabelTemplateRef: "tickLabelTemplateRef" }, host: { properties: { "class.igx-slider__ticks": "this.ticksClass", "class.igx-slider__ticks--top": "this.ticksTopClass", "class.igx-slider__ticks--tall": "this.hasPrimaryClass", "class.igx-slider__tick-labels--top-bottom": "this.labelsTopToBottomClass", "class.igx-slider__tick-labels--bottom-top": "this.labelsBottomToTopClass" } }, ngImport: i0, template: "@for (n of [].constructor(ticksLength); track $index; let idx = $index) {\n <div class=\"igx-slider__ticks-group\" [ngClass]=\"{ 'igx-slider__ticks-group--tall': isPrimary(idx)}\">\n <div class=\"igx-slider__ticks-tick\">\n <span class=\"igx-slider__ticks-label\" [ngClass]=\"{ 'igx-slider__tick-label--hidden': !hiddenTickLabels(idx)}\">\n <ng-container *ngTemplateOutlet=\"tickLabelTemplateRef ? tickLabelTemplateRef : tickLabelDefaultTemplate; context: context(idx)\"></ng-container>\n </span>\n </div>\n </div>\n}\n\n<ng-template #tickLabelDefaultTemplate let-value>\n {{ value }}\n</ng-template>\n", dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.2", ngImport: i0, type: IgxTicksComponent, decorators: [{
type: Component,
args: [{ selector: 'igx-ticks', imports: [NgClass, NgTemplateOutlet], template: "@for (n of [].constructor(ticksLength); track $index; let idx = $index) {\n <div class=\"igx-slider__ticks-group\" [ngClass]=\"{ 'igx-slider__ticks-group--tall': isPrimary(idx)}\">\n <div class=\"igx-slider__ticks-tick\">\n <span class=\"igx-slider__ticks-label\" [ngClass]=\"{ 'igx-slider__tick-label--hidden': !hiddenTickLabels(idx)}\">\n <ng-container *ngTemplateOutlet=\"tickLabelTemplateRef ? tickLabelTemplateRef : tickLabelDefaultTemplate; context: context(idx)\"></ng-container>\n </span>\n </div>\n </div>\n}\n\n<ng-template #tickLabelDefaultTemplate let-value>\n {{ value }}\n</ng-template>\n" }]
}], propDecorators: { primaryTicks: [{
type: Input
}], secondaryTicks: [{
type: Input
}], primaryTickLabels: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], secondaryTickLabels: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], ticksOrientation: [{
type: Input
}], tickLabelsOrientation: [{
type: Input
}], maxValue: [{
type: Input
}], minValue: [{
type: Input
}], labelsViewEnabled: [{
type: Input,
args: [{ transform: booleanAttribute }]
}], labels: [{
type: Input
}], tickLabelTemplateRef: [{
type: Input
}], ticksClass: [{
type: HostBinding,
args: ['class.igx-slider__ticks']
}], ticksTopClass: [{
type: HostBinding,
args: ['class.igx-slider__ticks--top']
}], hasPrimaryClass: [{
type: HostBinding,
args: ['class.igx-slider__ticks--tall']
}], labelsTopToBottomClass: [{
type: HostBinding,
args: ['class.igx-slider__tick-labels--top-bottom']
}], labelsBottomToTopClass: [{
type: HostBinding,
args: ['class.igx-slider__tick-labels--bottom-top']
}] } });
let NEXT_ID = 0;
/**
* **Ignite UI for Angular Slider** -
* [Documentation](https://www.infragistics.com/products/ignite-ui-angular/angular/components/slider/slider)
*
* The Ignite UI Slider allows selection in a given range by moving the thumb along the track. The track
* can be defined as continuous or stepped, and you can choose between single and range slider types.
*
* Example:
* ```html
* <igx-slider id="slider"
* [minValue]="0" [maxValue]="100"
* [continuous]=true [(ngModel)]="volume">
* </igx-slider>
* ```
*/
class IgxSliderComponent {
/**
* @hidden
*/
get thumbFrom() {
return this.thumbs.find(thumb => thumb.type === SliderHandle.FROM);
}
/**
* @hidden
*/
get thumbTo() {
return this.thumbs.find(thumb => thumb.type === SliderHandle.TO);
}
get labelFrom() {
return this.labelRefs.find(label => label.type === SliderHandle.FROM);
}
get labelTo() {
return this.labelRefs.find(label => label.type === SliderHandle.TO);
}
/**
* @hidden
*/
get disabledClass() {
return this.disabled;
}
/**
* Gets the type of the `IgxSliderComponent`.
* The slider can be IgxSliderType.SLIDER(default) or IgxSliderType.RANGE.
* ```typescript
* @ViewChild("slider2")
* public slider: IgxSliderComponent;
* ngAfterViewInit(){
* let type = this.slider.type;
* }
*/
get type() {
return this._type;
}
/**
* Sets the type of the `IgxSliderComponent`.
* The slider can be IgxSliderType.SLIDER(default) or IgxSliderType.RANGE.
* ```typescript
* sliderType: IgxSliderType = IgxSliderType.RANGE;
* ```
* ```html
* <igx-slider #slider2 [type]="sliderType" [(ngModel)]="rangeValue" [minValue]="0" [maxValue]="100">
* ```
*/
set type(type) {
this._type = type;
if (type === IgxSliderType.SLIDER) {
this.lowerValue = 0;
}
if (this._hasViewInit) {
this.updateTrack();
}
}
/**
* Enables `labelView`, by accepting a collection of primitive values with more than one element.
* Each element will be equally spread over the slider and it will serve as a thumb label.
* Once the property is set, it will precendence over {@link maxValue}, {@link minValue}, {@link step}.
* This means that the manipulation for those properties won't be allowed.
*/
get labels() {
return this._labels;
}
set labels(labels) {
this._labels = labels;
this._pMax = this.valueToFraction(this.upperBound, 0, 1);
this._pMin = this.valueToFraction(this.lowerBound, 0, 1);
this.positionHandlersAndUpdateTrack();
if (this._hasViewInit) {
this.stepDistance = this.calculateStepDistance();
this.setTickInterval();
}
}
/**
* Returns the template context corresponding
* to {@link IgxThumbFromTemplateDirective} and {@link IgxThumbToTemplateDirective} templates.
*
* ```typescript
* return {
* $implicit // returns the value of the label,
* labels // returns the labels collection the user has passed.
* }
* ```
*/
get context() {
return {
$implicit: this.value,
labels: this.labels
};
}
/**
* Sets the incremental/decremental step of the value when dragging the thumb.
* The default step is 1, and step should not be less or equal than 0.
* ```html
* <igx-slider #slider [(ngModel)]="task.percentCompleted" [step]="5">
* ```
*/
set step(step) {
this._step = step;
if (this._hasViewInit) {
this.stepDistance = this.calculateStepDistance();
this.normalizeByStep(this._value);
this.setValue(this._value, true);
this.positionHandlersAndUpdateTrack();
this.setTickInterval();
}
}
/**
* Returns the incremental/decremental dragging step of the {@link IgxSliderComponent}.
* ```typescript
* @ViewChild("slider2")
* public slider: IgxSliderComponent;
* ngAfterViewInit(){
* let step = this.slider.step;
* }
* ```
*/
get step() {
return this.labelsViewEnabled ? 1 : this._step;
}
/**
* Returns if the {@link IgxSliderComponent} is disabled.
* ```typescript
* @ViewChild("slider2")
* public slider: IgxSliderComponent;
* ngAfterViewInit(){
* let isDisabled = this.slider.disabled;
* }
* ```
*/
get disabled() {
return this._disabled;
}
/**
* Disables the component.
* ```html
* <igx-slider #slider [disabled]="true" [(ngModel)]="task.percentCompleted" [step]="5" [lowerBound]="20">
* ```
*/
set disabled(disable) {
this._disabled = disable;
if (this._hasViewInit) {
this.changeThumbFocusableState(disable);
}
}
/**
* Returns if the {@link IgxSliderComponent} is set as continuous.
* ```typescript
* @ViewChild("slider2")
* public slider: IgxSliderComponent;
* ngAfterViewInit(){
* let continuous = this.slider.continuous;
* }
* ```
*/
get continuous() {
return this._continuous;
}
/**
* Sets the {@link IgxSliderComponent} as continuous.
* By default is considered that the {@link IgxSliderComponent} is discrete.
* Discrete {@link IgxSliderComponent} slider has step indicators over the track and visible thumb labels during interaction.
* Continuous {@link IgxSliderComponent} does not have ticks and does not show bubble labels for values.
* ```html
* <igx-slider #slider [continuous]="'true'" [(ngModel)]="task.percentCompleted" [step]="5" [lowerBound]="20">
* ```
*/
set continuous(continuous) {
this._continuous = continuous;
if (this._hasViewInit) {
this.setTickInterval();
}
}
/**
* Returns the minimal displayed track value of the `IgxSliderComponent`.
* ```typescript
* @ViewChild("slider2")
* public slider: IgxSliderComponent;
* ngAfterViewInit(){
* let sliderMin = this.slider.minValue;
* }
* ```
*/
get minValue() {
if (this.labelsViewEnabled) {
return 0;
}
return this._minValue;
}
/**
* Sets the minimal displayed track value for the `IgxSliderComponent`.
* The default minimal value is 0.
* ```html
* <igx-slider [type]="sliderType" [minValue]="56" [maxValue]="100">
* ```
*/
set minValue(value) {
if (value >= this.maxValue) {
return;
}
else {
this._minValue = value;
}
if (value > this._upperBound) {
this.updateUpperBoundAndMaxTravelZone();
this.lowerBound = value;
}
// Refresh min travel zone limit.
this._pMin = 0;
// Recalculate step distance.
this.positionHandlersAndUpdateTrack();
if (this._hasViewInit) {
this.stepDistance = this.calculateStepDistance();
this.setTickInterval();
}
}
/**
* Returns the maximum displayed track value for the {@link IgxSliderComponent}.
* ```typescript
* @ViewChild("slider")
* public slider: IgxSliderComponent;
* ngAfterViewInit(){
* let sliderMax = this.slider.maxValue;
* }
* ```
*/
get maxValue() {
return this.labelsViewEnabled ?
this.labels.length - 1 :
this._maxValue;
}
/**
* Sets the maximal displayed track value for the `IgxSliderComponent`.
* The default maximum value is 100.
* ```html
* <igx-slider [type]="sliderType" [minValue]="56" [maxValue]="256">
* ```
*/
set maxValue(value) {
if (value <= this._minValue) {
return;
}
else {
this._maxValue = value;
}
if (value < this._lowerBound) {
this.updateLowerBoundAndMinTravelZone();
this.upperBound = value;
}
// refresh max travel zone limits.
this._pMax = 1;
// recalculate step distance.
this.positionHandlersAndUpdateTrack();
if (this._hasViewInit) {
this.stepDistance = this.calculateStepDistance();
this.setTickInterval();
}
}
/**
* Returns the lower boundary of settable values of the `IgxSliderComponent`.
* If not set, will return `minValue`.
* ```typescript
* @ViewChild("slider")
* public slider: IgxSliderComponent;
* ngAfterViewInit(){
* let sliderLowBound = this.slider.lowerBound;
* }
* ```
*/
get lowerBound() {
if (!Number.isNaN(this._lowerBound) && this._lowerBound !== undefined) {
return this.valueInRange(this._lowerBound, this.minValue, this.maxValue);
}
return this.minValue;
}
/**
* Sets the lower boundary of settable values of the `IgxSliderComponent`.
* If not set is the same as min value.
* ```html
* <igx-slider [step]="5" [lowerBound]="20">
* ```
*/
set lowerBound(value) {
if (value >= this.upperBound || (this.labelsViewEnabled && value < 0)) {
return;
}
this._lowerBound = this.valueInRange(value, this.minValue, this.maxValue);
// Refresh min travel zone.
this._pMin = this.valueToFraction(this._lowerBound, 0, 1);
this.positionHandlersAndUpdateTrack();
}
/**
* Returns the upper boundary of settable values of the `IgxSliderComponent`.
* If not set, will return `maxValue`
* ```typescript
* @ViewChild("slider")
* public slider: IgxSliderComponent;
* ngAfterViewInit(){
* let sliderUpBound = this.slider.upperBound;
* }
* ```
*/
get upperBound() {
if (!Number.isNaN(this._upperBound) && this._upperBound !== undefined) {
return this.valueInRange(this._upperBound, this.minValue, this.maxValue);
}
return this.maxValue;
}
/**
* Sets the upper boundary of the `IgxSliderComponent`.
* If not set is the same as max value.
* ```html
* <igx-slider [step]="5" [upperBound]="20">
* ```
*/
set upperBound(value) {
if (value <= this.lowerBound || (this.labelsViewEnabled && value > this.labels.length - 1)) {
return;
}
this._upperBound = this.valueInRange(value, this.minValue, this.maxValue);
// Refresh time travel zone.
this._pMax = this.valueToFraction(this._upperBound, 0, 1);
this.positionHandlersAndUpdateTrack();
}
/**
* Returns the slider value. If the slider is of type {@link IgxSliderType.SLIDER} the returned value is number.
* If the slider type is {@link IgxSliderType.RANGE}.
* The returned value represents an object of {@link lowerValue} and {@link upperValue}.
* ```typescript
* @ViewChild("slider2")
* public slider: IgxSliderComponent;
* public sliderValue(event){
* let sliderVal = this.slider.value;
* }
* ```
*/
get value() {
if (this.isRange) {
return {
lower: this.valueInRange(this.lowerValue, this.lowerBound, this.upperBound),
upper: this.valueInRange(this.upperValue, this.lowerBound, this.upperBound)
};
}
else {
return this.valueInRange(this.upperValue, this.lowerBound, this.upperBound);
}
}
/**
* Sets the slider value.
* If the slider is of type {@link IgxSliderType.SLIDER}.
* The argument is number. By default the {@link value} gets the {@link lowerBound}.
* If the slider type is {@link IgxSliderType.RANGE} the argument
* represents an object of {@link lowerValue} and {@link upperValue} properties.
* By default the object is associated with the {@link lowerBound} and {@link upperBound} property values.
* ```typescript
* rangeValue = {
* lower: 30,
* upper: 60
* };
* ```
* ```html
* <igx-slider [type]="sliderType" [(ngModel)]="rangeValue" [minValue]="56" [maxValue]="256">
* ```
*/
set value(value) {
this.normalizeByStep(value);
if (this._hasViewInit) {
this.setValue(this._value, true);
this.positionHandlersAndUpdateTrack();
}
}
/**
* Returns the number of the presented primary ticks.
* ```typescript
* const primaryTicks = this.slider.primaryTicks;
* ```
*/
get primaryTicks() {
if (this.labelsViewEnabled) {
return this._primaryTicks = this.labels.length;
}
return this._primaryTicks;
}
/**
* Sets the number of primary ticks. If {@link @labels} is enabled, this property won't function.
* Insted enable ticks by {@link showTicks} property.
* ```typescript
* this.slider.primaryTicks = 5;
* ```
*/
set primaryTicks(val) {
if (val <= 1) {
return;
}
this._primaryTicks = val;
}
/**
* Returns the number of the presented secondary ticks.
* ```typescript
* const secondaryTicks = this.slider.secondaryTicks;
* ```
*/
get secondaryTicks() {
return this._secondaryTicks;
}
/**
* Sets the number of secondary ticks. The property functions even when {@link labels} is enabled,
* but all secondary ticks won't present any tick labels.
* ```typescript
* this.slider.secondaryTicks = 5;
* ```
*/
set secondaryTicks(val) {
if (val < 1) {
return;
}
this._secondaryTicks = val;
}
/**
* @hidden
*/
get deactivateThumbLabel() {
return ((this.primaryTicks && this.primaryTickLabels) || (this.secondaryTicks && this.secondaryTickLabels)) &&
(this.ticksOrientation === TicksOrientation.Top || this.ticksOrientation === TicksOrientation.Mirror);
}
constructor() {
this.renderer = inject(Renderer2);
this._el = inject(ElementRef);
this._cdr = inject(ChangeDetectorRef);
this._ngZone = inject(NgZone);
this._dir = inject(_IgxDirectionality);
/**
* @hidden
*/
this.slierClass = true;
/**
* Sets the value of the `id` attribute.
* If not provided it will be automatically generated.
* ```html
* <igx-slider [id]="'igx-slider-32'" [(ngModel)]="task.percentCompleted" [step]="5" [lowerBound]="20">
* ```
*/
this.id = `igx-slider-${NEXT_ID++}`;
/**
* Sets the duration visibility of thumbs labels. The default value is 750 milliseconds.
* ```html
* <igx-slider #slider [thumbLabelVisibilityDuration]="3000" [(ngModel)]="task.percentCompleted" [step]="5">
* ```
*/
this.thumbLabelVisibilityDuration = 750;
/**
* Show/hide slider ticks
* ```html
* <igx-slier [showTicks]="true" [primaryTicks]="5"></igx-slier>
* ```
*/
this.showTicks = false;
/**
* show/hide primary tick labels
* ```html
* <igx-slider [primaryTicks]="5" [primaryTickLabels]="false"></igx-slider>
* ```
*/
this.primaryTickLabels = true;
/**
* show/hide secondary tick labels
* ```html
* <igx-slider [secondaryTicks]="5" [secondaryTickLabels]="false"></igx-slider>
* ```
*/
this.secondaryTickLabels = true;
/**
* Changes ticks orientation:
* bottom - The default orienation, below the slider track.
* top - Above the slider track
* mirror - combines top and bottom orientation.
* ```html
* <igx-slider [primaryTicks]="5" [ticksOrientation]="ticksOrientation"></igx-slider>
* ```
*/
this.ticksOrientation = TicksOrientation.Bottom;
/**
* Changes tick labels rotation:
* horizontal - The default rotation
* toptobottom - Rotates tick labels vertically to 90deg
* bottomtotop - Rotate tick labels vertically to -90deg
* ```html
* <igx-slider [primaryTicks]="5" [secondaryTicks]="3" [tickLabelsOrientation]="tickLabelsOrientaiton"></igx-slider>
* ```
*/
this.tickLabelsOrientation = TickLabelsOrientation.Horizontal;
/**
* This event is emitted every time the value is changed.
* ```typescript
* public change(event){
* alert("The value has been changed!");
* }
* ```
* ```html
* <igx-slider (valueChange)="change($event)" #slider [(ngModel)]="task.percentCompleted" [step]="5">
* ```
*/
this.valueChange = new EventEmitter();
/**
* This event is emitted every time the lower value of a range slider is changed.
* ```typescript
* public change(value){
* alert(`The lower value has been changed to ${value}`);
* }
* ```
* ```html
* <igx-slider [(lowerValue)]="model.lowervalue" (lowerValueChange)="change($event)" [step]="5">
* ```
*/
this.lowerValueChange = new EventEmitter();
/**
* This event is emitted every time the upper value of a range slider is changed.
* ```typescript
* public change(value){
* alert(`The upper value has been changed to ${value}`);
* }
* ```
* ```html
* <igx-slider [(upperValue)]="model.uppervalue" (upperValueChange)="change($event)" [step]="5">
* ```
*/
this.upperValueChange = new EventEmitter();
/**
* This event is emitted at the end of every slide interaction.
* ```typescript
* public change(event){
* alert("The value has been changed!");
* }
* ```
* ```html
* <igx-slider (dragFinished)="change($event)" #slider [(ngModel)]="task.percentCompleted" [step]="5">
* ```
*/
this.dragFinished = new EventEmitter();
/**
* @hidden
*/
this.thumbs = new QueryList();
/**
* @hidden
*/
this.labelRefs = new QueryList();
/**
* @hidden
*/
this.onPan = new Subject();
// Limit handle travel zone
this._pMin = 0;
this._pMax = 1;
// From/upperValue in percent values
this._hasViewInit = false;
this._minValue = 0;
this._maxValue = 100;
this._continuous = false;
this._disabled = false;
this._step = 1;
this._value = 0;
// ticks
this._primaryTicks = 0;
this._secondaryTicks = 0;
this._sliding = false;
this._labels = new Array();
this._type = IgxSliderType.SLIDER;
this._destroyer$ = new Subject();
this._indicatorsDestroyer$ = new Subject();
this._onChangeCallback = noop;
this._onTouchedCallback = noop;
this.stepDistance = this._step;
}
/**
* @hidden
*/
onFocus() {
this.toggleSliderIndicators();
}
/**
* Returns whether the `IgxSliderComponent` type is RANGE.
* ```typescript
* @ViewChild("slider")
* public slider: IgxSliderComponent;
* ngAfterViewInit(){
* let sliderRange = this.slider.isRange;
* }
* ```
*/
get isRange() {
return this.type === IgxSliderType.RANGE;
}
/**
* Returns the lower value of a RANGE `IgxSliderComponent`.
* ```typescript
* @ViewChild("slider")
* public slider: IgxSliderComponent;
* public lowValue(event){
* let sliderLowValue = this.slider.lowerValue;
* }
* ```
*/
get lowerValue() {
if (!Number.isNaN(this._lowerValue) && this._lowerValue !== undefined && this._lowerValue >= this.lowerBound) {
return this._lowerValue;
}
return this.lowerBound;
}
/**
* Sets the lower value of a RANGE `IgxSliderComponent`.
* ```typescript
* @ViewChild("slider")
* public slider: IgxSliderComponent;
* public lowValue(event){
* this.slider.lowerValue = value;
* }
* ```
*/
set lowerValue(value) {
const adjustedValue = this.valueInRange(value, this.lowerBound, this.upperBound);
if (this._lowerValue !== adjustedValue) {
this._lowerValue = adjustedValue;
this.lowerValueChange.emit(this._lowerValue);
this.value = { lower: this._lowerValue, upper: this._upperValue };
}
}
/**
* Returns the upper value of a RANGE `IgxSliderComponent`.
* Re