@lifesg/react-design-system 3.5.0-canary.7 → 3.5.0-canary.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/accordion/accordion-item.js +1 -1
- package/accordion/accordion-item.js.map +1 -1
- package/accordion/types.d.ts +7 -0
- package/button/button.style.js +20 -19
- package/button/button.style.js.map +1 -1
- package/cjs/accordion/accordion-item.js +1 -1
- package/cjs/accordion/accordion-item.js.map +1 -1
- package/cjs/button/button.style.js +3 -2
- package/cjs/button/button.style.js.map +1 -1
- package/cjs/file-download/file-download.js +1 -1
- package/cjs/file-download/file-download.js.map +1 -1
- package/cjs/file-download/file-list-card/file-list-card.js +1 -1
- package/cjs/file-download/file-list-card/file-list-card.js.map +1 -1
- package/cjs/file-download/file-list-card/file-list-card.styles.js +75 -59
- package/cjs/file-download/file-list-card/file-list-card.styles.js.map +1 -1
- package/cjs/file-upload/helper.js +1 -1
- package/cjs/file-upload/helper.js.map +1 -1
- package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.js +1 -1
- package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
- package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.style.js +19 -19
- package/cjs/fullscreen-image-carousel/fullscreen-image-carousel.style.js.map +1 -1
- package/cjs/navbar/menu.js +1 -1
- package/cjs/navbar/menu.js.map +1 -1
- package/cjs/navbar/menu.styles.js +1 -1
- package/cjs/navbar/menu.styles.js.map +1 -1
- package/cjs/navbar/navbar-items.js +1 -1
- package/cjs/navbar/navbar-items.js.map +1 -1
- package/cjs/navbar/navbar-items.styles.js +20 -21
- package/cjs/navbar/navbar-items.styles.js.map +1 -1
- package/file-download/file-download.d.ts +1 -1
- package/file-download/file-download.js +1 -1
- package/file-download/file-download.js.map +1 -1
- package/file-download/file-list-card/file-list-card.d.ts +1 -1
- package/file-download/file-list-card/file-list-card.js +1 -1
- package/file-download/file-list-card/file-list-card.js.map +1 -1
- package/file-download/file-list-card/file-list-card.styles.d.ts +8 -0
- package/file-download/file-list-card/file-list-card.styles.js +53 -37
- package/file-download/file-list-card/file-list-card.styles.js.map +1 -1
- package/file-download/file-list-card/types.d.ts +2 -1
- package/file-download/types.d.ts +7 -0
- package/file-upload/helper.d.ts +30 -0
- package/file-upload/helper.js +1 -1
- package/file-upload/helper.js.map +1 -1
- package/fullscreen-image-carousel/fullscreen-image-carousel.d.ts +1 -1
- package/fullscreen-image-carousel/fullscreen-image-carousel.js +1 -1
- package/fullscreen-image-carousel/fullscreen-image-carousel.js.map +1 -1
- package/fullscreen-image-carousel/fullscreen-image-carousel.style.d.ts +7 -0
- package/fullscreen-image-carousel/fullscreen-image-carousel.style.js +21 -21
- package/fullscreen-image-carousel/fullscreen-image-carousel.style.js.map +1 -1
- package/fullscreen-image-carousel/types.d.ts +16 -0
- package/navbar/menu.d.ts +2 -1
- package/navbar/menu.js +1 -1
- package/navbar/menu.js.map +1 -1
- package/navbar/menu.styles.js +3 -3
- package/navbar/menu.styles.js.map +1 -1
- package/navbar/navbar-items.js +1 -1
- package/navbar/navbar-items.js.map +1 -1
- package/navbar/navbar-items.styles.js +30 -31
- package/navbar/navbar-items.styles.js.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fullscreen-image-carousel.js","sources":["../../src/fullscreen-image-carousel/fullscreen-image-carousel.tsx"],"sourcesContent":["import {\n ChevronLeftIcon,\n ChevronRightIcon,\n CrossIcon,\n MagnifierMinusIcon,\n MagnifierPlusIcon,\n} from \"@lifesg/react-icons\";\nimport { BinIcon } from \"@lifesg/react-icons/bin\";\nimport { announce, clearAnnouncer } from \"@react-aria/live-announcer\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n ReactZoomPanPinchContentRef,\n ReactZoomPanPinchRef,\n TransformComponent,\n TransformWrapper,\n} from \"react-zoom-pan-pinch\";\nimport { ModalV2 } from \"../modal-v2\";\nimport { useStateCallback } from \"../shared/hooks\";\nimport { useEventListener } from \"../util\";\nimport {\n ArrowButton,\n BoxChip,\n CarouselModalContent,\n Chip,\n CloseButton,\n DeleteButton,\n FileInfoFileName,\n FileInfoFileSize,\n FileInfoTextWrapper,\n FocusableImageRegion,\n ImageGalleryContainer,\n ImageGallerySlide,\n ImageGallerySlides,\n ImageGallerySwipe,\n ImageGalleryWrapper,\n MagnifierButton,\n SlideImage,\n SlidePlaceholderImage,\n ThumbnailContainer,\n ThumbnailImage,\n ThumbnailItem,\n ThumbnailItemContainer,\n ThumbnailWrapper,\n TopActionButtons,\n} from \"./fullscreen-image-carousel.style\";\nimport {\n FullscreenImageCarouselCustomItemProps,\n FullscreenImageCarouselItemProps,\n FullscreenImageCarouselProps,\n FullscreenImageCarouselRef,\n ImageDimension,\n} from \"./types\";\n\nconst isCustomItem = (\n item: FullscreenImageCarouselItemProps | undefined\n): item is FullscreenImageCarouselCustomItemProps =>\n !!item && item.type === \"custom\";\n\nexport const Component = (\n {\n items,\n initialActiveItemIndex,\n hideThumbnail = false,\n hideNavigation = false,\n hideCounter = false,\n hideMagnifier = false,\n onDelete,\n onClose,\n insets,\n show,\n ...otherProps\n }: FullscreenImageCarouselProps,\n ref: React.Ref<FullscreenImageCarouselRef>\n) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [currentSlide, setCurrentSlide] = useStateCallback(\n initialActiveItemIndex ?? 0\n );\n const [imagesDimension, setImageDimension] = useState<\n Record<string, ImageDimension>\n >({});\n const [zoom, setZoom] = useState(1);\n const [startX, setStartX] = useState<number | undefined>();\n const [endX, setEndX] = useState<number | undefined>();\n const containerRef = useRef<HTMLDivElement>(null);\n const thumbnailRefs = useRef<(HTMLDivElement | null)[]>([]);\n const zoomRefs = useRef<(ReactZoomPanPinchContentRef | null)[]>([]);\n const imageRef = useRef<HTMLDivElement>(null);\n const diff = startX && endX ? startX - endX : 0;\n const currentItem = items[currentSlide];\n const hasAnyItemLabel = items.some(\n (item) => isCustomItem(item) && !!item.itemLabel?.trim()\n );\n const carouselItemNoun = hasAnyItemLabel ? \"item\" : \"image\";\n const hasFileInfo = useMemo(\n () =>\n items.some(\n (item) => item.fileName?.trim() || item.fileSize?.trim()\n ),\n [items]\n );\n\n const getItemAriaLabel = useCallback(\n (index: number) => {\n const item = items[index];\n const itemTypeLabel = hasAnyItemLabel ? \"Item\" : \"Image\";\n const prefix = isCustomItem(item)\n ? item.itemLabel?.trim() || \"\"\n : item.alt?.trim() || \"\";\n const positionLabel = `${itemTypeLabel} ${index + 1} of ${\n items.length\n }.`;\n\n return prefix ? `${prefix}. ${positionLabel}` : positionLabel;\n },\n [items, hasAnyItemLabel]\n );\n\n useImperativeHandle<FullscreenImageCarouselRef, FullscreenImageCarouselRef>(\n ref,\n () => ({\n currentItemIndex: currentSlide,\n setCurrentItem: goToSlide,\n goToPrevItem: goToPrevSlide,\n goToNextItem: goToNextSlide,\n })\n );\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEventListener(\"keydown\", handleKeyDown, \"document\");\n\n useEffect(() => {\n if (show) {\n imageRef.current?.focus();\n }\n }, [show]);\n\n useEffect(() => {\n if (items.length === 0) {\n setCurrentSlide(0);\n return;\n }\n\n if (currentSlide > items.length - 1) {\n setCurrentSlide(items.length - 1);\n }\n }, [currentSlide, items.length, setCurrentSlide]);\n\n useEffect(() => {\n thumbnailRefs.current?.[currentSlide]?.scrollIntoView({\n behavior: \"smooth\",\n inline: \"center\",\n });\n setZoom(1);\n }, [currentSlide]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleTouchStart = (e: React.TouchEvent) => {\n if (zoom <= 1) setStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n if (!startX || zoom > 1) return;\n setEndX(e.touches[0].clientX);\n };\n\n const handleTouchEnd = () => {\n if (!containerRef.current) return;\n if (Math.abs(diff) > containerRef.current.offsetWidth / 3) {\n if (diff > 0) {\n goToNextSlide();\n } else {\n goToPrevSlide();\n }\n }\n setStartX(undefined);\n setEndX(undefined);\n };\n\n const handleZoom = (e: ReactZoomPanPinchRef) => {\n setZoom(e.state.scale);\n };\n\n const handleDelete = () => {\n if (currentItem && onDelete) {\n onDelete(currentItem, currentSlide);\n }\n };\n\n function handleKeyDown(e: KeyboardEvent) {\n if (e.key === \"ArrowRight\") {\n goToNextSlide();\n } else if (e.key === \"ArrowLeft\") {\n goToPrevSlide();\n } else if (e.key === \"Escape\") {\n onClose?.();\n }\n }\n\n const handleMagnifier = () => {\n if (zoom === 1) {\n const zoomRatio = getZoomRatio();\n zoomRefs.current?.[currentSlide]?.centerView(zoomRatio);\n setZoom(zoomRatio ?? 1);\n } else {\n setZoom(1);\n zoomRefs.current?.[currentSlide]?.resetTransform();\n }\n };\n\n const setDimension = ({\n src,\n height,\n width,\n }: {\n src: string;\n height: number;\n width: number;\n }) => {\n setImageDimension((oldState) => {\n return { ...oldState, [src]: { height, width } };\n });\n };\n\n const getZoomRatio = () => {\n if (!currentItem || isCustomItem(currentItem)) {\n return;\n }\n\n const imageDimension = imagesDimension[currentItem.src];\n\n if (containerRef.current && !!imageDimension) {\n const { clientHeight, clientWidth } = containerRef.current;\n const { width, height } = imageDimension;\n const isSmallImg = width < clientWidth && height < clientHeight;\n\n const isImgLandscapeRelativeToDevice =\n height / width < clientHeight / clientWidth;\n\n if (isSmallImg) {\n return isImgLandscapeRelativeToDevice\n ? clientWidth / width\n : clientHeight / height;\n }\n\n return isImgLandscapeRelativeToDevice\n ? clientHeight / (height / (width / clientWidth))\n : clientWidth / (width / (height / clientHeight));\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const goToPrevSlide = () => {\n zoomRefs.current?.[currentSlide]?.resetTransform();\n setCurrentSlide(\n (prev) => (prev === 0 ? items.length - 1 : prev - 1),\n (slide) => {\n clearAnnouncer(\"polite\");\n announce(getItemAriaLabel(slide), \"polite\");\n }\n );\n };\n\n const goToNextSlide = () => {\n zoomRefs.current?.[currentSlide]?.resetTransform();\n setCurrentSlide(\n (prev) => (prev === items.length - 1 ? 0 : prev + 1),\n (slide) => {\n clearAnnouncer(\"polite\");\n announce(getItemAriaLabel(slide), \"polite\");\n }\n );\n };\n\n const goToSlide = (index: number) => {\n zoomRefs.current?.[currentSlide]?.resetTransform();\n setCurrentSlide(index);\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderSlides = () => {\n return (\n <ImageGallerySlides\n style={{\n transform: `translateX(calc(${\n -currentSlide * 100\n }% - ${diff}px))`,\n }}\n >\n {items.map((item, index) => {\n const isActive = index === currentSlide;\n const isActiveOrAdjacent =\n Math.abs(index - currentSlide) <= 1 ||\n (currentSlide === 0 && index === items.length - 1) ||\n (currentSlide === items.length - 1 && index === 0);\n\n return (\n <ImageGallerySlide key={index} data-testid=\"slide-item\">\n <FocusableImageRegion\n ref={isActive ? imageRef : null}\n tabIndex={isActive ? 0 : -1}\n >\n {isCustomItem(item) ? (\n isActiveOrAdjacent ? (\n item.renderContent()\n ) : (\n <SlidePlaceholderImage />\n )\n ) : (\n <TransformWrapper\n ref={(el) =>\n (zoomRefs.current[index] = el)\n }\n panning={{\n disabled: zoom <= 1,\n }}\n initialScale={1}\n onZoom={handleZoom}\n onZoomStop={handleZoom}\n onWheel={handleZoom}\n >\n <TransformComponent>\n <SlideImage\n src={item.src}\n alt={getItemAriaLabel(index)}\n placeholder={\n <SlidePlaceholderImage />\n }\n fit=\"scale-down\"\n retrieveImageDimension\n setDimension={setDimension}\n />\n </TransformComponent>\n </TransformWrapper>\n )}\n </FocusableImageRegion>\n </ImageGallerySlide>\n );\n })}\n </ImageGallerySlides>\n );\n };\n\n const renderFileInfo = () => {\n const { fileName, fileSize } = currentItem ?? {};\n const trimmedName = fileName?.trim();\n const trimmedSize = fileSize?.trim();\n\n return (\n <FileInfoTextWrapper\n $centerContent={!trimmedSize}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n data-testid=\"file-info-bar\"\n >\n {trimmedName && (\n <FileInfoFileName\n weight=\"semibold\"\n data-testid=\"file-info-name\"\n >\n {trimmedName}\n </FileInfoFileName>\n )}\n {trimmedSize && (\n <FileInfoFileSize data-testid=\"file-info-size\">\n {trimmedSize}\n </FileInfoFileSize>\n )}\n </FileInfoTextWrapper>\n );\n };\n\n const renderThumbnails = () => {\n return (\n <ThumbnailContainer\n $insetBottom={insets?.bottom}\n aria-hidden=\"true\"\n >\n <ThumbnailWrapper>\n {items.map((item, index) => {\n const src = isCustomItem(item)\n ? item.thumbnailSrc\n : item.thumbnailSrc ?? item.src;\n return (\n <ThumbnailItemContainer key={index}>\n <ThumbnailItem\n data-testid=\"thumbnail-item\"\n $active={index === currentSlide}\n onClick={() => goToSlide(index)}\n ref={(el) =>\n (thumbnailRefs.current[index] = el)\n }\n >\n {src ? (\n <ThumbnailImage\n src={src}\n alt={`Thumbnail ${index + 1}`}\n fit=\"cover\"\n />\n ) : (\n <SlidePlaceholderImage />\n )}\n </ThumbnailItem>\n </ThumbnailItemContainer>\n );\n })}\n </ThumbnailWrapper>\n </ThumbnailContainer>\n );\n };\n\n return (\n <ModalV2\n {...otherProps}\n data-testid=\"image-carousel-modal\"\n aria-label={hasAnyItemLabel ? \"Carousel\" : \"Image carousel\"}\n show={show}\n disableInitialFocus\n >\n <CarouselModalContent>\n <ImageGalleryContainer>\n <ImageGalleryWrapper>\n <ImageGallerySwipe\n ref={containerRef}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n {renderSlides()}\n </ImageGallerySwipe>\n\n {!hideNavigation && (\n <>\n <ArrowButton\n aria-label={`Previous ${carouselItemNoun}`}\n data-testid=\"prev-btn\"\n $position=\"left\"\n onClick={goToPrevSlide}\n $insetLeft={insets?.left}\n $insetRight={insets?.right}\n >\n <ChevronLeftIcon aria-hidden />\n </ArrowButton>\n <ArrowButton\n aria-label={`Next ${carouselItemNoun}`}\n data-testid=\"forward-btn\"\n $position=\"right\"\n onClick={goToNextSlide}\n $insetLeft={insets?.left}\n $insetRight={insets?.right}\n >\n <ChevronRightIcon aria-hidden />\n </ArrowButton>\n </>\n )}\n\n {!hideCounter && (\n <BoxChip aria-hidden=\"true\">\n <Chip weight=\"semibold\">{`${currentSlide + 1}/${\n items.length\n }`}</Chip>\n </BoxChip>\n )}\n </ImageGalleryWrapper>\n\n {!hideThumbnail && renderThumbnails()}\n </ImageGalleryContainer>\n <TopActionButtons\n $hasFileInfo={hasFileInfo}\n $insetTop={insets?.top}\n $insetLeft={insets?.left}\n $insetRight={insets?.right}\n >\n {hasFileInfo && renderFileInfo()}\n {!hideMagnifier && !isCustomItem(currentItem) && (\n <MagnifierButton\n aria-label={zoom === 1 ? \"Zoom in\" : \"Zoom out\"}\n onClick={handleMagnifier}\n >\n {zoom === 1 ? (\n <MagnifierPlusIcon aria-hidden />\n ) : (\n <MagnifierMinusIcon aria-hidden />\n )}\n </MagnifierButton>\n )}\n\n {onDelete && (\n <DeleteButton\n aria-label={`Delete ${\n (isCustomItem(currentItem) &&\n currentItem.itemLabel?.trim()) ||\n \"image\"\n }`}\n data-testid=\"delete-btn\"\n onClick={handleDelete}\n >\n <BinIcon aria-hidden />\n </DeleteButton>\n )}\n\n <CloseButton\n aria-label={\n hasAnyItemLabel\n ? \"Close carousel\"\n : \"Close image carousel\"\n }\n onClick={onClose}\n >\n <CrossIcon aria-hidden />\n </CloseButton>\n </TopActionButtons>\n </CarouselModalContent>\n </ModalV2>\n );\n};\n\nexport const FullscreenImageCarousel = forwardRef<\n FullscreenImageCarouselRef,\n FullscreenImageCarouselProps\n>(Component);\n"],"names":["isCustomItem","item","type","Component","_a","ref","items","initialActiveItemIndex","hideThumbnail","hideNavigation","hideCounter","hideMagnifier","onDelete","onClose","insets","show","otherProps","__rest","currentSlide","setCurrentSlide","useStateCallback","imagesDimension","setImageDimension","useState","zoom","setZoom","startX","setStartX","endX","setEndX","containerRef","useRef","thumbnailRefs","zoomRefs","imageRef","diff","currentItem","hasAnyItemLabel","some","itemLabel","trim","carouselItemNoun","hasFileInfo","useMemo","fileName","fileSize","_b","getItemAriaLabel","useCallback","index","itemTypeLabel","prefix","alt","positionLabel","length","useImperativeHandle","currentItemIndex","setCurrentItem","goToSlide","goToPrevItem","goToPrevSlide","goToNextItem","goToNextSlide","useEventListener","e","key","useEffect","current","focus","scrollIntoView","behavior","inline","handleZoom","state","scale","setDimension","src","height","width","oldState","Object","assign","getZoomRatio","imageDimension","clientHeight","clientWidth","isImgLandscapeRelativeToDevice","resetTransform","prev","slide","clearAnnouncer","announce","_jsx","ModalV2","disableInitialFocus","children","_jsxs","CarouselModalContent","ImageGalleryContainer","ImageGalleryWrapper","ImageGallerySwipe","onTouchStart","touches","clientX","onTouchMove","onTouchEnd","Math","abs","offsetWidth","undefined","ImageGallerySlides","style","transform","map","isActive","isActiveOrAdjacent","ImageGallerySlide","FocusableImageRegion","tabIndex","renderContent","SlidePlaceholderImage","TransformWrapper","el","panning","disabled","initialScale","onZoom","onZoomStop","onWheel","TransformComponent","SlideImage","placeholder","fit","retrieveImageDimension","_Fragment","ArrowButton","$position","onClick","$insetLeft","left","$insetRight","right","ChevronLeftIcon","ChevronRightIcon","BoxChip","Chip","weight","ThumbnailContainer","$insetBottom","bottom","ThumbnailWrapper","thumbnailSrc","ThumbnailItemContainer","ThumbnailItem","$active","ThumbnailImage","TopActionButtons","$hasFileInfo","$insetTop","top","trimmedName","trimmedSize","FileInfoTextWrapper","FileInfoFileName","FileInfoFileSize","renderFileInfo","MagnifierButton","zoomRatio","centerView","_d","_c","MagnifierPlusIcon","MagnifierMinusIcon","DeleteButton","BinIcon","CloseButton","CrossIcon","FullscreenImageCarousel","forwardRef"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fullscreen-image-carousel.js","sources":["../../src/fullscreen-image-carousel/fullscreen-image-carousel.tsx"],"sourcesContent":["import {\n ChevronLeftIcon,\n ChevronRightIcon,\n CrossIcon,\n MagnifierMinusIcon,\n MagnifierPlusIcon,\n} from \"@lifesg/react-icons\";\nimport { BinIcon } from \"@lifesg/react-icons/bin\";\nimport { announce, clearAnnouncer } from \"@react-aria/live-announcer\";\nimport {\n cloneElement,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport {\n ReactZoomPanPinchContentRef,\n ReactZoomPanPinchRef,\n TransformComponent,\n TransformWrapper,\n} from \"react-zoom-pan-pinch\";\nimport { ModalV2 } from \"../modal-v2\";\nimport { useStateCallback } from \"../shared/hooks\";\nimport { useEventListener } from \"../util\";\nimport {\n ArrowButton,\n BoxChip,\n CarouselModalContent,\n Chip,\n CloseButton,\n CustomActionButton,\n DeleteButton,\n FileInfoFileName,\n FileInfoFileSize,\n FileInfoTextWrapper,\n FocusableImageRegion,\n ImageGalleryContainer,\n ImageGallerySlide,\n ImageGallerySlides,\n ImageGallerySwipe,\n ImageGalleryWrapper,\n MagnifierButton,\n SlideImage,\n SlidePlaceholderImage,\n ThumbnailContainer,\n ThumbnailImage,\n ThumbnailItem,\n ThumbnailItemContainer,\n ThumbnailWrapper,\n TopActionButtons,\n} from \"./fullscreen-image-carousel.style\";\nimport {\n FullscreenImageCarouselCustomAction,\n FullscreenImageCarouselCustomItemProps,\n FullscreenImageCarouselItemProps,\n FullscreenImageCarouselProps,\n FullscreenImageCarouselRef,\n ImageDimension,\n} from \"./types\";\n\nconst isCustomItem = (\n item: FullscreenImageCarouselItemProps | undefined\n): item is FullscreenImageCarouselCustomItemProps =>\n !!item && item.type === \"custom\";\n\nexport const Component = (\n {\n items,\n initialActiveItemIndex,\n hideThumbnail = false,\n hideNavigation = false,\n hideCounter = false,\n hideMagnifier = false,\n customActions,\n onDelete,\n onClose,\n insets,\n topBarRef,\n show,\n ...otherProps\n }: FullscreenImageCarouselProps,\n ref: React.Ref<FullscreenImageCarouselRef>\n) => {\n // =============================================================================\n // CONST, STATE, REF\n // =============================================================================\n const [currentSlide, setCurrentSlide] = useStateCallback(\n initialActiveItemIndex ?? 0\n );\n const [imagesDimension, setImageDimension] = useState<\n Record<string, ImageDimension>\n >({});\n const [zoom, setZoom] = useState(1);\n const [startX, setStartX] = useState<number | undefined>();\n const [endX, setEndX] = useState<number | undefined>();\n const containerRef = useRef<HTMLDivElement>(null);\n const thumbnailRefs = useRef<(HTMLDivElement | null)[]>([]);\n const zoomRefs = useRef<(ReactZoomPanPinchContentRef | null)[]>([]);\n const imageRef = useRef<HTMLDivElement>(null);\n const diff = startX && endX ? startX - endX : 0;\n const currentItem = items[currentSlide];\n const resolvedCustomActions =\n currentItem?.customActions ?? customActions ?? [];\n const hasAnyItemLabel = items.some(\n (item) => isCustomItem(item) && !!item.itemLabel?.trim()\n );\n const carouselItemNoun = hasAnyItemLabel ? \"item\" : \"image\";\n const hasFileInfo = useMemo(\n () =>\n items.some(\n (item) => item.fileName?.trim() || item.fileSize?.trim()\n ),\n [items]\n );\n\n const getItemAriaLabel = useCallback(\n (index: number) => {\n const item = items[index];\n const itemTypeLabel = hasAnyItemLabel ? \"Item\" : \"Image\";\n const prefix = isCustomItem(item)\n ? item.itemLabel?.trim() || \"\"\n : item.alt?.trim() || \"\";\n const positionLabel = `${itemTypeLabel} ${index + 1} of ${\n items.length\n }.`;\n\n return prefix ? `${prefix}. ${positionLabel}` : positionLabel;\n },\n [items, hasAnyItemLabel]\n );\n\n useImperativeHandle<FullscreenImageCarouselRef, FullscreenImageCarouselRef>(\n ref,\n () => ({\n currentItemIndex: currentSlide,\n setCurrentItem: goToSlide,\n goToPrevItem: goToPrevSlide,\n goToNextItem: goToNextSlide,\n })\n );\n\n // =============================================================================\n // EFFECTS\n // =============================================================================\n useEventListener(\"keydown\", handleKeyDown, \"document\");\n\n useEffect(() => {\n if (show) {\n imageRef.current?.focus();\n }\n }, [show]);\n\n useEffect(() => {\n if (items.length === 0) {\n setCurrentSlide(0);\n return;\n }\n\n if (currentSlide > items.length - 1) {\n setCurrentSlide(items.length - 1);\n }\n }, [currentSlide, items.length, setCurrentSlide]);\n\n useEffect(() => {\n thumbnailRefs.current?.[currentSlide]?.scrollIntoView({\n behavior: \"smooth\",\n inline: \"center\",\n });\n setZoom(1);\n }, [currentSlide]);\n\n // =============================================================================\n // EVENT HANDLERS\n // =============================================================================\n const handleTouchStart = (e: React.TouchEvent) => {\n if (zoom <= 1) setStartX(e.touches[0].clientX);\n };\n\n const handleTouchMove = (e: React.TouchEvent) => {\n if (!startX || zoom > 1) return;\n setEndX(e.touches[0].clientX);\n };\n\n const handleTouchEnd = () => {\n if (!containerRef.current) return;\n if (Math.abs(diff) > containerRef.current.offsetWidth / 3) {\n if (diff > 0) {\n goToNextSlide();\n } else {\n goToPrevSlide();\n }\n }\n setStartX(undefined);\n setEndX(undefined);\n };\n\n const handleZoom = (e: ReactZoomPanPinchRef) => {\n setZoom(e.state.scale);\n };\n\n const handleDelete = () => {\n if (currentItem && onDelete) {\n onDelete(currentItem, currentSlide);\n }\n };\n\n const handleCustomAction = (\n action: FullscreenImageCarouselCustomAction\n ) => {\n if (currentItem) {\n action.onClick(currentItem, currentSlide);\n }\n };\n\n function handleKeyDown(e: KeyboardEvent) {\n if (e.key === \"ArrowRight\") {\n goToNextSlide();\n } else if (e.key === \"ArrowLeft\") {\n goToPrevSlide();\n } else if (e.key === \"Escape\") {\n onClose?.();\n }\n }\n\n const handleMagnifier = () => {\n if (zoom === 1) {\n const zoomRatio = getZoomRatio();\n zoomRefs.current?.[currentSlide]?.centerView(zoomRatio);\n setZoom(zoomRatio ?? 1);\n } else {\n setZoom(1);\n zoomRefs.current?.[currentSlide]?.resetTransform();\n }\n };\n\n const setDimension = ({\n src,\n height,\n width,\n }: {\n src: string;\n height: number;\n width: number;\n }) => {\n setImageDimension((oldState) => {\n return { ...oldState, [src]: { height, width } };\n });\n };\n\n const getZoomRatio = () => {\n if (!currentItem || isCustomItem(currentItem)) {\n return;\n }\n\n const imageDimension = imagesDimension[currentItem.src];\n\n if (containerRef.current && !!imageDimension) {\n const { clientHeight, clientWidth } = containerRef.current;\n const { width, height } = imageDimension;\n const isSmallImg = width < clientWidth && height < clientHeight;\n\n const isImgLandscapeRelativeToDevice =\n height / width < clientHeight / clientWidth;\n\n if (isSmallImg) {\n return isImgLandscapeRelativeToDevice\n ? clientWidth / width\n : clientHeight / height;\n }\n\n return isImgLandscapeRelativeToDevice\n ? clientHeight / (height / (width / clientWidth))\n : clientWidth / (width / (height / clientHeight));\n }\n };\n\n // =============================================================================\n // HELPER FUNCTIONS\n // =============================================================================\n const goToPrevSlide = () => {\n zoomRefs.current?.[currentSlide]?.resetTransform();\n setCurrentSlide(\n (prev) => (prev === 0 ? items.length - 1 : prev - 1),\n (slide) => {\n clearAnnouncer(\"polite\");\n announce(getItemAriaLabel(slide), \"polite\");\n }\n );\n };\n\n const goToNextSlide = () => {\n zoomRefs.current?.[currentSlide]?.resetTransform();\n setCurrentSlide(\n (prev) => (prev === items.length - 1 ? 0 : prev + 1),\n (slide) => {\n clearAnnouncer(\"polite\");\n announce(getItemAriaLabel(slide), \"polite\");\n }\n );\n };\n\n const goToSlide = (index: number) => {\n zoomRefs.current?.[currentSlide]?.resetTransform();\n setCurrentSlide(index);\n };\n\n // =============================================================================\n // RENDER FUNCTIONS\n // =============================================================================\n const renderSlides = () => {\n return (\n <ImageGallerySlides\n style={{\n transform: `translateX(calc(${\n -currentSlide * 100\n }% - ${diff}px))`,\n }}\n >\n {items.map((item, index) => {\n const isActive = index === currentSlide;\n const isActiveOrAdjacent =\n Math.abs(index - currentSlide) <= 1 ||\n (currentSlide === 0 && index === items.length - 1) ||\n (currentSlide === items.length - 1 && index === 0);\n\n return (\n <ImageGallerySlide key={index} data-testid=\"slide-item\">\n <FocusableImageRegion\n ref={isActive ? imageRef : null}\n tabIndex={isActive ? 0 : -1}\n >\n {isCustomItem(item) ? (\n isActiveOrAdjacent ? (\n item.renderContent()\n ) : (\n <SlidePlaceholderImage />\n )\n ) : (\n <TransformWrapper\n ref={(el) =>\n (zoomRefs.current[index] = el)\n }\n panning={{\n disabled: zoom <= 1,\n }}\n initialScale={1}\n onZoom={handleZoom}\n onZoomStop={handleZoom}\n onWheel={handleZoom}\n >\n <TransformComponent>\n <SlideImage\n src={item.src}\n alt={getItemAriaLabel(index)}\n placeholder={\n <SlidePlaceholderImage />\n }\n fit=\"scale-down\"\n retrieveImageDimension\n setDimension={setDimension}\n />\n </TransformComponent>\n </TransformWrapper>\n )}\n </FocusableImageRegion>\n </ImageGallerySlide>\n );\n })}\n </ImageGallerySlides>\n );\n };\n\n const renderFileInfo = () => {\n const { fileName, fileSize } = currentItem ?? {};\n const trimmedName = fileName?.trim();\n const trimmedSize = fileSize?.trim();\n\n return (\n <FileInfoTextWrapper\n $centerContent={!trimmedSize}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n data-testid=\"file-info-bar\"\n >\n {trimmedName && (\n <FileInfoFileName\n weight=\"semibold\"\n data-testid=\"file-info-name\"\n >\n {trimmedName}\n </FileInfoFileName>\n )}\n {trimmedSize && (\n <FileInfoFileSize data-testid=\"file-info-size\">\n {trimmedSize}\n </FileInfoFileSize>\n )}\n </FileInfoTextWrapper>\n );\n };\n\n const renderThumbnails = () => {\n return (\n <ThumbnailContainer\n $insetBottom={insets?.bottom}\n aria-hidden=\"true\"\n >\n <ThumbnailWrapper>\n {items.map((item, index) => {\n const src = isCustomItem(item)\n ? item.thumbnailSrc\n : item.thumbnailSrc ?? item.src;\n return (\n <ThumbnailItemContainer key={index}>\n <ThumbnailItem\n data-testid=\"thumbnail-item\"\n $active={index === currentSlide}\n onClick={() => goToSlide(index)}\n ref={(el) =>\n (thumbnailRefs.current[index] = el)\n }\n >\n {src ? (\n <ThumbnailImage\n src={src}\n alt={`Thumbnail ${index + 1}`}\n fit=\"cover\"\n />\n ) : (\n <SlidePlaceholderImage />\n )}\n </ThumbnailItem>\n </ThumbnailItemContainer>\n );\n })}\n </ThumbnailWrapper>\n </ThumbnailContainer>\n );\n };\n\n const renderTopActions = () => {\n return (\n <TopActionButtons\n ref={topBarRef}\n $hasFileInfo={hasFileInfo}\n $insetTop={insets?.top}\n $insetLeft={insets?.left}\n $insetRight={insets?.right}\n >\n {hasFileInfo && renderFileInfo()}\n\n {resolvedCustomActions.map((action, index) => (\n <CustomActionButton\n key={index}\n aria-label={action.ariaLabel}\n data-testid={action[\"data-testid\"]}\n onClick={() => handleCustomAction(action)}\n >\n {cloneElement(action.icon, { \"aria-hidden\": true })}\n </CustomActionButton>\n ))}\n\n {!hideMagnifier && !isCustomItem(currentItem) && (\n <MagnifierButton\n aria-label={zoom === 1 ? \"Zoom in\" : \"Zoom out\"}\n onClick={handleMagnifier}\n >\n {zoom === 1 ? (\n <MagnifierPlusIcon aria-hidden />\n ) : (\n <MagnifierMinusIcon aria-hidden />\n )}\n </MagnifierButton>\n )}\n\n {onDelete && (\n <DeleteButton\n aria-label={`Delete ${\n (isCustomItem(currentItem) &&\n currentItem.itemLabel?.trim()) ||\n \"image\"\n }`}\n data-testid=\"delete-btn\"\n onClick={handleDelete}\n >\n <BinIcon aria-hidden />\n </DeleteButton>\n )}\n\n <CloseButton\n aria-label={\n hasAnyItemLabel\n ? \"Close carousel\"\n : \"Close image carousel\"\n }\n onClick={onClose}\n >\n <CrossIcon aria-hidden />\n </CloseButton>\n </TopActionButtons>\n );\n };\n\n return (\n <ModalV2\n {...otherProps}\n data-testid=\"image-carousel-modal\"\n aria-label={hasAnyItemLabel ? \"Carousel\" : \"Image carousel\"}\n show={show}\n disableInitialFocus\n >\n <CarouselModalContent>\n <ImageGalleryContainer>\n <ImageGalleryWrapper>\n <ImageGallerySwipe\n ref={containerRef}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n {renderSlides()}\n </ImageGallerySwipe>\n\n {!hideNavigation && (\n <>\n <ArrowButton\n aria-label={`Previous ${carouselItemNoun}`}\n data-testid=\"prev-btn\"\n $position=\"left\"\n onClick={goToPrevSlide}\n $insetLeft={insets?.left}\n $insetRight={insets?.right}\n >\n <ChevronLeftIcon aria-hidden />\n </ArrowButton>\n <ArrowButton\n aria-label={`Next ${carouselItemNoun}`}\n data-testid=\"forward-btn\"\n $position=\"right\"\n onClick={goToNextSlide}\n $insetLeft={insets?.left}\n $insetRight={insets?.right}\n >\n <ChevronRightIcon aria-hidden />\n </ArrowButton>\n </>\n )}\n\n {!hideCounter && (\n <BoxChip aria-hidden=\"true\">\n <Chip weight=\"semibold\">{`${currentSlide + 1}/${\n items.length\n }`}</Chip>\n </BoxChip>\n )}\n </ImageGalleryWrapper>\n\n {!hideThumbnail && renderThumbnails()}\n </ImageGalleryContainer>\n {renderTopActions()}\n </CarouselModalContent>\n </ModalV2>\n );\n};\n\nexport const FullscreenImageCarousel = forwardRef<\n FullscreenImageCarouselRef,\n FullscreenImageCarouselProps\n>(Component);\n"],"names":["isCustomItem","item","type","Component","_a","ref","items","initialActiveItemIndex","hideThumbnail","hideNavigation","hideCounter","hideMagnifier","customActions","onDelete","onClose","insets","topBarRef","show","otherProps","__rest","currentSlide","setCurrentSlide","useStateCallback","imagesDimension","setImageDimension","useState","zoom","setZoom","startX","setStartX","endX","setEndX","containerRef","useRef","thumbnailRefs","zoomRefs","imageRef","diff","currentItem","resolvedCustomActions","_c","_b","hasAnyItemLabel","some","itemLabel","trim","carouselItemNoun","hasFileInfo","useMemo","fileName","fileSize","getItemAriaLabel","useCallback","index","itemTypeLabel","prefix","alt","positionLabel","length","useImperativeHandle","currentItemIndex","setCurrentItem","goToSlide","goToPrevItem","goToPrevSlide","goToNextItem","goToNextSlide","useEventListener","e","key","useEffect","current","focus","scrollIntoView","behavior","inline","handleZoom","state","scale","handleDelete","handleMagnifier","zoomRatio","getZoomRatio","centerView","_d","resetTransform","setDimension","src","height","width","oldState","Object","assign","imageDimension","clientHeight","clientWidth","isImgLandscapeRelativeToDevice","prev","slide","clearAnnouncer","announce","renderFileInfo","trimmedName","trimmedSize","_jsxs","FileInfoTextWrapper","_jsx","FileInfoFileName","weight","children","FileInfoFileSize","ModalV2","disableInitialFocus","CarouselModalContent","ImageGalleryContainer","ImageGalleryWrapper","ImageGallerySwipe","onTouchStart","touches","clientX","onTouchMove","onTouchEnd","Math","abs","offsetWidth","undefined","ImageGallerySlides","style","transform","map","isActive","isActiveOrAdjacent","ImageGallerySlide","FocusableImageRegion","tabIndex","renderContent","SlidePlaceholderImage","TransformWrapper","el","panning","disabled","initialScale","onZoom","onZoomStop","onWheel","TransformComponent","SlideImage","placeholder","fit","retrieveImageDimension","_Fragment","ArrowButton","$position","onClick","$insetLeft","left","$insetRight","right","ChevronLeftIcon","ChevronRightIcon","BoxChip","Chip","ThumbnailContainer","$insetBottom","bottom","ThumbnailWrapper","thumbnailSrc","ThumbnailItemContainer","ThumbnailItem","$active","ThumbnailImage","TopActionButtons","$hasFileInfo","top","action","CustomActionButton","ariaLabel","handleCustomAction","cloneElement","icon","MagnifierButton","MagnifierPlusIcon","MagnifierMinusIcon","DeleteButton","BinIcon","CloseButton","CrossIcon","renderTopActions","FullscreenImageCarousel","forwardRef"],"mappings":"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"}
|
|
@@ -33,6 +33,13 @@ export declare const MagnifierButton: import("styled-components/dist/types").ISt
|
|
|
33
33
|
as?: import("styled-components").WebTarget | undefined;
|
|
34
34
|
forwardedAs?: import("styled-components").WebTarget | undefined;
|
|
35
35
|
}, never>>> & string;
|
|
36
|
+
export declare const CustomActionButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("../shared/clickable-icon").ClickableIconProps & import("react").RefAttributes<HTMLButtonElement>, never> & Partial<Pick<import("../shared/clickable-icon").ClickableIconProps & import("react").RefAttributes<HTMLButtonElement>, never>> & {
|
|
37
|
+
as?: import("styled-components").WebTarget | undefined;
|
|
38
|
+
forwardedAs?: import("styled-components").WebTarget | undefined;
|
|
39
|
+
}, never> & Partial<Pick<import("styled-components").FastOmit<import("../shared/clickable-icon").ClickableIconProps & import("react").RefAttributes<HTMLButtonElement>, never> & Partial<Pick<import("../shared/clickable-icon").ClickableIconProps & import("react").RefAttributes<HTMLButtonElement>, never>> & {
|
|
40
|
+
as?: import("styled-components").WebTarget | undefined;
|
|
41
|
+
forwardedAs?: import("styled-components").WebTarget | undefined;
|
|
42
|
+
}, never>>> & string;
|
|
36
43
|
export declare const ArrowButton: import("styled-components/dist/types").IStyledComponentBase<"web", import("styled-components").FastOmit<import("styled-components").FastOmit<import("styled-components").FastOmit<import("../shared/clickable-icon").ClickableIconProps & import("react").RefAttributes<HTMLButtonElement>, never> & Partial<Pick<import("../shared/clickable-icon").ClickableIconProps & import("react").RefAttributes<HTMLButtonElement>, never>> & {
|
|
37
44
|
as?: import("styled-components").WebTarget | undefined;
|
|
38
45
|
forwardedAs?: import("styled-components").WebTarget | undefined;
|
|
@@ -74,7 +74,7 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
74
74
|
`}
|
|
75
75
|
`,x=i(g)``,f=i(g)`
|
|
76
76
|
color: ${n["icon-error"]};
|
|
77
|
-
`,m=i(g)``,b=i(g)`
|
|
77
|
+
`,m=i(g)``,b=i(g)``,u=i(g)`
|
|
78
78
|
z-index: 4;
|
|
79
79
|
position: absolute;
|
|
80
80
|
top: 50%;
|
|
@@ -99,19 +99,19 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
99
99
|
);
|
|
100
100
|
}
|
|
101
101
|
`}
|
|
102
|
-
`,
|
|
102
|
+
`,w=i.div`
|
|
103
103
|
position: relative;
|
|
104
104
|
width: 100%;
|
|
105
105
|
height: 100dvh;
|
|
106
106
|
display: flex;
|
|
107
107
|
flex-direction: column;
|
|
108
|
-
`,
|
|
108
|
+
`,v=i.div`
|
|
109
109
|
display: flex;
|
|
110
110
|
flex-direction: column;
|
|
111
111
|
width: 100%;
|
|
112
112
|
flex: 1;
|
|
113
113
|
min-height: 0;
|
|
114
|
-
`,
|
|
114
|
+
`,y=i.div`
|
|
115
115
|
user-select: none;
|
|
116
116
|
position: relative;
|
|
117
117
|
display: block;
|
|
@@ -119,13 +119,13 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
119
119
|
width: 100%;
|
|
120
120
|
flex: 1;
|
|
121
121
|
min-height: 0;
|
|
122
|
-
`,
|
|
122
|
+
`,j=i.div`
|
|
123
123
|
display: block;
|
|
124
124
|
user-select: none;
|
|
125
125
|
height: 100%;
|
|
126
126
|
overflow: hidden;
|
|
127
127
|
touch-action: pan-y;
|
|
128
|
-
`,
|
|
128
|
+
`,k=i.div`
|
|
129
129
|
display: flex;
|
|
130
130
|
transition: all 450ms ease-out 0s;
|
|
131
131
|
position: relative;
|
|
@@ -133,7 +133,7 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
133
133
|
user-select: none;
|
|
134
134
|
width: 100%;
|
|
135
135
|
height: 100%;
|
|
136
|
-
`,
|
|
136
|
+
`,M=i.div`
|
|
137
137
|
flex: 0 0 100%;
|
|
138
138
|
box-sizing: border-box;
|
|
139
139
|
display: flex;
|
|
@@ -149,7 +149,7 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
149
149
|
height: 100%;
|
|
150
150
|
width: 100%;
|
|
151
151
|
}
|
|
152
|
-
`,
|
|
152
|
+
`,W=i.div`
|
|
153
153
|
height: 100%;
|
|
154
154
|
width: 100%;
|
|
155
155
|
outline: none;
|
|
@@ -162,17 +162,17 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
162
162
|
outline: ${s["width-020"]} solid ${n["border-selected"]};
|
|
163
163
|
outline-offset: -2px;
|
|
164
164
|
}
|
|
165
|
-
`,
|
|
165
|
+
`,z=i(h)`
|
|
166
166
|
height: 100%;
|
|
167
167
|
width: 100%;
|
|
168
168
|
border-radius: ${c.none};
|
|
169
|
-
`,
|
|
169
|
+
`,B=i(o)`
|
|
170
170
|
width: 60vw;
|
|
171
171
|
height: auto;
|
|
172
172
|
max-height: 100%;
|
|
173
173
|
border-radius: ${c.none};
|
|
174
174
|
aspect-ratio: 4 / 3;
|
|
175
|
-
`,
|
|
175
|
+
`,R=i.div`
|
|
176
176
|
display: flex;
|
|
177
177
|
justify-content: center;
|
|
178
178
|
padding: ${d["spacing-16"]};
|
|
@@ -183,7 +183,7 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
183
183
|
margin-left: auto;
|
|
184
184
|
margin-right: auto;
|
|
185
185
|
z-index: 3;
|
|
186
|
-
`,
|
|
186
|
+
`,L=i(p.BodyXS)`
|
|
187
187
|
display: inline-flex;
|
|
188
188
|
padding: ${d["spacing-4"]} ${d["spacing-16"]};
|
|
189
189
|
justify-content: center;
|
|
@@ -191,7 +191,7 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
191
191
|
border-radius: ${c.full};
|
|
192
192
|
background-color: ${n.bg};
|
|
193
193
|
text-align: center;
|
|
194
|
-
`,
|
|
194
|
+
`,T=i.div`
|
|
195
195
|
flex-shrink: 0;
|
|
196
196
|
display: flex;
|
|
197
197
|
overflow: auto;
|
|
@@ -204,7 +204,7 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
204
204
|
${d["spacing-16"]} ${d["spacing-20"]} calc(${d["spacing-16"]} + ${i.$insetBottom||0}px);
|
|
205
205
|
`};
|
|
206
206
|
}
|
|
207
|
-
`,
|
|
207
|
+
`,S=i.div`
|
|
208
208
|
box-sizing: border-box;
|
|
209
209
|
display: flex;
|
|
210
210
|
align-items: center;
|
|
@@ -212,7 +212,7 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
212
212
|
justify-content: center;
|
|
213
213
|
margin-left: auto;
|
|
214
214
|
margin-right: auto;
|
|
215
|
-
`,
|
|
215
|
+
`,C=i.div`
|
|
216
216
|
display: flex;
|
|
217
217
|
align-items: center;
|
|
218
218
|
justify-content: center;
|
|
@@ -223,7 +223,7 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
223
223
|
height: 64px;
|
|
224
224
|
width: 64px;
|
|
225
225
|
}
|
|
226
|
-
`,
|
|
226
|
+
`,D=i.div`
|
|
227
227
|
cursor: pointer;
|
|
228
228
|
background-color: ${n["bg-inverse"]};
|
|
229
229
|
border-radius: ${c.md};
|
|
@@ -261,10 +261,10 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
261
261
|
border-color: ${n["border-hover"]};
|
|
262
262
|
}
|
|
263
263
|
`};
|
|
264
|
-
`,
|
|
264
|
+
`,F=i(h)`
|
|
265
265
|
height: 100%;
|
|
266
266
|
width: 100%;
|
|
267
|
-
`,
|
|
267
|
+
`,I=i.div`
|
|
268
268
|
flex: 1;
|
|
269
269
|
display: flex;
|
|
270
270
|
flex-direction: column;
|
|
@@ -278,17 +278,17 @@ import i,{css as e}from"styled-components";import{ClickableIcon as t}from"../sha
|
|
|
278
278
|
${i=>i.$centerContent&&e`
|
|
279
279
|
justify-content: center;
|
|
280
280
|
`}
|
|
281
|
-
`,
|
|
281
|
+
`,X=i(p.BodyBL)`
|
|
282
282
|
color: ${n["text-inverse"]};
|
|
283
283
|
overflow: hidden;
|
|
284
284
|
text-overflow: ellipsis;
|
|
285
285
|
white-space: nowrap;
|
|
286
286
|
min-width: 0;
|
|
287
|
-
`,
|
|
287
|
+
`,Y=i(p.BodyMD)`
|
|
288
288
|
color: ${n["text-inverse"]};
|
|
289
289
|
overflow: hidden;
|
|
290
290
|
text-overflow: ellipsis;
|
|
291
291
|
white-space: nowrap;
|
|
292
292
|
min-width: 0;
|
|
293
|
-
`;export{
|
|
293
|
+
`;export{u as ArrowButton,R as BoxChip,w as CarouselModalContent,L as Chip,x as CloseButton,b as CustomActionButton,f as DeleteButton,X as FileInfoFileName,Y as FileInfoFileSize,I as FileInfoTextWrapper,W as FocusableImageRegion,v as ImageGalleryContainer,M as ImageGallerySlide,k as ImageGallerySlides,j as ImageGallerySwipe,y as ImageGalleryWrapper,m as MagnifierButton,z as SlideImage,B as SlidePlaceholderImage,T as ThumbnailContainer,F as ThumbnailImage,D as ThumbnailItem,C as ThumbnailItemContainer,S as ThumbnailWrapper,$ as TopActionButtons};
|
|
294
294
|
//# sourceMappingURL=fullscreen-image-carousel.style.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"fullscreen-image-carousel.style.js","sources":["../../src/fullscreen-image-carousel/fullscreen-image-carousel.style.tsx"],"sourcesContent":["import styled, { css } from \"styled-components\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { ImagePlaceholder } from \"../shared/image-placeholder\";\nimport { InsetStyleProps } from \"../shared/types\";\nimport {\n Border,\n Colour,\n Font,\n MediaQuery,\n Radius,\n Shadow,\n Spacing,\n} from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { StatefulImage } from \"./stateful-image\";\n\n// =============================================================================\n// STYLE INTERFACES\n// =============================================================================\ninterface ArrowButtonStyleProps extends InsetStyleProps {\n $position: \"left\" | \"right\";\n}\n\ninterface ThumbnailItemStyleProps {\n $active?: boolean;\n}\n\ninterface TopActionButtonsStyleProps extends InsetStyleProps {\n $hasFileInfo?: boolean | undefined;\n}\n\ninterface FileInfoTextWrapperStyleProps {\n $centerContent?: boolean | undefined;\n}\n\n// =============================================================================\n// STYLING\n// =============================================================================\nconst IconButton = styled(ClickableIcon)`\n padding: 0;\n border-radius: 100%;\n background: ${Colour[\"bg\"]};\n color: ${Colour[\"icon-primary\"]};\n height: 2.5rem;\n width: 2.5rem;\n box-shadow: ${Shadow[\"md-strong\"]};\n\n svg {\n height: 1.5rem;\n width: 1.5rem;\n }\n\n &:focus {\n outline: none;\n }\n\n &:focus-visible {\n outline: ${Border[\"width-020\"]} solid ${Colour[\"border-selected\"]};\n outline-offset: 2px;\n }\n`;\n\nexport const TopActionButtons = styled.div<TopActionButtonsStyleProps>`\n order: -1;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: ${Spacing[\"spacing-16\"]};\n\n ${(props) =>\n props.$hasFileInfo\n ? css`\n flex-shrink: 0;\n background-color: ${Colour[\"bg-inverse\"]};\n padding-top: calc(\n ${Spacing[\"spacing-24\"]} + ${props.$insetTop || 0}px\n );\n padding-bottom: ${Spacing[\"spacing-24\"]};\n padding-left: calc(\n ${Spacing[\"spacing-32\"]} + ${props.$insetLeft || 0}px\n );\n padding-right: calc(\n ${Spacing[\"spacing-32\"]} + ${props.$insetRight || 0}px\n );\n\n ${MediaQuery.MaxWidth.sm} {\n padding-top: calc(\n ${Spacing[\"spacing-16\"]} + ${props.$insetTop || 0}px\n );\n padding-bottom: ${Spacing[\"spacing-16\"]};\n padding-left: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetLeft || 0}px\n );\n padding-right: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetRight || 0}px\n );\n }\n `\n : css`\n position: absolute;\n top: calc(\n ${Spacing[\"spacing-48\"]} + ${props.$insetTop || 0}px\n );\n right: calc(\n ${Spacing[\"spacing-48\"]} + ${props.$insetRight || 0}px\n );\n z-index: 5;\n\n ${MediaQuery.MaxWidth.sm} {\n top: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetTop || 0}px\n );\n right: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetRight || 0}px\n );\n }\n `}\n`;\n\nexport const CloseButton = styled(IconButton)``;\n\nexport const DeleteButton = styled(IconButton)`\n color: ${Colour[\"icon-error\"]};\n`;\n\nexport const MagnifierButton = styled(IconButton)``;\n\nexport const ArrowButton = styled(IconButton)<ArrowButtonStyleProps>`\n z-index: 4;\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n\n ${(props) =>\n props.$position === \"left\" &&\n css`\n left: calc(${Spacing[\"spacing-48\"]} + ${props.$insetLeft || 0}px);\n\n ${MediaQuery.MaxWidth.sm} {\n left: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetLeft || 0}px\n );\n }\n `}\n\n ${(props) =>\n props.$position === \"right\" &&\n css`\n right: calc(${Spacing[\"spacing-48\"]} + ${props.$insetRight || 0}px);\n\n ${MediaQuery.MaxWidth.sm} {\n right: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetRight || 0}px\n );\n }\n `}\n`;\n\nexport const CarouselModalContent = styled.div`\n position: relative;\n width: 100%;\n height: 100dvh;\n display: flex;\n flex-direction: column;\n`;\n\nexport const ImageGalleryContainer = styled.div`\n display: flex;\n flex-direction: column;\n width: 100%;\n flex: 1;\n min-height: 0;\n`;\n\nexport const ImageGalleryWrapper = styled.div`\n user-select: none;\n position: relative;\n display: block;\n overflow: hidden;\n width: 100%;\n flex: 1;\n min-height: 0;\n`;\n\nexport const ImageGallerySwipe = styled.div`\n display: block;\n user-select: none;\n height: 100%;\n overflow: hidden;\n touch-action: pan-y;\n`;\n\nexport const ImageGallerySlides = styled.div`\n display: flex;\n transition: all 450ms ease-out 0s;\n position: relative;\n text-align: center;\n user-select: none;\n width: 100%;\n height: 100%;\n`;\n\nexport const ImageGallerySlide = styled.div`\n flex: 0 0 100%;\n box-sizing: border-box;\n display: flex;\n justify-content: center;\n align-items: center;\n\n .react-transform-wrapper {\n height: 100%;\n width: 100%;\n }\n\n .react-transform-component {\n height: 100%;\n width: 100%;\n }\n`;\n\nexport const FocusableImageRegion = styled.div`\n height: 100%;\n width: 100%;\n outline: none;\n\n &:focus {\n outline: none;\n }\n\n &:focus-visible {\n outline: ${Border[\"width-020\"]} solid ${Colour[\"border-selected\"]};\n outline-offset: -2px;\n }\n`;\n\nexport const SlideImage = styled(StatefulImage)`\n height: 100%;\n width: 100%;\n border-radius: ${Radius[\"none\"]};\n`;\n\nexport const SlidePlaceholderImage = styled(ImagePlaceholder)`\n width: 60vw;\n height: auto;\n max-height: 100%;\n border-radius: ${Radius[\"none\"]};\n aspect-ratio: 4 / 3;\n`;\n\nexport const BoxChip = styled.div`\n display: flex;\n justify-content: center;\n padding: ${Spacing[\"spacing-16\"]};\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n margin-left: auto;\n margin-right: auto;\n z-index: 3;\n`;\n\nexport const Chip = styled(Typography.BodyXS)`\n display: inline-flex;\n padding: ${Spacing[\"spacing-4\"]} ${Spacing[\"spacing-16\"]};\n justify-content: center;\n align-items: center;\n border-radius: ${Radius[\"full\"]};\n background-color: ${Colour[\"bg\"]};\n text-align: center;\n`;\n\n// -----------------------------------------------------------------------------\n// THUMBNAIL STYLING\n// -----------------------------------------------------------------------------\n\nexport const ThumbnailContainer = styled.div<InsetStyleProps>`\n flex-shrink: 0;\n display: flex;\n overflow: auto;\n background-color: ${Colour[\"bg-inverse\"]};\n padding: ${(props) =>\n css`\n ${Spacing[\"spacing-24\"]} ${Spacing[\n \"spacing-16\"\n ]} calc(${Spacing[\"spacing-24\"]} + ${props.$insetBottom ||\n 0}px);\n `}\n ${MediaQuery.MaxWidth.sm} {\n padding: ${(props) =>\n css`\n ${Spacing[\"spacing-16\"]} ${Spacing[\n \"spacing-20\"\n ]} calc(${Spacing[\"spacing-16\"]} + ${props.$insetBottom ||\n 0}px);\n `};\n }\n`;\n\nexport const ThumbnailWrapper = styled.div`\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: ${Spacing[\"spacing-16\"]};\n justify-content: center;\n margin-left: auto;\n margin-right: auto;\n`;\n\nexport const ThumbnailItemContainer = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100px;\n width: 100px;\n\n ${MediaQuery.MaxWidth.sm} {\n height: 64px;\n width: 64px;\n }\n`;\n\nexport const ThumbnailItem = styled.div<ThumbnailItemStyleProps>`\n cursor: pointer;\n background-color: ${Colour[\"bg-inverse\"]};\n border-radius: ${Radius[\"md\"]};\n border: ${Border[\"solid\"]} transparent;\n box-sizing: content-box;\n\n flex-shrink: 0;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n height: 92px;\n width: 92px;\n\n ${MediaQuery.MaxWidth.sm} {\n height: 60px;\n width: 60px;\n }\n\n ${(props) =>\n props.$active\n ? css`\n border-width: ${Border[\"width-040\"]};\n border-color: ${Colour[\"border-selected\"]};\n\n ${MediaQuery.MaxWidth.sm} {\n border-width: ${Border[\"width-020\"]};\n }\n\n &:hover {\n border-color: ${Colour[\"border-selected-hover\"]};\n }\n `\n : css`\n border-width: ${Border[\"width-010\"]};\n\n &:hover {\n border-color: ${Colour[\"border-hover\"]};\n }\n `};\n`;\n\nexport const ThumbnailImage = styled(StatefulImage)`\n height: 100%;\n width: 100%;\n`;\n\n// -----------------------------------------------------------------------------\n// FILE INFO BAR STYLING\n// -----------------------------------------------------------------------------\n\nexport const FileInfoTextWrapper = styled.div<FileInfoTextWrapperStyleProps>`\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: ${Spacing[\"spacing-8\"]};\n overflow: hidden;\n min-width: 0;\n min-height: calc(\n ${Font.Spec[\"body-lh-baseline\"]} + ${Spacing[\"spacing-8\"]} +\n ${Font.Spec[\"body-lh-md\"]}\n );\n ${(props) =>\n props.$centerContent &&\n css`\n justify-content: center;\n `}\n`;\n\nexport const FileInfoFileName = styled(Typography.BodyBL)`\n color: ${Colour[\"text-inverse\"]};\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n`;\n\nexport const FileInfoFileSize = styled(Typography.BodyMD)`\n color: ${Colour[\"text-inverse\"]};\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n`;\n"],"names":["IconButton","styled","ClickableIcon","Colour","Shadow","Border","TopActionButtons","div","Spacing","props","$hasFileInfo","css","$insetTop","$insetLeft","$insetRight","MediaQuery","MaxWidth","sm","CloseButton","DeleteButton","MagnifierButton","ArrowButton","$position","CarouselModalContent","ImageGalleryContainer","ImageGalleryWrapper","ImageGallerySwipe","ImageGallerySlides","ImageGallerySlide","FocusableImageRegion","SlideImage","StatefulImage","Radius","SlidePlaceholderImage","ImagePlaceholder","BoxChip","Chip","Typography","BodyXS","ThumbnailContainer","$insetBottom","ThumbnailWrapper","ThumbnailItemContainer","ThumbnailItem","$active","ThumbnailImage","FileInfoTextWrapper","Font","Spec","$centerContent","FileInfoFileName","BodyBL","FileInfoFileSize","BodyMD"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"fullscreen-image-carousel.style.js","sources":["../../src/fullscreen-image-carousel/fullscreen-image-carousel.style.tsx"],"sourcesContent":["import styled, { css } from \"styled-components\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { ImagePlaceholder } from \"../shared/image-placeholder\";\nimport { InsetStyleProps } from \"../shared/types\";\nimport {\n Border,\n Colour,\n Font,\n MediaQuery,\n Radius,\n Shadow,\n Spacing,\n} from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { StatefulImage } from \"./stateful-image\";\n\n// =============================================================================\n// STYLE INTERFACES\n// =============================================================================\ninterface ArrowButtonStyleProps extends InsetStyleProps {\n $position: \"left\" | \"right\";\n}\n\ninterface ThumbnailItemStyleProps {\n $active?: boolean;\n}\n\ninterface TopActionButtonsStyleProps extends InsetStyleProps {\n $hasFileInfo?: boolean | undefined;\n}\n\ninterface FileInfoTextWrapperStyleProps {\n $centerContent?: boolean | undefined;\n}\n\n// =============================================================================\n// STYLING\n// =============================================================================\nconst IconButton = styled(ClickableIcon)`\n padding: 0;\n border-radius: 100%;\n background: ${Colour[\"bg\"]};\n color: ${Colour[\"icon-primary\"]};\n height: 2.5rem;\n width: 2.5rem;\n box-shadow: ${Shadow[\"md-strong\"]};\n\n svg {\n height: 1.5rem;\n width: 1.5rem;\n }\n\n &:focus {\n outline: none;\n }\n\n &:focus-visible {\n outline: ${Border[\"width-020\"]} solid ${Colour[\"border-selected\"]};\n outline-offset: 2px;\n }\n`;\n\nexport const TopActionButtons = styled.div<TopActionButtonsStyleProps>`\n order: -1;\n display: flex;\n align-items: center;\n justify-content: flex-end;\n gap: ${Spacing[\"spacing-16\"]};\n\n ${(props) =>\n props.$hasFileInfo\n ? css`\n flex-shrink: 0;\n background-color: ${Colour[\"bg-inverse\"]};\n padding-top: calc(\n ${Spacing[\"spacing-24\"]} + ${props.$insetTop || 0}px\n );\n padding-bottom: ${Spacing[\"spacing-24\"]};\n padding-left: calc(\n ${Spacing[\"spacing-32\"]} + ${props.$insetLeft || 0}px\n );\n padding-right: calc(\n ${Spacing[\"spacing-32\"]} + ${props.$insetRight || 0}px\n );\n\n ${MediaQuery.MaxWidth.sm} {\n padding-top: calc(\n ${Spacing[\"spacing-16\"]} + ${props.$insetTop || 0}px\n );\n padding-bottom: ${Spacing[\"spacing-16\"]};\n padding-left: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetLeft || 0}px\n );\n padding-right: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetRight || 0}px\n );\n }\n `\n : css`\n position: absolute;\n top: calc(\n ${Spacing[\"spacing-48\"]} + ${props.$insetTop || 0}px\n );\n right: calc(\n ${Spacing[\"spacing-48\"]} + ${props.$insetRight || 0}px\n );\n z-index: 5;\n\n ${MediaQuery.MaxWidth.sm} {\n top: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetTop || 0}px\n );\n right: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetRight || 0}px\n );\n }\n `}\n`;\n\nexport const CloseButton = styled(IconButton)``;\n\nexport const DeleteButton = styled(IconButton)`\n color: ${Colour[\"icon-error\"]};\n`;\n\nexport const MagnifierButton = styled(IconButton)``;\n\nexport const CustomActionButton = styled(IconButton)``;\n\nexport const ArrowButton = styled(IconButton)<ArrowButtonStyleProps>`\n z-index: 4;\n position: absolute;\n top: 50%;\n transform: translateY(-50%);\n\n ${(props) =>\n props.$position === \"left\" &&\n css`\n left: calc(${Spacing[\"spacing-48\"]} + ${props.$insetLeft || 0}px);\n\n ${MediaQuery.MaxWidth.sm} {\n left: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetLeft || 0}px\n );\n }\n `}\n\n ${(props) =>\n props.$position === \"right\" &&\n css`\n right: calc(${Spacing[\"spacing-48\"]} + ${props.$insetRight || 0}px);\n\n ${MediaQuery.MaxWidth.sm} {\n right: calc(\n ${Spacing[\"spacing-20\"]} + ${props.$insetRight || 0}px\n );\n }\n `}\n`;\n\nexport const CarouselModalContent = styled.div`\n position: relative;\n width: 100%;\n height: 100dvh;\n display: flex;\n flex-direction: column;\n`;\n\nexport const ImageGalleryContainer = styled.div`\n display: flex;\n flex-direction: column;\n width: 100%;\n flex: 1;\n min-height: 0;\n`;\n\nexport const ImageGalleryWrapper = styled.div`\n user-select: none;\n position: relative;\n display: block;\n overflow: hidden;\n width: 100%;\n flex: 1;\n min-height: 0;\n`;\n\nexport const ImageGallerySwipe = styled.div`\n display: block;\n user-select: none;\n height: 100%;\n overflow: hidden;\n touch-action: pan-y;\n`;\n\nexport const ImageGallerySlides = styled.div`\n display: flex;\n transition: all 450ms ease-out 0s;\n position: relative;\n text-align: center;\n user-select: none;\n width: 100%;\n height: 100%;\n`;\n\nexport const ImageGallerySlide = styled.div`\n flex: 0 0 100%;\n box-sizing: border-box;\n display: flex;\n justify-content: center;\n align-items: center;\n\n .react-transform-wrapper {\n height: 100%;\n width: 100%;\n }\n\n .react-transform-component {\n height: 100%;\n width: 100%;\n }\n`;\n\nexport const FocusableImageRegion = styled.div`\n height: 100%;\n width: 100%;\n outline: none;\n\n &:focus {\n outline: none;\n }\n\n &:focus-visible {\n outline: ${Border[\"width-020\"]} solid ${Colour[\"border-selected\"]};\n outline-offset: -2px;\n }\n`;\n\nexport const SlideImage = styled(StatefulImage)`\n height: 100%;\n width: 100%;\n border-radius: ${Radius[\"none\"]};\n`;\n\nexport const SlidePlaceholderImage = styled(ImagePlaceholder)`\n width: 60vw;\n height: auto;\n max-height: 100%;\n border-radius: ${Radius[\"none\"]};\n aspect-ratio: 4 / 3;\n`;\n\nexport const BoxChip = styled.div`\n display: flex;\n justify-content: center;\n padding: ${Spacing[\"spacing-16\"]};\n position: absolute;\n bottom: 0;\n left: 0;\n right: 0;\n margin-left: auto;\n margin-right: auto;\n z-index: 3;\n`;\n\nexport const Chip = styled(Typography.BodyXS)`\n display: inline-flex;\n padding: ${Spacing[\"spacing-4\"]} ${Spacing[\"spacing-16\"]};\n justify-content: center;\n align-items: center;\n border-radius: ${Radius[\"full\"]};\n background-color: ${Colour[\"bg\"]};\n text-align: center;\n`;\n\n// -----------------------------------------------------------------------------\n// THUMBNAIL STYLING\n// -----------------------------------------------------------------------------\n\nexport const ThumbnailContainer = styled.div<InsetStyleProps>`\n flex-shrink: 0;\n display: flex;\n overflow: auto;\n background-color: ${Colour[\"bg-inverse\"]};\n padding: ${(props) =>\n css`\n ${Spacing[\"spacing-24\"]} ${Spacing[\n \"spacing-16\"\n ]} calc(${Spacing[\"spacing-24\"]} + ${props.$insetBottom ||\n 0}px);\n `}\n ${MediaQuery.MaxWidth.sm} {\n padding: ${(props) =>\n css`\n ${Spacing[\"spacing-16\"]} ${Spacing[\n \"spacing-20\"\n ]} calc(${Spacing[\"spacing-16\"]} + ${props.$insetBottom ||\n 0}px);\n `};\n }\n`;\n\nexport const ThumbnailWrapper = styled.div`\n box-sizing: border-box;\n display: flex;\n align-items: center;\n gap: ${Spacing[\"spacing-16\"]};\n justify-content: center;\n margin-left: auto;\n margin-right: auto;\n`;\n\nexport const ThumbnailItemContainer = styled.div`\n display: flex;\n align-items: center;\n justify-content: center;\n height: 100px;\n width: 100px;\n\n ${MediaQuery.MaxWidth.sm} {\n height: 64px;\n width: 64px;\n }\n`;\n\nexport const ThumbnailItem = styled.div<ThumbnailItemStyleProps>`\n cursor: pointer;\n background-color: ${Colour[\"bg-inverse\"]};\n border-radius: ${Radius[\"md\"]};\n border: ${Border[\"solid\"]} transparent;\n box-sizing: content-box;\n\n flex-shrink: 0;\n overflow: hidden;\n display: flex;\n align-items: center;\n justify-content: center;\n height: 92px;\n width: 92px;\n\n ${MediaQuery.MaxWidth.sm} {\n height: 60px;\n width: 60px;\n }\n\n ${(props) =>\n props.$active\n ? css`\n border-width: ${Border[\"width-040\"]};\n border-color: ${Colour[\"border-selected\"]};\n\n ${MediaQuery.MaxWidth.sm} {\n border-width: ${Border[\"width-020\"]};\n }\n\n &:hover {\n border-color: ${Colour[\"border-selected-hover\"]};\n }\n `\n : css`\n border-width: ${Border[\"width-010\"]};\n\n &:hover {\n border-color: ${Colour[\"border-hover\"]};\n }\n `};\n`;\n\nexport const ThumbnailImage = styled(StatefulImage)`\n height: 100%;\n width: 100%;\n`;\n\n// -----------------------------------------------------------------------------\n// FILE INFO BAR STYLING\n// -----------------------------------------------------------------------------\n\nexport const FileInfoTextWrapper = styled.div<FileInfoTextWrapperStyleProps>`\n flex: 1;\n display: flex;\n flex-direction: column;\n gap: ${Spacing[\"spacing-8\"]};\n overflow: hidden;\n min-width: 0;\n min-height: calc(\n ${Font.Spec[\"body-lh-baseline\"]} + ${Spacing[\"spacing-8\"]} +\n ${Font.Spec[\"body-lh-md\"]}\n );\n ${(props) =>\n props.$centerContent &&\n css`\n justify-content: center;\n `}\n`;\n\nexport const FileInfoFileName = styled(Typography.BodyBL)`\n color: ${Colour[\"text-inverse\"]};\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n`;\n\nexport const FileInfoFileSize = styled(Typography.BodyMD)`\n color: ${Colour[\"text-inverse\"]};\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n min-width: 0;\n`;\n"],"names":["IconButton","styled","ClickableIcon","Colour","Shadow","Border","TopActionButtons","div","Spacing","props","$hasFileInfo","css","$insetTop","$insetLeft","$insetRight","MediaQuery","MaxWidth","sm","CloseButton","DeleteButton","MagnifierButton","CustomActionButton","ArrowButton","$position","CarouselModalContent","ImageGalleryContainer","ImageGalleryWrapper","ImageGallerySwipe","ImageGallerySlides","ImageGallerySlide","FocusableImageRegion","SlideImage","StatefulImage","Radius","SlidePlaceholderImage","ImagePlaceholder","BoxChip","Chip","Typography","BodyXS","ThumbnailContainer","$insetBottom","ThumbnailWrapper","ThumbnailItemContainer","ThumbnailItem","$active","ThumbnailImage","FileInfoTextWrapper","Font","Spec","$centerContent","FileInfoFileName","BodyBL","FileInfoFileSize","BodyMD"],"mappings":"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"}
|
|
@@ -6,6 +6,16 @@ export interface FullscreenImageCarouselRef {
|
|
|
6
6
|
goToPrevItem: () => void;
|
|
7
7
|
goToNextItem: () => void;
|
|
8
8
|
}
|
|
9
|
+
/** Custom button rendered in the carousel's top bar */
|
|
10
|
+
export interface FullscreenImageCarouselCustomAction {
|
|
11
|
+
/** Icon element rendered inside the button */
|
|
12
|
+
icon: JSX.Element;
|
|
13
|
+
/** Accessible name for the button */
|
|
14
|
+
ariaLabel: string;
|
|
15
|
+
/** Called when the action is activated */
|
|
16
|
+
onClick: (item: FullscreenImageCarouselItemProps, index: number) => void;
|
|
17
|
+
"data-testid"?: string | undefined;
|
|
18
|
+
}
|
|
9
19
|
export interface FullscreenImageCarouselProps extends Pick<ModalProps, "show" | "rootComponentId" | "animationFrom" | "zIndex"> {
|
|
10
20
|
items: FullscreenImageCarouselItemProps[];
|
|
11
21
|
/** The index of the visible item, starts from 0 */
|
|
@@ -14,13 +24,19 @@ export interface FullscreenImageCarouselProps extends Pick<ModalProps, "show" |
|
|
|
14
24
|
hideNavigation?: boolean | undefined;
|
|
15
25
|
hideCounter?: boolean | undefined;
|
|
16
26
|
hideMagnifier?: boolean | undefined;
|
|
27
|
+
/** Additional icon buttons rendered in the top bar, before the default buttons. An item's own `customActions` replaces this list for that item */
|
|
28
|
+
customActions?: FullscreenImageCarouselCustomAction[] | undefined;
|
|
17
29
|
onDelete?: ((item: FullscreenImageCarouselItemProps, index: number) => void) | undefined;
|
|
18
30
|
onClose?: (() => void) | undefined;
|
|
19
31
|
insets?: Insets | undefined;
|
|
32
|
+
/** Ref to the top bar element, which holds the file info and the action buttons */
|
|
33
|
+
topBarRef?: React.Ref<HTMLDivElement> | undefined;
|
|
20
34
|
}
|
|
21
35
|
interface FullscreenImageCarouselBaseItemProps {
|
|
22
36
|
fileName?: string | undefined;
|
|
23
37
|
fileSize?: string | undefined;
|
|
38
|
+
/** Replaces the component-level `customActions` while this item is active. Leave `undefined` to inherit the component-level list; pass `[]` to render none */
|
|
39
|
+
customActions?: FullscreenImageCarouselCustomAction[] | undefined;
|
|
24
40
|
}
|
|
25
41
|
export interface FullscreenImageCarouselImageItemProps extends FullscreenImageCarouselBaseItemProps {
|
|
26
42
|
type?: "image" | undefined;
|
package/navbar/menu.d.ts
CHANGED
|
@@ -2,7 +2,8 @@ import React from "react";
|
|
|
2
2
|
import { NavItemCommonProps } from "./types";
|
|
3
3
|
interface Props<T> {
|
|
4
4
|
items: NavItemCommonProps<T>[];
|
|
5
|
+
selectedId?: string | undefined;
|
|
5
6
|
onItemClick: (event: React.MouseEvent<HTMLAnchorElement>, item: NavItemCommonProps<T>) => void;
|
|
6
7
|
}
|
|
7
|
-
export declare const Menu: <T>({ items, onItemClick }: Props<T>) => JSX.Element;
|
|
8
|
+
export declare const Menu: <T>({ items, selectedId, onItemClick, }: Props<T>) => JSX.Element;
|
|
8
9
|
export {};
|
package/navbar/menu.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__rest as
|
|
1
|
+
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as t,Fragment as i}from"react/jsx-runtime";import{MobileWrapper as n,MenuItem as o,Link as r}from"./menu.styles.js";const l=({items:l,selectedId:s,onItemClick:c})=>{const d=e=>t=>{t.stopPropagation(),c(t,e)};return(null==l?void 0:l.length)?t(n,{children:l.map(((i,n)=>{const{children:l,options:c,weight:m}=i,a=e(i,["children","options","weight"]),p=`menu__mobile-${n+1}`,h=i.id===s;return t(o,{children:t(r,Object.assign({"data-testid":p},a,c,{weight:h?"bold":m,"aria-current":h?"page":void 0,onClick:d(i),underlineStyle:"none",children:l}))},n)}))}):t(i,{})};export{l as Menu};
|
|
2
2
|
//# sourceMappingURL=menu.js.map
|
package/navbar/menu.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.js","sources":["../../src/navbar/menu.tsx"],"sourcesContent":["import React from \"react\";\nimport { Link, MenuItem, MobileWrapper } from \"./menu.styles\";\nimport { NavItemCommonProps } from \"./types\";\n\ninterface Props<T> {\n items: NavItemCommonProps<T>[];\n onItemClick: (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemCommonProps<T>\n ) => void;\n}\n\nexport const Menu = <T,>({
|
|
1
|
+
{"version":3,"file":"menu.js","sources":["../../src/navbar/menu.tsx"],"sourcesContent":["import React from \"react\";\nimport { Link, MenuItem, MobileWrapper } from \"./menu.styles\";\nimport { NavItemCommonProps } from \"./types\";\n\ninterface Props<T> {\n items: NavItemCommonProps<T>[];\n selectedId?: string | undefined;\n onItemClick: (\n event: React.MouseEvent<HTMLAnchorElement>,\n item: NavItemCommonProps<T>\n ) => void;\n}\n\nexport const Menu = <T,>({\n items,\n selectedId,\n onItemClick,\n}: Props<T>): JSX.Element => {\n const handleLinkClick = (item: NavItemCommonProps<T>) => {\n return (event: React.MouseEvent<HTMLAnchorElement>) => {\n event.stopPropagation(); // in mobile, this prevents the drawer from intercepting event\n onItemClick(event, item);\n };\n };\n\n if (!items?.length) return <></>;\n\n return (\n <MobileWrapper>\n {items.map((item, index) => {\n const { children, options, weight, ...otherItemAttrs } = item;\n const testId = `menu__mobile-${index + 1}`;\n const selected = item.id === selectedId;\n\n return (\n <MenuItem key={index}>\n <Link\n data-testid={testId}\n {...otherItemAttrs}\n {...options}\n weight={selected ? \"bold\" : weight}\n aria-current={selected ? \"page\" : undefined}\n onClick={handleLinkClick(item)}\n underlineStyle=\"none\"\n >\n {children}\n </Link>\n </MenuItem>\n );\n })}\n </MobileWrapper>\n );\n};\n"],"names":["Menu","items","selectedId","onItemClick","handleLinkClick","item","event","stopPropagation","length","_jsx","MobileWrapper","children","map","index","options","weight","otherItemAttrs","__rest","testId","selected","id","MenuItem","Link","Object","assign","undefined","onClick","underlineStyle"],"mappings":"8KAaO,MAAMA,EAAO,EAChBC,QACAC,aACAC,kBAEA,MAAMC,EAAmBC,GACbC,IACJA,EAAMC,kBACNJ,EAAYG,EAAOD,EAAK,EAIhC,OAAKJ,aAAK,EAALA,EAAOO,QAGRC,EAACC,EAAa,CAAAC,SACTV,EAAMW,KAAI,CAACP,EAAMQ,KACd,MAAMF,SAAEA,EAAQG,QAAEA,EAAOC,OAAEA,GAA8BV,EAAnBW,EAAcC,EAAKZ,EAAnD,CAAA,WAAA,UAAA,WACAa,EAAS,gBAAgBL,EAAQ,IACjCM,EAAWd,EAAKe,KAAOlB,EAE7B,OACIO,EAACY,EAAQ,CAAAV,SACLF,EAACa,EAAIC,OAAAC,OAAA,CAAA,cACYN,GACTF,EACAF,GACJC,OAAQI,EAAW,OAASJ,EAAM,eACpBI,EAAW,YAASM,EAClCC,QAAStB,EAAgBC,GACzBsB,eAAe,OAAMhB,SAEpBA,MAVME,EAYJ,MAtBAJ,OAyBP"}
|
package/navbar/menu.styles.js
CHANGED
|
@@ -10,7 +10,7 @@ import e from"styled-components";import{lineClampCss as r}from"../shared/styles/
|
|
|
10
10
|
`,a=e.li`
|
|
11
11
|
width: 100%;
|
|
12
12
|
display: flex;
|
|
13
|
-
`,
|
|
13
|
+
`,p=e(d.LinkBL)`
|
|
14
14
|
width: 100%;
|
|
15
15
|
text-align: left;
|
|
16
16
|
color: ${t.text};
|
|
@@ -19,7 +19,7 @@ import e from"styled-components";import{lineClampCss as r}from"../shared/styles/
|
|
|
19
19
|
|
|
20
20
|
// use border, as padding still shows an extra line after the ellipsis
|
|
21
21
|
border: ${o.solid} transparent;
|
|
22
|
-
border-width: ${i["spacing-
|
|
22
|
+
border-width: 10px ${i["spacing-16"]} 10px ${i["spacing-24"]};
|
|
23
23
|
border-radius: ${s.md};
|
|
24
24
|
|
|
25
25
|
${r(2)}
|
|
@@ -31,5 +31,5 @@ import e from"styled-components";import{lineClampCss as r}from"../shared/styles/
|
|
|
31
31
|
background-color: ${t["bg-hover"]};
|
|
32
32
|
color: ${t.text};
|
|
33
33
|
}
|
|
34
|
-
`;export{
|
|
34
|
+
`;export{p as Link,a as MenuItem,l as MobileWrapper};
|
|
35
35
|
//# sourceMappingURL=menu.styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"menu.styles.js","sources":["../../src/navbar/menu.styles.tsx"],"sourcesContent":["import styled from \"styled-components\";\nimport { lineClampCss } from \"../shared/styles\";\nimport { Border, Colour, Radius, Spacing } from \"../theme\";\nimport { Typography } from \"../typography\";\n\nexport const MobileWrapper = styled.ul`\n list-style: none;\n display: flex;\n flex-direction: column;\n\n margin: 0;\n padding: 0;\n\n border-left: ${Border[\"width-040\"]} solid ${Colour[\"border-selected\"]};\n`;\n\nexport const MenuItem = styled.li`\n width: 100%;\n display: flex;\n`;\n\nexport const Link = styled(Typography.LinkBL)`\n width: 100%;\n text-align: left;\n color: ${Colour[\"text\"]};\n\n margin: 0 ${Spacing[\"spacing-8\"]};\n\n // use border, as padding still shows an extra line after the ellipsis\n border: ${Border[\"solid\"]} transparent;\n border-width: ${Spacing[\"spacing-
|
|
1
|
+
{"version":3,"file":"menu.styles.js","sources":["../../src/navbar/menu.styles.tsx"],"sourcesContent":["import styled from \"styled-components\";\nimport { lineClampCss } from \"../shared/styles\";\nimport { Border, Colour, Radius, Spacing } from \"../theme\";\nimport { Typography } from \"../typography\";\n\nexport const MobileWrapper = styled.ul`\n list-style: none;\n display: flex;\n flex-direction: column;\n\n margin: 0;\n padding: 0;\n\n border-left: ${Border[\"width-040\"]} solid ${Colour[\"border-selected\"]};\n`;\n\nexport const MenuItem = styled.li`\n width: 100%;\n display: flex;\n`;\n\nexport const Link = styled(Typography.LinkBL)`\n width: 100%;\n text-align: left;\n color: ${Colour[\"text\"]};\n\n margin: 0 ${Spacing[\"spacing-8\"]};\n\n // use border, as padding still shows an extra line after the ellipsis\n border: ${Border[\"solid\"]} transparent;\n border-width: 10px ${Spacing[\"spacing-16\"]} 10px ${Spacing[\"spacing-24\"]};\n border-radius: ${Radius[\"md\"]};\n\n ${lineClampCss(2)}\n white-space: pre-wrap;\n\n &:hover,\n &:active,\n &:focus {\n background-color: ${Colour[\"bg-hover\"]};\n color: ${Colour[\"text\"]};\n }\n`;\n"],"names":["MobileWrapper","styled","ul","Border","Colour","MenuItem","li","Link","Typography","LinkBL","Spacing","Radius","lineClampCss"],"mappings":"mOAKO,MAAMA,EAAgBC,EAAOC,EAAE;;;;;;;;mBAQnBC,EAAO,sBAAsBC,EAAO;EAG1CC,EAAWJ,EAAOK,EAAE;;;EAKpBC,EAAON,EAAOO,EAAWC,OAAO;;;aAGhCL,EAAa;;gBAEVM,EAAQ;;;cAGVP,EAAc;yBACHO,EAAQ,sBAAsBA,EAAQ;qBAC1CC,EAAW;;MAE1BC,EAAa;;;;;;4BAMSR,EAAO;iBAClBA,EAAa;;"}
|
package/navbar/navbar-items.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as n,Fragment as t,jsxs as i}from"react/jsx-runtime";import{useState as r,useRef as l,useEffect as o}from"react";import{Menu as d}from"../menu/menu.js";import{Menu as a}from"./menu.js";import"../util/calendar-helper.js";import"../util/date-helper.js";import"../util/date-input-helper.js";import{useId as s}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{MobileWrapper as c,Wrapper as u,LinkItem as p,Link as m,LinkLabel as h,LinkButton as g,ChevronIconDesktop as b,LinkIndicator as v,LinkIconContainer as $,ExpandCollapseButton as f,ChevronIcon as j}from"./navbar-items.styles.js";const
|
|
1
|
+
import{__rest as e}from"../_virtual/_tslib.js";import{jsx as n,Fragment as t,jsxs as i}from"react/jsx-runtime";import{useState as r,useRef as l,useEffect as o}from"react";import{Menu as d}from"../menu/menu.js";import{Menu as a}from"./menu.js";import"../util/calendar-helper.js";import"../util/date-helper.js";import"../util/date-input-helper.js";import{useId as s}from"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import{MobileWrapper as c,Wrapper as u,LinkItem as p,Link as m,LinkLabel as h,LinkButton as g,ChevronIconDesktop as b,LinkIndicator as v,LinkIconContainer as $,ExpandCollapseButton as f,ChevronIcon as j}from"./navbar-items.styles.js";const x=({items:x,selectedId:k,mobile:I=!1,hideNavBranding:C,hideLinkIndicator:M=!1,onItemClick:O})=>{const[_,w]=r(null),L=l(null),y=s(),P=e=>{var n;return!!(null===(n=e.subMenu)||void 0===n?void 0:n.some((e=>e.id===k)))},E=I?x.findIndex((e=>"component"!==e.itemType&&P(e))):-1,B=E<0?null:E;o((()=>{I&&w(B)}),[I,B]),o((()=>{if(I)return;const e=e=>{L.current&&!L.current.contains(e.target)&&w(null)};return document.addEventListener("click",e,!0),()=>{document.removeEventListener("click",e,!0)}}),[I]);const D=(e,n)=>t=>{t.stopPropagation(),I&&w((t=>{var i;return(null===(i=e.subMenu)||void 0===i?void 0:i.length)&&t!==n?n:null})),O(t,e)},T=(e,n)=>{e.stopPropagation(),O(e,n)},A=(e,t)=>n(d.Content,{id:t,children:n(d.Section,{showDivider:!1,children:e.map(((e,t)=>n(d.Link,{href:e.href,children:e.children},`${e.id}-${t}`)))})}),F=e=>n(a,{items:e,selectedId:k,onItemClick:T}),H=(r,l)=>{const{children:o,options:a,subMenu:s}=r,c=e(r,["children","options","subMenu"]),u=!!(null==s?void 0:s.length),O=(e=>e.id===k||P(e))(r),L=I&&u&&_===l,E=!I&&u&&_===l||L,B=I||null===_?O:_===l,T=!M&&B,H=B?I?"bold":"semibold":"regular",N=I?`link__mobile-${l+1}`:`link__${l+1}`,S=()=>T?n(v,{"data-testid":`${N}-indicator`,$selected:B}):null;return n(p,{$hiddenBranding:C,children:u?(e=>{const p=`navbar-submenu-${y}-${r.id}`;return I?i(t,{children:[i(m,Object.assign({"data-testid":N,$weight:H,$selected:B},c,{"aria-current":O?"page":void 0,"aria-haspopup":"menu","aria-expanded":E,onClick:D(r,l)},a,{children:[n(h,{children:o}),S(),I&&u?n($,{children:n(f,{"data-testid":`${N}-expand-collapse-button`,$selected:B,$expanded:E,focusHighlight:!1,focusOutline:"browser","aria-label":E?"Collapse":"Expand",children:n(j,{$selected:B})})}):null]})),L&&F(s)]}):n(d,{position:e?"bottom-end":"bottom",customOffset:0,menuContent:A(s,p),triggerOnFocus:!0,isModal:!1,onPopoverAppear:()=>{w(l)},onPopoverDismiss:()=>{w((e=>e===l?null:e))},children:i(g,Object.assign({type:"button",tabIndex:0,"data-testid":N,$weight:H,$selected:B,"aria-haspopup":"menu","aria-expanded":E},a,{children:[n(h,{children:o}),S(),n(b,{$selected:B,$expanded:E})]}))})})(l===x.length-1):i(m,Object.assign({tabIndex:0,"data-testid":N,$weight:H,$selected:B},c,{"aria-current":O?"page":void 0,onClick:D(r,l)},a,{children:[n(h,{children:o}),S()]}))},l)},N=()=>x.map(((e,t)=>{var i;return"component"===e.itemType?n("li",{children:null!==(i=e.children)&&void 0!==i?i:null},t):H(e,t)}));return x&&x.length>0?I?n(c,{ref:L,children:N()}):n(u,{ref:L,$alignLeft:C,children:N()}):n(t,{})};export{x as NavbarItems};
|
|
2
2
|
//# sourceMappingURL=navbar-items.js.map
|