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}}