diff --git a/CHANGELOG.md b/CHANGELOG.md
index 7d22d40ebe8..987e4040046 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -62,6 +62,8 @@ All notable changes for each version of this project will be documented in this
- `indicatorsOrientation` input is added, which can be used to set the position of indicators it can be top or bottom
- `animationType` input is added, which can be used to set animation when changing slides
- `indicatorTemplate` directive is added, which can be used to provide a custom indicator for carousel. If this property is not provided, a default indicator template will be used instead.
+ - `nextButtonTemplate` directive is added, which is used to provide a custom next button template. If not provided, a default next button is used.
+ - `prevButtonTemplate` directive is added, which is used to provide a custom previous button template. If not provided, a default previous button is used.
## 8.2.6
diff --git a/projects/igniteui-angular/src/lib/carousel/README.md b/projects/igniteui-angular/src/lib/carousel/README.md
index 1121334bfe1..e8770a77810 100644
--- a/projects/igniteui-angular/src/lib/carousel/README.md
+++ b/projects/igniteui-angular/src/lib/carousel/README.md
@@ -42,16 +42,40 @@ Keyboard navigation will be enabled when the **IgxCarousel** component is focuse
- `End` will focus the last slide inside the carousel view.
### Templates
-The **IgxCarousel** supports templating of its indicators
+The **IgxCarousel** supports templating indicators and navigation buttons
#### Defining item template:
```html
...
-
- brightness_7
- brightness_5
-
+
+ brightness_7
+ brightness_5
+
+
+```
+
+#### Defining next button template:
+```html
+
+ ...
+
+
+ add
+
+
+
+```
+
+#### Defining previous button template:
+```html
+
+ ...
+
+
+ remove
+
+
```
diff --git a/projects/igniteui-angular/src/lib/carousel/carousel.component.html b/projects/igniteui-angular/src/lib/carousel/carousel.component.html
index 4a42a238f33..906322b8429 100644
--- a/projects/igniteui-angular/src/lib/carousel/carousel.component.html
+++ b/projects/igniteui-angular/src/lib/carousel/carousel.component.html
@@ -5,6 +5,22 @@
+
+
+ arrow_forward
+
+
+
+
+
+ arrow_back
+
+
+
-
-
- arrow_back
-
-
- arrow_forward
-
-
+
+
+
+
+
+
+
+
+
diff --git a/projects/igniteui-angular/src/lib/carousel/carousel.component.spec.ts b/projects/igniteui-angular/src/lib/carousel/carousel.component.spec.ts
index 85d30855bba..e59ba0809b6 100644
--- a/projects/igniteui-angular/src/lib/carousel/carousel.component.spec.ts
+++ b/projects/igniteui-angular/src/lib/carousel/carousel.component.spec.ts
@@ -515,7 +515,7 @@ describe('Carousel', () => {
});
describe('Templates Tests: ', () => {
- it('verify that template can be defined in the markup', () => {
+ it('verify that templates can be defined in the markup', () => {
fixture = TestBed.createComponent(CarouselTemplateSetInMarkupTestComponent);
carousel = fixture.componentInstance.carousel;
fixture.detectChanges();
@@ -526,9 +526,15 @@ describe('Carousel', () => {
const indicator = HelperTestFunctions.getIndicators(fixture)[index] as HTMLElement;
expect(indicator.innerText).toEqual(index.toString());
}
+
+ expect(HelperTestFunctions.getNextButtonArrow(fixture)).toBeNull();
+ expect(HelperTestFunctions.getPreviousButtonArrow(fixture)).toBeNull();
+
+ expect(HelperTestFunctions.getNextButton(fixture).innerText).toEqual('next');
+ expect(HelperTestFunctions.getPreviousButton(fixture).innerText).toEqual('prev');
});
- it('verify that template can be changed', () => {
+ it('verify that templates can be changed', () => {
fixture = TestBed.createComponent(CarouselTemplateSetInTypescriptTestComponent);
carousel = fixture.componentInstance.carousel;
fixture.detectChanges();
@@ -538,8 +544,12 @@ describe('Carousel', () => {
expect(HelperTestFunctions.getIndicators(fixture).length).toBe(4);
expect(HelperTestFunctions.getIndicatorsDots(fixture).length).toBe(4);
+ expect(HelperTestFunctions.getNextButtonArrow(fixture)).toBeDefined();
+ expect(HelperTestFunctions.getPreviousButtonArrow(fixture)).toBeDefined();
carousel.indicatorTemplate = fixture.componentInstance.customIndicatorTemplate1;
+ carousel.nextButtonTemplate = fixture.componentInstance.customNextTemplate;
+ carousel.prevButtonTemplate = fixture.componentInstance.customPrevTemplate;
fixture.detectChanges();
expect(HelperTestFunctions.getIndicators(fixture).length).toBe(4);
@@ -548,6 +558,11 @@ describe('Carousel', () => {
const indicator = HelperTestFunctions.getIndicators(fixture)[index] as HTMLElement;
expect(indicator.innerText).toEqual(index.toString());
}
+ expect(HelperTestFunctions.getNextButtonArrow(fixture)).toBeNull();
+ expect(HelperTestFunctions.getPreviousButtonArrow(fixture)).toBeNull();
+
+ expect(HelperTestFunctions.getNextButton(fixture).innerText).toEqual('next');
+ expect(HelperTestFunctions.getPreviousButton(fixture).innerText).toEqual('prev');
carousel.indicatorTemplate = fixture.componentInstance.customIndicatorTemplate2;
fixture.detectChanges();
@@ -565,10 +580,14 @@ describe('Carousel', () => {
}
carousel.indicatorTemplate = null;
+ carousel.nextButtonTemplate = null;
+ carousel.prevButtonTemplate = null;
fixture.detectChanges();
expect(HelperTestFunctions.getIndicators(fixture).length).toBe(4);
expect(HelperTestFunctions.getIndicatorsDots(fixture).length).toBe(4);
+ expect(HelperTestFunctions.getNextButtonArrow(fixture)).toBeDefined();
+ expect(HelperTestFunctions.getPreviousButtonArrow(fixture)).toBeDefined();
});
});
@@ -704,8 +723,8 @@ describe('Carousel', () => {
expect(carousel.total).toEqual(0);
expect(HelperTestFunctions.getIndicatorsContainer(fixture)).toBeNull();
expect(HelperTestFunctions.getIndicatorsContainer(fixture, CarouselIndicatorsOrientation.top)).toBeNull();
- expect(HelperTestFunctions.getNextButton(fixture).hidden).toBeTruthy();
- expect(HelperTestFunctions.getPreviousButton(fixture).hidden).toBeTruthy();
+ expect(HelperTestFunctions.getNextButton(fixture)).toBeNull();
+ expect(HelperTestFunctions.getPreviousButton(fixture)).toBeNull();
// add a slide
fixture.componentInstance.addSlides();
@@ -724,6 +743,7 @@ describe('Carousel', () => {
class HelperTestFunctions {
public static NEXT_BUTTON_CLASS = '.igx-carousel__arrow--next';
public static PRIV_BUTTON_CLASS = '.igx-carousel__arrow--prev';
+ public static BUTTON_ARROW_CLASS = '.igx-nav-arrow';
public static ACTIVE_SLIDE_CLASS = 'igx-slide--current';
public static PREVIOUS_SLIDE_CLASS = 'igx-slide--previous';
public static INDICATORS_TOP_CLASS = '.igx-carousel-indicators--top';
@@ -741,6 +761,16 @@ class HelperTestFunctions {
return fixture.nativeElement.querySelector(HelperTestFunctions.PRIV_BUTTON_CLASS);
}
+ public static getNextButtonArrow(fixture): HTMLElement {
+ const next = HelperTestFunctions.getNextButton(fixture);
+ return next.querySelector(HelperTestFunctions.BUTTON_ARROW_CLASS);
+ }
+
+ public static getPreviousButtonArrow(fixture): HTMLElement {
+ const prev = HelperTestFunctions.getPreviousButton(fixture);
+ return prev.querySelector(HelperTestFunctions.BUTTON_ARROW_CLASS);
+ }
+
public static getIndicatorsContainer(fixture, position = CarouselIndicatorsOrientation.bottom): HTMLElement {
const carouselNative = fixture.nativeElement;
if (position === CarouselIndicatorsOrientation.bottom) {
@@ -819,6 +849,14 @@ class CarouselAnimationsComponent {
{{slide.index}}
+
+
+ next
+
+
+
+ prev
+
`
})
@@ -837,6 +875,14 @@ class CarouselTemplateSetInMarkupTestComponent {
{{slide.index}}: Active
+
+ next
+
+
+
+ prev
+
+
Slide1
Slide2
@@ -851,6 +897,10 @@ class CarouselTemplateSetInTypescriptTestComponent {
public customIndicatorTemplate1;
@ViewChild('customIndicatorTemplate2', { read: TemplateRef, static: false })
public customIndicatorTemplate2;
+ @ViewChild('customNextTemplate', { read: TemplateRef, static: false })
+ public customNextTemplate;
+ @ViewChild('customPrevTemplate', { read: TemplateRef, static: false })
+ public customPrevTemplate;
}
@Component({
diff --git a/projects/igniteui-angular/src/lib/carousel/carousel.component.ts b/projects/igniteui-angular/src/lib/carousel/carousel.component.ts
index 7354c543edd..bd41cef0a96 100644
--- a/projects/igniteui-angular/src/lib/carousel/carousel.component.ts
+++ b/projects/igniteui-angular/src/lib/carousel/carousel.component.ts
@@ -23,7 +23,7 @@ import { IgxIconModule } from '../icon/index';
import { IBaseEventArgs } from '../core/utils';
import { Subject, merge } from 'rxjs';
import { takeUntil } from 'rxjs/operators';
-import { IgxCarouselIndicatorDirective } from './carousel.directives';
+import { IgxCarouselIndicatorDirective, IgxCarouselNextButtonDirective, IgxCarouselPrevButtonDirective } from './carousel.directives';
import { useAnimation, AnimationBuilder, AnimationPlayer, AnimationReferenceMetadata } from '@angular/animations';
import { slideInLeft, fadeIn, rotateInCenter } from '../animations/main';
import { IgxSlideComponent, Direction } from './slide.component';
@@ -40,8 +40,7 @@ export enum CarouselIndicatorsOrientation {
export enum CarouselAnimationType {
none = 'none',
slide = 'slide',
- fade = 'fade',
- grow = 'grow'
+ fade = 'fade'
}
export interface CarouselAnimationSettings {
@@ -248,7 +247,13 @@ export class IgxCarouselComponent implements OnDestroy, AfterContentInit {
}
@ViewChild('defaultIndicator', { read: TemplateRef, static: true })
- protected defaultIndicator: TemplateRef;
+ private defaultIndicator: TemplateRef;
+
+ @ViewChild('defaultNextButton', { read: TemplateRef, static: true })
+ private defaultNextButton: TemplateRef;
+
+ @ViewChild('defaultPrevButton', { read: TemplateRef, static: true })
+ private defaultPrevButton: TemplateRef;
/**
* The custom template, if any, that should be used when rendering carousel indicators
@@ -272,6 +277,52 @@ export class IgxCarouselComponent implements OnDestroy, AfterContentInit {
@ContentChild(IgxCarouselIndicatorDirective, { read: TemplateRef, static: false })
public indicatorTemplate: TemplateRef = null;
+ /**
+ * The custom template, if any, that should be used when rendering carousel next button
+ *
+ * ```typescript
+ * // Set in typescript
+ * const myCustomTemplate: TemplateRef = myComponent.customTemplate;
+ * myComponent.carousel.nextButtonTemplate = myCustomTemplate;
+ * ```
+ * ```html
+ *
+ *
+ * ...
+ *
+ *
+ * add
+ *
+ *
+ *
+ * ```
+ */
+ @ContentChild(IgxCarouselNextButtonDirective, { read: TemplateRef, static: false })
+ public nextButtonTemplate: TemplateRef = null;
+
+ /**
+ * The custom template, if any, that should be used when rendering carousel previous button
+ *
+ * ```typescript
+ * // Set in typescript
+ * const myCustomTemplate: TemplateRef = myComponent.customTemplate;
+ * myComponent.carousel.nextButtonTemplate = myCustomTemplate;
+ * ```
+ * ```html
+ *
+ *
+ * ...
+ *
+ *
+ * remove
+ *
+ *
+ *
+ * ```
+ */
+ @ContentChild(IgxCarouselPrevButtonDirective, { read: TemplateRef, static: false })
+ public prevButtonTemplate: TemplateRef = null;
+
/**
* The collection of `slides` currently in the carousel.
* ```typescript
@@ -545,6 +596,26 @@ export class IgxCarouselComponent implements OnDestroy, AfterContentInit {
return this.defaultIndicator;
}
+ /**
+ * @hidden
+ */
+ public get getNextButtonTemplate(): TemplateRef {
+ if (this.nextButtonTemplate) {
+ return this.nextButtonTemplate;
+ }
+ return this.defaultNextButton;
+ }
+
+ /**
+ * @hidden
+ */
+ public get getPrevButtonTemplate(): TemplateRef {
+ if (this.prevButtonTemplate) {
+ return this.prevButtonTemplate;
+ }
+ return this.defaultPrevButton;
+ }
+
/**
* @hidden
* @memberof IgxCarouselComponent
@@ -785,6 +856,22 @@ export class IgxCarouselComponent implements OnDestroy, AfterContentInit {
}, this.interval);
}
}
+
+ /**
+ *@hidden
+ */
+ public get nextButtonDisabled() {
+ return !this.loop && this.current === (this.total - 1);
+ }
+
+ /**
+ *@hidden
+ */
+ public get prevButtonDisabled() {
+ return !this.loop && this.current === 0;
+ }
+
+
/**
*@hidden
*/
@@ -894,8 +981,20 @@ export interface ISlideEventArgs extends IBaseEventArgs {
* @hidden
*/
@NgModule({
- declarations: [IgxCarouselComponent, IgxSlideComponent, IgxCarouselIndicatorDirective],
- exports: [IgxCarouselComponent, IgxSlideComponent, IgxCarouselIndicatorDirective],
+ declarations: [
+ IgxCarouselComponent,
+ IgxSlideComponent,
+ IgxCarouselIndicatorDirective,
+ IgxCarouselNextButtonDirective,
+ IgxCarouselPrevButtonDirective
+ ],
+ exports: [
+ IgxCarouselComponent,
+ IgxSlideComponent,
+ IgxCarouselIndicatorDirective,
+ IgxCarouselNextButtonDirective,
+ IgxCarouselPrevButtonDirective
+ ],
imports: [CommonModule, IgxIconModule]
})
export class IgxCarouselModule {
diff --git a/projects/igniteui-angular/src/lib/carousel/carousel.directives.ts b/projects/igniteui-angular/src/lib/carousel/carousel.directives.ts
index db5c492da1d..ea26c4a5e93 100644
--- a/projects/igniteui-angular/src/lib/carousel/carousel.directives.ts
+++ b/projects/igniteui-angular/src/lib/carousel/carousel.directives.ts
@@ -5,3 +5,15 @@ import { Directive, TemplateRef } from '@angular/core';
})
export class IgxCarouselIndicatorDirective {
}
+
+@Directive({
+ selector: '[igxCarouselNextButton]'
+})
+export class IgxCarouselNextButtonDirective {
+}
+
+@Directive({
+ selector: '[igxCarouselPrevButton]'
+})
+export class IgxCarouselPrevButtonDirective {
+}
diff --git a/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-component.scss b/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-component.scss
index 16acc4c6a70..854f4d618aa 100644
--- a/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-component.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-component.scss
@@ -28,7 +28,7 @@
}
/// @access private
-@mixin _igx-carousel-naviation-partial {
+@mixin _igx-carousel-navigation-partial {
@include b(igx-nav-dot) {
@extend %igx-nav-dot !optional;
@@ -36,6 +36,18 @@
@extend %igx-nav-dot--active !optional;
}
}
+
+ @include b(igx-nav-arrow) {
+ @extend %igx-nav-arrow !optional;
+
+ @include m(disabled) {
+ @extend %igx-nav-arrow--disabled !optional;
+ }
+
+ &:hover {
+ @extend %igx-nav-arrow--hover !optional;
+ }
+ }
}
/// @access private
@@ -75,23 +87,15 @@
@include e(arrow, $m: prev) {
@extend %igx-carousel-arrow !optional;
@extend %igx-carousel-arrow--prev !optional;
-
- &:hover {
- @extend %igx-carousel-arrow--hover !optional;
- }
}
@include e(arrow, $m: next) {
@extend %igx-carousel-arrow !optional;
@extend %igx-carousel-arrow--next !optional;
-
- &:hover {
- @extend %igx-carousel-arrow--hover !optional;
- }
}
@include _igx-carousel-indicators-partial();
- @include _igx-carousel-naviation-partial();
+ @include _igx-carousel-navigation-partial();
@include _igx-carousel-slide-partial();
}
diff --git a/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-theme.scss b/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-theme.scss
index 88bdf1ffe95..9c3ed411d72 100644
--- a/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-theme.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/components/carousel/_carousel-theme.scss
@@ -10,8 +10,10 @@
/// @param {Color} $slide-background [null] - The slide background color.
/// @param {Color} $button-background [null] - The previous/next buttons idle background color.
/// @param {Color} $button-hover-background [null] - The previous/next buttons hover background color.
+/// @param {Color} $button-disabled-background [null] - The previous/next buttons disabled background color.
/// @param {Color} $button-arrow-color [null] - The previous/next buttons idle arrow color.
/// @param {Color} $button-hover-arrow-color [null] - The previous/next buttons hover arrow color.
+/// @param {Color} $button-disabled-arrow-color [null] - The previous/next buttons disabled arrow color.
/// @param {Color} $indicator-dot-color [null] - The active indicator dot color.
/// @param {Color} $indicator-border-color [null] - The idle indicator border color.
/// @param {Color} $indicator-active-border-color [null] - The active indicator border color.
@@ -47,8 +49,10 @@
$button-background: null,
$button-hover-background: null,
+ $button-disabled-background: null,
$button-arrow-color: null,
$button-hover-arrow-color: null,
+ $button-disabled-arrow-color: null,
$indicator-dot-color: null,
$indicator-border-color: null,
@@ -82,6 +86,10 @@
$button-hover-arrow-color: text-contrast($button-hover-background);
}
+ @if not($button-disabled-arrow-color) and $button-disabled-background {
+ $button-disabled-arrow-color: rgba(text-contrast($button-disabled-background), .3);
+ }
+
@return extend($theme, (
name: $name,
palette: $palette,
@@ -92,9 +100,11 @@
button-shadow: $button-shadow,
button-background: $button-background,
+ button-disabled-background: $button-disabled-background,
button-hover-background: $button-hover-background,
button-arrow-color: $button-arrow-color,
button-hover-arrow-color: $button-hover-arrow-color,
+ button-disabled-arrow-color: $button-disabled-arrow-color,
indicator-dot-color: $indicator-dot-color,
indicator-border-color: $indicator-border-color,
@@ -136,16 +146,12 @@
flex-flow: column nowrap;
}
- %igx-carousel-arrow {
+ %igx-nav-arrow {
display: flex;
- margin: $carousel-arrow-margin;
- position: absolute;
justify-content: center;
align-items: center;
width: 46px;
height: 46px;
- top: 50%;
- transform: translateY(-50%);
cursor: pointer;
border-radius: 50%;
outline-style: none;
@@ -153,19 +159,34 @@
color: --var($theme, 'button-arrow-color');
background: --var($theme, 'button-background');
box-shadow: --var($theme, 'button-shadow');
- z-index: 3;
+ }
- span {
- display: flex;
- align-items: center;
+ %igx-nav-arrow--disabled {
+ background: --var($theme, 'button-disabled-background');
+ color: --var($theme, 'button-disabled-arrow-color');
+ pointer-events: none;
+ box-shadow: none;
+
+ igx-icon {
+ color: currentColor;
}
}
- %igx-carousel-arrow--hover {
+ %igx-nav-arrow--hover {
color: --var($theme, 'button-hover-arrow-color');
background: --var($theme, 'button-hover-background');
}
+ %igx-carousel-arrow {
+ margin: $carousel-arrow-margin;
+ position: absolute;
+ top: 50%;
+ transform: translateY(-50%);
+ z-index: 3;
+ outline: none;
+ user-select: none;
+ }
+
%igx-carousel-arrow--next {
#{$right}: 0;
}
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_carousel.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_carousel.scss
index 6a7ff4bbb42..524f6f40562 100644
--- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_carousel.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/dark/_carousel.scss
@@ -10,10 +10,20 @@
/// @prop {Color} slide-background [#222] - The slide background color.
/// @prop {Color} button-background [#222] - The previous/next buttons idle background color.
/// @prop {Color} button-hover-background [#222] - The previous/next buttons hover background color.
+/// @prop {Map} button-disabled-background [igx-color: ('grays', 100), hexrgba: (#222)] - The previous/next buttons disabled background color.
+/// @prop {Map} button-disabled-arrow-color [igx-color: ('grays' 400), hexrgba: (#222)] - The previous/next buttons disabled color.
$_base-dark-carousel: (
slide-background: #222,
button-background: #222,
button-hover-background: #222,
+ button-disabled-background: (
+ igx-color: ('grays', 100),
+ hexrgba: (#222)
+ ),
+ button-disabled-arrow-color: (
+ igx-color: ('grays' 400),
+ hexrgba: (#222)
+ ),
);
/// Generates a dark carousel schema based on a mix of $_light-carousel and $_base-dark-carousel
diff --git a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_carousel.scss b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_carousel.scss
index 63870ab21c9..a629781222a 100644
--- a/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_carousel.scss
+++ b/projects/igniteui-angular/src/lib/core/styles/themes/schemas/light/_carousel.scss
@@ -12,8 +12,10 @@
/// @prop {Color} slide-background [#fff] - The slide background color.
/// @prop {Color} button-background [#fff] - The previous/next buttons idle background color.
/// @prop {Color} button-hover-background [#fff] - The previous/next buttons hover background color.
+/// @prop {Map} button-disabled-background [igx-color: ('grays', 100), hexrgba: ()] - The previous/next buttons disabled background color.
/// @prop {Map} button-arrow-color [igx-color: ('grays', 700)] - The previous/next buttons idle arrow color.
/// @prop {Map} button-hover-arrow-color [igx-color: ('grays', 900)] - The previous/next buttons hover arrow color.
+/// @prop {Map} button-disabled-arrow-color [igx-color: ('grays' 400)] - The previous/next buttons disabled color.
/// @prop {Color} indicator-dot-color [#fff] - The active indicator dot color.
/// @prop {Color} indicator-border-color [#fff] - The idle indicator border color.
/// @prop {Color} indicator-active-border-color [#fff] - The active indicator border color.
@@ -39,9 +41,18 @@ $_light-carousel: extend(
igx-color: ('grays', 900)
),
+ button-disabled-background: (
+ igx-color: ('grays', 100),
+ hexrgba: ()
+ ),
+
+ button-disabled-arrow-color: (
+ igx-color: ('grays' 400)
+ ),
+
indicator-dot-color: #fff,
indicator-border-color: #fff,
- indicator-active-border-color: #fff
+ indicator-active-border-color: #fff,
)
);
diff --git a/src/app/carousel/carousel.sample.html b/src/app/carousel/carousel.sample.html
index d94edb0c002..7dca81b7a6c 100644
--- a/src/app/carousel/carousel.sample.html
+++ b/src/app/carousel/carousel.sample.html
@@ -34,6 +34,18 @@ Desktop
+
+