diff --git a/CHANGELOG.md b/CHANGELOG.md
index 5fde0240d1..ec812685c6 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,4 +1,5 @@
# Changelog
+- Add Play/Pause button to carousel. [#1944](https://github.com/bigcommerce/cornerstone/pull/1944)
## Draft
- Carousel buttons do not receive focus. [#1937](https://github.com/bigcommerce/cornerstone/pull/1937)
diff --git a/assets/js/theme/common/carousel/utils/heroCarouselSetup.js b/assets/js/theme/common/carousel/utils/heroCarouselSetup.js
index 089f7720e1..e7aa880538 100644
--- a/assets/js/theme/common/carousel/utils/heroCarouselSetup.js
+++ b/assets/js/theme/common/carousel/utils/heroCarouselSetup.js
@@ -1,3 +1,5 @@
+import playPause from './playPause';
+
const showCarouselIfSlidesAnalyzedSetup = ($carousel) => {
const analyzedSlides = [];
return ($slides) => ($slide) => {
@@ -11,6 +13,8 @@ const showCarouselIfSlidesAnalyzedSetup = ($carousel) => {
export default ($heroCarousel) => {
if ($heroCarousel.length === 0) return;
+ playPause($heroCarousel);
+
const $slidesNodes = $heroCarousel.find('.heroCarousel-slide');
const showCarouselIfSlidesAnalyzed = showCarouselIfSlidesAnalyzedSetup($heroCarousel)($slidesNodes);
diff --git a/assets/js/theme/common/carousel/utils/playPause.js b/assets/js/theme/common/carousel/utils/playPause.js
new file mode 100644
index 0000000000..7fc67b55dd
--- /dev/null
+++ b/assets/js/theme/common/carousel/utils/playPause.js
@@ -0,0 +1,38 @@
+import { throttle } from 'lodash';
+
+const playAction = 'slickPlay';
+const pauseAction = 'slickPause';
+
+export default ($heroCarousel) => {
+ const $playPauseButton = $('.js-hero-play-pause-button');
+
+ if ($playPauseButton.length === 0) return;
+
+ const slickSettings = $heroCarousel[0].slick;
+ if (!slickSettings) return;
+
+ const { slideCount, options: { speed } } = slickSettings;
+ if (slideCount < 2) {
+ $playPauseButton.css('display', 'none');
+ return;
+ }
+
+ const onPlayPauseClick = () => {
+ const isCarouselPlaying = $playPauseButton.data('play');
+ const action = isCarouselPlaying ? pauseAction : playAction;
+ const {
+ play,
+ ariaPlay,
+ pause,
+ ariaPause,
+ } = $playPauseButton.data('labels');
+
+ $heroCarousel.slick(action);
+ $playPauseButton
+ .data('play', !isCarouselPlaying)
+ .text(action === playAction ? pause : play)
+ .attr('aria-label', action === playAction ? ariaPause : ariaPlay);
+ };
+
+ $playPauseButton.on('click', throttle(onPlayPauseClick, speed, { trailing: false }));
+};
diff --git a/assets/scss/components/stencil/heroCarousel/_heroCarousel.scss b/assets/scss/components/stencil/heroCarousel/_heroCarousel.scss
index 2d8b726d82..61f0826e08 100644
--- a/assets/scss/components/stencil/heroCarousel/_heroCarousel.scss
+++ b/assets/scss/components/stencil/heroCarousel/_heroCarousel.scss
@@ -68,7 +68,6 @@
left: 25px;
}
}
-
.slick-dots {
bottom: spacing("third");
@@ -224,3 +223,37 @@
margin-top: spacing("single");
}
}
+
+.heroCarousel-play-pause-button {
+ position: absolute;
+ left: 15px;
+ bottom: spacing("third");
+ height: 32px;
+ min-width: 80px;
+ max-width: 90px;
+ font-size: 14px;
+ line-height: 1.25;
+ font-weight: 700;
+ white-space: nowrap;
+ overflow: hidden;
+ text-overflow: ellipsis;
+ color: $slick-play-pause-button-color;
+ transition: color 100ms ease-out;
+ z-index: zIndex("lowest");
+ border: 1px solid $slick-play-pause-button-borderColor;
+ @include carouselOpaqueBackgrounds($slick-play-pause-button-bgColor);
+
+ @include breakpoint("small") {
+ max-width: 150px;
+ font-size: 18px;
+ }
+
+ @include breakpoint("medium") {
+ left: 25px;
+ bottom: spacing("single");
+ }
+
+ &:hover {
+ color: $slick-play-pause-button-color-hover;
+ }
+}
diff --git a/assets/scss/settings/vendor/slick/_settings.scss b/assets/scss/settings/vendor/slick/_settings.scss
index 91cc77358a..825c2ee846 100644
--- a/assets/scss/settings/vendor/slick/_settings.scss
+++ b/assets/scss/settings/vendor/slick/_settings.scss
@@ -5,24 +5,28 @@
//
// -----------------------------------------------------------------------------
-$slick-font-path: "./fonts/";
-$slick-font-family: inherit;
-$slick-loader-path: null;
-$slick-arrow-color: stencilColor("carousel-arrow-color");
-$slick-arrow-color-hover: stencilColor("carousel-arrow-color--hover");
-$slick-arrow-bgColor: rgba(stencilColor("carousel-arrow-bgColor"), 0.9);
-$slick-arrow-borderColor: stencilColor("carousel-arrow-borderColor");
-$slick-dot-color: stencilColor("carousel-dot-color");
-$slick-dot-color-active: stencilColor("carousel-dot-color-active");
-$slick-dot-bgColor: rgba(stencilColor("carousel-dot-bgColor"), 0.9);
-$slick-prev-character: "";
-$slick-next-character: "";
-$slick-dot-character: "";
-$slick-dot-size: 60px;
-$slick-opacity-default: 1;
-$slick-opacity-on-hover: 0.8;
-$slick-opacity-not-active: 0.6;
-$slick-arrows-offset: -5px;
+$slick-font-path: "./fonts/";
+$slick-font-family: inherit;
+$slick-loader-path: null;
+$slick-arrow-color: stencilColor("carousel-arrow-color");
+$slick-arrow-color-hover: stencilColor("carousel-arrow-color--hover");
+$slick-arrow-bgColor: rgba(stencilColor("carousel-arrow-bgColor"), 0.9);
+$slick-arrow-borderColor: stencilColor("carousel-arrow-borderColor");
+$slick-play-pause-button-color: stencilColor("carousel-play-pause-button-textColor");
+$slick-play-pause-button-color-hover: stencilColor("carousel-play-pause-button-textColor--hover");
+$slick-play-pause-button-bgColor: rgba(stencilColor("carousel-play-pause-button-bgColor"), 0.9);
+$slick-play-pause-button-borderColor: stencilColor("carousel-play-pause-button-borderColor");
+$slick-dot-color: stencilColor("carousel-dot-color");
+$slick-dot-color-active: stencilColor("carousel-dot-color-active");
+$slick-dot-bgColor: rgba(stencilColor("carousel-dot-bgColor"), 0.9);
+$slick-prev-character: "";
+$slick-next-character: "";
+$slick-dot-character: "";
+$slick-dot-size: 60px;
+$slick-opacity-default: 1;
+$slick-opacity-on-hover: 0.8;
+$slick-opacity-not-active: 0.6;
+$slick-arrows-offset: -5px;
// Stencil Additional Settings
diff --git a/config.json b/config.json
index 3b15f26dfd..cbb2c13d8f 100644
--- a/config.json
+++ b/config.json
@@ -55,6 +55,7 @@
"homepage_top_products_count": 4,
"homepage_show_carousel": true,
"homepage_show_carousel_arrows": true,
+ "homepage_show_carousel_play_pause_button": true,
"homepage_stretch_carousel_images": false,
"homepage_new_products_column_count": 4,
"homepage_featured_products_column_count": 4,
@@ -179,6 +180,10 @@
"carousel-arrow-color--hover": "#474747",
"carousel-arrow-bgColor": "#ffffff",
"carousel-arrow-borderColor": "#ffffff",
+ "carousel-play-pause-button-textColor": "8f8f8f",
+ "carousel-play-pause-button-textColor--hover": "#474747",
+ "carousel-play-pause-button-bgColor": "#ffffff",
+ "carousel-play-pause-button-borderColor": "#ffffff",
"card-title-color": "#333333",
"card-title-color-hover": "#757575",
"card-figcaption-button-background": "#ffffff",
@@ -474,6 +479,10 @@
"carousel-arrow-color--hover": "#474747",
"carousel-arrow-bgColor": "#ffffff",
"carousel-arrow-borderColor": "#ffffff",
+ "carousel-play-pause-button-textColor": "#8F8F8F",
+ "carousel-play-pause-button-textColor--hover": "#474747",
+ "carousel-play-pause-button-bgColor": "#ffffff",
+ "carousel-play-pause-button-borderColor": "#ffffff",
"card-title-color": "#ff957f",
"card-title-color-hover": "#fab9a3",
"card-figcaption-button-background": "#85cdcf",
@@ -679,6 +688,10 @@
"carousel-arrow-color--hover": "#765B42",
"carousel-arrow-bgColor": "#ffffff",
"carousel-arrow-borderColor": "#ffffff",
+ "carousel-play-pause-button-textColor": "#D47A21",
+ "carousel-play-pause-button-textColor--hover": "#765B42",
+ "carousel-play-pause-button-bgColor": "#ffffff",
+ "carousel-play-pause-button-borderColor": "#ffffff",
"card-title-color": "#bd5b00",
"card-title-color-hover": "#7f5e3f",
"card-figcaption-button-background": "#f3b679",
diff --git a/lang/en.json b/lang/en.json
index 6bd571467b..8665a6d5f2 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -898,7 +898,11 @@
"carousel": {
"arrowAriaLabel": "Go to slide [NUMBER] of",
"dotAriaLabel": "Slide number",
- "activeDotAriaLabel": "active"
+ "activeDotAriaLabel": "active",
+ "playPauseButtonPlay": "Play",
+ "playPauseButtonPause": "Pause",
+ "playPauseButtonAriaPlay": "Play carousel",
+ "playPauseButtonAriaPause": "Pause carousel"
},
"validation_messages": {
"valid_email": "You must enter a valid email.",
diff --git a/schema.json b/schema.json
index 190e2c393a..e60f27bff0 100644
--- a/schema.json
+++ b/schema.json
@@ -990,6 +990,12 @@
"force_reload": true,
"id": "homepage_show_carousel_arrows"
},
+ {
+ "type": "checkbox",
+ "label": "i18n.ShowCarouselPlayPauseButton",
+ "force_reload": true,
+ "id": "homepage_show_carousel_play_pause_button"
+ },
{
"type": "checkbox",
"label": "i18n.AllowImageToStretchOn",
@@ -1041,6 +1047,21 @@
"label": "i18n.ArrowBorder",
"id": "carousel-arrow-borderColor"
},
+ {
+ "type": "color",
+ "label": "i18n.PlayPauseButtonText",
+ "id": "carousel-play-pause-button-textColor"
+ },
+ {
+ "type": "color",
+ "label": "i18n.PlayPauseButtonBackground",
+ "id": "carousel-play-pause-button-bgColor"
+ },
+ {
+ "type": "color",
+ "label": "i18n.PlayPauseButtonBorder",
+ "id": "carousel-play-pause-button-borderColor"
+ },
{
"type": "heading",
"content": "i18n.Products"
diff --git a/schemaTranslations.json b/schemaTranslations.json
index d26ee2b577..b995c6da9a 100644
--- a/schemaTranslations.json
+++ b/schemaTranslations.json
@@ -936,6 +936,13 @@
"uk": "Показати стрілки каруселі",
"zh": "显示轮播箭头"
},
+ "i18n.ShowCarouselPlayPauseButton": {
+ "default": "Show carousel Play/Pause button",
+ "fr": "Show carousel Play/Pause button",
+ "it": "Show carousel Play/Pause button",
+ "uk": "Show carousel Play/Pause button",
+ "zh": "Show carousel Play/Pause button"
+ },
"i18n.AllowImageToStretchOn": {
"default": "Allow image to stretch on large screens",
"fr": "Permettre à l’image de s’étirer sur de grands écrans",
@@ -1006,6 +1013,27 @@
"uk": "Кордон стрілки",
"zh": "箭头边框"
},
+ "i18n.PlayPauseButtonText": {
+ "default": "Play/Pause button text",
+ "fr": "Play/Pause button text",
+ "it": "Play/Pause button text",
+ "uk": "Play/Pause button text",
+ "zh": "Play/Pause button text"
+ },
+ "i18n.PlayPauseButtonBackground": {
+ "default": "Play/Pause button background",
+ "fr": "Play/Pause button background",
+ "it": "Play/Pause button background",
+ "uk": "Play/Pause button background",
+ "zh": "Play/Pause button background"
+ },
+ "i18n.PlayPauseButtonBorder": {
+ "default": "Play/Pause button border",
+ "fr": "Play/Pause button border",
+ "it": "Play/Pause button border",
+ "uk": "Play/Pause button border",
+ "zh": "Play/Pause button border"
+ },
"i18n.NumberOfFeaturedProducts": {
"default": "Number of featured products",
"fr": "Nombre de produits en vedette",
diff --git a/templates/components/carousel.html b/templates/components/carousel.html
index 42c845d4f7..8ed022dc06 100644
--- a/templates/components/carousel.html
+++ b/templates/components/carousel.html
@@ -63,4 +63,19 @@
{{#and arrows (if carousel.slides.length '>' 1)}}
{{/and}}
+ {{#if play_pause_button}}
+
+ {{/if}}
diff --git a/templates/pages/home.html b/templates/pages/home.html
index 5c731f2424..1ae7a9cd88 100644
--- a/templates/pages/home.html
+++ b/templates/pages/home.html
@@ -14,7 +14,7 @@
{{#partial "hero"}}
{{{region name="home_below_menu"}}}
{{#if carousel}}
- {{> components/carousel arrows=theme_settings.homepage_show_carousel_arrows}}
+ {{> components/carousel arrows=theme_settings.homepage_show_carousel_arrows play_pause_button=theme_settings.homepage_show_carousel_play_pause_button}}
{{/if}}
{{{region name="home_below_carousel"}}}
{{/partial}}