{"version":3,"file":"thumbnail-image-gallery.js?v=9.1.8","mappings":"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","sources":["webpack://empori-base/./src/backoffice/controllers/common.ts","webpack://empori-base/./src/controls/ImageGalleryFullscreen.tsx","webpack://empori-base/./src/controls/ImageGalleryWithThumbnails.tsx","webpack://empori-base/./src/util/util.ts"],"sourcesContent":["export interface EnumListItem {\r\n label: string;\r\n value: string;\r\n}\r\n\r\nexport interface MediaSelectionItem {\r\n name: string;\r\n id: number;\r\n udi: string;\r\n icon: string;\r\n trashed: boolean;\r\n key: string;\r\n parentId: number;\r\n alias: string;\r\n path: string;\r\n metaData: MediaSelectionMetaData;\r\n thumbnail: string;\r\n image: string;\r\n updateDate: string;\r\n filtered: boolean | null;\r\n $$hashKey: string;\r\n isFolder: boolean;\r\n width: number;\r\n height: number;\r\n aspectRatio: number;\r\n selectable: boolean;\r\n flexStyle: MediaSelectionFlexStyle;\r\n selected: boolean;\r\n altText?: string;\r\n}\r\n\r\ninterface MediaSelectionMetaData {\r\n ContentTypeAlias: string;\r\n UpdateDate: string;\r\n MediaPath: string;\r\n IsContainer: boolean;\r\n}\r\n\r\ninterface MediaSelectionFlexStyle {\r\n flex: string;\r\n 'max-width': string;\r\n 'min-width': string;\r\n 'min-height': string;\r\n}\r\n\r\nexport interface MediaPickerOutput {\r\n multiPicker: boolean;\r\n view: string;\r\n size: string;\r\n updatedMediaNodes: any[]; // TODO: Find out what this does contain\r\n infiniteMode: boolean;\r\n inFront: boolean;\r\n moveRight: boolean;\r\n level: number;\r\n styleIndex: number;\r\n animating: boolean;\r\n $$hashKey: string;\r\n selection: MediaSelectionItem[];\r\n title: string;\r\n}\r\n\r\nexport interface LinkPickerOutPut {\r\n target: LinkPickerTarget;\r\n}\r\n\r\nexport interface LinkPickerTarget {\r\n anchor: string;\r\n id: string;\r\n name: string;\r\n target: string;\r\n udi: string; // Umbraco reference\r\n url: string;\r\n}\r\n\r\nexport const isImage = (url: string) => {\r\n return /\\.(jpg|jpeg|png|webp|avif|gif|svg)$/.test(url);\r\n};\r\n\r\nexport const isVideo = (url: string) => {\r\n return /\\.(mp4|ogg|mov)$/.test(url);\r\n};","import * as React from 'react';\r\nimport { Swiper, SwiperSlide, useSwiper } from 'swiper/react';\r\nimport ReactDOM from 'react-dom';\r\nimport { isImage } from '../backoffice/controllers/common';\r\nimport { className } from '@empori/util';\r\n\r\nexport function FullscreenSlide(slide: string) {\r\n const isSlideImage = isImage(slide);\r\n\r\n return(\r\n
\r\n {!isSlideImage &&\r\n }\r\n
\r\n );\r\n}\r\n\r\ninterface ToobarProps {\r\n onClose: () => void;\r\n totalSlides: number;\r\n currentSlideIndex: number;\r\n}\r\n\r\nexport function FullscreenToolbar(props: ToobarProps) {\r\n const [ ready, getReady ] = React.useState(false);\r\n const swiper = useSwiper();\r\n const prevPossible = props.currentSlideIndex !== 0;\r\n const nextPossible = props.currentSlideIndex + 1 < props.totalSlides;\r\n\r\n // Only for a simple fade-in animation.\r\n React.useEffect(() => {\r\n setTimeout(() => {\r\n getReady(true);\r\n }, 500);\r\n }, []);\r\n\r\n return(\r\n
\r\n swiper.slidePrev()}>\r\n \r\n \r\n \r\n {`${props.currentSlideIndex + 1}/${props.totalSlides}`}\r\n \r\n \r\n swiper.slideNext()}>\r\n \r\n \r\n
\r\n );\r\n}\r\n\r\ninterface ImageGalleryFullscreenProps {\r\n slideImgUrls: string[];\r\n toggled: boolean;\r\n viewingIndex: number;\r\n open: () => void;\r\n close: () => void;\r\n setIndex: (index: number) => void;\r\n}\r\n\r\nexport function ImageGalleryFullscreen(props: ImageGalleryFullscreenProps) {\r\n const { toggled, slideImgUrls } = props;\r\n\r\n if (!toggled || !slideImgUrls) {\r\n return
props.open()}>\r\n \r\n
;\r\n }\r\n\r\n return(\r\n ReactDOM.createPortal(\r\n
\r\n props.setIndex(swiper.realIndex)}\r\n initialSlide={props.viewingIndex}>\r\n {slideImgUrls.map((slide, index) =>\r\n \r\n {FullscreenSlide(slide)}\r\n )}\r\n \r\n \r\n
, document.body\r\n )\r\n );\r\n}\r\n\r\ninterface ImageGalleryFullscreenWrapperProps {\r\n slideImgUrls: string[];\r\n onClose: (activeIndex: number) => void;\r\n activeIndex: number;\r\n}\r\n\r\nexport function ImageGalleryFullscreenWrapper(props: ImageGalleryFullscreenWrapperProps) {\r\n const [currentIndex, setCurrentIndex] = React.useState(props.activeIndex);\r\n\r\n return(\r\n setCurrentIndex(fsSwiper.realIndex)}\r\n initialSlide={currentIndex}>\r\n {props.slideImgUrls.map((slide, index) =>\r\n \r\n {FullscreenSlide(slide)}\r\n )}\r\n props.onClose(currentIndex)}\r\n totalSlides={props.slideImgUrls.length}\r\n currentSlideIndex={currentIndex} />\r\n \r\n );\r\n}","import { className } from '@empori/util';\r\nimport * as React from 'react';\r\nimport { Swiper, SwiperSlide, useSwiper } from 'swiper/react';\r\nimport { ImageWithInfo } from '../empracoTypes';\r\nimport { FaIcon } from '../generic/icon';\r\nimport { ImageGalleryFullscreen } from './ImageGalleryFullscreen';\r\nimport { Slide } from '../empracoTypes';\r\nimport { Direction } from '../util/util';\r\n\r\ninterface SlideProps {\r\n image: ImageWithInfo;\r\n index: number;\r\n}\r\n\r\nfunction SlideItem({ image, index }: SlideProps) {\r\n return ;\r\n}\r\n\r\ninterface NavArrowProps {\r\n direction: Direction;\r\n}\r\n\r\nfunction NavArrow ({ direction }: NavArrowProps) {\r\n const swiper = useSwiper();\r\n\r\n const handleChange = () => {\r\n if (direction === Direction.next) {\r\n swiper.slideNext();\r\n return;\r\n }\r\n\r\n swiper.slidePrev();\r\n };\r\n\r\n return (\r\n
\r\n \r\n
\r\n );\r\n}\r\n\r\ninterface ThumbnailProps {\r\n index: number;\r\n image: ImageWithInfo;\r\n active: boolean;\r\n}\r\n\r\nfunction Thumbnail({ index, image, active }: ThumbnailProps) {\r\n const swiper = useSwiper();\r\n\r\n return(\r\n
swiper.slideTo(index + 1)}>\r\n
\r\n
\r\n );\r\n}\r\n\r\ninterface ThumbnailImageGalleryProps {\r\n images: ImageWithInfo[];\r\n}\r\n\r\nexport default function ThumbnailImageGallery({ images }: ThumbnailImageGalleryProps) {\r\n const [ activeIndex, setActiveIndex ] = React.useState(0);\r\n const [ fullscreen, setFullscreen ] = React.useState(false);\r\n\r\n if (!images || images && images.length < 1) {\r\n return null;\r\n }\r\n\r\n return (\r\n 1}\r\n spaceBetween={0}\r\n slidesPerView={1}\r\n onSlideChangeTransitionStart={swiper => setActiveIndex(swiper.realIndex)}\r\n lazy>\r\n {images.map((image, index) =>\r\n \r\n \r\n )}\r\n \r\n \r\n
\r\n {images.map((image, index) =>\r\n )}\r\n
\r\n img.imgUrlOriginal)}\r\n viewingIndex={activeIndex}\r\n close={() => setFullscreen(false)}\r\n open={() => setFullscreen(true)}\r\n setIndex={setActiveIndex} />\r\n \r\n );\r\n}","import * as React from 'react';\r\n\r\nexport type MappedArrayObject = {\r\n [key: string]: T;\r\n};\r\n\r\nexport type GroupedArrayObject = {\r\n [key: string]: T[];\r\n};\r\n\r\nexport function arrayToObject(array: T[], key: (item: T) => string): MappedArrayObject {\r\n const obj: MappedArrayObject = {};\r\n\r\n for (let item of array) {\r\n obj[key(item)] = item;\r\n }\r\n\r\n return obj;\r\n}\r\n\r\nexport function groupArray(array: T[], key: (item: T) => string): GroupedArrayObject {\r\n const obj: GroupedArrayObject = {};\r\n\r\n for (let item of array) {\r\n const itemKey = key(item);\r\n (obj[itemKey] || (obj[itemKey] = [])).push(item);\r\n }\r\n\r\n return obj;\r\n}\r\n\r\nexport function camelCase(value?: string) {\r\n if (!value || value.length <= 1) {\r\n return value ?? '';\r\n }\r\n\r\n return value.charAt(0).toLocaleLowerCase() + value.substring(1);\r\n}\r\n\r\nconst formatMustasch = /{([^{}]*)}/g;\r\n\r\n/**\r\n * Format a string template in a provided mustasch format using an object as a lookup source.\r\n *\r\n * @example\r\n * formatObject('test {key1} format', { key1: 'string' }) // \"test string format\"\r\n *\r\n * @param format Format string template.\r\n * @param object Object to use as lookup.\r\n * @param replacementFunc Optional callback function for each parsed tag.\r\n * Returned `string` will be used instead of given mapped item.\r\n * @returns Formatted string template.\r\n */\r\nexport function formatObject(format: string, object?: any, replacementFunc?: (key: string, item: any) => string) {\r\n if (object == null) {\r\n return '';\r\n }\r\n\r\n return format.replace(formatMustasch, (a: string, b: string) => {\r\n let val = object[b] ?? object[camelCase(b)];\r\n let formatVal = replacementFunc?.(b, val);\r\n return formatVal ?? val;\r\n });\r\n}\r\n\r\nconst byte = 1024;\r\nexport const FileSizeUnits = {\r\n KiB: byte,\r\n MiB: byte * byte,\r\n GiB: byte * byte * byte,\r\n TiB: byte * byte * byte * byte,\r\n PiB: byte * byte * byte * byte * byte,\r\n EiB: byte * byte * byte * byte * byte * byte\r\n};\r\n\r\n/**\r\n * Returns a new array with one item replaced at given index.\r\n * Does not mutate the original array.\r\n * @param items The original array\r\n * @param index What item to replace\r\n * @param newItem The new replacementitem\r\n */\r\nexport function replaceItem(items: T[], index: number, newItem: T) {\r\n return items.map((item, idx) => idx === index ? newItem : item);\r\n}\r\n\r\nexport const FileExtensions = {\r\n PDF: '.pdf',\r\n MP4: '.mp4',\r\n OGG: '.ogg',\r\n SVG: '.svg',\r\n GIF: '.gif'\r\n};\r\n\r\nexport function thousandSeparator(num: number) {\r\n return num.toString().replace(/\\B(?=(\\d{3})+(?!\\d))/g, ' ');\r\n};\r\n\r\n// eslint-disable-next-line no-shadow\r\nexport enum Direction {\r\n prev,\r\n next\r\n}\r\n\r\n// eslint-disable-next-line no-shadow\r\nexport enum ThemeIds {\r\n raw = 'Raw',\r\n exclusive = 'Exclusive'\r\n}\r\n\r\nexport function parseStyleString(styleString: string) {\r\n const styleObj: React.CSSProperties = {};\r\n\r\n if (!styleString) {\r\n return styleObj;\r\n }\r\n\r\n styleString.split(';').forEach(style => {\r\n const [property, value] = style.split(':').map(str => str.trim());\r\n\r\n if (property && value) {\r\n (styleObj as any)[property] = value;\r\n }\r\n });\r\n\r\n return styleObj;\r\n}\r\n\r\nexport function useDebounce(value: T, delay = 500) {\r\n const [debouncedValue, setDebouncedValue] = React.useState();\r\n const timerRef = React.useRef(0);\r\n\r\n React.useEffect(() => {\r\n timerRef.current = setTimeout(() => setDebouncedValue(value), delay) as unknown as number;\r\n\r\n return () => {\r\n clearTimeout(timerRef.current);\r\n };\r\n }, [value, delay]);\r\n\r\n return debouncedValue;\r\n}\r\n"],"names":["isImage","url","test","FullscreenSlide","slide","isSlideImage","className","style","backgroundImage","backgroundColor","controls","src","type","FullscreenToolbar","props","ready","getReady","swiper","prevPossible","currentSlideIndex","nextPossible","totalSlides","setTimeout","disabled","onClick","slidePrev","onClose","slideNext","ImageGalleryFullscreen","toggled","slideImgUrls","onSlideChange","setIndex","realIndex","initialSlide","viewingIndex","map","index","close","length","document","body","open","ImageGalleryFullscreenWrapper","currentIndex","setCurrentIndex","activeIndex","fsSwiper","SlideItem","image","loading","imgUrl","alt","imgAlt","NavArrow","direction","next","clsName","Thumbnail","active","slideTo","title","ThumbnailImageGallery","images","setActiveIndex","fullscreen","setFullscreen","loop","spaceBetween","slidesPerView","onSlideChangeTransitionStart","lazy","prev","img","imgUrlOriginal","FileSizeUnits","KiB","MiB","byte","GiB","TiB","PiB","EiB","FileExtensions","PDF","MP4","OGG","SVG","GIF","thousandSeparator","num","toString","replace","Direction","ThemeIds"],"sourceRoot":""}