diff --git a/.storybook/preview.js b/.storybook/preview.js
index 6518f27423..04dd941019 100644
--- a/.storybook/preview.js
+++ b/.storybook/preview.js
@@ -20,22 +20,29 @@ const SORT_ORDER = {
'Getting Started',
'Design Principles',
'Contributing',
- 'Code of Conduct'
+ 'Code of Conduct',
+ ],
+ Advanced: [
+ 'Static CSS',
+ 'Base Components',
+ 'Theme',
+ 'Grid',
+ 'Icons',
+ 'Event Tracking',
],
- Advanced: ['Static CSS', 'Base Components', 'Theme', 'Grid', 'Icons'],
Typography: ['Heading', 'SubHeading', 'Text'],
Layout: [],
Forms: [],
Components: [],
- Icons: []
+ Icons: [],
};
addParameters({
options: {
storySort: sortStories(SORT_ORDER),
- showRoots: true
+ showRoots: true,
},
- docs: { components }
+ docs: { components },
});
const Story = styled.div`
@@ -50,11 +57,11 @@ const Story = styled.div`
}
`;
-const withStoryStyles = storyFn => {
+const withStoryStyles = (storyFn) => {
return {storyFn()};
};
-const withThemeProvider = storyFn => (
+const withThemeProvider = (storyFn) => (
{storyFn()}
@@ -71,7 +78,7 @@ if (!__TEST__) {
addDecorator(withThemeProvider);
-const withTrackingAction = storyFn => (
+const withTrackingAction = (storyFn) => (
{storyFn()}
diff --git a/src/components/Carousel/Carousel.js b/src/components/Carousel/Carousel.js
index a84e5b5b3c..0087d5e7fc 100644
--- a/src/components/Carousel/Carousel.js
+++ b/src/components/Carousel/Carousel.js
@@ -78,6 +78,7 @@ const Carousel = ({
hideControls = false,
getAriaLabelledBy = () => {},
children,
+ tracking,
...props
}) => {
const slidesTotal = slides.length;
@@ -101,6 +102,7 @@ const Carousel = ({
animationDuration={animationDuration}
onNext={handleNextSlide}
onPrevious={handlePreviousSlide}
+ tracking={tracking}
>
{({
state,
@@ -221,6 +223,14 @@ Carousel.propTypes = {
* Add additional components inside a carousel.
*/
children: PropTypes.oneOfType([childrenPropType, childrenRenderPropType]),
+ /**
+ * Additional data that is dispatched with the tracking event.
+ */
+ tracking: PropTypes.shape({
+ label: PropTypes.string.isRequired,
+ component: PropTypes.string,
+ customParameters: PropTypes.object,
+ }),
};
export default Carousel;
diff --git a/src/components/Step/Step.js b/src/components/Step/Step.js
index dd2977a5e0..ddcae563d4 100644
--- a/src/components/Step/Step.js
+++ b/src/components/Step/Step.js
@@ -27,6 +27,7 @@ function Step({
stepInterval = 1,
animationDuration = 0,
stepDuration = 0,
+ tracking = {},
onPlay = () => {},
onPause = () => {},
onNext = () => {},
@@ -40,6 +41,7 @@ function Step({
stepInterval,
animationDuration,
stepDuration,
+ tracking,
onPlay,
onPause,
onNext,
@@ -110,6 +112,14 @@ Step.propTypes = {
* Function called with an object containing current state and prop getters.
*/
children: PropTypes.func,
+ /**
+ * Additional data that is dispatched with the tracking event.
+ */
+ tracking: PropTypes.shape({
+ label: PropTypes.string.isRequired,
+ component: PropTypes.string,
+ customParameters: PropTypes.object,
+ }),
};
export default Step;
diff --git a/src/components/Step/hooks/use-step.js b/src/components/Step/hooks/use-step.js
index 3f7b677342..164d2bf4da 100644
--- a/src/components/Step/hooks/use-step.js
+++ b/src/components/Step/hooks/use-step.js
@@ -17,6 +17,7 @@ import { useReducer, useEffect, useRef } from 'react';
import { isFunction } from 'lodash/fp';
import * as StepService from '../StepService';
+import useClickHandler from '../../../hooks/use-click-handler';
export default function useStep(props = {}) {
if (__DEV__ && props.cycle && !props.totalSteps) {
@@ -40,6 +41,27 @@ export default function useStep(props = {}) {
const [state, dispatch] = useReducer(StepService.reducer, initialState);
const playingInterval = useRef(null);
const animationEndCallback = useRef(null);
+ const { onNext, onPrevious, onPause, onPlay, tracking } = props;
+ const handleNext = useClickHandler(
+ onNext,
+ { label: 'next', ...tracking },
+ 'carousel',
+ );
+ const handlePrevious = useClickHandler(
+ onPrevious,
+ { label: 'previous', ...tracking },
+ 'carousel',
+ );
+ const handlePause = useClickHandler(
+ onPause,
+ { label: 'pause', ...tracking },
+ 'carousel',
+ );
+ const handlePlay = useClickHandler(
+ onPlay,
+ { label: 'play', ...tracking },
+ 'carousel',
+ );
useEffect(() => {
const playable = shouldPlay();
@@ -56,7 +78,7 @@ export default function useStep(props = {}) {
// ACTIONS
function next() {
- const { totalSteps, cycle, stepInterval, onNext } = props;
+ const { totalSteps, cycle, stepInterval } = props;
const newStep = StepService.calculateNextStep({
step: state.step,
stepInterval,
@@ -65,14 +87,14 @@ export default function useStep(props = {}) {
});
updateSlide(newStep, () => {
- if (isFunction(onNext)) {
- onNext(getStateAndHelpers());
+ if (isFunction(handleNext)) {
+ handleNext(getStateAndHelpers());
}
});
}
function previous() {
- const { totalSteps, cycle, stepInterval, onPrevious } = props;
+ const { totalSteps, cycle, stepInterval } = props;
const newStep = StepService.calculatePreviousStep({
step: state.step,
stepInterval,
@@ -81,29 +103,25 @@ export default function useStep(props = {}) {
});
updateSlide(newStep, () => {
- if (isFunction(onPrevious)) {
- onPrevious(getStateAndHelpers());
+ if (isFunction(handlePrevious)) {
+ handlePrevious(getStateAndHelpers());
}
});
}
function pause() {
- const { onPause } = props;
-
updatePause(true);
- if (isFunction(onPause)) {
- onPause(getStateAndHelpers());
+ if (isFunction(handlePause)) {
+ handlePause(getStateAndHelpers());
}
}
function play() {
- const { onPlay } = props;
-
updatePause(false);
- if (isFunction(onPlay)) {
- onPlay(getStateAndHelpers());
+ if (isFunction(handlePlay)) {
+ handlePlay(getStateAndHelpers());
}
}