{"version":3,"sources":["webpack:///./src/hooks/useLabel.js","webpack:///./src/requests/updateBasketItems.js","webpack:///./src/hooks/useUpdateBasket.js","webpack:///./src/hooks/useCta.js","webpack:///./src/hooks/usePrice.js","webpack:///./src/hooks/useViewportDimensions.js","webpack:///./src/components/faqs/FAQs.styled.js","webpack:///./src/components/faqs/FAQs.js","webpack:///./src/gtm-events/partsFaq.js","webpack:///./src/requests/getPdf.js","webpack:///./src/requests/emailBasket.js","webpack:///./src/helpers/sumBasket.js","webpack:///./src/gtm-events/partDownload.js","webpack:///./src/requests/getCatalogueByBikeModel.js","webpack:///./src/requests/getBikeModel.js","webpack:///./src/requests/getCataloguePage.js","webpack:///./src/components/price/Price.styled.js","webpack:///./src/components/price/Price.js","webpack:///./src/gtm-events/removeFromBasket.js","webpack:///./src/gtm-events/partIncreaseMini.js","webpack:///./src/gtm-events/partDecreaseMini.js","webpack:///./src/components/basket/Basket.styled.js","webpack:///./src/components/basket/Basket.js","webpack:///./src/components/basket-panel/BasketPanel.styled.js","webpack:///./src/components/basket-panel/BasketPanel.js","webpack:///./src/gtm-events/partSendToDealer.js","webpack:///./src/components/basket-summary/BasketSummary.styled.js","webpack:///./src/components/bike-details/BikeDetails.styled.js","webpack:///./src/components/bike-details/BikeDetails.js","webpack:///./src/hooks/useGetBasketChanges.js","webpack:///./src/components/cart-menu/CartMenu.styled.js","webpack:///./src/components/cart-menu/CartMenu.js","webpack:///./src/components/category-modal/CategoryModal.styled.js","webpack:///./src/components/category-modal/CategoryModal.js","webpack:///./src/components/email-basket/EmailBasket.js","webpack:///./src/components/email-basket-modal/EmailBasketModal.js","webpack:///./src/components/loader/Loader.js","webpack:///./src/components/mobile-list-view/MobileListView.styled.js","webpack:///./src/components/mobile-list-view/MobileListView.js","webpack:///./src/gtm-events/toolTip.js","webpack:///./src/components/parts-table-row/PartsTableRow.styled.js","webpack:///./src/components/parts-table-row/PartsTableRow.js","webpack:///./src/components/mobile-parts-diagram/MobilePartsDiagram.styled.js","webpack:///./src/components/mobile-parts-diagram/MobilePartsDiagram.js","webpack:///./src/components/no-results/NoResults.styled.js","webpack:///./src/components/no-results/NoResults.js","webpack:///./src/components/parts-catalog/PartsCatalog.styled.js","webpack:///./src/components/parts-catalog/PartsCatalog.js","webpack:///./src/components/parts-diagram/PartsDiagram.styled.js","webpack:///./src/components/parts-diagram/PartsDiagram.js","webpack:///./src/components/parts-header/PartsHeader.styled.js","webpack:///./src/components/parts-header/PartsHeader.js","webpack:///./src/components/parts-table/PartsTable.styled.js","webpack:///./src/components/parts-table/PartsTable.js","webpack:///./src/gtm-events/partDecreaseAssembly.js","webpack:///./src/gtm-events/partIncreaseAssembly.js","webpack:///./src/gtm-events/partsRemoveBasketAssembly.js","webpack:///./src/gtm-events/partsAddBasket.js","webpack:///./src/components/zoom-control/ZoomControl.styled.js","webpack:///./src/components/zoom-control/ZoomControl.js","webpack:///./src/components/parts-stepper/PartsStepper.styled.js","webpack:///./src/components/parts-stepper/PartsStepper.js"],"names":["useLabel","labels","useSelector","getLabels","labelName","fallback","updateBasketItems","items","api","post","useUpdateBasket","basket","getBasket","dispatch","useDispatch","a","part","quantity","updatedBasketItem","find","sku","displayIndex","data","OrderLines","basketSummary","setBasketItems","setBasketSumary","setError","useCta","ctas","getCtas","ctaName","usePrice","currencyCode","currencyCodeSelector","languageCode","getLanguageCode","amount","formatPrice","useViewportDimensions","useState","getViewportDimensions","viewportDimensions","setViewportDimensions","useEffect","handleResize","window","addEventListener","removeEventListener","Wrapper","styled","section","theme","colors","offWhite","spacing","Title","h2","fonts","dinRegular","Questions","div","widths","full","FAQs","title","questions","bike","expanded","setExpanded","onToggle","index","questionTitle","pushToDataLayer","name","category","action","document","location","href","label","props","configuratorBikeName","configuratorBikeId","id","configuratorBikeYear","year","partsFaqEvent","map","question","answer","heading","key","dangerouslySetInnerHTML","__html","getPdf","emailBasket","email","receiveCommunication","sumBasket","reduce","sum","item","configuratorAccessoryCategory","getCatalogueByBikeModel","modelId","get","getBikeModel","bikeId","getCataloguePage","partsModalPage","span","Value","Required","Price","price","requiredQuantity","getLabel","replace","configuratorAccessoryName","configuratorAccessoryId","minBp","Summary","p","Table","table","Header","thead","maxBp","InformationWrapper","$padding","Body","tbody","Row","tr","Sku","td","Name","PriceWrapper","Quantity","quantityButtonStyles","css","Focusable","QuantityMinus","button","QuantityValue","QuantityPlus","RemoveWrapper","Remove","RemoveIcon","Icon","Empty","Basket","titleReference","summaryReference","getBike","getPartsList","updateBasket","activeInformaiton","setActiveInformation","length","smallIcon","show","onShow","onClose","asHtml","unitPriceLocalised","type","onClick","Math","max","partDecreaseMiniEvent","aria-hidden","partIncreaseMiniEvent","removeFromBasketEvent","role","Frame","Overlay","Dialog","Main","Close","primary","CloseIcon","Footer","PartsBasketWrapper","BasketSummary","PriceLabel","Submit","SubmitIcon","BasketTitle","BasketTitleSummary","BasketPanel","summary","showSummaryInfo","setShowSummaryInfo","cta","parts","fadeIn","useTransition","from","opacity","enter","leave","reverse","slideIn","position","top","right","bottom","width","transform","innerWidth","zIndex","config","duration","dialogRef","createRef","random","toString","substring","handleEscape","event","keyCode","bodyNoScroll","add","remove","fadeInStyles","fadeInItem","style","slideInStyles","slideInItem","ref","aria-labelledby","aria-describedby","aria-label","onChange","lineItem","partIncreaseEvent","partDecreaseEvent","totalPriceLocalised","clickText","partSendToDealerEvent","disabled","Array","isArray","totalsGrid","menu","Grid","h1","BikeHeader","BikeImage","img","BikeTitle","dinDemi","Attributes","dl","BikeDetails","onCtaClick","bikeAttributes","value","displacement","genre","icon","family","join","src","thumbnail","alt","height","filter","attribute","Fragment","useGetBasketChanges","previousBasket","usePrevious","latestChange","setLatestChange","change","accumulated","line","previousLine","timeout","setTimeout","clearTimeout","outline","Tray","TrayHeader","TrayTitle","TrayClose","TrayCloseIcon","TrayBody","TrayToggle","gray","TrayToggleIcon","Product","Actions","Action","ActionDivider","ActionLabel","ActionIconWrapper","ActionIcon","ActionIndicator","ActionNotification","visible","ActionNotificationTitle","strong","ActionNotificationDescription","PriceValue","CartMenu","actions","image","onCheckout","onTrayClose","onTrayOpen","trayExpanded","indicator","basketNotification","Content","CategoryModal","getCta","headerOffset","useHeaderOffset","transitions","inset","innerHeight","useMemo","close","linkGridItems","catalogue","_links","rel","setPartsModalPage","to","breadcumb","path","breadCrumbs","Id","styles","links","WithLabels","agreeToTermsRequired","emailCancelCta","emailOptInText","emailPlaceholderText","emailSubmitCta","emailSubtitle","emailTermsText","emailTitle","invalidEmail","open","LocalisedLoader","text","Menu","MenuButton","MenuDivider","MenuButtonText","MenuButtonIcon","MenuButtonChevron","MenuItem","children","MobileListView","view","basketCount","currentView","setCurrentView","submit","EmailBasket","onCancel","onSubmit","values","padded","small","partDownloadEvent","TableCell","TableViewCell","TableAddOrRemoveCell","SequenceWrapper","Sequence","selected","MobileSequence","showsMobileSequence","MobileGroup","MobileLabel","ChangeQuantity","minus","AddOrRemove","buttons","$added","PartsTableRow","inBasket","onMinus","onPlus","onToggleCart","onViewPart","priceLocalised","sequence","isTabletLargeOrAbove","useBreakpoint","activeInformation","onMouseEnter","setHighlightedPart","parseInt","onMouseLeave","toolTipEvent","partsTableRrp","partsTableQty","offsetTop","PartsDiagramWrapper","PartsDiagramContainer","MobilePartsDiagram","hotspots","highlightedPart","getHighlightedPart","headerHeight","useElementDimensions","tabIndex","output","Message","NoResults","query","Container","PartsCatalog","breadcrumb","catalog","Preview","Zoom","PrismaZoom","ImageWrapper","Image","Hotspot","y","imageHeight","x","imageWidth","scale","body","HotspotScreenReader","Control","PartsDiagram","hotSpots","useComponentDimensions","containerRef","dimensions","zoom","setZoom","prismaZoomRef","useRef","filtered","self","findIndex","hotspot","zoomPercentage","hotspotScale","constrainedWidth","min","constrainedHeight","onZoomChange","zoomLevel","maxZoom","scrollVelocity","allowTouchEvents","hash","partName","onZoomIn","current","zoomIn","onZoomOut","zoomOut","header","PartsCount","PartsCountIcon","SearchForm","form","PartsHeader","onShowCategories","onSearchChange","partsCount","iconLeft","preventDefault","target","elements","search","onReset","reset","placeholder","maxLength","Head","CartIcon","TableHeader","th","$center","PartsTable","rows","querySelector","scrollIntoView","block","row","partsRemoveBasketEvent","partsAddBasketEvent","buttonStyles","ZoomIn","ZoomOut","zoomLabelStyle","ZoomInLabel","ZoomOutLabel","ButtonIcon","Meter","MeterLabel","MeterInner","ZoomControl","StepperComponent","RestrictedWidth","PartsStepper","bikeSearchCompleted","catalogueCompleted","partsCompleted","product","useHideElement","classList","catalogQueryString","toQueryString","productCode","completedSteps","undefined","step","steps","number","bold","uppercase","activeStep","linear","bordered","shade","hideStepNumbersIfCompleted"],"mappings":"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","file":"b41455d85582a0888ed1.js","sourcesContent":["import { useSelector } from 'react-redux';\nimport { getLabels } from 'src/redux/app/selectors';\n\nconst useLabel = () => {\n const labels = useSelector(getLabels);\n return (labelName, fallback) => labels[labelName] || fallback || labelName;\n};\n\nexport default useLabel;\n","import { api } from '@triumph/shared';\n\nconst updateBasketItems = (items) => api.post('/api/partsfinder/basket/items', items);\n\nexport default updateBasketItems;\n","import { useDispatch, useSelector } from 'react-redux';\nimport { setBasketItems, setBasketSumary, setError } from 'src/redux/app/actions';\nimport { getBasket } from 'src/redux/app/selectors';\nimport updateBasketItems from 'src/requests/updateBasketItems';\n\nconst useUpdateBasket = () => {\n const basket = useSelector(getBasket);\n const dispatch = useDispatch();\n\n return async ({ part, quantity }) => {\n const updatedBasketItem = {\n ...(basket.find(({ sku, displayIndex }) => sku === part.sku && displayIndex === part.displayIndex) || {\n ...part,\n }),\n quantity,\n };\n\n try {\n const {\n data: { OrderLines: items, ...basketSummary },\n } = await updateBasketItems([updatedBasketItem]);\n\n dispatch(setBasketItems(items));\n dispatch(setBasketSumary(basketSummary));\n } catch (e) {\n dispatch(setError(true));\n }\n };\n};\n\nexport default useUpdateBasket;\n","import { useSelector } from 'react-redux';\nimport { getCtas } from 'src/redux/app/selectors';\n\nconst useCta = () => {\n const ctas = useSelector(getCtas);\n return (ctaName, fallback) => ctas[ctaName] || fallback || '#';\n};\n\nexport default useCta;\n","import { useSelector } from 'react-redux';\nimport { getLanguageCode, formatPrice } from '@triumph/shared';\nimport { currencyCodeSelector } from 'src/redux/app/selectors';\n\nconst usePrice = () => {\n const currencyCode = useSelector(currencyCodeSelector) || 'GBP';\n const languageCode = getLanguageCode();\n\n return (amount) => formatPrice(amount, currencyCode, languageCode);\n};\n\nexport default usePrice;\n","import React, { useEffect, useState } from 'react';\nimport { getViewportDimensions } from '@triumph/shared';\n\nconst useViewportDimensions = () => {\n const [viewportDimensions, setViewportDimensions] = useState(getViewportDimensions());\n\n useEffect(() => {\n const handleResize = () => {\n setViewportDimensions(getViewportDimensions());\n };\n\n window.addEventListener('resize', handleResize);\n return () => window.removeEventListener('resize', handleResize);\n }, []);\n\n return viewportDimensions;\n};\n\nexport default useViewportDimensions;\n","import React from 'react';\nimport { theme } from '@triumph/shared';\nimport styled from 'styled-components';\n\nexport const Wrapper = styled.section`\n background-color: ${theme.colors.offWhite};\n padding: clamp(${theme.spacing(7)}, 5vw, ${theme.spacing(8)}) ${theme.spacing(2)};\n`;\n\nexport const Title = styled.h2`\n margin-bottom: clamp(${theme.spacing(6)}, 5vw, ${theme.spacing(7)});\n font-family: ${theme.fonts.dinRegular};\n font-style: normal;\n font-weight: 600;\n font-size: 1.375rem;\n line-height: 1.09;\n text-align: center;\n text-transform: uppercase;\n color: #000;\n`;\n\nexport const Questions = styled.div`\n max-width: ${theme.widths.full};\n margin-inline: auto;\n\n > * + * {\n margin-top: ${theme.spacing(1)};\n }\n`;\n","import React, { useState } from 'react';\nimport { Accordion } from '@triumph/shared';\nimport partsFaqEvent from 'src/gtm-events/partsFaq';\nimport { Wrapper, Title, Questions } from './FAQs.styled';\n\nconst FAQs = ({ title, questions = [], bike }) => {\n const [expanded, setExpanded] = useState();\n\n const onToggle = (index, questionTitle) => {\n setExpanded(index === expanded ? null : index);\n\n if (index !== expanded) {\n partsFaqEvent({ questionTitle, bike });\n }\n };\n\n return (\n <Wrapper>\n {title && <Title>{title}</Title>}\n <Questions>\n {questions.map(({ question, answer, title: questionTitle }, index) => (\n <Accordion\n title={questionTitle}\n heading={question}\n key={`${questionTitle}-${index}`}\n onToggle={() => onToggle(index, questionTitle)}\n expanded={index === expanded}\n >\n {/* eslint-disable-next-line react/no-danger */}\n <div dangerouslySetInnerHTML={{ __html: answer }} />\n </Accordion>\n ))}\n </Questions>\n </Wrapper>\n );\n};\n\nexport default FAQs;\n","import { pushToDataLayer } from '@triumph/shared';\n\nexport default ({ bike, questionTitle }) =>\n pushToDataLayer({\n name: 'partsFaq',\n category: 'FAQ',\n action: document.location.href,\n label: questionTitle,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n },\n });\n","const getPdf = () => '/api/partsfinder/pdf';\n\nexport default getPdf;\n","import { api } from '@triumph/shared';\n\n// TODO TRIUZSB-49 update this to use the real API endpoint once known\nconst emailBasket = (email, receiveCommunication) =>\n api.post('/api/basket/email', {\n email,\n receiveCommunication,\n });\n\nexport default emailBasket;\n","const sumBasket = (basket) => {\n if (!basket) {\n return 0;\n }\n\n return basket.reduce((sum, item) => sum + item.quantity, 0);\n};\n\nexport default sumBasket;\n","import { pushToDataLayer } from \"@triumph/shared\";\n\nexport default ({ bike, category }) => pushToDataLayer({\n name: 'partDownload',\n category: 'Parts - Assembly',\n action: `Download Basket`,\n label: bike.name,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n configuratorAccessoryCategory: category.name,\n },\n});","import { api } from '@triumph/shared';\n\nconst getCatalogueByBikeModel = (modelId) => api.get(`/api/partsfinder/catalogue?ModelId=${modelId}`);\n\nexport default getCatalogueByBikeModel;\n","import { api } from '@triumph/shared';\n\nconst getBikeModel = (bikeId, modelId) => api.get(`/api/partsfinder/bike/${bikeId}?ModelId=${modelId}`);\n\nexport default getBikeModel;\n","import { api } from '@triumph/shared';\n\nconst getCataloguePage = (partsModalPage) => api.get(`/api/partsfinder/cataloguepage?id=${partsModalPage}`);\n\nexport default getCataloguePage;\n","import styled from 'styled-components';\nimport { theme } from '@triumph/shared';\n\nexport const Wrapper = styled.span`\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.8125rem;\n line-height: 1.25rem;\n color: #666;\n`;\n\nexport const Value = styled.span`\n span {\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n color: #2a2a2a;\n }\n`;\n\nexport const Required = styled.span`\n white-space: nowrap;\n`;\n","import React from 'react';\nimport usePrice from 'src/hooks/usePrice';\nimport { useLabel } from 'src/hooks';\nimport { Required, Value, Wrapper } from './Price.styled';\n\nconst Price = ({ price, requiredQuantity }) => {\n const getLabel = useLabel();\n const formatPrice = usePrice();\n return (\n <Wrapper>\n <Value\n dangerouslySetInnerHTML={{\n __html: getLabel('partsTablePerItem').replace('{0}', `<span>${price || formatPrice(0)}</span>`),\n }}\n />\n {requiredQuantity > 0 ? (\n requiredQuantity && <Required>{getLabel('partsTableRequired').replace('{0}', requiredQuantity)}</Required>\n ) : (\n <span>{getLabel('partsTableAsRequired')}</span>\n )}\n </Wrapper>\n );\n};\n\nexport default Price;\n","import { pushToDataLayer } from '@triumph/shared';\n\nexport default ({ part, bike, category }) =>\n pushToDataLayer({\n name: 'removeFromBasket',\n category: 'Parts - Mini Basket',\n action: 'Mini Basket - Remove',\n label: part.sku,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n configuratorAccessoryCategory: category.name,\n configuratorAccessoryName: part.name,\n configuratorAccessoryId: part.sku,\n },\n });\n","import { pushToDataLayer } from '@triumph/shared';\n\nexport default ({ part, bike, category }) =>\n pushToDataLayer({\n name: 'partIncreaseMini',\n category: 'Parts - Mini Basket',\n action: 'Mini Basket - Increase',\n label: part.sku,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n configuratorAccessoryCategory: category.name,\n configuratorAccessoryName: part.name,\n configuratorAccessoryId: part.sku,\n },\n });\n","import { pushToDataLayer } from '@triumph/shared';\n\nexport default ({ part, bike, category }) =>\n pushToDataLayer({\n name: 'partDecreaseMini',\n category: 'Parts - Mini Basket',\n action: 'Mini Basket - Decrease',\n label: part.sku,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n configuratorAccessoryCategory: category.name,\n configuratorAccessoryName: part.name,\n configuratorAccessoryId: part.sku,\n },\n });\n","import styled, { css } from 'styled-components';\nimport { Focusable, Icon, maxBp, minBp, theme } from '@triumph/shared';\n\nexport const Wrapper = styled.div``;\n\nexport const Title = styled.h2`\n margin: 0 0 ${theme.spacing(2)};\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1.375rem;\n line-height: 1.09;\n text-transform: uppercase;\n color: #000;\n\n @media ${minBp('tabletLarge')} {\n font-size: 1.5625rem;\n line-height: 1.32;\n text-align: center;\n }\n`;\n\nexport const Summary = styled.p`\n margin: 0 0 ${theme.spacing(3)};\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.375;\n color: #666;\n\n @media ${minBp('tabletLarge')} {\n margin-bottom: ${theme.spacing(7)};\n font-size: 0.875rem;\n line-height: 1.428;\n text-align: center;\n }\n`;\n\nexport const Table = styled.table`\n width: 100%;\n display: table;\n margin-bottom: clamp(20px, 5vw, 50px);\n`;\n\nexport const Header = styled.thead`\n @media ${maxBp('tabletLarge')} {\n display: none;\n }\n\n th {\n padding-bottom: 15px;\n border-bottom: 1px solid #e6e6e6;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1.428;\n text-align: left;\n color: #666;\n }\n`;\n\nexport const InformationWrapper = styled.div`\n display: flex;\n gap: 0.25rem;\n\n .information__show {\n transform: translateY(10%);\n }\n @media ${minBp('tabletLarge')} {\n ${({ $padding = false }) =>\n $padding &&\n `\n padding-left: ${theme.spacing(2)};\n `};\n }\n`;\n\nexport const Body = styled.tbody`\n @media ${maxBp('tabletLarge')} {\n > * + * {\n margin-top: ${theme.spacing(2)};\n }\n }\n`;\n\nexport const Row = styled.tr`\n vertical-align: middle;\n\n @media ${maxBp('tabletLarge')} {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n align-items: center;\n border: 1px solid #e6e6e6;\n }\n\n @media ${minBp('tabletLarge')} {\n padding: ${theme.spacing(3)} 0;\n width: 100%;\n border-bottom: 1px solid #e6e6e6;\n\n td {\n height: 80px;\n border-bottom: 1px solid #e6e6e6;\n }\n }\n`;\n\nexport const Sku = styled.td`\n grid-column: 1 / -1;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.8125rem;\n line-height: 1.538;\n color: #666;\n\n @media ${maxBp('tabletLarge')} {\n padding: ${theme.spacing(2)} ${theme.spacing(2)} 0;\n }\n`;\n\nexport const Name = styled.td`\n grid-column: 1 / -1;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.375;\n color: #2a2a2a;\n\n @media ${maxBp('tabletLarge')} {\n padding: 0 ${theme.spacing(2)} ${theme.spacing(2)};\n border-bottom: 1px solid #e6e6e6;\n }\n`;\n\nexport const PriceWrapper = styled.td`\n span {\n line-height: 1.25rem;\n }\n\n @media ${maxBp('tabletLarge')} {\n padding: ${theme.spacing(2)};\n }\n`;\n\nexport const Quantity = styled.div`\n display: flex;\n align-items: center;\n gap: 0.25rem;\n padding: ${theme.spacing(1)};\n\n @media ${minBp('additional.mobile')} {\n gap: ${theme.spacing(1)};\n }\n`;\n\nconst quantityButtonStyles = css`\n position: relative;\n width: 1.25rem;\n height: 1.25rem;\n border: none;\n appearance: none;\n background: none;\n color: #000;\n cursor: pointer;\n\n > * {\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n }\n\n ${Focusable()}\n`;\n\nexport const QuantityMinus = styled.button`\n ${quantityButtonStyles}\n font-size: 1px;\n`;\n\nexport const QuantityValue = styled.span`\n display: block;\n width: 1.875rem;\n height: 1.875rem;\n border: 1px solid #000;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1.875rem;\n text-align: center;\n`;\n\nexport const QuantityPlus = styled.button`\n ${quantityButtonStyles}\n font-size: 0.75rem;\n`;\n\nexport const RemoveWrapper = styled.td`\n text-align: right;\n\n @media ${maxBp('tabletLarge')} {\n padding-right: ${theme.spacing(2)};\n }\n`;\n\nexport const Remove = styled.button`\n appearance: none;\n max-width: 12rem;\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: 0.15rem;\n padding: 0.4rem;\n border-radius: 0.3em;\n border: none;\n background-color: #000;\n color: #fff;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.8125rem;\n line-height: 1;\n text-transform: capitalize;\n cursor: pointer;\n outline-offset: 2px;\n\n ${Focusable()}\n\n @media ${minBp('additional.mobile')} {\n gap: 0.25rem;\n padding: 0.6rem;\n }\n`;\n\nexport const RemoveIcon = styled(Icon)`\n margin-right: 0.3125rem;\n font-size: 0.5625rem;\n`;\n\nexport const Empty = styled.p`\n margin-bottom: 2rem;\n`;\n","import React, { useState } from 'react';\nimport { Icon, Information, Note } from '@triumph/shared';\nimport { useLabel, useUpdateBasket } from 'src/hooks';\nimport Price from 'components/price';\nimport { Label } from 'src/_utility';\nimport removeFromBasketEvent from 'src/gtm-events/removeFromBasket';\nimport partIncreaseMiniEvent from 'src/gtm-events/partIncreaseMini';\nimport partDecreaseMiniEvent from 'src/gtm-events/partDecreaseMini';\nimport { getBike, getPartsList } from 'src/redux/app/selectors';\nimport { useSelector } from 'react-redux';\nimport {\n Body,\n Header,\n Row,\n RemoveIcon,\n Remove,\n Sku,\n Name,\n PriceWrapper,\n Quantity,\n QuantityMinus,\n QuantityValue,\n QuantityPlus,\n RemoveWrapper,\n Wrapper,\n Table,\n Title,\n Summary,\n InformationWrapper,\n Empty,\n} from './Basket.styled';\n\nconst Basket = ({ items = [], titleReference, summaryReference }) => {\n const getLabel = useLabel();\n const bike = useSelector(getBike);\n const category = useSelector(getPartsList);\n const updateBasket = useUpdateBasket();\n const [activeInformaiton, setActiveInformation] = useState(null);\n\n return (\n <Wrapper>\n <Title id={titleReference}>\n <Label name=\"basketTitle\" />\n </Title>\n <Summary id={summaryReference}>\n <Label name=\"basketSummary\" />\n </Summary>\n {items.length > 0 ? (\n <Table>\n <Header>\n <tr>\n <th>\n <Label name=\"PartNo\" />\n </th>\n <th>\n <Label name=\"partsTableItemName\" />\n </th>\n <th>\n <InformationWrapper>\n <Information\n title={getLabel('partsTableRrpInfoTitle')}\n smallIcon\n show={activeInformaiton === 'rrp'}\n onShow={() => setActiveInformation('rrp')}\n onClose={() => setActiveInformation(null)}\n >\n <Label name=\"partsTableRrpInfo\" asHtml />\n </Information>\n <Label name=\"partsTableRrp\" />\n </InformationWrapper>\n </th>\n <th>\n <InformationWrapper $padding>\n <Information\n title={getLabel('partsTableQtyInfoTitle')}\n smallIcon\n show={activeInformaiton === 'qty'}\n onShow={() => setActiveInformation('qty')}\n onClose={() => setActiveInformation(null)}\n >\n <Label name=\"partsTableQtyInfo\" asHtml />\n </Information>{' '}\n <Label name=\"partsTableQty\" />\n </InformationWrapper>\n </th>\n <th></th>\n </tr>\n </Header>\n <Body>\n {items.map((part) => (\n <Row key={part.sku + part.displayIndex}>\n <Sku>{part.sku}</Sku>\n <Name>{part.name}</Name>\n <PriceWrapper>\n {part?.unitPriceLocalised === 'POA' ? (\n part?.unitPriceLocalised\n ) : (\n <Price price={part?.unitPriceLocalised} requiredQuantity={part?.requiredQuantity} />\n )}\n </PriceWrapper>\n <td>\n <Quantity>\n <QuantityMinus\n type=\"button\"\n onClick={() => {\n updateBasket({\n part,\n quantity: Math.max(0, part.quantity - 1),\n });\n\n partDecreaseMiniEvent({ bike, category, part });\n }}\n >\n <Icon name=\"minus\" aria-hidden />\n </QuantityMinus>\n <QuantityValue>{part?.quantity}</QuantityValue>\n <QuantityPlus\n type=\"button\"\n onClick={() => {\n updateBasket({\n part,\n quantity: part.quantity + 1,\n });\n\n partIncreaseMiniEvent({ bike, category, part });\n }}\n >\n <Icon name=\"plus\" aria-hidden />\n </QuantityPlus>\n </Quantity>\n </td>\n <RemoveWrapper>\n <Remove\n onClick={() => {\n updateBasket({\n part,\n quantity: 0,\n });\n\n removeFromBasketEvent({ bike, category, part });\n }}\n >\n <RemoveIcon name=\"close\" aria-hidden />\n {getLabel('basketRemove')}\n </Remove>\n </RemoveWrapper>\n </Row>\n ))}\n </Body>\n </Table>\n ) : (\n <Empty>{getLabel('basketEmpty')}</Empty>\n )}\n <Note role=\"alert\" title={getLabel('basketDisclaimerTitle')}>\n {getLabel('basketDisclaimerText')}\n </Note>\n </Wrapper>\n );\n};\n\nexport default Basket;\n","import styled from 'styled-components';\nimport { Icon, theme, minBp, Focusable } from '@triumph/shared';\n\nexport const Frame = styled.div`\n position: absolute;\n inset: 0;\n overflow: hidden;\n z-index: 4000;\n`;\n\nexport const Overlay = styled.div`\n position: absolute;\n inset: 0;\n display: block;\n background-color: rgba(0, 0, 0, 0.6);\n`;\n\nexport const Wrapper = styled.div`\n position: absolute;\n top: 0;\n right: 0;\n bottom: 0;\n display: flex;\n justify-content: flex-end;\n z-index: 4000;\n`;\n\nexport const Dialog = styled.div`\n position: relative;\n top: 0;\n right: 0;\n bottom: 0;\n width: min(52rem, 80vw);\n display: flex;\n flex-direction: column;\n background-color: #fff;\n`;\n\nexport const Main = styled.div`\n position: relative;\n flex: 1;\n padding: ${theme.spacing(7)} ${theme.spacing(6)};\n overflow: auto;\n`;\n\nexport const Close = styled.button`\n position: absolute;\n top: ${theme.spacing(5)};\n right: ${theme.spacing(5)};\n display: grid;\n place-items: center;\n width: 1.875rem;\n height: 1.875rem;\n border: none;\n padding: 0;\n appearance: none;\n background: none;\n color: #2a2a2a;\n cursor: pointer;\n transition: color 200ms ease-in-out;\n\n &:hover,\n &:focus {\n color: ${theme.colors.primary};\n }\n\n ${Focusable()}\n`;\n\nexport const CloseIcon = styled(Icon)`\n font-size: 0.9375rem;\n`;\n\nexport const Footer = styled.div`\n display: grid;\n grid-template-columns: repeat(2, 1fr);\n grid-template-rows: 5rem;\n background-color: ${theme.colors.primary};\n color: #fff;\n font-family: ${theme.fonts.dinRegular};\n text-align: center;\n`;\n\nexport const PartsBasketWrapper = styled.div`\n margin-bottom: clamp(20px, 5vw, 50px);\n`;\n\nexport const BasketSummary = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 3rem;\n background-color: #000;\n font-weight: 600;\n font-size: 0.8125rem;\n line-height: 1.538;\n`;\n\nexport const PriceLabel = styled.span`\n display: flex;\n gap: 0.5rem;\n\n .information__show {\n transform: translateY(10%);\n\n .icon {\n color: #fff;\n }\n }\n`;\n\nexport const Price = styled.span`\n font-size: 1.5625rem;\n line-height: 1.32;\n`;\n\nexport const Submit = styled.button`\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: ${theme.spacing(1)};\n border: none;\n appearance: none;\n background-color: ${theme.colors.primary};\n color: #fff;\n cursor: pointer;\n font-family: ${theme.fonts.dinRegular};\n font-size: 1rem;\n line-height: 1.25;\n text-transform: uppercase;\n transition: background-color 0.2s ease-in-out;\n\n &:is(:hover, :focus):not(:disabled) {\n background-color: #8f111f;\n }\n\n &:disabled {\n cursor: not-allowed;\n }\n\n ${Focusable()}\n`;\n\nexport const SubmitIcon = styled(Icon)`\n transform: rotate(90deg) translateX(-15%);\n font-size: 0.5rem;\n`;\n\nexport const BasketTitle = styled.h2`\n margin: 0 0 ${theme.spacing(2)};\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1.375rem;\n line-height: 1.09;\n text-transform: uppercase;\n color: #000;\n\n @media ${minBp('tabletLarge')} {\n font-size: 1.5625rem;\n line-height: 1.32;\n text-align: center;\n }\n`;\n\nexport const BasketTitleSummary = styled.p`\n margin: 0 0 ${theme.spacing(3)};\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.375;\n color: #666;\n\n @media ${minBp('tabletLarge')} {\n margin-bottom: ${theme.spacing(7)};\n font-size: 0.875rem;\n line-height: 1.428;\n text-align: center;\n }\n`;\n","import React, { createRef, useEffect, useState } from 'react';\nimport { bodyNoScroll, Information, PartsBasket, Note } from '@triumph/shared';\nimport { useLabel, usePrice, useUpdateBasket } from 'src/hooks';\nimport { animated, useTransition } from 'react-spring';\nimport { Label } from 'src/_utility';\nimport { useSelector } from 'react-redux';\nimport { getBike, getLabels, getPartsList } from 'src/redux/app/selectors';\nimport useCta from 'src/hooks/useCta';\nimport partIncreaseEvent from 'src/gtm-events/partIncreaseMini';\nimport partDecreaseEvent from 'src/gtm-events/partDecreaseMini';\nimport removeFromBasketEvent from 'src/gtm-events/removeFromBasket';\nimport partSendToDealerEvent from 'src/gtm-events/partSendToDealer';\nimport {\n BasketSummary,\n BasketTitle,\n BasketTitleSummary,\n Close,\n CloseIcon,\n Dialog,\n Footer,\n Frame,\n Main,\n Overlay,\n PartsBasketWrapper,\n Price,\n PriceLabel,\n Submit,\n SubmitIcon,\n Wrapper,\n} from './BasketPanel.styled';\n\nconst BasketPanel = ({ onClose, items = [], summary, show = false }) => {\n const labels = useSelector(getLabels);\n const updateBasket = useUpdateBasket();\n const [showSummaryInfo, setShowSummaryInfo] = useState(false);\n const getLabel = useLabel();\n const formatPrice = usePrice();\n const cta = useCta();\n const bike = useSelector(getBike);\n const parts = useSelector(getPartsList);\n\n const fadeIn = useTransition(show, {\n key: (item) => item,\n from: { opacity: 0 },\n enter: { opacity: 1 },\n leave: { opacity: 0 },\n reverse: show,\n });\n\n const slideIn = useTransition(show, {\n key: (item) => item,\n from: {\n position: 'absolute',\n top: 0,\n right: 0,\n bottom: 0,\n width: 'min(52rem, 80vw)',\n transform: `translateX(${window.innerWidth}px)`,\n zIndex: 2000,\n },\n enter: { transform: 'translateX(0px)' },\n leave: { transform: `translateX(${window.innerWidth}px)` },\n config: { duration: 600 },\n reverse: show,\n });\n\n const dialogRef = createRef();\n const titleReference = Math.random()\n .toString(36)\n .substring(2, 15);\n const summaryReference = Math.random()\n .toString(36)\n .substring(2, 15);\n\n const handleEscape = (event) => {\n if (event.keyCode === 27) {\n setShowSummaryInfo(false);\n onClose();\n }\n };\n\n useEffect(() => {\n window.addEventListener('keydown', handleEscape, true);\n return () => {\n window.removeEventListener('keydown', handleEscape, true);\n };\n });\n\n useEffect(() => (show ? bodyNoScroll.add() : bodyNoScroll.remove()), [show]);\n\n return fadeIn(\n (fadeInStyles, fadeInItem) =>\n fadeInItem && (\n <Frame>\n <animated.div style={fadeInStyles}>\n <Overlay onClick={onClose} />\n </animated.div>\n {slideIn(\n (slideInStyles, slideInItem) =>\n slideInItem && (\n <animated.div style={slideInStyles}>\n <Wrapper>\n <Dialog\n ref={dialogRef}\n role=\"dialog\"\n aria-labelledby={titleReference}\n aria-describedby={summaryReference}\n >\n <Main>\n <Close\n onClick={() => {\n setShowSummaryInfo(false);\n onClose();\n }}\n aria-label={getLabel('close')}\n >\n <CloseIcon name=\"close\" aria-hidden=\"true\" />\n </Close>\n <div>\n <BasketTitle id={titleReference}>\n <Label name=\"basketTitle\" />\n </BasketTitle>\n <BasketTitleSummary id={summaryReference}>\n <Label name=\"basketSummary\" />\n </BasketTitleSummary>\n <PartsBasketWrapper>\n <PartsBasket\n items={items}\n labels={labels}\n onChange={({ type, ...lineItem }) => {\n updateBasket(lineItem);\n\n const event = {\n part: lineItem.part,\n category: parts,\n bike,\n };\n\n if (type === 'increase') {\n partIncreaseEvent(event);\n }\n\n if (type === 'decrease') {\n partDecreaseEvent(event);\n }\n\n if (type === 'remove') {\n removeFromBasketEvent(event);\n }\n }}\n />\n </PartsBasketWrapper>\n <Note role=\"alert\" title={getLabel('basketDisclaimerTitle')}>\n {getLabel('basketDisclaimerText')}\n </Note>\n </div>\n </Main>\n <Footer>\n <BasketSummary>\n <PriceLabel>\n <Information\n title={getLabel('totalPrice')}\n smallIcon\n show={showSummaryInfo}\n onShow={() => setShowSummaryInfo(true)}\n onClose={() => setShowSummaryInfo(false)}\n >\n <Label name=\"basketModalPriceInfo\" asHtml />\n </Information>\n <Label name=\"trayTotal\" />\n </PriceLabel>\n <Price>{summary?.totalPriceLocalised || formatPrice(0)}</Price>\n </BasketSummary>\n <Submit\n type=\"button\"\n onClick={() => {\n partSendToDealerEvent({ bike });\n document.location = cta('basket');\n }}\n disabled={!(Array.isArray(items) && items.length > 0)}\n >\n {getLabel('basketCta')}\n <SubmitIcon name=\"chevron-down\" aria-hidden />\n </Submit>\n </Footer>\n </Dialog>\n </Wrapper>\n </animated.div>\n )\n )}\n </Frame>\n )\n );\n};\n\nexport default BasketPanel;\n","import { pushToDataLayer } from \"@triumph/shared\";\n\nexport default ({ clickText, bike }) => pushToDataLayer({\n name: 'partSendToDealer',\n category: 'Parts - Mini Basket',\n action: 'Mini Basket CTA',\n label: clickText,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n },\n});","import styled, { css } from 'styled-components';\nimport { Icon, maxBp, minBp, theme } from '@triumph/shared';\n\nexport const Wrapper = styled.div``;\n\nexport const Tray = styled.div`\n background-color: #fff;\n\n @media ${minBp('tabletLarge')} {\n display: none;\n }\n`;\n\nexport const TrayTitle = styled.button`\n position: sticky;\n top: 0;\n height: 4rem;\n width: 100%;\n padding: 0 ${theme.spacing(3)};\n border: none;\n background: #2a2a2a;\n cursor: pointer;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.375;\n text-align: center;\n text-transform: uppercase;\n color: #fff;\n\n span + span {\n margin-left: 0.3125rem;\n color: #aeaeae;\n }\n`;\n\nexport const TrayTitleIcon = styled(Icon)`\n position: absolute;\n top: 50%;\n right: ${theme.spacing(3)};\n font-size: 0.625rem;\n transform: translateY(-50%) scaleY(${({ expanded = false }) => (!expanded ? -1 : 1)});\n transition: transform 100ms ease-in-out;\n`;\n\nexport const TrayContent = styled.div`\n padding: ${theme.spacing(5)} ${theme.spacing(2)};\n\n @media ${minBp('tabletLarge')} {\n padding-inline: 0;\n }\n`;\n\nexport const Desktop = styled.div`\n @media ${maxBp('tabletLarge')} {\n display: none;\n }\n`;\n\nexport const Content = styled.div`\n display: flex;\n flex-direction: column;\n\n gap: ${theme.spacing(6)};\n\n @media ${minBp('tabletLarge')} {\n gap: ${theme.spacing(5)};\n }\n`;\n\nexport const Title = styled.h2`\n padding: 0 0 ${theme.spacing(6)};\n border-bottom: 1px solid #ccc;\n margin: 0;\n font-family: ${theme.fonts.dinRegular};\n font-style: normal;\n font-weight: 600;\n font-size: 1.375rem;\n line-height: 1.363;\n text-transform: uppercase;\n color: #000;\n\n @media ${maxBp('tabletLarge')} {\n display: none;\n }\n`;\n\nexport const Empty = styled.p``;\n\nexport const Items = styled.div`\n display: grid;\n gap: ${theme.spacing(5)};\n\n @media ${minBp('tabletLarge')} {\n gap: ${theme.spacing(3)};\n }\n`;\n\nexport const Item = styled.div`\n display: grid;\n grid-template-columns: 3fr 1fr 1fr;\n gap: 0.3125rem ${theme.spacing(4)};\n padding-bottom: ${theme.spacing(5)};\n border-bottom: 1px solid #ccc;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.375;\n text-transform: uppercase;\n color: #2a2a2a;\n\n @media ${minBp('tabletLarge')} {\n padding-bottom: ${theme.spacing(3)};\n }\n`;\n\nexport const Sku = styled.span`\n grid-column: 1 / -1;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1.428;\n color: #666;\n`;\n\nexport const Name = styled.span``;\n\nexport const Quantity = styled.span``;\n\nexport const Price = styled.span`\n display: flex;\n flex-direction: column;\n`;\n\nexport const PriceNote = styled.span`\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.8125rem;\n line-height: 1.538;\n color: #666;\n`;\n\nexport const Totals = styled.div`\n display: grid;\n grid-gap: ${theme.spacing(3)};\n`;\n\nconst totalsGrid = css`\n display: grid;\n grid-template-columns: 1fr 1fr;\n grid-gap: ${theme.spacing(3)};\n\n > * :last-child {\n text-align: right;\n }\n`;\n\nexport const TotalRow = styled.div`\n ${totalsGrid};\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.375;\n color: #666;\n`;\n\nexport const TotalRRP = styled.div`\n ${totalsGrid};\n font-family: ${theme.fonts.dinRegular};\n font-style: normal;\n font-weight: 600;\n font-size: 1.375rem;\n line-height: 1.363;\n text-transform: uppercase;\n color: #2a2a2a;\n`;\n\nexport const Menu = styled.menu`\n display: grid;\n gap: clamp(${theme.spacing(3)}, 5vw, ${theme.spacing(5)});\n padding: ${theme.spacing(5)} 0 0;\n border-top: 1px solid #ccc;\n margin: 0;\n list-style: none;\n`;\n\nexport const MenuButton = styled.button`\n display: flex;\n align-items: center;\n width: 100%;\n gap: ${theme.spacing(3)};\n padding: 0;\n border: none;\n background: none;\n color: #2a2a2a;\n cursor: pointer;\n\n &:hover,\n &:focus {\n color: ${theme.colors.primary};\n }\n`;\n\nexport const MenuButtonText = styled.span`\n font-family: ${theme.fonts.dinRegular};\n font-size: 1rem;\n line-height: 1.375;\n text-transform: capitalize;\n`;\n\nexport const MenuButtonIcon = styled(Icon)`\n font-size: 1.125rem;\n`;\n","import React from 'react';\nimport { theme, minBp } from '@triumph/shared';\nimport styled from 'styled-components';\n\nexport const Wrapper = styled.section`\n background-color: #f6f6f6;\n padding: clamp(${theme.spacing(6)}, 5vw, 4.6875rem) ${theme.spacing(2)};\n border-bottom: 1px solid #dedede;\n`;\n\nexport const Grid = styled.div`\n display: grid;\n grid-gap: ${theme.spacing(6)};\n max-width: 70rem;\n margin-inline: auto;\n\n @media ${minBp('desktop')} {\n align-items: center;\n grid-template-columns: 1fr 1fr;\n grid-gap: 8rem;\n }\n`;\n\nexport const Title = styled.h1`\n margin: 0 0 ${theme.spacing(5)};\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1.5rem;\n line-height: 1.083;\n text-transform: uppercase;\n color: #000;\n`;\n\nexport const Summary = styled.p`\n font-family: ${theme.fonts.dinRegular};\n font-size: 1rem;\n line-height: 1.375;\n color: #2a2a2a;\n margin: ${theme.spacing(5)} 0px;\n`;\n\nexport const BikeHeader = styled.div`\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: ${theme.spacing(5)};\n padding-bottom: 1rem;\n border-bottom: 1px solid #e6e6e6;\n margin-bottom: ${theme.spacing(5)};\n\n @media ${minBp('desktop')} {\n padding-bottom: 1.125rem;\n }\n`;\n\nexport const BikeImage = styled.img`\n margin-left: -${theme.spacing(5)};\n margin-right: -${theme.spacing(5)};\n`;\n\nexport const BikeTitle = styled.h2`\n font-family: ${theme.fonts.dinRegular};\n font-size: 1.375rem;\n line-height: 1.153;\n text-transform: uppercase;\n color: #000;\n\n span {\n display: block;\n font-family: ${theme.fonts.dinDemi};\n }\n`;\n\nexport const Attributes = styled.dl`\n display: flex;\n flex-wrap: wrap;\n row-gap: ${theme.spacing(1)};\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1.4285;\n color: #333;\n\n dd,\n dt {\n width: 50%;\n margin: 0;\n }\n\n dt {\n text-align: right;\n }\n`;\n","import React, { useState } from 'react';\nimport { Action, ExpandablePanel } from '@triumph/shared';\nimport { useLabel } from 'src/hooks';\nimport { Wrapper, Grid, Title, Summary, BikeHeader, BikeTitle, BikeImage, Attributes } from './BikeDetails.styled';\n\nconst BikeDetails = ({ bike, cta, onCtaClick, summary, title }) => {\n const getLabel = useLabel();\n const [expanded, setExpanded] = useState(false);\n\n const bikeAttributes = [\n { key: getLabel('selectedBikeDisplacement'), value: bike?.displacement },\n { key: getLabel('selectedBikeFamily'), value: bike?.genre },\n { key: getLabel('selectedBikeModel'), value: bike?.name },\n { key: getLabel('selectedBikeYear'), value: bike?.year },\n ];\n\n return (\n <Wrapper>\n <Grid>\n <div>\n <Title dangerouslySetInnerHTML={{ __html: title }} />\n <Summary dangerouslySetInnerHTML={{ __html: summary }} />\n {cta && onCtaClick && (\n <Action onClick={onCtaClick} icon=\"arrow-down\">\n {cta}\n </Action>\n )}\n </div>\n {bike && (\n <ExpandablePanel expanded={expanded} onToggle={() => setExpanded(!expanded)} title={getLabel('selectedBike')}>\n <BikeHeader>\n <div>\n <BikeTitle\n dangerouslySetInnerHTML={{\n __html: [bike?.family ? `<span>${bike.family}</span>` : '', bike.name].join(' '),\n }}\n />\n </div>\n <BikeImage src={bike.thumbnail.src} alt={bike.thumbnail.alt} width=\"156\" height=\"88\" />\n </BikeHeader>\n <Attributes>\n {bikeAttributes\n .filter((attribute) => attribute.value)\n .map(({ key, value }) => (\n <React.Fragment key={key}>\n {/* eslint-disable-next-line react/no-danger */}\n <dd dangerouslySetInnerHTML={{ __html: `${key}:` }} />\n {/* eslint-disable-next-line react/no-danger */}\n <dt dangerouslySetInnerHTML={{ __html: value }} />\n </React.Fragment>\n ))}\n </Attributes>\n </ExpandablePanel>\n )}\n </Grid>\n </Wrapper>\n );\n};\n\nexport default BikeDetails;\n","import { useEffect, useState } from 'react';\nimport { useSelector } from 'react-redux';\nimport { usePrevious } from '@triumph/shared';\nimport { getBasket } from 'src/redux/app/selectors';\n\nconst useGetBasketChanges = () => {\n const basket = useSelector(getBasket);\n const previousBasket = usePrevious(basket);\n\n const [latestChange, setLatestChange] = useState();\n\n useEffect(() => {\n if (!basket || !previousBasket) {\n return;\n }\n\n const change = basket.reduce((accumulated, line) => {\n if (accumulated) {\n return accumulated;\n }\n\n const previousLine = previousBasket.find(({ sku }) => sku === line.sku);\n\n if (!previousLine || previousLine.quantity < line.quantity) {\n return {\n sku: line.sku,\n quantity: line.quantity,\n };\n }\n\n return null;\n }, null);\n\n setLatestChange(change);\n\n const timeout = change ? setTimeout(() => setLatestChange(null), 3000) : null;\n\n return () => {\n if (timeout) {\n clearTimeout(timeout);\n }\n };\n }, [basket]);\n\n return latestChange;\n};\n\nexport default useGetBasketChanges;\n","import styled from 'styled-components';\nimport { Focusable, Icon, maxBp, minBp, theme } from '@triumph/shared';\n\nexport const Wrapper = styled.section`\n display: flex;\n width: 100vw;\n height: 4.375rem;\n background-color: #fff;\n border-top: 1px solid ${theme.colors.outline};\n z-index: 1000;\n\n @media ${minBp('tabletLarge')} {\n height: 5rem;\n }\n`;\n\nexport const Tray = styled.div`\n position: absolute;\n top: 0;\n bottom: 4.375rem;\n display: flex;\n flex-direction: column;\n width: 100%;\n background-color: #fff;\n z-index: 9;\n\n @media ${minBp('tabletLarge')} {\n display: none;\n }\n`;\n\nexport const TrayHeader = styled.div`\n display: flex;\n align-items: center;\n background-color: #b3b3b3;\n`;\n\nexport const TrayTitle = styled.span`\n display: flex;\n align-items: center;\n flex: 1;\n height: 4.0625rem;\n padding-inline: ${theme.spacing(4)};\n font-family: ${theme.fonts.dinRegular};\n font-size: 1.25rem;\n line-height: 1;\n text-transform: uppercase;\n color: #000;\n`;\n\nexport const TrayClose = styled.button`\n display: block;\n width: 4.0625rem;\n height: 4.0625rem;\n appearance: none;\n background-color: transparent;\n border: none;\n cursor: pointer;\n color: #2a2a2a;\n\n &:hover,\n &:focus {\n color: #000;\n }\n\n ${Focusable()}\n`;\n\nexport const TrayCloseIcon = styled(Icon)`\n font-size: 0.9375rem;\n`;\n\nexport const TrayBody = styled.div`\n padding: ${theme.spacing(5)} ${theme.spacing(4)};\n overflow-y: auto;\n`;\n\nexport const TrayToggle = styled.button`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 4rem;\n border: none;\n appearance: none;\n margin: 0;\n background-color: ${theme.colors.gray[20]};\n cursor: pointer;\n transition: background-color 0.2s ease-in-out;\n color: black;\n\n &:hover,\n &:focus {\n background-color: ${theme.colors.gray[40]};\n }\n\n @media ${minBp('tabletLarge')} {\n display: none;\n }\n\n ${Focusable()}\n`;\n\nexport const TrayToggleIcon = styled(Icon)`\n font-size: ${({ name }) => (name === 'close' ? '1rem' : '1.5rem')};\n`;\n\nexport const Product = styled.div`\n display: flex;\n align-items: center;\n justify-content: flex-start;\n flex: 1;\n padding-inline: ${theme.spacing(6)};\n overflow: hidden;\n\n @media ${maxBp('tabletLarge')} {\n display: none;\n }\n`;\n\nexport const Actions = styled.div`\n display: none;\n\n @media ${minBp('tabletLarge')} {\n display: flex;\n }\n`;\n\nexport const Action = styled.button`\n position: relative;\n width: 8rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.375rem;\n appearance: none;\n border: none;\n background-color: transparent;\n padding-inline: ${theme.spacing(6)};\n cursor: pointer;\n color: #808080;\n text-align: center;\n text-underline-position: under;\n\n ${({ disabled }) =>\n disabled &&\n `\n opacity: 25%;\n pointer-events: none;\n `}\n\n ${Focusable()}\n`;\n\nexport const ActionDivider = styled.div`\n width: 1px;\n height: 100%;\n background: ${theme.colors.outline};\n`;\n\nexport const ActionLabel = styled.span`\n font-family: ${theme.fonts.dinDemi};\n font-size: 0.9rem;\n transition: 0.2s ease-in-out;\n`;\n\nexport const ActionIconWrapper = styled.div`\n position: relative;\n`;\n\nexport const ActionIcon = styled(Icon)`\n color: #000;\n height: 1.5rem;\n width: 100%;\n`;\n\nexport const ActionIndicator = styled.span`\n position: absolute;\n bottom: 0;\n right: 0;\n display: block;\n width: 1.25rem;\n height: 1.25rem;\n border-radius: 100%;\n font-size: 0.8125rem;\n font-family: ${theme.fonts.dinRegular};\n line-height: 1.62;\n background-color: ${theme.colors.primary};\n color: #fff;\n transform: translate(50%, 25%);\n`;\n\nexport const ActionNotification = styled.div`\n background: ${theme.colors.gray['84']};\n position: absolute;\n top: ${({ visible }) => (visible ? '-80%' : '-70%')};\n padding: ${theme.spacing(2)} ${theme.spacing(4)};\n pointer-events: none;\n display: flex;\n flex-direction: column;\n gap: 0.125rem;\n text-align: center;\n transition-properties: opacity, top;\n transition-duration: 0.2s;\n opacity: ${({ visible }) => (visible ? 100 : 0)};\n\n :after {\n content: '';\n position: absolute;\n left: calc(50% - 0.5rem);\n bottom: -0.5rem;\n width: 1rem;\n height: 1rem;\n background: ${theme.colors.gray['84']};\n transform: rotate(45deg);\n }\n`;\n\nexport const ActionNotificationTitle = styled.strong`\n white-space: nowrap;\n color: white;\n text-transform: uppercase;\n`;\n\nexport const ActionNotificationDescription = styled.div`\n white-space: nowrap;\n font-size: 0.75rem;\n color: ${theme.colors.gray['20']};\n transition-properties: opacity;\n transition-duration: 0.1s;\n opacity: ${({ visible }) => (visible ? 100 : 0)};\n`;\n\nexport const Price = styled.div`\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 0.1875rem;\n flex: 1;\n background-color: #000;\n color: #fff;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n text-align: center;\n cursor: pointer;\n\n @media ${minBp('tabletLarge')} {\n max-width: 12rem;\n }\n`;\n\nexport const PriceLabel = styled.span`\n display: flex;\n gap: 0.25rem;\n font-size: 0.8125rem;\n line-height: 1.538;\n\n .information__show {\n transform: translateY(8%);\n\n > .icon {\n color: #fff;\n }\n }\n`;\n\nexport const PriceValue = styled.span`\n font-size: 1.5rem;\n line-height: 1.0833;\n text-transform: uppercase;\n`;\n\nexport const Submit = styled.button`\n flex: 1;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: ${theme.spacing(2)};\n border: none;\n appearance: none;\n margin: 0;\n background-color: ${theme.colors.primary};\n cursor: pointer;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.25;\n text-transform: uppercase;\n color: #fff;\n transition: background-color 0.2s ease-in-out;\n\n &:is(:hover, :focus):not(:disabled) {\n background: #8f111f;\n }\n\n &:disabled {\n cursor: not-allowed;\n }\n\n @media ${minBp('tabletLarge')} {\n max-width: 12rem;\n }\n\n ${Focusable()}\n`;\n\nexport const SubmitIcon = styled(Icon)`\n transform: rotate(90deg);\n font-size: 0.5rem;\n`;\n","import React, { useEffect, useState, Fragment } from 'react';\nimport usePrice from 'src/hooks/usePrice';\nimport { Label } from 'src/_utility';\nimport { useLabel } from 'src/hooks';\nimport { MobileListView } from 'components';\nimport { BikeName, Information } from '@triumph/shared';\nimport useGetBasketChanges from 'src/hooks/useGetBasketChanges';\nimport {\n Action,\n ActionDivider,\n ActionIcon,\n ActionIconWrapper,\n ActionIndicator,\n ActionLabel,\n ActionNotification,\n ActionNotificationDescription,\n ActionNotificationTitle,\n Actions,\n Price,\n PriceLabel,\n PriceValue,\n Product,\n Submit,\n SubmitIcon,\n Tray,\n TrayBody,\n TrayClose,\n TrayCloseIcon,\n TrayHeader,\n TrayTitle,\n TrayToggle,\n TrayToggleIcon,\n Wrapper,\n} from './CartMenu.styled';\n\nconst CartMenu = ({\n actions = [],\n image,\n items = [],\n name,\n family,\n onCheckout,\n onTrayClose,\n onTrayOpen,\n price,\n trayExpanded,\n}) => {\n const getLabel = useLabel();\n const formatPrice = usePrice();\n const change = useGetBasketChanges();\n\n const [showSummaryInfo, setShowSummaryInfo] = useState(false);\n\n const handleEscape = (event) => {\n if (event.keyCode === 27) onTrayClose();\n };\n\n useEffect(() => {\n window.addEventListener('keydown', handleEscape, true);\n return () => {\n window.removeEventListener('keydown', handleEscape, true);\n };\n });\n\n return (\n <Wrapper>\n {trayExpanded && (\n <Tray>\n <TrayHeader>\n <TrayTitle>\n <Label name=\"trayTitle\" />\n </TrayTitle>\n <TrayClose onClick={onTrayClose} aria-label={getLabel('trayCloseLabel')}>\n <TrayCloseIcon name=\"close\" aria-hidden />\n </TrayClose>\n </TrayHeader>\n <TrayBody>\n <MobileListView bike={{ name, image, family }} items={[]} />\n </TrayBody>\n </Tray>\n )}\n <TrayToggle aria-label={getLabel('trayOpenLabel')} onClick={onTrayOpen}>\n <TrayToggleIcon name={trayExpanded ? 'close' : 'basket'} aria-hidden />\n </TrayToggle>\n <Product>\n <BikeName image={image} name={name} family={family} />\n </Product>\n <Actions>\n {actions.map(({ icon, label, indicator, basketNotification, ...props }) => (\n <Fragment key={label}>\n <ActionDivider />\n <Action {...props}>\n {basketNotification && (\n <ActionNotification visible={!!change}>\n <ActionNotificationTitle>{getLabel('addedToBasket')}</ActionNotificationTitle>\n <ActionNotificationDescription visible={!!change}>\n {change?.quantity} x {change?.sku}\n </ActionNotificationDescription>\n </ActionNotification>\n )}\n <ActionIconWrapper>\n <ActionIcon name={icon} aria-hidden />\n {indicator && <ActionIndicator>{indicator}</ActionIndicator>}\n </ActionIconWrapper>\n <ActionLabel>\n <Label name={label} />\n </ActionLabel>\n </Action>\n </Fragment>\n ))}\n </Actions>\n <Price onClick={onTrayOpen}>\n <PriceLabel>\n <Information\n title={getLabel('totalPrice')}\n smallIcon\n show={showSummaryInfo}\n onShow={() => setShowSummaryInfo(true)}\n onClose={() => setShowSummaryInfo(false)}\n >\n <Label name=\"basketModalPriceInfo\" asHtml />\n </Information>\n <Label name=\"trayTotal\" />\n </PriceLabel>\n <PriceValue>{price || formatPrice(0)}</PriceValue>\n </Price>\n <Submit type=\"button\" onClick={() => onCheckout()} disabled={!(Array.isArray(items) && items.length > 0)}>\n <Label name=\"trayCta\" />\n <SubmitIcon name=\"chevron-down\" aria-hidden />\n </Submit>\n </Wrapper>\n );\n};\n\nexport default CartMenu;\n","import styled from 'styled-components';\nimport { Focusable, Icon, theme } from '@triumph/shared';\n\nexport const Frame = styled.div`\n position: fixed;\n inset: 0;\n z-index: 4000;\n overflow: hidden;\n`;\n\nexport const Wrapper = styled.div`\n position: absolute;\n inset: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: ${theme.spacing(3)};\n padding: ${theme.spacing(2)};\n background-color: #fff;\n z-index: 2000;\n\n > * {\n width: 100%;\n ;\n`;\n\nexport const Header = styled.div`\n position: relative;\n`;\n\nexport const Title = styled.p`\n padding: ${theme.spacing(5)} ${theme.spacing(6)};\n margin: 0;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1.5rem;\n line-height: 1.0833;\n text-align: center;\n text-transform: uppercase;\n`;\n\nexport const Close = styled.button`\n position: absolute;\n top: 0;\n right: 0;\n display: grid;\n place-items: center;\n width: 1.875rem;\n height: 1.875rem;\n border: none;\n padding: 0;\n appearance: none;\n background: none;\n color: #2a2a2a;\n cursor: pointer;\n transition: color 200ms ease-in-out;\n\n &:hover,\n &:focus {\n color: ${theme.colors.primary};\n }\n\n ${Focusable()}\n`;\n\nexport const CloseIcon = styled(Icon)`\n font-size: 1.25rem;\n`;\n\nexport const Content = styled.div`\n flex: 1 1 0;\n overflow: auto;\n max-width: ${theme.widths.full};\n display: flex;\n flex-direction: column;\n gap: 2rem;\n`;\n","import React, { useEffect, useMemo } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useTransition, animated } from 'react-spring';\nimport { Breadcrumb, LinkGrid, useHeaderOffset } from '@triumph/shared';\nimport { useLabel } from 'src/hooks';\nimport { setPartsModalPage } from 'src/redux/app/actions';\nimport FocusTrap from 'focus-trap-react';\nimport useCta from 'src/hooks/useCta';\nimport { Wrapper, Title, Header, Close, Content, CloseIcon, Frame } from './CategoryModal.styled';\n\nconst CategoryModal = ({ bikeId, category, expanded = false, modelId, onClose }) => {\n const getLabel = useLabel();\n const getCta = useCta();\n const dispatch = useDispatch();\n const headerOffset = useHeaderOffset();\n\n const transitions = useTransition(expanded, {\n from: {\n position: 'fixed',\n inset: 0,\n top: `${headerOffset}px`,\n transform: `translateY(${window.innerHeight}px)`,\n zIndex: 2000,\n },\n enter: { transform: 'translateY(0px)' },\n leave: { transform: `translateY(${window.innerHeight}px)` },\n reverse: expanded,\n });\n\n const titleReference = useMemo(() => Math.random()\n .toString(36)\n .substring(2, 15), []);\n\n useEffect(() => {\n const close = (event) => {\n if (event.key === 'Escape') {\n onClose();\n }\n };\n\n window.addEventListener('keydown', close, true);\n\n return () => {\n window.removeEventListener('keydown', close, true);\n };\n });\n\n const linkGridItems = useMemo(\n () =>\n (category?.catalogue || []).map(({ id, image, name, _links }) =>\n _links?.[0].rel === 'catalogue'\n ? {\n id,\n image,\n name,\n onClick: () => dispatch(setPartsModalPage(id)),\n }\n : {\n id,\n image,\n name,\n to: `/parts/${bikeId}/${modelId}/${id}`,\n }\n ),\n [category]\n );\n\n const breadcumb = [\n {\n name: getLabel('bikeSelectorTitle'),\n path: getCta('bikeSearch'),\n },\n ...(category?.breadCrumbs?.map((item) => ({\n name: item.Name,\n onClick: () => dispatch(setPartsModalPage(item.Id)),\n })) || []),\n ];\n\n return transitions(\n (styles, item) =>\n item && (\n <Frame>\n <animated.div style={styles}>\n <FocusTrap>\n <Wrapper role=\"dialog\" aria-labelledby={titleReference}>\n <Header>\n <Title id={titleReference}>{getLabel('categoryModalTitle')}</Title>\n <Close onClick={onClose} aria-label={getLabel('close')}>\n <CloseIcon name=\"close\" aria-hidden />\n </Close>\n </Header>\n <Content>\n <Breadcrumb items={breadcumb} />\n <LinkGrid links={linkGridItems} />\n </Content>\n </Wrapper>\n </FocusTrap>\n </animated.div>\n </Frame>\n )\n );\n};\n\nexport default CategoryModal;\n","import React from 'react';\nimport { EmailBasket } from '@triumph/shared';\nimport { useLabel } from 'src/hooks';\n\nconst WithLabels = (props) => {\n const getLabel = useLabel();\n\n const labels = {\n agreeToTermsRequired: getLabel('agreeToTermsRequired'),\n emailCancelCta: getLabel('emailCancelCta'),\n emailOptInText: getLabel('emailOptInText'),\n emailPlaceholderText: getLabel('emailPlaceholderText'),\n emailSubmitCta: getLabel('emailSubmitCta'),\n emailSubtitle: getLabel('emailSubtitle'),\n emailTermsText: getLabel('emailTermsText'),\n emailTitle: getLabel('emailTitle'),\n invalidEmail: getLabel('invalidEmail'),\n };\n\n return <EmailBasket labels={labels} {...props} />;\n};\n\nexport default WithLabels;\n","import React from 'react';\nimport { EmailBasketModal } from '@triumph/shared';\nimport { useLabel } from 'src/hooks';\n\nconst WithLabels = (props) => {\n const getLabel = useLabel();\n const labels = {\n agreeToTermsRequired: getLabel('agreeToTermsRequired'),\n emailCancelCta: getLabel('emailCancelCta'),\n emailOptInText: getLabel('emailOptInText'),\n emailPlaceholderText: getLabel('emailPlaceholderText'),\n emailSubmitCta: getLabel('emailSubmitCta'),\n emailSubtitle: getLabel('emailSubtitle'),\n emailTermsText: getLabel('emailTermsText'),\n emailTitle: getLabel('emailTitle'),\n invalidEmail: getLabel('invalidEmail'),\n open: getLabel('open'),\n };\n return <EmailBasketModal labels={labels} {...props} />;\n};\n\nexport default WithLabels;\n","import React from 'react';\nimport { Loader } from '@triumph/shared';\nimport { useLabel } from 'src/hooks';\n\nconst LocalisedLoader = () => {\n const getLabel = useLabel();\n return <Loader text={getLabel('loadingLabel')} />;\n};\n\nexport default LocalisedLoader;\n","import styled from 'styled-components';\nimport { Action, Focusable, Icon, theme } from '@triumph/shared';\n\nexport const Back = styled(Action)`\n margin-bottom: ${theme.spacing(5)};\n color: #666;\n`;\n\nexport const Menu = styled.menu`\n list-style: none;\n padding: 0;\n margin: ${theme.spacing(3)} 0;\n`;\n\nexport const MenuButton = styled.button`\n display: flex;\n align-items: center;\n width: 100%;\n gap: ${theme.spacing(3)};\n height: 3.875rem;\n padding: 0;\n background: none;\n border: none;\n border-width: 0 0 1px;\n color: #2a2a2a;\n cursor: pointer;\n\n ${({ disabled }) =>\n disabled &&\n `\n opacity: 25%;\n pointer-events: none;\n `}\n\n &:hover,\n &:focus {\n color: ${theme.colors.primary};\n }\n\n ${Focusable()}\n`;\n\nexport const MenuDivider = styled.div`\n height: 1px;\n background: #e6e6e6;\n`;\n\nexport const MenuButtonText = styled.span`\n font-family: ${theme.fonts.dinRegular};\n font-size: 1rem;\n line-height: 1.375;\n text-transform: capitalize;\n`;\n\nexport const MenuButtonIcon = styled(Icon)`\n font-size: 1.125rem;\n`;\n\nexport const MenuButtonChevron = styled(Icon)`\n margin-left: auto;\n color: #000;\n font-size: 1rem;\n`;\n\nexport const BasketTitle = styled.h2`\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1.375rem;\n line-height: 1.09;\n text-transform: uppercase;\n color: #000;\n`;\n\nexport const BasketSummary = styled.p`\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.375;\n color: #666;\n`;\n","import React, { useState } from 'react';\nimport { useSelector } from 'react-redux';\nimport { BikeName } from '@triumph/shared';\nimport { Basket, EmailBasket } from 'components';\nimport { useLabel } from 'src/hooks';\nimport { getBasket, getPartsList } from 'src/redux/app/selectors';\nimport getPdf from 'src/requests/getPdf';\nimport emailBasket from 'src/requests/emailBasket';\nimport sumBasket from 'src/helpers/sumBasket';\nimport partDownloadEvent from 'src/gtm-events/partDownload';\nimport {\n Back,\n Menu,\n MenuButton,\n MenuButtonChevron,\n MenuButtonIcon,\n MenuButtonText,\n MenuDivider,\n} from './MobileListView.styled';\n\nconst MenuItem = ({ onClick, children, icon, disabled }) => (\n <li>\n <MenuButton onClick={onClick} disabled={disabled}>\n <MenuButtonIcon name={icon} aria-hidden />\n <MenuButtonText>{children}</MenuButtonText>\n <MenuButtonChevron name=\"chevron-right-thin\" aria-hidden />\n </MenuButton>\n </li>\n);\n\nconst MobileListView = ({ bike, view = 'index', onClose }) => {\n const getLabel = useLabel();\n const basket = useSelector(getBasket);\n const parts = useSelector(getPartsList);\n const basketCount = sumBasket(basket);\n\n const [currentView, setCurrentView] = useState(view);\n\n const submit = async ({ email, receiveCommunication }) => {\n await emailBasket(email, receiveCommunication);\n onClose();\n };\n\n if (currentView === 'email') {\n return <EmailBasket onCancel={() => setCurrentView('index')} onSubmit={(values) => submit(values)} />;\n }\n\n if (currentView === 'basket') {\n return <Basket items={basket} />;\n }\n\n return (\n <>\n <BikeName name={bike.name} image={bike.image} family={bike.family} padded small />\n <Menu>\n <MenuItem\n icon=\"download\"\n onClick={() => {\n window.open(getPdf());\n partDownloadEvent({ bike, category: parts });\n }}\n disabled={!basketCount}\n >\n {getLabel('trayDownload')}\n </MenuItem>\n <MenuDivider />\n {/* Temporarily disabled. See TRIUZSB-49. */}\n {/* <MenuItem icon=\"email\" onClick={() => setCurrentView('email')}>\n {getLabel('trayEmail')}\n </MenuItem> */}\n <MenuItem icon=\"basket\" onClick={() => setCurrentView('basket')}>\n {getLabel('trayBasket')}\n </MenuItem>\n <MenuDivider />\n </Menu>\n </>\n );\n};\n\nexport default MobileListView;\n","import { pushToDataLayer } from \"@triumph/shared\";\n\nexport default ({ clickText, bike, category }) => pushToDataLayer({\n name: 'toolTip',\n category: 'Parts - Assembly',\n action: `Part Tooltip`,\n label: clickText,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n configuratorAccessoryCategory: category.name,\n },\n});","import styled from 'styled-components';\nimport { Focusable, Icon, maxBp, minBp, theme } from '@triumph/shared';\n\nexport const Row = styled.tr`\n vertical-align: middle;\n\n @media ${maxBp('tabletLarge')} {\n display: grid;\n grid-template-columns: repeat(3, 1fr);\n align-items: start;\n border: 1px solid #e6e6e6;\n }\n\n @media ${minBp('tabletLarge')} {\n td {\n min-height: 5rem;\n padding: 1.25rem 0;\n }\n }\n\n & + & {\n @media ${maxBp('tabletLarge')} {\n margin-top: ${theme.spacing(2)};\n }\n\n td {\n @media ${minBp('tabletLarge')} {\n border-top: 1px solid #e6e6e6;\n }\n }\n }\n`;\n\nexport const TableCell = styled.td`\n @media ${maxBp('tabletLarge')} {\n display: flex;\n flex-direction: column;\n gap: 4px;\n padding: ${theme.spacing(1)} 0 ${theme.spacing(1)} ${theme.spacing(1)};\n }\n`;\n\nexport const TableViewCell = styled(TableCell)`\n grid-column: 1 / span 3;\n padding: 0 0.625rem 0.9375rem;\n`;\n\nexport const TableAddOrRemoveCell = styled(TableCell)`\n padding-top: 2rem;\n place-items: center;\n padding: 2rem ${theme.spacing(1)} ${theme.spacing(1)} ${theme.spacing(1)};\n\n @media ${minBp('tabletLarge')} {\n width: 0.1%;\n white-space: nowrap;\n padding: 2rem 0 ${theme.spacing(1)} ${theme.spacing(1)};\n }\n`;\n\nexport const SequenceWrapper = styled.td`\n @media ${maxBp('tabletLarge')} {\n display: none;\n }\n`;\n\nexport const Sequence = styled.span`\n display: block;\n width: 1.6875rem;\n height: 1.6875rem;\n border-radius: 50%;\n background-color: ${({ selected = false }) => (selected ? theme.colors.primary : '#2A2A2A')};\n color: #fff;\n font-family: ${theme.fonts.dinRegular};\n font-size: 0.8125rem;\n line-height: 1.875rem;\n text-align: center;\n`;\n\nexport const MobileSequence = styled.div`\n display: flex;\n justify-content: center;\n align-items: center;\n width: 1.5rem;\n height: 1.5rem;\n border-radius: 50%;\n background-color: ${theme.colors.primary};\n color: white;\n font-family: ${theme.fonts.dinDemi};\n font-size: 0.75rem;\n\n @media ${minBp('tabletLarge')} {\n display: none;\n }\n`;\n\nexport const Sku = styled.td`\n @media ${maxBp('tabletLarge')} {\n display: flex;\n gap: 0.5rem;\n align-items: center;\n grid-column: 1 / -1;\n padding: ${theme.spacing(2)} ${theme.spacing(1)}\n ${({ showsMobileSequence }) => (showsMobileSequence ? theme.spacing(1) : 0)};\n }\n\n span {\n font-family: ${theme.fonts.dinDemi};\n font-size: 0.8125rem;\n line-height: 1.538;\n color: #666;\n }\n`;\n\nexport const Name = styled.td`\n @media ${maxBp('tabletLarge')} {\n grid-column: 1 / -1;\n padding: 0 ${theme.spacing(1)} ${theme.spacing(2)};\n border-bottom: 1px solid #e6e6e6;\n }\n\n span {\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.4375;\n color: #2a2a2a;\n }\n`;\n\nexport const MobileGroup = styled.div`\n width: 7rem;\n display: flex;\n flex-direction: column;\n align-items: center;\n\n @media ${minBp('tabletLarge')} {\n width: auto;\n }\n`;\n\nexport const MobileLabel = styled.span`\n display: flex;\n gap: 0.25rem;\n align-items: center;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.8125rem;\n line-height: 1.534;\n color: #666;\n\n @media ${minBp('tabletLarge')} {\n display: none;\n }\n`;\n\nexport const QuantityValue = styled.span`\n display: grid;\n place-items: center;\n width: 2.5rem;\n height: 2.5rem;\n border: 1px solid #000;\n background-color: #fff;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1;\n\n @media ${minBp('tabletLarge')} {\n width: 2.25rem;\n height: 2.25rem;\n }\n`;\n\nexport const Quantity = styled.div`\n display: flex;\n align-items: center;\n gap: 0.25rem;\n\n @media ${minBp('additional.mobile')} {\n gap: ${theme.spacing(1)};\n }\n`;\n\nexport const ChangeQuantity = styled.button`\n display: block;\n appearance: none;\n width: 1.25rem;\n height: 1.25rem;\n padding: 0;\n border: none;\n margin: 0;\n background: none;\n font-size: ${({ minus }) => (minus ? '0.075rem' : '0.75rem')};\n line-height: 1;\n cursor: pointer;\n color: black;\n\n &:disabled {\n pointer-events: none;\n color: ${theme.colors.gray[40]};\n }\n\n ${Focusable()}\n`;\n\nexport const QuantityValueAndLabel = styled.div`\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n gap: 0.3125rem;\n`;\n\nexport const View = styled.button`\n display: flex;\n place-items: center;\n gap: 0.5rem;\n appearance: none;\n background: white;\n padding: 0.5rem 0;\n border: none;\n cursor: pointer;\n text-transform: uppercase;\n font-family: ${theme.fonts.dinDemi};\n color: black;\n\n ${Focusable()}\n`;\n\nexport const ViewIcon = styled(Icon)`\n font-size: 0.75rem;\n color: ${theme.colors.buttons.primary};\n`;\n\nexport const AddOrRemove = styled.button`\n display: flex;\n place-items: center;\n appearance: none;\n gap: ${theme.spacing(1)};\n padding: 0.625rem ${({ $added = false }) => ($added ? '0' : '0.4rem')};\n border: none;\n cursor: pointer;\n background-color: ${({ $added = false }) => ($added ? '#fff' : '#2a2a2a')} !important;\n color: ${({ $added = false }) => ($added ? '#000' : '#fff')} !important;\n font-family: ${theme.fonts.dinRegular};\n\n &:hover,\n &:focus {\n background-color: #000;\n }\n\n .icon {\n flex-shrink: 0;\n font-size: ${({ $added = false }) => ($added ? '0.5rem' : '0.8125rem')};\n }\n\n ${Focusable()}\n\n @media ${minBp('additional.mobile')} {\n padding: 0.625rem ${({ $added = false }) => ($added ? '0' : '1rem')};\n }\n`;\n","import React, { useState } from 'react';\nimport { Icon, Information, useBreakpoint } from '@triumph/shared';\nimport { Label } from 'src/_utility';\nimport { Price } from 'components';\nimport { useLabel } from 'src/hooks';\nimport { setHighlightedPart } from 'src/redux/app/actions';\nimport { useDispatch } from 'react-redux';\nimport toolTipEvent from 'src/gtm-events/toolTip';\nimport {\n AddOrRemove,\n ChangeQuantity,\n MobileGroup,\n MobileLabel,\n MobileSequence,\n Name,\n Quantity,\n QuantityValue,\n Row,\n Sequence,\n SequenceWrapper,\n Sku,\n TableAddOrRemoveCell,\n TableCell,\n TableViewCell,\n View,\n ViewIcon,\n} from './PartsTableRow.styled';\n\nexport default function PartsTableRow({\n bike,\n category,\n displayIndex,\n inBasket = false,\n labels,\n name,\n onMinus,\n onPlus,\n onToggleCart,\n onViewPart,\n priceLocalised,\n requiredQuantity,\n showsMobileSequence = false,\n selected = false,\n sequence,\n sku,\n}) {\n const getLabel = useLabel();\n const dispatch = useDispatch();\n const isTabletLargeOrAbove = useBreakpoint('tabletLarge');\n const [activeInformation, setActiveInformation] = useState(null);\n\n return (\n <Row\n onMouseEnter={() => isTabletLargeOrAbove && dispatch(setHighlightedPart(parseInt(sequence)))}\n onMouseLeave={() => isTabletLargeOrAbove && dispatch(setHighlightedPart(null))}\n >\n <SequenceWrapper id={`seq-${sequence}`}>\n <Sequence selected={selected}>{sequence}</Sequence>\n </SequenceWrapper>\n <Sku showsMobileSequence={showsMobileSequence}>\n {showsMobileSequence && <MobileSequence selected={selected}>{sequence}</MobileSequence>}\n <span>{sku}</span>\n </Sku>\n <Name>\n <span>{name}</span>\n </Name>\n <TableCell>\n <MobileLabel>\n <Information\n title={<Label name=\"partsTableRrpInfoTitle\" />}\n smallIcon\n show={activeInformation === 'rrp'}\n onShow={() => {\n setActiveInformation('rrp');\n toolTipEvent({\n clickText: labels.partsTableRrp,\n bike,\n category,\n });\n }}\n onClose={() => setActiveInformation(null)}\n >\n <Label name=\"partsTableRrpInfo\" asHtml />\n </Information>{' '}\n <Label name=\"partsTableRrp\" />\n </MobileLabel>\n <Price price={priceLocalised} requiredQuantity={requiredQuantity} />\n </TableCell>\n <TableCell>\n <MobileGroup>\n <MobileLabel>\n <Information\n title={<Label name=\"partsTableQtyInfoTitle\" />}\n smallIcon\n show={activeInformation === 'qty'}\n onShow={() => {\n setActiveInformation('qty');\n toolTipEvent({\n clickText: labels.partsTableQty,\n bike,\n category,\n });\n }}\n onClose={() => setActiveInformation(null)}\n >\n <Label name=\"partsTableQtyInfo\" asHtml />\n </Information>\n <Label name=\"partsTableQty\" />\n </MobileLabel>\n <Quantity>\n <ChangeQuantity type=\"button\" onClick={onMinus} disabled={!(inBasket?.quantity >= 1)} minus>\n <Icon name=\"minus\" aria-hidden />\n </ChangeQuantity>\n <QuantityValue>{inBasket?.quantity || 0}</QuantityValue>\n <ChangeQuantity type=\"button\" onClick={onPlus}>\n <Icon name=\"plus\" aria-hidden />\n </ChangeQuantity>\n </Quantity>\n </MobileGroup>\n </TableCell>\n <TableAddOrRemoveCell>\n <AddOrRemove type=\"button\" $added={inBasket} onClick={onToggleCart}>\n <Icon name={inBasket ? 'close' : 'cart'} aria-hidden />\n {inBasket ? getLabel('basketRemove') : getLabel('basketAdd')}\n </AddOrRemove>\n </TableAddOrRemoveCell>\n {!isTabletLargeOrAbove && onViewPart && (\n <TableViewCell>\n <strong>{getLabel('partsId')}: {sequence}</strong>\n </TableViewCell>\n )}\n </Row>\n );\n}\n","import styled from 'styled-components';\nimport { Focusable, Icon, minBp, theme } from '@triumph/shared';\n\nexport const Wrapper = styled.div``;\n\nexport const Dialog = styled.div`\n position: fixed;\n top: ${({ offsetTop }) => offsetTop}px;\n right: 0;\n bottom: 4.375rem;\n left: 0;\n display: flex;\n flex-direction: column;\n align-items: center;\n background-color: #fff;\n z-index: 2000;\n\n > * {\n width: 100%;\n ;\n`;\n\nexport const Header = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n position: relative;\n min-height: 6.625rem;\n background-color: #e6e6e6;\n`;\n\nexport const Title = styled.p`\n padding: 0 ${theme.spacing(6)};\n margin: 0;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1.625rem;\n line-height: 1;\n text-align: center;\n text-transform: uppercase;\n color: #000;\n`;\n\nexport const Close = styled.button`\n position: absolute;\n top: 0.8125rem;\n right: 0.8125rem;\n display: grid;\n place-items: center;\n width: 1.875rem;\n height: 1.875rem;\n border: none;\n padding: 0;\n appearance: none;\n background: none;\n color: #2a2a2a;\n cursor: pointer;\n transition: color 200ms ease-in-out;\n\n &:hover,\n &:focus {\n color: ${theme.colors.primary};\n }\n\n ${Focusable()};\n`;\n\nexport const CloseIcon = styled(Icon)`\n font-size: 0.9375rem;\n`;\n\nexport const Content = styled.div`\n display: flex;\n flex-direction: column;\n overflow: hidden;\n width: 100vw;\n height: 100%;\n`;\n\nexport const Parts = styled.div`\n position: relative;\n padding: 0;\n`;\n\nexport const NoSelection = styled.div`\n height: 100%;\n display: grid;\n place-items: center;\n flex: 1;\n padding: 4rem;\n border: ${theme.spacing(2)} solid #fff;\n background-color: #f6f6f6;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1.428;\n text-align: center;\n color: #808080;\n flex-shrink: 0;\n`;\n\nexport const PartsDiagramWrapper = styled.div`\n position: relative;\n flex-grow: 1;\n`;\n\nexport const PartsDiagramContainer = styled.div`\n position: absolute;\n inset: 0;\n overflow: hidden;\n`;\n\nexport const ListParts = styled.div`\n display: flex;\n flex: 1;\n gap: ${theme.spacing(3)};\n width: 100%;\n max-width: calc(100vw - 1px);\n padding: ${theme.spacing(2)};\n scroll-padding: 0 ${theme.spacing(2)};\n overflow: auto;\n white-space: nowrap;\n scroll-snap-type: x proximity;\n flex-shrink: 0;\n\n > * {\n flex: 1 0 auto;\n scroll-snap-align: start;\n width: 80vw;\n }\n`;\n\nexport const Part = styled.table`\n border-collapse: collapse;\n`;\n\nexport const PriceWrapper = styled.div`\n display: flex;\n flex-direction: column;\n gap: 0.375rem;\n\n > span + span {\n line-height: 1.4;\n }\n`;\n\nexport const QuantityValue = styled.span`\n display: grid;\n place-items: center;\n width: 2.625rem;\n height: 2.625rem;\n border: 1px solid #000;\n background-color: #fff;\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1;\n\n @media ${minBp('tabletLarge')} {\n width: 1.875rem;\n height: 1.875rem;\n }\n`;\n\nexport const Quantity = styled.div`\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: flex-start;\n gap: 0.3125rem;\n\n @media ${minBp('tabletLarge')} {\n display: none;\n }\n`;\n","import React, { useEffect, useMemo } from 'react';\nimport { useElementDimensions } from '@triumph/shared';\nimport { useLabel, useUpdateBasket } from 'src/hooks';\nimport { PartsDiagram } from 'components';\nimport { getBasket, getBike, getHighlightedPart, getLabels, getPartsList } from 'src/redux/app/selectors';\nimport { useSelector } from 'react-redux';\nimport partsAddBasketEvent from 'src/gtm-events/partsAddBasket';\nimport partsRemoveBasketEvent from 'src/gtm-events/partsRemoveBasketAssembly';\nimport partIncreaseEvent from 'src/gtm-events/partIncreaseAssembly';\nimport partDecreaseEvent from 'src/gtm-events/partDecreaseAssembly';\nimport PartsTableRow from '../parts-table-row';\nimport {\n Close,\n CloseIcon,\n Content,\n Dialog,\n Header,\n ListParts,\n PartsDiagramWrapper,\n PartsDiagramContainer,\n NoSelection,\n Part,\n Parts,\n Title,\n Wrapper,\n} from './MobilePartsDiagram.styled';\n\nconst MobilePartsDiagram = ({ hotspots = [], image, name, onClose, parts = [], show = false }) => {\n const updateBasket = useUpdateBasket();\n const highlightedPart = useSelector(getHighlightedPart);\n const basket = useSelector(getBasket);\n const labels = useSelector(getLabels);\n const bike = useSelector(getBike);\n const category = useSelector(getPartsList);\n const getLabel = useLabel();\n const { height: headerHeight } = useElementDimensions('.header');\n\n const filteredParts = useMemo(\n () =>\n highlightedPart > -1 ? parts.filter(({ sequence }) => parseInt(sequence) === parseInt(highlightedPart)) : parts,\n [parts, highlightedPart]\n );\n\n const titleReference = Math.random()\n .toString(36)\n .substring(2, 15);\n\n useEffect(() => {\n const handleEscape = (event) => {\n if (event.key === 'Escape') {\n onClose();\n }\n };\n\n window.addEventListener('keydown', handleEscape, true);\n\n return () => {\n window.removeEventListener('keydown', handleEscape, true);\n };\n });\n\n if (!show) {\n return null;\n }\n\n return (\n <Wrapper>\n <Dialog role=\"dialog\" aria-labelledby={titleReference} offsetTop={headerHeight * -1}>\n <Header>\n <Title id={titleReference}>{name}</Title>\n <Close onClick={onClose} aria-label={getLabel('close')}>\n <CloseIcon name=\"close\" aria-hidden />\n </Close>\n </Header>\n <Content tabIndex=\"0\">\n <PartsDiagramWrapper>\n <PartsDiagramContainer>\n <PartsDiagram image={image} name={name} />\n </PartsDiagramContainer>\n </PartsDiagramWrapper>\n </Content>\n </Dialog>\n </Wrapper>\n );\n};\n\nexport default MobilePartsDiagram;\n","import styled from 'styled-components';\nimport { theme } from '@triumph/shared';\n\nexport const Wrapper = styled.output`\n display: block;\n padding: clamp(${theme.spacing(5)}, 5vw, ${theme.spacing(6)});\n background-color: #f6f6f6;\n`;\n\nexport const Title = styled.h2`\n margin: 0 0 ${theme.spacing(1)};\n font-family: ${theme.fonts.dinDemi};\n font-size: 1.25rem;\n line-height: 1.2;\n text-transform: uppercase;\n color: #000;\n word-break: break-all;\n\n span {\n color: ${theme.colors.primary};\n }\n`;\n\nexport const Message = styled.p`\n margin: 0;\n font-family: ${theme.fonts.dinRegular};\n font-size: 1rem;\n line-height: 1.375;\n color: #666;\n`;\n","import React from 'react';\nimport { useLabel } from 'src/hooks';\nimport { Message, Title, Wrapper } from './NoResults.styled';\n\nconst NoResults = ({ query }) => {\n const getLabel = useLabel();\n return (\n <Wrapper>\n <Title\n // eslint-disable-next-line react/no-danger\n dangerouslySetInnerHTML={{\n __html: getLabel('partsSearchNoResultsTitle').replace('{0}', query),\n }}\n />\n <Message>{getLabel('partsSearchNoResultsText')}</Message>\n </Wrapper>\n );\n};\n\nexport default NoResults;\n","import React from 'react';\nimport styled from 'styled-components';\nimport { theme } from '@triumph/shared';\n\nexport const Wrapper = styled.div`\n padding: clamp(${theme.spacing(6)}, 5vw, ${theme.spacing(7)}) ${theme.spacing(2)}\n clamp(${theme.spacing(7)}, 5vw, ${theme.spacing(8)});\n`;\n\nexport const Container = styled.div`\n max-width: ${theme.widths.full};\n margin-inline: auto;\n\n > * + * {\n margin-top: clamp(${theme.spacing(6)}, 5vw, ${theme.spacing(7)});\n }\n`;\n","import React from 'react';\nimport { Breadcrumb, LinkGrid } from '@triumph/shared';\nimport { Wrapper, Container } from './PartsCatalog.styled';\n\nconst PartsCatalog = ({ breadcrumb = [], catalog = [] }) => (\n <Wrapper>\n <Container>\n <Breadcrumb items={breadcrumb} />\n <LinkGrid links={catalog} />\n </Container>\n </Wrapper>\n);\n\nexport default PartsCatalog;\n","import PrismaZoom from 'react-prismazoom';\nimport { maxBp, minBp, theme } from '@triumph/shared';\nimport styled from 'styled-components';\n\nexport const Wrapper = styled.section`\n position: relative;\n display: flex;\n flex-direction: column;\n width: 100%;\n height: 100%;\n`;\n\nexport const Preview = styled.div`\n position: relative;\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 1;\n overflow: hidden;\n height: 100%;\n\n &:after {\n content: '';\n position: absolute;\n bottom: 0;\n left: 0;\n width: 100%;\n height: 2.5rem;\n background: linear-gradient(180deg, rgba(0, 0, 0, 0) 0%, rgba(0, 0, 0, 0.05) 100%);\n pointer-events: none;\n }\n`;\n\nexport const Zoom = styled(PrismaZoom)`\n display: flex;\n align-items: center;\n justify-content: center;\n width: 100%;\n height: 100%;\n`;\n\nexport const ImageWrapper = styled.div`\n position: relative;\n display: flex;\n justify-content: center;\n align-items: center;\n width: 100%;\n height: 100%;\n`;\n\nexport const Image = styled.div`\n position: relative;\n background-image: ${({ src }) => `url('${src}')`};\n background-size: contain;\n background-repeat: no-repeat;\n display: block;\n width: ${({ width }) => `${width}px`};\n height: ${({ height }) => `${height}px`};\n`;\n\nexport const Hotspot = styled.button`\n position: absolute;\n top: ${({ y, imageHeight }) => `${(y / imageHeight) * 100}%`};\n left: ${({ x, imageWidth }) => `${(x / imageWidth) * 100}%`};\n width: ${({ scale }) => `${scale}rem`};\n height: ${({ scale }) => `${scale}rem`};\n transform: ${({ scale }) => `translate(${-0.25 * scale}rem, ${-0.25 * scale}rem)`};\n display: flex;\n align-items: center;\n justify-content: center;\n padding: 0;\n border: ${({ selected = false }) => (selected ? `2px solid ${theme.colors.primary}` : '1px solid #666')};\n appearance: none;\n background: white;\n border-radius: 50%;\n cursor: pointer;\n color: ${theme.colors.body};\n background-color: transparent;\n\n span {\n display: none;\n font-family: ${theme.fonts.dinRegular};\n font-size: ${({ scale }) => `${0.5 * scale}rem`};\n height: ${({ scale }) => `${0.5 * scale}rem`};\n }\n\n &:hover,\n &:focus {\n border: ${({ selected = false }) => (selected ? `2px` : '1px')} solid ${theme.colors.primary};\n }\n`;\n\nexport const HotspotScreenReader = styled.span`\n position: absolute !important;\n clip: rect(1px, 1px, 1px, 1px) !important;\n clip-path: inset(50%) !important;\n width: 1px !important;\n height: 1px !important;\n padding: 0 !important;\n border: 0 !important;\n margin: -1px !important;\n overflow: hidden !important;\n white-space: nowrap !important;\n`;\n\nexport const Control = styled.div`\n @media ${maxBp('tabletLarge')} {\n position: absolute;\n bottom: ${theme.spacing(2)};\n right: ${theme.spacing(2)};\n }\n\n @media ${minBp('tabletLarge')} {\n display: grid;\n place-items: center;\n height: 6.875rem;\n }\n`;\n","import { useComponentDimensions } from '@triumph/shared';\nimport React, { useMemo, useRef, useState } from 'react';\nimport { useDispatch, useSelector } from 'react-redux';\nimport { useLabel } from 'src/hooks';\nimport { setHighlightedPart } from 'src/redux/app/actions';\nimport { getHighlightedPart } from 'src/redux/app/selectors';\nimport useViewportDimensions from 'src/hooks/useViewportDimensions';\nimport { ZoomControl } from '..';\nimport {\n Control,\n Hotspot,\n HotspotScreenReader,\n Image,\n ImageWrapper,\n Preview,\n Wrapper,\n Zoom,\n} from './PartsDiagram.styled';\n\nconst PartsDiagram = ({ hotSpots = [], image, name, parts = [] }) => {\n const { ref: containerRef, dimensions } = useComponentDimensions();\n const getLabel = useLabel();\n const dispatch = useDispatch();\n const highlightedPart = useSelector(getHighlightedPart);\n const [zoom, setZoom] = useState(1);\n const prismaZoomRef = useRef();\n const maxZoom = 4;\n\n const onZoomChange = (zoomLevel) => setZoom(zoomLevel);\n const onZoomIn = () => prismaZoomRef.current.zoomIn(zoom);\n const onZoomOut = () => prismaZoomRef.current.zoomOut(zoom / 2);\n\n const viewportDimensions = useViewportDimensions();\n\n // The API can return the the same hotspot in multiple parts so duplicates must be removed.\n const filtered = useMemo(\n () =>\n hotSpots.filter(\n (value, index, self) =>\n index ===\n self.findIndex(\n (hotspot) => hotspot.x === value.x && hotspot.y === value.y && hotspot.sequence === value.sequence\n )\n ),\n [hotSpots]\n );\n\n let zoomPercentage = 0;\n let hotspotScale = 1.25;\n\n if (zoom >= 2) {\n zoomPercentage = 0.5;\n hotspotScale = 1.2;\n }\n\n if (zoom >= 4) {\n zoomPercentage = 1;\n hotspotScale = 1.1;\n }\n\n const constrainedWidth = Math.min(\n image.width,\n dimensions?.width || 0,\n image.width * ((dimensions?.height || 0) / image.height)\n );\n const constrainedHeight = image.height * (constrainedWidth / image.width);\n\n return (\n <Wrapper>\n <Preview>\n <Zoom ref={prismaZoomRef} onZoomChange={onZoomChange} maxZoom={maxZoom} scrollVelocity={0} allowTouchEvents>\n <ImageWrapper ref={containerRef}>\n <Image src={image.src} width={constrainedWidth} height={constrainedHeight}>\n {filtered.map((hotspot) => (\n <Hotspot\n key={`${hotspot.x}-${hotspot.y}-${hotspot.sequence}`}\n onClick={() => {\n dispatch(setHighlightedPart(parseInt(hotspot.sequence)));\n window.location.hash = `seq-${hotspot.sequence}`;\n }}\n scale={hotspotScale}\n imageWidth={image.width}\n imageHeight={image.height}\n selected={highlightedPart === parseInt(hotspot.sequence)}\n aria-label={parts.find(({ sequence }) => sequence === hotspot.sequence)?.partName}\n {...hotspot}\n >\n <HotspotScreenReader>\n {getLabel('selectHotspot')} {hotspot.sequence}\n </HotspotScreenReader>\n <span>{hotspot.sequence}</span>\n </Hotspot>\n ))}\n </Image>\n </ImageWrapper>\n </Zoom>\n </Preview>\n <Control>\n <ZoomControl zoom={zoomPercentage} onZoomIn={onZoomIn} onZoomOut={onZoomOut} />\n </Control>\n </Wrapper>\n );\n};\n\nexport default PartsDiagram;\n","import styled from 'styled-components';\nimport { Action, Icon, maxBp, minBp, theme } from '@triumph/shared';\n\nexport const Wrapper = styled.section`\n @media ${minBp('tabletLarge')} {\n display: flex;\n justify-content: space-between;\n gap: ${theme.spacing(5)};\n padding: ${theme.spacing(6)} 3.125rem;\n border-bottom: 1px solid #e6e6e6;\n background-color: #f6f6f6;\n }\n`;\n\nexport const Header = styled.header`\n position: relative;\n flex: 1 1 0;\n padding: ${theme.spacing(4)} ${theme.spacing(2)};\n background-color: #f6f6f6;\n\n @media ${maxBp('tabletLarge')} {\n border-bottom: 1px solid #e6e6e6;\n }\n\n @media ${minBp('tabletLarge')} {\n padding: 0;\n }\n`;\n\nexport const Summary = styled.div`\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: center;\n gap: ${theme.spacing(5)};\n\n @media ${minBp('tabletLarge')} {\n justify-content: flex-start;\n gap: ${theme.spacing(2)};\n }\n`;\n\nexport const Title = styled.h1`\n margin: 0 0 ${theme.spacing(2)};\n font-family: ${theme.fonts.dinDemi};\n font-size: 1.75rem;\n line-height: 1;\n text-align: center;\n text-transform: uppercase;\n color: #000;\n\n @media ${minBp('tabletLarge')} {\n margin-bottom: ${theme.spacing(1)};\n text-align: left;\n }\n`;\n\nexport const PartsCount = styled.span`\n font-family: ${theme.fonts.dinDemi};\n font-size: 0.875rem;\n line-height: 1.4285;\n color: #808080;\n`;\n\nexport const PartsCountIcon = styled(Icon)`\n margin-left: ${theme.spacing(1)};\n font-size: 0.625rem;\n`;\n\nexport const SearchForm = styled.form`\n display: flex;\n align-items: center;\n flex: 0 0 0;\n gap: clamp(${theme.spacing(2)}, 5vw, ${theme.spacing(3)});\n flex: 1;\n padding: ${theme.spacing(3)} ${theme.spacing(2)};\n\n @media ${minBp('tabletLarge')} {\n padding: 0;\n max-width: 23rem;\n }\n\n input {\n height: 3rem;\n font-family: ${theme.fonts.dinDemi};\n background: white;\n border-radius: 0;\n padding-right: ${theme.spacing(6)};\n background-image: url(\"data:image/svg+xml,%3Csvg width='16' height='16' viewBox='0 0 16 16' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M6.65143 12.0086C5.23429 12.0086 3.87429 11.4367 2.88 10.4303C1.88571 9.42387 1.32571 8.0629 1.32571 6.64475C1.33714 5.22659 1.89714 3.86562 2.90286 2.87062C3.90857 1.87563 5.26857 1.31523 6.68571 1.32666C8.09143 1.32666 9.45143 1.8985 10.4343 2.8935C11.4514 3.91137 12 5.2609 12 6.66762C12 8.08578 11.4394 9.44732 10.4343 10.4417C9.42857 11.4487 8.06857 12.0086 6.65143 12.0086ZM16 15.0965L11.8171 10.9107C12.8 9.72123 13.3371 8.22302 13.3371 6.67906C13.3371 4.90636 12.64 3.21372 11.3829 1.95568C10.1257 0.697641 8.43429 0 6.66286 0C4.89143 0 3.18857 0.709078 1.94286 1.96712C0.697143 3.21372 0 4.9178 0 6.69049C0 8.46319 0.708572 10.1558 1.96571 11.4024C3.22286 12.649 4.92571 13.3467 6.69714 13.3352C8.24 13.3352 9.72514 12.7863 10.9029 11.8142L15.0857 16L16 15.0965Z' fill='black'/%3E%3C/svg%3E%0A\");\n background-position: center right ${theme.spacing(2)};\n background-repeat: no-repeat;\n }\n\n button {\n width: 6rem;\n height: 2.25rem;\n }\n\n // Disable the clear button when placeholder is shown AKA, the field is empty.\n input:placeholder-shown + button {\n background-color: #f6f6f6;\n color: #000 !important;\n pointer-events: none;\n\n @media ${minBp('tabletLarge')} {\n background-color: #fff;\n }\n }\n`;\n","import React from 'react';\nimport { useLabel } from 'src/hooks';\nimport { Action, Button, FormFieldInput } from '@triumph/shared';\nimport { Header, PartsCount, PartsCountIcon, SearchForm, Summary, Title, Wrapper } from './PartsHeader.styled';\n\nconst PartsHeader = ({ category, onShowCategories, onSearchChange, partsCount }) => {\n const getLabel = useLabel();\n\n return (\n <Wrapper>\n <Header>\n <Title>{category}</Title>\n <Summary>\n <Action icon=\"pencil\" iconLeft primary onClick={onShowCategories}>\n {getLabel('partsChangeCategory')}\n </Action>\n {partsCount > 0 && (\n <PartsCount>\n {getLabel('partsCount').replace('{0}', partsCount)}\n <PartsCountIcon name=\"arrow-down\" aria-hidden />\n </PartsCount>\n )}\n </Summary>\n </Header>\n <SearchForm\n onSubmit={(event) => {\n event.preventDefault();\n onSearchChange({ value: event.target.elements?.search?.value, submit: true });\n }}\n onReset={() => onSearchChange({ value: '', reset: true })}\n >\n <FormFieldInput\n type=\"text\"\n name=\"search\"\n placeholder={getLabel('partsSearchPlaceholder')}\n onChange={({ target }) => onSearchChange({ value: target.value })}\n maxLength={256}\n />\n <Button type=\"reset\">{getLabel('partsSearchClear')}</Button>\n </SearchForm>\n </Wrapper>\n );\n};\n\nexport default PartsHeader;\n","import styled from 'styled-components';\nimport { Icon, maxBp, minBp, theme } from '@triumph/shared';\n\nexport const Table = styled.table`\n width: 100%;\n border-collapse: collapse;\n\n @media ${minBp('tabletLarge')} {\n th,\n td {\n &:not(:first-child) {\n padding-left: ${theme.spacing(3)};\n }\n\n &:not(:last-child) {\n padding-right: ${theme.spacing(3)};\n }\n }\n }\n`;\n\nexport const Head = styled.thead`\n @media ${maxBp('tabletLarge')} {\n display: none;\n }\n`;\n\nexport const CartIcon = styled(Icon)`\n position: relative;\n font-size: 1.25rem;\n color: #666;\n transform: translateY(22%);\n`;\n\nexport const TableHeader = styled.th`\n padding-bottom: ${theme.spacing(2)};\n border-bottom: 1px solid #e6e6e6;\n color: #666;\n font-family: ${theme.fonts.dinRegular};\n font-style: normal;\n font-weight: 600;\n font-size: 0.875rem;\n line-height: 1.428;\n text-align: left;\n vertical-align: baseline;\n max-width: 5rem;\n text-overflow: ellipsis;\n white-space: nowrap;\n overflow: hidden;\n\n > span {\n display: flex;\n align-items: baseline;\n gap: 0.25rem;\n\n > div > button {\n transform: translateY(10%);\n }\n }\n\n ${({ $center = false }) =>\n $center &&\n `\n text-align: center;\n\n > span {\n display: flex;\n justify-content: center;\n }\n `};\n`;\n\nexport const Sku = styled.td`\n @media ${maxBp('tabletLarge')} {\n grid-column: 1 / -1;\n padding: ${theme.spacing(2)} ${theme.spacing(1)} 0;\n }\n\n span {\n font-family: ${theme.fonts.dinDemi};\n font-size: 0.8125rem;\n line-height: 1.538;\n color: #666;\n }\n`;\n","import React, { useEffect, useState } from 'react';\nimport { Information } from '@triumph/shared';\nimport { Label } from 'src/_utility';\nimport { useUpdateBasket } from 'src/hooks';\nimport { useSelector } from 'react-redux';\nimport { getBike, getHighlightedPart, getLabels, getPartsList } from 'src/redux/app/selectors';\nimport toolTipEvent from 'src/gtm-events/toolTip';\nimport partsAddBasketEvent from 'src/gtm-events/partsAddBasket';\nimport partsRemoveBasketEvent from 'src/gtm-events/partsRemoveBasketAssembly';\nimport partIncreaseEvent from 'src/gtm-events/partIncreaseAssembly';\nimport partDecreaseEvent from 'src/gtm-events/partDecreaseAssembly';\nimport { CartIcon, Head, Table, TableHeader } from './PartsTable.styled';\nimport PartsTableRow from '../parts-table-row';\n\nexport default function PartsTable({ basket, children, onViewPart, rows = [] }) {\n const updateBasket = useUpdateBasket();\n const labels = useSelector(getLabels);\n const highlightedPart = useSelector(getHighlightedPart);\n const bike = useSelector(getBike);\n const parts = useSelector(getPartsList);\n const [activeInformation, setActiveInformation] = useState(null);\n\n useEffect(() => {\n if (!window.location.hash) {\n return;\n }\n\n // eslint-disable-next-line no-unused-expressions\n document.querySelector(window.location.hash)?.scrollIntoView({\n block: 'center',\n });\n }, [window.location.hash]);\n\n if (!basket) {\n return null;\n }\n\n return (\n <Table>\n <Head>\n <tr>\n <TableHeader>\n <Label name=\"partsTableRef\" />\n </TableHeader>\n <TableHeader>\n <Label name=\"PartNo\" />\n </TableHeader>\n <TableHeader>\n <Label name=\"partsTableItemName\" />\n </TableHeader>\n <TableHeader>\n <span>\n <Information\n title={<Label name=\"partsTableRrpInfoTitle\" />}\n smallIcon\n show={activeInformation === 'rrp'}\n onShow={() => {\n setActiveInformation('rrp');\n toolTipEvent({\n clickText: labels.partsTableRrp,\n bike,\n category: parts,\n });\n }}\n onClose={() => setActiveInformation(null)}\n >\n <Label name=\"partsTableRrpInfo\" asHtml />\n </Information>{' '}\n <Label name=\"partsTableRrp\" />\n </span>\n </TableHeader>\n <TableHeader $center>\n <span>\n <Information\n title={<Label name=\"partsTableQtyInfoTitle\" />}\n smallIcon\n show={activeInformation === 'qty'}\n onShow={() => {\n setActiveInformation('qty');\n toolTipEvent({\n clickText: labels.partsTableQty,\n bike,\n category: parts,\n });\n }}\n onClose={() => setActiveInformation(null)}\n >\n <Label name=\"partsTableQtyInfo\" asHtml />\n </Information>{' '}\n <Label name=\"partsTableQty\" />\n </span>\n </TableHeader>\n <TableHeader $center>\n <CartIcon name=\"cart\" aria-hidden />\n </TableHeader>\n </tr>\n </Head>\n <tbody>\n {Array.isArray(rows) && rows.length > 0\n ? rows.map((row) => {\n const inBasket = basket.find(\n ({ sku, displayIndex }) => row.sku === sku && row.displayIndex === displayIndex\n );\n\n return (\n <PartsTableRow\n selected={parseInt(row.sequence) === highlightedPart}\n inBasket={inBasket}\n onMinus={() => {\n updateBasket({\n part: row,\n quantity: Math.max(0, inBasket?.quantity - 1),\n });\n\n partDecreaseEvent({ part: row, bike, category: parts });\n }}\n onPlus={() => {\n updateBasket({\n part: row,\n quantity: inBasket ? inBasket?.quantity + 1 || 1 : 1,\n });\n\n partIncreaseEvent({ part: row, bike, category: parts });\n }}\n onToggleCart={() => {\n updateBasket({\n part: row,\n quantity: inBasket ? 0 : 1,\n });\n\n if (inBasket) {\n partsRemoveBasketEvent({ part: row, bike, category: parts });\n } else {\n partsAddBasketEvent({ part: row, bike, category: parts });\n }\n }}\n onViewPart={onViewPart}\n key={row.sku + row.displayIndex}\n category={parts}\n bike={bike}\n labels={labels}\n {...row}\n />\n );\n })\n : children}\n </tbody>\n </Table>\n );\n}\n","import { pushToDataLayer } from '@triumph/shared';\n\nexport default ({ part, bike, category }) =>\n pushToDataLayer({\n name: 'partDecreaseAssembly',\n category: 'Parts - Assembly',\n action: 'Basket - Decrease',\n label: part.sku,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n configuratorAccessoryCategory: category.name,\n configuratorAccessoryName: part.name,\n configuratorAccessoryId: part.sku,\n },\n });\n","import { pushToDataLayer } from '@triumph/shared';\n\nexport default ({ part, bike, category }) =>\n pushToDataLayer({\n name: 'partIncreaseAssembly',\n category: 'Parts - Assembly',\n action: 'Basket - Increase',\n label: part.sku,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n configuratorAccessoryCategory: category.name,\n configuratorAccessoryName: part.name,\n configuratorAccessoryId: part.sku,\n },\n });\n","import { pushToDataLayer } from '@triumph/shared';\n\nexport default ({ part, bike, category }) =>\n pushToDataLayer({\n name: 'partsRemoveBasketAssembly',\n category: 'Parts - Assembly',\n action: `Basket - Remove`,\n label: part.sku,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n configuratorAccessoryCategory: category.name,\n configuratorAccessoryName: part.name,\n configuratorAccessoryId: part.sku,\n },\n });\n","import { pushToDataLayer } from \"@triumph/shared\";\n\nexport default ({ part, bike, category }) => pushToDataLayer({\n name: 'partsAddBasket',\n category: 'Parts - Assembly',\n action: `Basket - Add`,\n label: part.sku,\n props: {\n configuratorBikeName: bike.name,\n configuratorBikeId: bike.id,\n configuratorBikeYear: bike.year,\n configuratorAccessoryCategory: category.name,\n configuratorAccessoryName: part.name,\n configuratorAccessoryId: part.sku,\n },\n});","import { theme, minBp, Icon, maxBp, Focusable } from '@triumph/shared';\nimport styled, { css } from 'styled-components';\n\nexport const Wrapper = styled.div`\n display: flex;\n flex-direction: column;\n align-items: center;\n\n @media ${minBp('tabletLarge')} {\n flex-direction: row-reverse;\n }\n`;\n\nconst buttonStyles = css`\n flex-shrink: 0;\n display: flex;\n align-items: center;\n justify-content: center;\n width: 1.875rem;\n height: 1.875rem;\n border: none;\n appearance: none;\n background: #fff;\n box-shadow: 0px 0px 6px rgba(0, 0, 0, 0.25);\n color: #000;\n cursor: pointer;\n font-size: 0.8125rem;\n\n &:disabled {\n color: #b3b3b3;\n cursor: not-allowed;\n }\n\n ${Focusable()}\n`;\n\nexport const ZoomIn = styled.button`\n ${buttonStyles}\n border-radius: 0.625rem 0.625rem 0 0;\n\n @media ${minBp('tabletLarge')} {\n border-radius: 0 0.625rem 0.625rem 0;\n }\n`;\n\nexport const ZoomOut = styled.button`\n ${buttonStyles}\n border-radius: 0 0 0.625rem 0.625rem;\n\n @media ${minBp('tabletLarge')} {\n border-radius: 0.625rem 0 0 0.625rem;\n }\n`;\n\nconst zoomLabelStyle = css`\n font-family: ${theme.fonts.dinRegular};\n font-weight: 600;\n font-size: 1rem;\n line-height: 1.25;\n text-transform: uppercase;\n color: ${({ disabled = false }) => (disabled ? '#b3b3b3' : '#000')};\n transition: color 200ms ease-in-out;\n pointer-events: none;\n\n @media ${maxBp('tabletLarge')} {\n display: none;\n }\n`;\n\nexport const ZoomInLabel = styled.span`\n ${zoomLabelStyle}\n margin-left: ${theme.spacing(3)};\n`;\n\nexport const ZoomOutLabel = styled.span`\n ${zoomLabelStyle}\n margin-right: ${theme.spacing(3)};\n`;\n\nexport const ButtonIcon = styled(Icon)`\n flex-shrink: 0;\n font-size: 0.8125rem;\n transition: color 200ms ease-in-out;\n`;\n\nexport const Meter = styled.div`\n width: 0.625rem;\n height: 3.125rem;\n background-color: #f0f0f0;\n\n @media ${minBp('tabletLarge')} {\n width: 3.75rem;\n height: 0.625rem;\n }\n`;\n\nexport const MeterLabel = styled.span`\n position: absolute;\n left: -10000px;\n top: auto;\n width: 1px;\n height: 1px;\n overflow: hidden;\n`;\n\nexport const MeterInner = styled.div`\n width: 100%;\n height: ${({ value }) => value * 100}%;\n background-color: ${theme.colors.primary};\n transition: height 100ms ease-in-out;\n\n @media ${minBp('tabletLarge')} {\n width: ${({ value }) => value * 100}%;\n height: 100%;\n transition: width 100ms ease-in-out;\n }\n`;\n","import React from 'react';\nimport { useLabel } from 'src/hooks';\nimport {\n ButtonIcon,\n Meter,\n MeterInner,\n MeterLabel,\n Wrapper,\n ZoomIn,\n ZoomInLabel,\n ZoomOut,\n ZoomOutLabel,\n} from './ZoomControl.styled';\n\nconst ZoomControl = ({\n onZoomIn,\n onZoomOut,\n zoom = 0, // Between 0 - 1.\n}) => {\n const getLabel = useLabel();\n return (\n <Wrapper>\n <ZoomInLabel disabled={!(zoom < 1)} onClick={onZoomIn}>\n {getLabel('partsZoomIn')}\n </ZoomInLabel>\n <ZoomIn disabled={!(zoom < 1)} onClick={onZoomIn} aria-label={getLabel('partsZoomIn')}>\n <ButtonIcon name=\"magnify-plus\" aria-hidden />\n </ZoomIn>\n <Meter>\n <MeterLabel>{zoom * 100} / 100%</MeterLabel>\n <MeterInner value={zoom}></MeterInner>\n </Meter>\n <ZoomOut disabled={!(zoom > 0)} onClick={onZoomOut} aria-label={getLabel('partsZoomOut')}>\n <ButtonIcon name=\"magnify-minus\" aria-hidden />\n </ZoomOut>\n <ZoomOutLabel disabled={!(zoom > 0)}>{getLabel('partsZoomOut')}</ZoomOutLabel>\n </Wrapper>\n );\n};\n\nexport default ZoomControl;\n","import styled from 'styled-components';\n\nexport const StepperComponent = styled.div`\n background: white;\n border-bottom: 1px solid #dedede;\n`;\n\nexport const RestrictedWidth = styled.div`\n margin: 0 auto;\n max-width: 78rem;\n`;\n","import React from 'react';\nimport { Stepper, toQueryString, useHideElement} from '@triumph/shared';\nimport { useLabel } from 'src/hooks';\nimport useCta from 'src/hooks/useCta';\nimport { useSelector } from 'react-redux';\nimport { getBike } from 'src/redux/app/selectors';\nimport { RestrictedWidth, StepperComponent } from './PartsStepper.styled';\n\nconst PartsStepper = ({ bikeSearchCompleted, catalogueCompleted, partsCompleted, product }) => {\n const getLabel = useLabel();\n const getCta = useCta();\n const bike = useSelector(getBike);\n \n useHideElement('[data-navigation-target=\"header-basket\"]');\n\n useHideElement('[data-navigation-target=\"header-basket\"]');\n\n document.body.classList.add('parts-section');\n\n const catalogQueryString = bike\n ? (product\n ? toQueryString({\n bikeId: bike.id,\n modelId: bike.productCode,\n product: product\n })\n : toQueryString({\n bikeId: bike.id,\n modelId: bike.productCode\n }))\n : null;\n\n const completedSteps = [\n bikeSearchCompleted ? 1 : undefined,\n catalogueCompleted ? 2 : undefined,\n partsCompleted ? 3 : undefined,\n ].filter((step) => !!step);\n\n return (\n <StepperComponent>\n <RestrictedWidth>\n <Stepper\n steps={[\n {\n href: getCta('bikeSearch'),\n label: getLabel('stepperBike'),\n number: 1,\n bold: true,\n uppercase: true,\n },\n {\n href: `${getCta('partsCatalogue')}?${catalogQueryString}`,\n label: getLabel('stepperCatalogue'),\n number: 2,\n bold: true,\n uppercase: true,\n },\n {\n label: getLabel('stepperParts'),\n number: 3,\n uppercase: true,\n },\n ]}\n completedSteps={completedSteps}\n activeStep={completedSteps.length}\n linear\n bordered\n shade={false}\n hideStepNumbersIfCompleted\n />\n </RestrictedWidth>\n </StepperComponent>\n );\n};\n\nexport default PartsStepper;\n"],"sourceRoot":""}