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()); } }