From 9b92cdd49483f4870d9922def3e51a7aff146489 Mon Sep 17 00:00:00 2001 From: Charlotte Emms <43961396+cemms1@users.noreply.github.com> Date: Wed, 11 Dec 2024 11:01:28 +0000 Subject: [PATCH] Create carousel navigation buttons component and use in scrollable carousel (#12976) --- .../components/CarouselNavigationButtons.tsx | 89 +++++++++++++++++++ .../src/components/ScrollableCarousel.tsx | 81 ++++------------- 2 files changed, 106 insertions(+), 64 deletions(-) create mode 100644 dotcom-rendering/src/components/CarouselNavigationButtons.tsx diff --git a/dotcom-rendering/src/components/CarouselNavigationButtons.tsx b/dotcom-rendering/src/components/CarouselNavigationButtons.tsx new file mode 100644 index 00000000000..92457cd1522 --- /dev/null +++ b/dotcom-rendering/src/components/CarouselNavigationButtons.tsx @@ -0,0 +1,89 @@ +import { css } from '@emotion/react'; +import { from, space } from '@guardian/source/foundations'; +import type { ThemeButton } from '@guardian/source/react-components'; +import { + Button, + SvgChevronLeftSingle, + SvgChevronRightSingle, +} from '@guardian/source/react-components'; +import { palette } from '../palette'; + +type Props = { + previousButtonEnabled: boolean; + nextButtonEnabled: boolean; + onClickPreviousButton: () => void; + onClickNextButton: () => void; + dataLinkNameNextButton: string; + dataLinkNamePreviousButton: string; +}; + +const themeButton: Partial = { + borderTertiary: palette('--carousel-chevron-border'), + textTertiary: palette('--carousel-chevron'), + backgroundTertiaryHover: palette('--carousel-chevron-hover'), +}; + +const themeButtonDisabled: Partial = { + borderTertiary: palette('--carousel-chevron-border-disabled'), + textTertiary: palette('--carousel-chevron-disabled'), + backgroundTertiaryHover: 'transparent', +}; + +const buttonStyles = css` + display: none; + ${from.tablet} { + display: flex; + gap: ${space[1]}px; + margin-left: auto; + } +`; + +/** + * Navigation buttons for use in a carousel-like component + */ +export const CarouselNavigationButtons = ({ + previousButtonEnabled, + nextButtonEnabled, + onClickPreviousButton, + onClickNextButton, + dataLinkNameNextButton, + dataLinkNamePreviousButton, +}: Props) => { + return ( +
+
+ ); +}; diff --git a/dotcom-rendering/src/components/ScrollableCarousel.tsx b/dotcom-rendering/src/components/ScrollableCarousel.tsx index 28b1a55b183..714cabba628 100644 --- a/dotcom-rendering/src/components/ScrollableCarousel.tsx +++ b/dotcom-rendering/src/components/ScrollableCarousel.tsx @@ -6,14 +6,10 @@ import { space, textSansBold17Object, } from '@guardian/source/foundations'; -import type { ThemeButton } from '@guardian/source/react-components'; -import { - Button, - SvgChevronLeftSingle, - SvgChevronRightSingle, -} from '@guardian/source/react-components'; import { useEffect, useRef, useState } from 'react'; +import { nestedOphanComponents } from '../lib/ophan-helpers'; import { palette } from '../palette'; +import { CarouselNavigationButtons } from './CarouselNavigationButtons'; type Props = { children: React.ReactNode; @@ -39,18 +35,6 @@ const gridColumnWidth = 60; const gridGap = 20; const gridGapMobile = 10; -const themeButton: Partial = { - borderTertiary: palette('--carousel-chevron-border'), - textTertiary: palette('--carousel-chevron'), - backgroundTertiaryHover: palette('--carousel-chevron-hover'), -}; - -const themeButtonDisabled: Partial = { - borderTertiary: palette('--carousel-chevron-border-disabled'), - textTertiary: palette('--carousel-chevron-disabled'), - backgroundTertiaryHover: 'transparent', -}; - /** * On mobile the carousel extends into the outer margins to use the full width * of the screen. From tablet onwards the carousel sits within the page grid. @@ -161,15 +145,6 @@ const carouselStyles = css` } `; -const buttonStyles = css` - display: none; - ${from.tablet} { - display: flex; - gap: ${space[1]}px; - margin-left: auto; - } -`; - const itemStyles = css` display: flex; scroll-snap-align: start; @@ -346,44 +321,22 @@ export const ScrollableCarousel = ({ > {children} - {showNavigation && ( -
-
+ {showNavigation && ( + scrollTo('left')} + onClickNextButton={() => scrollTo('right')} + dataLinkNamePreviousButton={nestedOphanComponents( + 'carousel', + 'previous-button', + )} + dataLinkNameNextButton={nestedOphanComponents( + 'carousel', + 'next-button', + )} + /> )} );