diff --git a/cypress/full/carousel_page_spec.ts b/cypress/full/carousel_page_spec.ts
index 7affa4d3fe..a0246fc600 100644
--- a/cypress/full/carousel_page_spec.ts
+++ b/cypress/full/carousel_page_spec.ts
@@ -118,29 +118,30 @@ describe('Carousel page test suite', () => {
describe('Pause on hover ', () => {
const pauseOnHoverSlides = carousel.exampleDemosArr.pauseOnHover;
- it('example contains carousel component with slides, arrows and "Toggle pause on hover" button', () => {
+ it('example contains carousel component with slides, arrows', () => {
carousel.scrollToMenu('Pause on hover');
carousel.isCarouselHaveIndicatorsItemsCtrls(pauseOnHoverSlides);
carousel.isEachSlideHave(pauseOnHoverSlides, ['.item', '.carousel-caption', 'h3']);
- carousel.isBtnTxtEqual(pauseOnHoverSlides, 'Toggle pause on hover ');
});
- it('when user click on "Toggle pause on hover" and hover slide - then after 5 sec slide stay opened', () => {
+ it('when user hover slide - then after 5 sec slide stay opened', () => {
carousel.scrollToMenu('Pause on hover');
- carousel.clickOnBtn(pauseOnHoverSlides);
carousel.hoverSlide(pauseOnHoverSlides, 1);
carousel.isCarouselItemActive(pauseOnHoverSlides, 0);
cy.tick(6000);
carousel.isCarouselItemActive(pauseOnHoverSlides, 0);
});
- it('when user click on "Toggle pause on hover" again, hover slide - then after 5 sec slide changed', () => {
+ it('when user hover slide then move mouse out - then after 5 sec slide changed', () => {
carousel.scrollToMenu('Pause on hover');
- carousel.dblClickOnBtn(pauseOnHoverSlides);
carousel.hoverSlide(pauseOnHoverSlides, 1);
carousel.isCarouselItemActive(pauseOnHoverSlides, 0);
cy.tick(6000);
+ carousel.isCarouselItemActive(pauseOnHoverSlides, 0);
+ carousel.mouseLeave(pauseOnHoverSlides);
+ cy.tick(6000);
carousel.isCarouselItemActive(pauseOnHoverSlides, 1);
+
});
});
diff --git a/cypress/support/carousel.po.ts b/cypress/support/carousel.po.ts
index 9d7b580798..d08c551bef 100644
--- a/cypress/support/carousel.po.ts
+++ b/cypress/support/carousel.po.ts
@@ -16,7 +16,7 @@ export class CarouselPo extends BaseComponent {
optionalCaptions: 'demo-carousel-captions',
configuringDefaults: 'demo-carousel-config',
dynamicSlides: 'demo-carousel-dynamic',
- pauseOnHover: 'demo-carousel-no-pause',
+ pauseOnHover: 'demo-carousel-pause-on-hover',
customContent: 'demo-carousel-custom-content',
disableLooping: 'demo-carousel-disable-looping',
disableIndicator: 'demo-carousel-disable-indicator',
@@ -73,6 +73,10 @@ export class CarouselPo extends BaseComponent {
cy.get(`${baseSelector} ${this.carouselClass} div`).eq(slideIndex).trigger('mouseenter');
}
+ mouseLeave(baseSelector: string) {
+ cy.get(`${baseSelector} ${this.carouselClass}`).trigger('mouseleave');
+ }
+
isCarouselIndicatorDisabled(baseSelector: string, disabled: boolean) {
cy.get(`${baseSelector} ${this.carouselClass}`)
.should(disabled ? 'to.not.have.descendants' : 'to.have.descendants', this.indicatorClass)
diff --git a/demo/src/app/components/+carousel/carousel-section.list.ts b/demo/src/app/components/+carousel/carousel-section.list.ts
index a03ca7ba81..8319f8a5b9 100644
--- a/demo/src/app/components/+carousel/carousel-section.list.ts
+++ b/demo/src/app/components/+carousel/carousel-section.list.ts
@@ -2,7 +2,7 @@ import { DemoCarouseBasicComponent } from './demos/basic/basic';
import { DemoCarouselCaptionsComponent } from './demos/captions/captions';
import { DemoCarouselConfigComponent } from './demos/config/config';
import { DemoCarouselDynamicComponent } from './demos/dynamic/dynamic';
-import { DemoCarouselNoPauseComponent } from './demos/no-pause/no-pause';
+import { DemoCarouselPauseOnHoverComponent } from './demos/pause-on-hover/pause-on-hover';
import { DemoCarouselCustomContentComponent } from './demos/custom-content/custom-content';
import { DemoCarouselIntervalComponent } from './demos/interval/interval';
import { DemoCarouselDisableIndicatorComponent } from './demos/disable-indicator/disable-indicator';
@@ -20,6 +20,7 @@ import { ExamplesComponent } from '../../docs/demo-section-components/demo-examp
import { ApiSectionsComponent } from '../../docs/demo-section-components/demo-api-section/index';
import { NgApiDocComponent, NgApiDocConfigComponent } from '../../docs/api-docs';
+import { DemoCarouselPauseOnFocusComponent } from './demos/pause-on-focus/pause-on-focus';
export const demoComponentContent: ContentSection[] = [
{
@@ -69,10 +70,20 @@ export const demoComponentContent: ContentSection[] = [
{
title: 'Pause on hover',
anchor: 'pause-on-hover',
- description: `
Click button to pause on hover.
`,
- component: require('!!raw-loader!./demos/no-pause/no-pause.ts'),
- html: require('!!raw-loader!./demos/no-pause/no-pause.html'),
- outlet: DemoCarouselNoPauseComponent
+ description: `If noPause
is set to false
+ , carousel autoplay will be stopped when carousel receives hover.
`,
+ component: require('!!raw-loader!./demos/pause-on-hover/pause-on-hover.ts'),
+ html: require('!!raw-loader!./demos/pause-on-hover/pause-on-hover.html'),
+ outlet: DemoCarouselPauseOnHoverComponent
+ },
+ {
+ title: 'Pause on focus',
+ anchor: 'pause-on-focus',
+ description: `If pauseOnFocus
is set to true
+ , carousel autoplay will be stopped when carousel receives focus.
`,
+ component: require('!!raw-loader!./demos/pause-on-focus/pause-on-focus.ts'),
+ html: require('!!raw-loader!./demos/pause-on-focus/pause-on-focus.html'),
+ outlet: DemoCarouselPauseOnFocusComponent
},
{
title: 'Custom content',
diff --git a/demo/src/app/components/+carousel/demos/accessibility/accessibility.html b/demo/src/app/components/+carousel/demos/accessibility/accessibility.html
index 8e02305ca3..067c576cf2 100644
--- a/demo/src/app/components/+carousel/demos/accessibility/accessibility.html
+++ b/demo/src/app/components/+carousel/demos/accessibility/accessibility.html
@@ -1 +1,35 @@
The alt
attribute is meant to help users not miss any content, so make sure your text is helpful to anyone not seeing the image.
+
+Keyboard interaction
+
+
+
+
+
+ LEFT_ARROW
+
+ |
+
+ Move to a previous slide
+ |
+
+
+
+
+ RIGHT_ARROW
+
+ |
+
+ Move to a next slide
+ |
+
+
+
+ SPACE or ENTER
+ |
+
+ Move to a next slide
+ |
+
+
+
diff --git a/demo/src/app/components/+carousel/demos/index.ts b/demo/src/app/components/+carousel/demos/index.ts
index 494435ba90..2aa016ac11 100644
--- a/demo/src/app/components/+carousel/demos/index.ts
+++ b/demo/src/app/components/+carousel/demos/index.ts
@@ -2,7 +2,7 @@ import { DemoCarouselDynamicComponent } from './dynamic/dynamic';
import { DemoCarouseBasicComponent } from './basic/basic';
import { DemoCarouselCaptionsComponent } from './captions/captions';
import { DemoCarouselConfigComponent } from './config/config';
-import { DemoCarouselNoPauseComponent } from './no-pause/no-pause';
+import { DemoCarouselPauseOnHoverComponent } from './pause-on-hover/pause-on-hover';
import { DemoCarouselCustomContentComponent } from './custom-content/custom-content';
import { DemoCarouselIntervalComponent } from './interval/interval';
import { DemoCarouselDisableIndicatorComponent } from './disable-indicator/disable-indicator';
@@ -11,24 +11,30 @@ import { DemoCarouselSlideChangedEventComponent } from './slide-changed-event/sl
import { DemoCarouselMultilistComponent } from './multilist/multilist';
import { DemoCarouselMultilistSingleOffsetComponent } from './multilist-single-offset/multilist-single-offset';
import { DemoCarouselMultilistFromIndexComponent } from './multilist-from-index/multilist-from-index';
-import { DemoCarouselMultilistIndicatorsByChunkComponent } from './multilist-indicators-by-chunk/multilist-indicators-by-chunk';
+
+import {
+ DemoCarouselMultilistIndicatorsByChunkComponent
+} from './multilist-indicators-by-chunk/multilist-indicators-by-chunk';
+
import { DemoAccessibilityComponent } from './accessibility/accessibility';
+import { DemoCarouselPauseOnFocusComponent } from './pause-on-focus/pause-on-focus';
export const DEMO_COMPONENTS = [
- DemoCarouselDynamicComponent,
+ DemoAccessibilityComponent,
DemoCarouseBasicComponent,
DemoCarouselCaptionsComponent,
DemoCarouselConfigComponent,
- DemoCarouselNoPauseComponent,
DemoCarouselConfigComponent,
DemoCarouselCustomContentComponent,
- DemoCarouselIntervalComponent,
DemoCarouselDisableIndicatorComponent,
DemoCarouselDisableLoopingComponent,
- DemoCarouselSlideChangedEventComponent,
+ DemoCarouselDynamicComponent,
+ DemoCarouselIntervalComponent,
DemoCarouselMultilistComponent,
- DemoCarouselMultilistSingleOffsetComponent,
DemoCarouselMultilistFromIndexComponent,
DemoCarouselMultilistIndicatorsByChunkComponent,
- DemoAccessibilityComponent
+ DemoCarouselMultilistSingleOffsetComponent,
+ DemoCarouselPauseOnFocusComponent,
+ DemoCarouselPauseOnHoverComponent,
+ DemoCarouselSlideChangedEventComponent
];
diff --git a/demo/src/app/components/+carousel/demos/no-pause/no-pause.ts b/demo/src/app/components/+carousel/demos/no-pause/no-pause.ts
deleted file mode 100644
index 3b80c8dce2..0000000000
--- a/demo/src/app/components/+carousel/demos/no-pause/no-pause.ts
+++ /dev/null
@@ -1,9 +0,0 @@
-import { Component } from '@angular/core';
-
-@Component({
- selector: 'demo-carousel-no-pause',
- templateUrl: './no-pause.html'
-})
-export class DemoCarouselNoPauseComponent {
- noPause = true;
-}
diff --git a/demo/src/app/components/+carousel/demos/no-pause/no-pause.html b/demo/src/app/components/+carousel/demos/pause-on-focus/pause-on-focus.html
similarity index 84%
rename from demo/src/app/components/+carousel/demos/no-pause/no-pause.html
rename to demo/src/app/components/+carousel/demos/pause-on-focus/pause-on-focus.html
index 82b04bb1a4..e50724e98d 100644
--- a/demo/src/app/components/+carousel/demos/no-pause/no-pause.html
+++ b/demo/src/app/components/+carousel/demos/pause-on-focus/pause-on-focus.html
@@ -1,4 +1,4 @@
-
+
@@ -21,9 +21,3 @@
Third slide label
-
-
-
-
diff --git a/demo/src/app/components/+carousel/demos/pause-on-focus/pause-on-focus.ts b/demo/src/app/components/+carousel/demos/pause-on-focus/pause-on-focus.ts
new file mode 100644
index 0000000000..8a28b80f14
--- /dev/null
+++ b/demo/src/app/components/+carousel/demos/pause-on-focus/pause-on-focus.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'demo-carousel-pause-on-focus',
+ templateUrl: './pause-on-focus.html'
+})
+export class DemoCarouselPauseOnFocusComponent {}
diff --git a/demo/src/app/components/+carousel/demos/pause-on-hover/pause-on-hover.html b/demo/src/app/components/+carousel/demos/pause-on-hover/pause-on-hover.html
new file mode 100644
index 0000000000..8a014bb7a1
--- /dev/null
+++ b/demo/src/app/components/+carousel/demos/pause-on-hover/pause-on-hover.html
@@ -0,0 +1,23 @@
+
+
+
+
+
First slide label
+
Nulla vitae elit libero, a pharetra augue mollis interdum.
+
+
+
+
+
+
Second slide label
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
+
+
+
+
+
+
Third slide label
+
Praesent commodo cursus magna, vel scelerisque nisl consectetur.
+
+
+
diff --git a/demo/src/app/components/+carousel/demos/pause-on-hover/pause-on-hover.ts b/demo/src/app/components/+carousel/demos/pause-on-hover/pause-on-hover.ts
new file mode 100644
index 0000000000..1b1e5bc039
--- /dev/null
+++ b/demo/src/app/components/+carousel/demos/pause-on-hover/pause-on-hover.ts
@@ -0,0 +1,7 @@
+import { Component } from '@angular/core';
+
+@Component({
+ selector: 'demo-carousel-pause-on-hover',
+ templateUrl: './pause-on-hover.html'
+})
+export class DemoCarouselPauseOnHoverComponent {}
diff --git a/demo/src/ng-api-doc.ts b/demo/src/ng-api-doc.ts
index 5854bd5a1f..c9248cd9bb 100644
--- a/demo/src/ng-api-doc.ts
+++ b/demo/src/ng-api-doc.ts
@@ -263,6 +263,11 @@ export const ngdoc: any = {
"type": "boolean",
"description": ""
},
+ {
+ "name": "pauseOnFocus",
+ "type": "boolean",
+ "description": ""
+ },
{
"name": "showIndicators",
"type": "boolean",
@@ -343,6 +348,41 @@ export const ngdoc: any = {
],
"returnType": "void"
},
+ {
+ "name": "keydownPress",
+ "description": "Swith slides by enter, space and arrows keys
\n",
+ "args": [
+ {
+ "name": "event",
+ "type": "KeyboardEvent"
+ }
+ ],
+ "returnType": "void"
+ },
+ {
+ "name": "onMouseLeave",
+ "description": "Play on mouse leave
\n",
+ "args": [],
+ "returnType": "void"
+ },
+ {
+ "name": "onMouseUp",
+ "description": "Play on mouse up
\n",
+ "args": [],
+ "returnType": "void"
+ },
+ {
+ "name": "pauseFocusIn",
+ "description": "When slides on focus autoplay is stopped(optional)
\n",
+ "args": [],
+ "returnType": "void"
+ },
+ {
+ "name": "pauseFocusOut",
+ "description": "When slides out of focus autoplay is started
\n",
+ "args": [],
+ "returnType": "void"
+ },
{
"name": "selectSlide",
"description": "Rolling to specified slide
\n",
@@ -440,12 +480,24 @@ export const ngdoc: any = {
"description": "",
"methods": [],
"properties": [
+ {
+ "name": "indicatorsByChunk",
+ "defaultValue": "false",
+ "type": "boolean",
+ "description": "If true
- carousel indicators indicate slides chunks\nworks ONLY if singleSlideOffset = FALSE
\n"
+ },
{
"name": "interval",
"defaultValue": "5000",
"type": "number",
"description": "Default interval of auto changing of slides
\n"
},
+ {
+ "name": "itemsPerSlide",
+ "defaultValue": "1",
+ "type": "number",
+ "description": "If value more then 1 — carousel works in multilist mode
\n"
+ },
{
"name": "noPause",
"defaultValue": "false",
@@ -458,11 +510,23 @@ export const ngdoc: any = {
"type": "boolean",
"description": "Is slides can wrap from the last to the first slide
\n"
},
+ {
+ "name": "pauseOnFocus",
+ "defaultValue": "false",
+ "type": "boolean",
+ "description": "Slides can be paused on focus
\n"
+ },
{
"name": "showIndicators",
"defaultValue": "true",
"type": "boolean",
"description": "Show carousel-indicators
\n"
+ },
+ {
+ "name": "singleSlideOffset",
+ "defaultValue": "false",
+ "type": "boolean",
+ "description": "If true
— carousel shifts by one element. By default carousel shifts by number\nof visible elements (itemsPerSlide field)
\n"
}
]
},
diff --git a/package-lock.json b/package-lock.json
index 9cfbd1ce80..82eba0bda4 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -7765,7 +7765,8 @@
"ansi-regex": {
"version": "2.1.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"aproba": {
"version": "1.2.0",
@@ -7786,12 +7787,14 @@
"balanced-match": {
"version": "1.0.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"brace-expansion": {
"version": "1.1.11",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"balanced-match": "^1.0.0",
"concat-map": "0.0.1"
@@ -7806,17 +7809,20 @@
"code-point-at": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"concat-map": {
"version": "0.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"console-control-strings": {
"version": "1.1.0",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"core-util-is": {
"version": "1.0.2",
@@ -7933,7 +7939,8 @@
"inherits": {
"version": "2.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"ini": {
"version": "1.3.5",
@@ -7945,6 +7952,7 @@
"version": "1.0.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"number-is-nan": "^1.0.0"
}
@@ -7959,6 +7967,7 @@
"version": "3.0.4",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"brace-expansion": "^1.1.7"
}
@@ -7966,12 +7975,14 @@
"minimist": {
"version": "0.0.8",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"minipass": {
"version": "2.3.5",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"safe-buffer": "^5.1.2",
"yallist": "^3.0.0"
@@ -7990,6 +8001,7 @@
"version": "0.5.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"minimist": "0.0.8"
}
@@ -8070,7 +8082,8 @@
"number-is-nan": {
"version": "1.0.1",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"object-assign": {
"version": "4.1.1",
@@ -8082,6 +8095,7 @@
"version": "1.4.0",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"wrappy": "1"
}
@@ -8167,7 +8181,8 @@
"safe-buffer": {
"version": "5.1.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"safer-buffer": {
"version": "2.1.2",
@@ -8203,6 +8218,7 @@
"version": "1.0.2",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"code-point-at": "^1.0.0",
"is-fullwidth-code-point": "^1.0.0",
@@ -8222,6 +8238,7 @@
"version": "3.0.1",
"bundled": true,
"dev": true,
+ "optional": true,
"requires": {
"ansi-regex": "^2.0.0"
}
@@ -8265,12 +8282,14 @@
"wrappy": {
"version": "1.0.2",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
},
"yallist": {
"version": "3.0.3",
"bundled": true,
- "dev": true
+ "dev": true,
+ "optional": true
}
}
},
@@ -12626,6 +12645,11 @@
"integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=",
"dev": true
},
+ "n": {
+ "version": "5.0.0-next.0",
+ "resolved": "https://registry.npmjs.org/n/-/n-5.0.0-next.0.tgz",
+ "integrity": "sha512-F0dc44VDUjDrYk/vLRIYvCrGEChLikSsAqgTEv7aJtCoNWuWP6BARHf8HqSAjQrWRF98Ve28CGkyS1tqZgb1tg=="
+ },
"nan": {
"version": "2.14.0",
"resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz",
diff --git a/src/carousel/carousel.component.html b/src/carousel/carousel.component.html
index ffb42bd731..a025e5a62d 100644
--- a/src/carousel/carousel.component.html
+++ b/src/carousel/carousel.component.html
@@ -1,16 +1,16 @@
-
+
-
-
diff --git a/src/carousel/carousel.component.ts b/src/carousel/carousel.component.ts
index 5b6ffa1201..eb668e8504 100644
--- a/src/carousel/carousel.component.ts
+++ b/src/carousel/carousel.component.ts
@@ -46,6 +46,8 @@ export class CarouselComponent implements AfterViewInit, OnDestroy {
@Input() noPause: boolean;
/* If `true` — carousel-indicators are visible */
@Input() showIndicators: boolean;
+ /* If `true` - autoplay will be stopped on focus */
+ @Input() pauseOnFocus: boolean;
/* If `true` - carousel indicators indicate slides chunks
works ONLY if singleSlideOffset = FALSE */
@Input() indicatorsByChunk = false;
@@ -255,6 +257,73 @@ export class CarouselComponent implements AfterViewInit, OnDestroy {
}
}
+ /**
+ * Swith slides by enter, space and arrows keys
+ * @internal
+ */
+ keydownPress(event: KeyboardEvent) {
+ // tslint:disable-next-line:deprecation
+ if (event.keyCode === 13 || event.key === 'Enter' || event.keyCode === 32 || event.key === 'Space') {
+ this.nextSlide();
+ event.preventDefault();
+
+ return;
+ }
+
+ // tslint:disable-next-line:deprecation
+ if (event.keyCode === 37 || event.key === 'LeftArrow') {
+ this.previousSlide();
+
+ return;
+ }
+
+ // tslint:disable-next-line:deprecation
+ if (event.keyCode === 39 || event.key === 'RightArrow') {
+ this.nextSlide();
+
+ return;
+ }
+ }
+
+ /**
+ * Play on mouse leave
+ * @internal
+ */
+ onMouseLeave(): void {
+ if (!this.pauseOnFocus) {
+ this.play();
+ }
+ }
+
+ /**
+ * Play on mouse up
+ * @internal
+ */
+ onMouseUp(): void {
+ if (!this.pauseOnFocus) {
+ this.play();
+ }
+ }
+
+ /**
+ * When slides on focus autoplay is stopped(optional)
+ * @internal
+ */
+ pauseFocusIn(): void {
+ if (this.pauseOnFocus) {
+ this.isPlaying = false;
+ this.resetTimer();
+ }
+ }
+
+ /**
+ * When slides out of focus autoplay is started
+ * @internal
+ */
+ pauseFocusOut(): void {
+ this.play();
+ }
+
/**
* Rolling to specified slide
* @param index: {number} index of slide, which must be shown
diff --git a/src/carousel/carousel.config.ts b/src/carousel/carousel.config.ts
index 3bef69649c..420678d2f6 100644
--- a/src/carousel/carousel.config.ts
+++ b/src/carousel/carousel.config.ts
@@ -2,20 +2,22 @@ import { Injectable } from '@angular/core';
@Injectable()
export class CarouselConfig {
- /** Default interval of auto changing of slides */
+ /* Default interval of auto changing of slides */
interval = 5000;
- /** Is loop of auto changing of slides can be paused */
+ /* Is loop of auto changing of slides can be paused */
noPause = false;
- /** Is slides can wrap from the last to the first slide */
+ /* Is slides can wrap from the last to the first slide */
noWrap = false;
- /** Show carousel-indicators */
+ /* Show carousel-indicators */
showIndicators = true;
- /* If `true` - carousel indicators indicate slides chunks
- works ONLY if singleSlideOffset = FALSE */
+ /* Slides can be paused on focus */
+ pauseOnFocus = false;
+
+ /* If `true` - carousel indicators indicate slides chunks works ONLY if singleSlideOffset = FALSE */
indicatorsByChunk = false;
/* If value more then 1 — carousel works in multilist mode */