diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e45edd9ddd..8031e66803f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -66,6 +66,7 @@ All notable changes for each version of this project will be documented in this - `ticksOrientation` input was added. Allows to change ticks orientation to top|bottom|mirror. - `tickLabelsOrientation` input was added. Allows you to change the rotation of all tick labels from horizontal to vertical(toptobottom, bottomtotop). - `igxSliderTickLabel` directive has been introduced. Allows you to set a custom template for all tick labels. + - `isContinuous` - input has been deleted. The option is not supported anymore. - `IgxCarousel`: - `keyboardSupport` input is added, which can be used to enable and disable keyboard navigation diff --git a/projects/igniteui-angular/migrations/update-9_0_0/changes/inputs.json b/projects/igniteui-angular/migrations/update-9_0_0/changes/inputs.json new file mode 100644 index 00000000000..c1cc6a5946a --- /dev/null +++ b/projects/igniteui-angular/migrations/update-9_0_0/changes/inputs.json @@ -0,0 +1,13 @@ +{ + "@scheme": "../../common/schema/binding.schema.json", + "changes": [ + { + "name": "isContinuous", + "replaceWith": "continuous", + "owner": { + "selector": "igx-slider", + "type": "component" + } + } + ] +} diff --git a/projects/igniteui-angular/src/lib/core/utils.ts b/projects/igniteui-angular/src/lib/core/utils.ts index 1d4a72f24ea..3e6aa4f65ca 100644 --- a/projects/igniteui-angular/src/lib/core/utils.ts +++ b/projects/igniteui-angular/src/lib/core/utils.ts @@ -1,5 +1,7 @@ import { Injectable, PLATFORM_ID, Inject } from '@angular/core'; import { isPlatformBrowser } from '@angular/common'; +import { Observable } from 'rxjs'; +import ResizeObserver from 'resize-observer-polyfill'; /** *@hidden @@ -321,3 +323,20 @@ export const NAVIGATION_KEYS = new Set([ export const ROW_EXPAND_KEYS = new Set('right down arrowright arrowdown'.split(' ')); export const ROW_COLLAPSE_KEYS = new Set('left up arrowleft arrowup'.split(' ')); export const SUPPORTED_KEYS = new Set([...Array.from(NAVIGATION_KEYS), 'tab', 'enter', 'f2', 'escape', 'esc']); + +/** + * @hidden + * @internal + * + * Creates a new ResizeObserver on `target` and returns it as an Observable. + */ +export function resizeObservable(target: HTMLElement): Observable { + return new Observable((observer) => { + const instance = new ResizeObserver((entries: ResizeObserverEntry[]) => { + observer.next(entries); + }); + instance.observe(target); + const unsubscribe = () => instance.disconnect(); + return unsubscribe; + }); +} diff --git a/projects/igniteui-angular/src/lib/slider/label/thumb-label.component.ts b/projects/igniteui-angular/src/lib/slider/label/thumb-label.component.ts index c0336b690a0..6ebb922a8f0 100644 --- a/projects/igniteui-angular/src/lib/slider/label/thumb-label.component.ts +++ b/projects/igniteui-angular/src/lib/slider/label/thumb-label.component.ts @@ -1,4 +1,4 @@ -import { Component, NgModule, Input, TemplateRef, HostBinding, ElementRef } from '@angular/core'; +import { Component, Input, TemplateRef, HostBinding, ElementRef } from '@angular/core'; import { SliderHandle } from '../slider.common'; @Component({ diff --git a/projects/igniteui-angular/src/lib/slider/slider.common.ts b/projects/igniteui-angular/src/lib/slider/slider.common.ts index 841a62ba9a7..94a77d543fe 100644 --- a/projects/igniteui-angular/src/lib/slider/slider.common.ts +++ b/projects/igniteui-angular/src/lib/slider/slider.common.ts @@ -73,16 +73,16 @@ export enum SliderHandle { * Slider Tick labels Orientation */ export enum TickLabelsOrientation { - horizontal, - toptobottom, - bottomtotop + Horizontal, + TopToBottom, + BottomToTop } /** * Slider Ticks orientation */ export enum TicksOrientation { - top, - bottom, - mirror + Top, + Bottom, + Mirror } diff --git a/projects/igniteui-angular/src/lib/slider/slider.component.spec.ts b/projects/igniteui-angular/src/lib/slider/slider.component.spec.ts index aa077ab64e9..f6983956e18 100644 --- a/projects/igniteui-angular/src/lib/slider/slider.component.spec.ts +++ b/projects/igniteui-angular/src/lib/slider/slider.component.spec.ts @@ -1400,7 +1400,7 @@ describe('IgxSlider', () => { expect(ticksTop).toBeNull(); fixture.componentInstance.showTicks = true; - fixture.componentInstance.ticksOrientation = TicksOrientation.mirror; + fixture.componentInstance.ticksOrientation = TicksOrientation.Mirror; fixture.detectChanges(); ticks = fixture.debugElement.nativeElement.querySelector(SLIDER_TICKS_ELEMENT); @@ -1470,7 +1470,7 @@ describe('IgxSlider', () => { expect(bottomTicks).not.toBeNull(); - fixture.componentInstance.ticksOrientation = TicksOrientation.top; + fixture.componentInstance.ticksOrientation = TicksOrientation.Top; fixture.detectChanges(); let topTIcks = fixture.debugElement.nativeElement.querySelector(SLIDER_TICKS_TOP_ELEMENT); @@ -1479,7 +1479,7 @@ describe('IgxSlider', () => { expect(topTIcks).not.toBeNull(); expect(bottomTicks).toBeNull(); - fixture.componentInstance.ticksOrientation = TicksOrientation.mirror; + fixture.componentInstance.ticksOrientation = TicksOrientation.Mirror; fixture.detectChanges(); topTIcks = fixture.debugElement.nativeElement.querySelector(SLIDER_TICKS_TOP_ELEMENT); @@ -1499,7 +1499,7 @@ describe('IgxSlider', () => { expect(labelsBottomTop).toBeNull(); expect(labelsTopBottom).toBeNull(); - fixture.componentInstance.tickLabelsOrientation = TickLabelsOrientation.bottomtotop; + fixture.componentInstance.tickLabelsOrientation = TickLabelsOrientation.BottomToTop; fixture.detectChanges(); labelsBottomTop = nativeElem.querySelector(BOTTOM_TO_TOP_TICK_LABLES); @@ -1507,7 +1507,7 @@ describe('IgxSlider', () => { expect(labelsBottomTop).not.toBeNull(); expect(labelsTopBottom).toBeNull(); - fixture.componentInstance.tickLabelsOrientation = TickLabelsOrientation.toptobottom; + fixture.componentInstance.tickLabelsOrientation = TickLabelsOrientation.TopToBottom; fixture.detectChanges(); labelsBottomTop = nativeElem.querySelector(BOTTOM_TO_TOP_TICK_LABLES); @@ -1596,10 +1596,10 @@ export class SliderTicksComponent { public primaryTicks = 0; public secondaryTicks = 0; public showTicks = true; - public ticksOrientation = TicksOrientation.bottom; + public ticksOrientation = TicksOrientation.Bottom; public primaryTickLabels = true; public secondaryTickLabels = true; - public tickLabelsOrientation = TickLabelsOrientation.horizontal; + public tickLabelsOrientation = TickLabelsOrientation.Horizontal; } @Component({ selector: 'igx-slider-test-component', diff --git a/projects/igniteui-angular/src/lib/slider/slider.component.ts b/projects/igniteui-angular/src/lib/slider/slider.component.ts index 4f752bc0709..49179a5fb14 100644 --- a/projects/igniteui-angular/src/lib/slider/slider.component.ts +++ b/projects/igniteui-angular/src/lib/slider/slider.component.ts @@ -10,16 +10,13 @@ import { ViewChildren, QueryList, ChangeDetectorRef, - AfterContentChecked, - NgZone, OnChanges } from '@angular/core'; import { ControlValueAccessor, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms'; import { EditorProvider } from '../core/edit-provider'; -import { DeprecateProperty } from '../core/deprecateDecorators'; import { IgxSliderThumbComponent } from './thumb/thumb-slider.component'; -import { Subject, merge, Observable, timer } from 'rxjs'; -import { takeUntil, retry } from 'rxjs/operators'; +import { Subject, merge, Observable, timer, pipe } from 'rxjs'; +import { takeUntil, throttleTime } from 'rxjs/operators'; import { SliderHandle, IgxThumbFromTemplateDirective, IgxThumbToTemplateDirective, @@ -33,7 +30,7 @@ import { SliderHandle, import { IgxThumbLabelComponent } from './label/thumb-label.component'; import { IgxTicksComponent } from './ticks/ticks.component'; import { IgxTickLabelsPipe } from './ticks/tick.pipe'; -import { HammerModule } from '@angular/platform-browser'; +import { resizeObservable } from '../core/utils'; const noop = () => { }; @@ -65,7 +62,6 @@ export class IgxSliderComponent implements EditorProvider, OnInit, AfterViewInit, - AfterContentChecked, OnChanges, OnDestroy { @@ -95,7 +91,6 @@ export class IgxSliderComponent implements private _destroyer$ = new Subject(); private _indicatorsDestroyer$ = new Subject(); private _indicatorsTimer: Observable; - private _onTypeChanged: Subject = new Subject(); private _onChangeCallback: (_: any) => void = noop; private _onTouchedCallback: () => void = noop; @@ -260,9 +255,6 @@ export class IgxSliderComponent implements if (this._hasViewInit) { this.updateTrack(); } - - this._cdr.detectChanges(); - this._onTypeChanged.next(type); } /** @@ -293,7 +285,7 @@ export class IgxSliderComponent implements this._pMin = this.valueToFraction(this.lowerBound, 0, 1); this.stepDistance = this.calculateStepDistance(); - this.positionHandlesAndUpdateTrack(); + this.positionHandlersAndUpdateTrack(); if (this._hasViewInit) { this.setTickInterval(); @@ -329,8 +321,8 @@ export class IgxSliderComponent implements public set step(step: number) { this._step = step; + this.stepDistance = this.calculateStepDistance(); if (this._hasViewInit) { - this.stepDistance = this.calculateStepDistance(); this.normalizeByStep(this.value); this.setTickInterval(); } @@ -409,30 +401,6 @@ export class IgxSliderComponent implements } } - /** - * Returns if the {@link IgxSliderComponent} is set as continuous. - * ```typescript - * @ViewChild("slider2") - * public slider: IgxSliderComponent; - * ngAfterViewInit(){ - * let continuous = this.slider.continuous; - * } - * ``` - */ - @Input() - @DeprecateProperty(`IgxSliderComponent \`isContinuous\` property is deprecated.\nUse \`continuous\` instead.`) - public get isContinuous(): boolean { - return this.continuous; - } - - /** - * @hidden - * @internal - */ - public set isContinuous(continuous: boolean) { - this.continuous = continuous; - } - /** *Returns the minimal value of the `IgxSliderComponent`. *```typescript @@ -475,7 +443,7 @@ export class IgxSliderComponent implements this._pMin = 0; // Recalculate step distance. this.stepDistance = this.calculateStepDistance(); - this.positionHandlesAndUpdateTrack(); + this.positionHandlersAndUpdateTrack(); if (this._hasViewInit) { this.setTickInterval(); } @@ -521,7 +489,7 @@ export class IgxSliderComponent implements this._pMax = 1; // recalculate step distance. this.stepDistance = this.calculateStepDistance(); - this.positionHandlesAndUpdateTrack(); + this.positionHandlersAndUpdateTrack(); if (this._hasViewInit) { this.setTickInterval(); } @@ -562,7 +530,7 @@ export class IgxSliderComponent implements // Refresh min travel zone. this._pMin = this.valueToFraction(this._lowerBound, 0, 1); - this.positionHandlesAndUpdateTrack(); + this.positionHandlersAndUpdateTrack(); } /** @@ -599,7 +567,7 @@ export class IgxSliderComponent implements this._upperBound = this.valueInRange(value, this.minValue, this.maxValue); // Refresh time travel zone. this._pMax = this.valueToFraction(this._upperBound, 0, 1); - this.positionHandlesAndUpdateTrack(); + this.positionHandlersAndUpdateTrack(); } /** @@ -653,7 +621,7 @@ export class IgxSliderComponent implements this._onChangeCallback(this.value); if (this._hasViewInit) { - this.positionHandlesAndUpdateTrack(); + this.positionHandlersAndUpdateTrack(); } } @@ -705,7 +673,7 @@ export class IgxSliderComponent implements * ``` */ public set secondaryTicks(val: number) { - if (val <= 1 ) { + if (val < 1 ) { return; } @@ -749,7 +717,7 @@ export class IgxSliderComponent implements * ``` */ @Input() - public ticksOrientation: TicksOrientation = TicksOrientation.bottom; + public ticksOrientation: TicksOrientation = TicksOrientation.Bottom; /** * Changes tick labels rotation: @@ -761,14 +729,14 @@ export class IgxSliderComponent implements * ``` */ @Input() - public tickLabelsOrientation = TickLabelsOrientation.horizontal; + public tickLabelsOrientation = TickLabelsOrientation.Horizontal; /** * @hidden */ public get deactivateThumbLabel() { return ((this.primaryTicks && this.primaryTickLabels) || (this.secondaryTicks && this.secondaryTickLabels)) && - (this.ticksOrientation === TicksOrientation.top || this.ticksOrientation === TicksOrientation.mirror); + (this.ticksOrientation === TicksOrientation.Top || this.ticksOrientation === TicksOrientation.Mirror); } /** @@ -983,16 +951,16 @@ export class IgxSliderComponent implements * @hidden */ public get showTopTicks() { - return this.ticksOrientation === TicksOrientation.top || - this.ticksOrientation === TicksOrientation.mirror; + return this.ticksOrientation === TicksOrientation.Top || + this.ticksOrientation === TicksOrientation.Mirror; } /** * @hidden */ public get showBottomTicks() { - return this.ticksOrientation === TicksOrientation.bottom || - this.ticksOrientation === TicksOrientation.mirror; + return this.ticksOrientation === TicksOrientation.Bottom || + this.ticksOrientation === TicksOrientation.Mirror; } /** @@ -1019,37 +987,30 @@ export class IgxSliderComponent implements */ public ngAfterViewInit() { this._hasViewInit = true; - this.positionHandlesAndUpdateTrack(); + this.positionHandlersAndUpdateTrack(); this.setTickInterval(); this.changeThumbFocusableState(this.disabled); this.subscribeTo(this.thumbFrom, this.thumbChanged.bind(this)); this.subscribeTo(this.thumbTo, this.thumbChanged.bind(this)); - // Implementing a workaround in regards of the following bug: https://github.com/angular/angular/issues/30088 - // this.thumbs.changes.pipe(takeUntil(this._destroyer$)).subscribe(change => { - // const thumbFrom = change.find((thumb: IgxSliderThumbComponent) => thumb.type === SliderHandle.FROM); - // const labelFrom = this.labelRefs.find((label: IgxThumbLabelComponent) => label.type === SliderHandle.FROM); - // this.positionHandle(thumbFrom, labelFrom, this.lowerValue); - // // this.subscribeTo(thumbFrom, this.thumbChanged.bind(this)); - // this.changeThumbFocusableState(this.disabled); - // }); - - this._onTypeChanged.pipe(takeUntil(this._destroyer$)).subscribe((type: SliderType) => { - const thumbFrom = this.thumbs.find((thumb: IgxSliderThumbComponent) => thumb.type === SliderHandle.FROM); - const labelFrom = this.labelRefs.find((label: IgxThumbLabelComponent) => label.type === SliderHandle.FROM); - this.positionHandle(thumbFrom, labelFrom, this.lowerValue); + this.thumbs.changes.pipe(takeUntil(this._destroyer$)).subscribe(change => { + const thumbFrom = change.find((thumb: IgxSliderThumbComponent) => thumb.type === SliderHandle.FROM); + this.positionHandler(thumbFrom, null, this.lowerValue); this.subscribeTo(thumbFrom, this.thumbChanged.bind(this)); this.changeThumbFocusableState(this.disabled); }); - } - /** - * @hidden - */ - public ngAfterContentChecked() { - // Calculates the distance between every step in pixels. - this.stepDistance = this.calculateStepDistance(); + this.labelRefs.changes.pipe(takeUntil(this._destroyer$)).subscribe(change => { + const labelFrom = this.labelRefs.find((label: IgxThumbLabelComponent) => label.type === SliderHandle.FROM); + this.positionHandler(null, labelFrom, this.lowerValue); + }); + + resizeObservable(this._el.nativeElement).pipe( + throttleTime(40), + takeUntil(this._destroyer$)).subscribe(() => { + this.stepDistance = this.calculateStepDistance(); + }); } /** @@ -1105,9 +1066,9 @@ export class IgxSliderComponent implements // Update To/From Values this.onPan.next(mouseX); - // Finally do positionHandlesAndUpdateTrack the DOM + // Finally do positionHandlersAndUpdateTrack the DOM // based on data values - this.positionHandlesAndUpdateTrack(); + this.positionHandlersAndUpdateTrack(); this._onTouchedCallback(); } @@ -1235,7 +1196,7 @@ export class IgxSliderComponent implements )` : interval; } - private positionHandle(thumbHandle: ElementRef, labelHandle: ElementRef, position: number) { + private positionHandler(thumbHandle: ElementRef, labelHandle: ElementRef, position: number) { const positionLeft = `${this.valueToFraction(position) * 100}%`; if (thumbHandle) { @@ -1247,12 +1208,12 @@ export class IgxSliderComponent implements } } - private positionHandlesAndUpdateTrack() { + private positionHandlersAndUpdateTrack() { if (!this.isRange) { - this.positionHandle(this.thumbTo, this.labelTo, this.value as number); + this.positionHandler(this.thumbTo, this.labelTo, this.value as number); } else { - this.positionHandle(this.thumbTo, this.labelTo, (this.value as IRangeSliderValue).upper); - this.positionHandle(this.thumbFrom, this.labelFrom, (this.value as IRangeSliderValue).lower); + this.positionHandler(this.thumbTo, this.labelTo, (this.value as IRangeSliderValue).upper); + this.positionHandler(this.thumbFrom, this.labelFrom, (this.value as IRangeSliderValue).lower); } if (this._hasViewInit) { diff --git a/projects/igniteui-angular/src/lib/slider/ticks/ticks.component.ts b/projects/igniteui-angular/src/lib/slider/ticks/ticks.component.ts index 32cb997dd57..78be769edf0 100644 --- a/projects/igniteui-angular/src/lib/slider/ticks/ticks.component.ts +++ b/projects/igniteui-angular/src/lib/slider/ticks/ticks.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, ElementRef, AfterViewInit, TemplateRef, HostBinding } from '@angular/core'; +import { Component, Input, TemplateRef, HostBinding } from '@angular/core'; import { TicksOrientation, TickLabelsOrientation } from '../slider.common'; /** @@ -53,7 +53,7 @@ export class IgxTicksComponent { */ @HostBinding('class.igx-slider__ticks--top') public get ticksTopClass() { - return this.ticksOrientation === TicksOrientation.top; + return this.ticksOrientation === TicksOrientation.Top; } /** @@ -69,7 +69,7 @@ export class IgxTicksComponent { */ @HostBinding('class.igx-slider__tick-labels--top-bottom') public get labelsTopToBottomClass() { - return this.tickLabelsOrientation === TickLabelsOrientation.toptobottom; + return this.tickLabelsOrientation === TickLabelsOrientation.TopToBottom; } /** @@ -77,7 +77,7 @@ export class IgxTicksComponent { */ @HostBinding('class.igx-slider__tick-labels--bottom-top') public get labelsBottomToTopClass() { - return this.tickLabelsOrientation === TickLabelsOrientation.bottomtotop; + return this.tickLabelsOrientation === TickLabelsOrientation.BottomToTop; } /** diff --git a/src/app/card/card.sample.html b/src/app/card/card.sample.html index 810d80d364d..679335fa787 100644 --- a/src/app/card/card.sample.html +++ b/src/app/card/card.sample.html @@ -75,7 +75,7 @@
{{ cards[9].subtitle }}
- +
08:00 12:00 diff --git a/src/app/slider/slider.sample.html b/src/app/slider/slider.sample.html index f4126fc30ed..0cf41f6d190 100644 --- a/src/app/slider/slider.sample.html +++ b/src/app/slider/slider.sample.html @@ -1,45 +1,20 @@ - +

Slider

-
- - - -
-
- - - - - - -
- - +
+

Slider ticks

+ + +
+
+

Slider ticks

+ + + {{ tickLabel(value, primary, idx, labels) }} + + +
+
- - +
+
+

Slider ticks

+ + + + + + + +
+ +
diff --git a/src/app/slider/slider.sample.scss b/src/app/slider/slider.sample.scss index f5390cd2e0c..b10a252012e 100644 --- a/src/app/slider/slider.sample.scss +++ b/src/app/slider/slider.sample.scss @@ -17,13 +17,13 @@ padding-top: 10px; } -.sample-component { - position: relative; - width: 100%; - padding-top: 70px; +.sample-column { + padding-top: 50px; } -igx-slider { - width: 80%; - margin: 50px auto; +.slider-ticks-btns h4 { + padding: 15px; +} +.slider-ticks-btns button { + margin: 10px; } diff --git a/src/app/slider/slider.sample.ts b/src/app/slider/slider.sample.ts index 71e59b1f319..9a5929874b7 100644 --- a/src/app/slider/slider.sample.ts +++ b/src/app/slider/slider.sample.ts @@ -20,8 +20,8 @@ export class SliderSampleComponent { private _lowerValue: Date; private _upperValue: Date; - public labelOrientaion = TickLabelsOrientation.horizontal; - public ticksOrientation = TicksOrientation.bottom; + public labelOrientaion = TickLabelsOrientation.Horizontal; + public ticksOrientation = TicksOrientation.Bottom; public primaryTickLabels = true; public secondaryTickLabels = true; public sliderType: SliderType = SliderType.RANGE; @@ -62,26 +62,26 @@ export class SliderSampleComponent { } public changeLabels() { - this.labels = new Array('asd', 'bsd'); + this.labels = new Array('08:00', '12:00', '16:00', '20:00', '00:00'); } public changeLabelOrientation() { - if (this.labelOrientaion === TickLabelsOrientation.horizontal) { - this.labelOrientaion = TickLabelsOrientation.toptobottom; - } else if(this.labelOrientaion === TickLabelsOrientation.toptobottom) { - this.labelOrientaion = TickLabelsOrientation.bottomtotop; + if (this.labelOrientaion === TickLabelsOrientation.Horizontal) { + this.labelOrientaion = TickLabelsOrientation.TopToBottom; + } else if(this.labelOrientaion === TickLabelsOrientation.TopToBottom) { + this.labelOrientaion = TickLabelsOrientation.BottomToTop; } else { - this.labelOrientaion = TickLabelsOrientation.horizontal; + this.labelOrientaion = TickLabelsOrientation.Horizontal; } } public changeTicksOrientation() { - if (this.ticksOrientation === TicksOrientation.mirror) { - this.ticksOrientation = TicksOrientation.top; - } else if (this.ticksOrientation === TicksOrientation.top) { - this.ticksOrientation = TicksOrientation.bottom; + if (this.ticksOrientation === TicksOrientation.Mirror) { + this.ticksOrientation = TicksOrientation.Top; + } else if (this.ticksOrientation === TicksOrientation.Top) { + this.ticksOrientation = TicksOrientation.Bottom; } else { - this.ticksOrientation = TicksOrientation.mirror; + this.ticksOrientation = TicksOrientation.Mirror; } }