import React, { FC, useEffect, useRef, useState } from 'react'; import IconLoader from '../../blocks/IconLoader'; import css from './index.module.css'; import Content from '../Content'; import { MilaGridColumn, MilaGridVoid } from '../../index'; import ResizeObserver from 'resize-observer-polyfill'; import classnames from 'classnames'; import CategoryModal from '../CategoryModal'; import SimpleBar from 'simplebar-react'; import 'simplebar/dist/simplebar.min.css'; export interface SubCategory { slug: string; description: string; name: string; milaInternalId: string; } export interface Category { slug: string; name: string; subcategories: Array; image: string; milaInternalId: string; } interface PackageCategoryTabProps { categories: Array; onSelectCategory: (category, slug) => void; variant: 'normal' | 'banner' | 'partner'; selectedIndex: number; title: string; description: string; Translations: { showAll: string; showServices: string; title: string; }; } const PackageCategoryTab: FC = ({ categories, onSelectCategory, variant, selectedIndex, title, description, Translations, }) => { const [category, setCategory] = useState(null); const [modalIsOpen, setIsOpen] = useState(false); const openModal = (): void => { setIsOpen(true); }; const closeModal = (): void => { setIsOpen(false); }; const [elementsCount, _] = useState(categories.length); const tabRef = useRef(null); const gridRef = useRef(null); const [tabIndex, setTabIndex] = useState(-1); const [showSlider, setShowSlider] = useState(false); const scrollableNodeRef = useRef(null); useEffect(() => { if (tabIndex === -1) return; const target = gridRef.current.children[tabIndex]; const scrollRect = scrollableNodeRef.current.getBoundingClientRect(); const activeRect = target.getBoundingClientRect(); const scrollLeftPosition = activeRect.left - scrollRect.left - scrollRect.width / 2 + activeRect.width / 2; scrollableNodeRef?.current.scrollTo({ behavior: 'smooth', left: scrollableNodeRef.current.scrollLeft + scrollLeftPosition, }); }, [tabIndex]); useEffect(() => { setTabIndex(selectedIndex); setCategory(categories[selectedIndex]); }, [selectedIndex]); const ro = new ResizeObserver((entries, _) => { const containerWidth = entries[0].contentRect.width; setShowSlider( containerWidth < elementsCount * 80 + (elementsCount - 1) * 20, ); }); useEffect(() => { ro.observe(tabRef.current); return (): void => ro.unobserve(tabRef.current); }, [tabRef]); const [shadow, setShadow] = useState('right'); const handleScroll = (e): void => { if (e.target.scrollLeft === 0) { setShadow('right'); } else if ( e.target.scrollLeft === e.target.scrollWidth - e.target.clientWidth ) { setShadow('left'); } else { setShadow('both'); } }; useEffect(() => { if (showSlider) { handleScroll({ target: scrollableNodeRef.current, }); } }, [scrollableNodeRef]); return ( <>
{variant != 'banner' && (

{title}

{description && (
{description}
)}
)} 4 ? { columns: ['sm-12', 'lg-10'], offset: ['lg-1'] } : { columns: ['sm-12', 'lg-10', 'xl-8', 'xxl-6'], offset: ['lg-1', 'xl-2', 'xxl-3'], })} className={css.category__gridSpacer} >
4 ? 'evenly' : 'normal'} > {categories.map((item, index) => { return (
{ const selectedCategory = categories[index]; setCategory(selectedCategory); if (selectedCategory.subcategories.length === 0) { onSelectCategory(selectedCategory, 'all'); } else if ( selectedCategory.subcategories.length === 1 ) { onSelectCategory( selectedCategory, selectedCategory.subcategories[0].slug, ); } else { openModal(); } }} > {item.name}
); })}
{showSlider && (variant === 'banner' || variant === 'partner') && (
)}
{ closeModal(); onSelectCategory(category, slug); }} onRequestClose={closeModal} selectedCategory={category} Translations={Translations} /> ); }; export default PackageCategoryTab;