<div class="Carousel js-carousel " data-target="#carousel1" style="">
<div class="row _centeritems">
<div class="col _span-6 ">
<div class="iconlist ">
<div class="iconlist-item Carousel-trigger icon _before _curate _circle _font-large js-swapimage" style="" data-srcset="//media.sproutsocial.com/uploads/localization/en/smart-inbox-apply-tags.png, //media.sproutsocial.com/uploads/localization/en/smart-inbox-apply-tags@2x.png 2x">
<div class="text">
<h3 class=" " style="">
Curate
</h3>
<p id="" class="">
Curate interesting marketing content and add internal notes so advocates know why it matters.
</p>
</div>
<div class="icon _after _arrow"></div>
</div>
<div class="iconlist-item Carousel-trigger icon _before _distribute _circle _font-large js-swapimage" style="" data-srcset="//media.sproutsocial.com/uploads/localization/en/smart-inbox-collision-detection.png, //media.sproutsocial.com/uploads/localization/en/smart-inbox-collision-detection@2x.png 2x">
<div class="text">
<h3 class=" " style="">
Distribute
</h3>
<p id="" class="">
Make it easy for advocates to share approved content with suggested messaging.
</p>
</div>
<div class="icon _after _arrow"></div>
</div>
<div class="iconlist-item Carousel-trigger icon _before _analyze _circle _font-large js-swapimage" style="" data-srcset="//media.sproutsocial.com/uploads/localization/en/smart-inbox-assign-task.png, //media.sproutsocial.com/uploads/localization/en/smart-inbox-assign-task@2x.png 2x">
<div class="text">
<h3 class=" " style="">
Analyze
</h3>
<p id="" class="">
<strong>We understand the impact</strong> that social conversations have across your enterprise, from marketing and sales to talent and support.
</p>
</div>
<div class="icon _after _arrow"></div>
</div>
</div>
</div>
<div class="col _span-6 ">
<div class="Carousel-image-wrapper">
<img id="carousel1" class="Carousel-image" alt="Create an Exceptional Brand Experience On Social">
</div>
</div>
</div>
</div>
<div class="Carousel js-carousel {{#if hover}}js-hover _hover{{/if}} {{#if preventpreload}}js-preventPreload{{/if}} {{#if reverse}}_reverse{{/if}} {{modifier}}" data-target="#{{id}}" style="{{style}}">
<div class="row _centeritems">
<div class="col _span-{{iconlistcolspan}} {{iconlistcolmodifier}}">
<div class="iconlist {{iconlistmodifier}}">
{{#if itemsheader}}
{{> @heading itemsheader}}
{{/if}}
{{> @children}}
</div>
</div>
<div class="col _span-{{imagecolspan}} {{imagecolmodifier}}">
<div class="Carousel-image-wrapper">
<img id="{{id}}" class="Carousel-image" alt="{{alt}}">
</div>
</div>
</div>
</div>
{
"id": "carousel1",
"alt": "Create an Exceptional Brand Experience On Social",
"reverse": null,
"modifier": null,
"style": null,
"iconlistcolspan": 6,
"imagecolspan": 6,
"hover": null,
"preventpreload": null,
"children": [
{
"component": "iconlist-item",
"context": {
"modifier": "Carousel-trigger icon _before _curate _circle _font-large",
"carousel": true,
"src": "//media.sproutsocial.com/uploads/localization/en/smart-inbox-apply-tags.png",
"src2x": "//media.sproutsocial.com/uploads/localization/en/smart-inbox-apply-tags@2x.png",
"children": [
{
"component": "heading",
"context": {
"text": "Curate",
"level": 3
}
},
{
"component": "p",
"context": {
"text": "Curate interesting marketing content and add internal notes so advocates know why it matters."
}
}
]
}
},
{
"component": "iconlist-item",
"context": {
"modifier": "Carousel-trigger icon _before _distribute _circle _font-large",
"carousel": true,
"src": "//media.sproutsocial.com/uploads/localization/en/smart-inbox-collision-detection.png",
"src2x": "//media.sproutsocial.com/uploads/localization/en/smart-inbox-collision-detection@2x.png",
"children": [
{
"component": "heading",
"context": {
"text": "Distribute",
"level": 3
}
},
{
"component": "p",
"context": {
"text": "Make it easy for advocates to share approved content with suggested messaging."
}
}
]
}
},
{
"component": "iconlist-item",
"context": {
"modifier": "Carousel-trigger icon _before _analyze _circle _font-large",
"carousel": true,
"src": "//media.sproutsocial.com/uploads/localization/en/smart-inbox-assign-task.png",
"src2x": "//media.sproutsocial.com/uploads/localization/en/smart-inbox-assign-task@2x.png",
"children": [
{
"component": "heading",
"context": {
"text": "Analyze",
"level": 3
}
},
{
"component": "p",
"context": {
"text": "<strong>We understand the impact</strong> that social conversations have across your enterprise, from marketing and sales to talent and support."
}
}
]
}
}
]
}
// Carousel
//
// An extension of the iconlist pattern to allow accommodate interactivity.
//
// Markup: Carousel.html
//
// Style guide: Patterns.Carousel
$item-default: get-color(neutral, 400) !default;
$item-hover: get-color(neutral, 500) !default;
$item-active: theme-color(link) !default;
.Carousel {
align-items: center;
&-trigger:not(.is-active)::before,
&-trigger:not(.is-active)::after,
&-trigger:not(.is-active) {
color: $item-default;
opacity: .8;
cursor: pointer;
}
&-trigger:not(.is-active):hover::before,
&-trigger:not(.is-active):focus::after,
&-trigger:not(.is-active):focus,
&-trigger:not(.is-active):hover {
color: $item-hover;
opacity: .8;
}
&._hover &-trigger:not(:hover):not(.is-active) {
opacity: .8;
}
.iconlist {
.iconlist-item > .icon._arrow,
.iconlist-item > .icon._arrow-left {
display: none;
font-size: 1.25em;
}
}
&-image-wrapper {
position: relative;
}
&-image {
position: absolute;
top: 0;
left: 10px;
max-width: none;
transform: translateY(10px);
}
.iconlist .iconlist-item {
align-items: flex-start;
& > .icon._arrow,
& > .icon._arrow-left {
align-self: center;
}
}
.iconlist-item.is-active {
h3 {
color: theme-color(text, dark);
}
& > .icon._arrow,
& > .icon._arrow-left {
margin-top: 0;
}
}
.iconlist-item:not(.is-active) {
cursor: pointer;
h3,
p,
div {
color: $item-default;
}
&:hover {
h3,
p,
div {
color: $item-hover;
}
}
.button._secondary {
@include button-color(
$button-border-color: $item-default,
$button-text-color: $item-default,
$button-background-color: transparent,
$button-border-color-hover: $item-hover,
$button-text-color-hover: $item-hover
);
}
}
&._reverse {
.Carousel-image {
top: 0;
right: 10px;
left: auto;
}
.iconlist-item > .icon._arrow {
order: 1;
transform: rotate(180deg);
}
}
._bordered .iconlist-item {
align-items: center;
& > .icon._arrow,
& > .icon._arrow-left {
display: none;
}
&.is-active {
color: $item-active;
cursor: default;
}
}
.iconlist-item._checkmark:not(._circle) {
align-items: center;
&::before {
color: $item-default;
}
.text {
@include font-weight-semibold;
}
> .icon._arrow,
> .icon._arrow-left {
width: auto;
margin-left: .75rem;
font-size: .75rem;
}
&.is-active::before,
&.is-active:hover::before {
color: $item-active;
}
}
}
@media #{$mobile-media} {
.Carousel {
&-image-wrapper {
height: 300px;
margin-bottom: -3rem; // to hide section padding
overflow: hidden;
}
&-image {
width: 100%;
height: auto;
}
}
}
@media #{$desktop-media} {
.Carousel {
.iconlist:not(._bordered) .iconlist-item > .icon._arrow,
.iconlist:not(._bordered) .iconlist-item > .icon._arrow-left {
display: block;
width: 10%;
flex: 0 0 auto;
font-size: 1.5em;
color: $item-active;
text-align: center;
visibility: hidden;
}
.iconlist:not(._bordered) .iconlist-item.is-active > .icon._arrow,
.iconlist:not(._bordered) .iconlist-item.is-active > .icon._arrow-left {
visibility: visible;
}
&-image-wrapper {
height: 520px;
}
&-image {
width: auto;
height: 520px;
}
&._reverse {
.row > .col:first-child {
order: 1;
}
.row > .col:last-child {
order: 0;
}
}
}
}
import Util from '@sproutsocial/sprout-brand/modules/util';
import JS_CLASSES from '../../../constants/js-classes';
/**
* ImageSwapper is a fun class that handles the magic of swapping images in carousels
* @example
* const carousels = document.querySelectorAll('.js-carousel');
* each(carousels, (el)=> { new ImageSwapper({ container: el }); });
*/
class ImageSwapper {
static defaultProps = {
container: null, // DOM object of our "carousel"
childClass: '.js-swapimage', // Interaction class
carouselInterval: false // if set to an integer will automatically persist the carousel
};
constructor(props = {}) {
this.props = Object.assign({}, ImageSwapper.defaultProps, props);
if (props.container === null) {
throw 'ImageSwapper requires a container prop.';
}
const carousel = this.props.container;
const carouselItems = carousel.querySelectorAll(this.props.childClass);
Util.each(carouselItems, el => {
if (carousel.classList.contains('js-hover')) {
el.addEventListener('mouseover', this.swapImage.bind(el));
}
el.addEventListener('click', this.swapImage.bind(el));
el.addEventListener('keypress', this.swapImage.bind(el));
});
Util.triggerEvent(carouselItems[0], 'click');
if (!carousel.classList.contains('js-preventPreload')) {
this.getImagesToPreload(carouselItems);
}
if (this.props.carouselInterval) {
this.carouselImages(this.props.container, this.props.carouselInterval);
}
}
/**
* Takes in a carousel element and an integer for an interval
* then triggers a click to the next carousel item with a setInterval
*/
carouselImages(el, interval) {
const carouselItems = el.children;
let counter = 0;
setInterval(() => {
counter = (counter + 1) % carouselItems.length;
Util.triggerEvent(carouselItems[counter], 'click');
}, interval);
}
/**
* Gets passed an array of elements and grabs their
* data-srcset's from the markup and creates an array
* then sends that created array to our pre-loading function
*/
getImagesToPreload(el) {
const isRetina = Util.isRetina();
Util.each(el, el => {
const dataSource = el.getAttribute('data-srcset');
const dataSourceArray = dataSource.split(',');
let img;
if (isRetina) {
let retinaImg = dataSourceArray[1];
retinaImg = retinaImg.split(' ');
img = retinaImg[1];
} else {
img = dataSourceArray[0];
}
this.preloadImages(img);
});
}
/**
* Takes in an image URL and makes a network request for the image.
*/
preloadImages(imgURL) {
const imageObject = new Image();
imageObject.src = imgURL;
}
/**
* SwapImage removes the active state of other carousel items then
* adds an active state for the current one, it also updates the
* target carousel with a data attribute of the srcset
*/
swapImage() {
// Remove the active state from the other items
const parentCarousel = Util.closest(this, JS_CLASSES.CAROUSEL);
Util.each(parentCarousel.querySelectorAll('.is-active'), el => {
el.classList.remove('is-active');
});
// Add the active state
this.classList.add('is-active');
// get the srcset from the data attribute and update its intended target
const imageSrcset = this.getAttribute('data-srcset');
const imageTargetId = parentCarousel.hasAttribute('data-target')
? parentCarousel.getAttribute('data-target')
: this.getAttribute('data-target');
const imageTarget = imageTargetId
? document.getElementById(imageTargetId.substr(1))
: parentCarousel.querySelector(JS_CLASSES.CAROUSEL_TARGET);
imageTarget.setAttribute('srcset', imageSrcset);
parentCarousel.classList.add('is-loading');
imageTarget.addEventListener('load', () => {
parentCarousel.classList.remove('is-loading');
});
if (window.picturefill) {
window.picturefill({
elements: [imageTarget],
reevaluate: true
});
}
}
}
export default ImageSwapper;
There are no notes for this item.