@lifesg/react-design-system 4.0.0-alpha.11 → 4.0.0-alpha.12
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/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 +1 -1
- package/cjs/file-download/file-list-card/file-list-card.styles.js.map +1 -1
- package/cjs/file-download/file-list-card/file-list-card.styles_lzbqkk.css +18 -0
- package/cjs/file-upload/helper.js +1 -1
- package/cjs/file-upload/helper.js.map +1 -1
- package/cjs/footer/footer-disclaimer-links-data.js +1 -1
- package/cjs/footer/footer-disclaimer-links-data.js.map +1 -1
- package/cjs/footer/footer.styles.js +1 -1
- package/cjs/footer/footer.styles.js.map +1 -1
- package/cjs/footer/{footer.styles_1msorhc.css → footer.styles_14hnlcq.css} +4 -4
- 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/index.js +1 -1
- package/cjs/masthead/sgds-day.css +0 -1
- package/cjs/masthead/sgds-night.css +0 -1
- package/cjs/navbar/navbar-logo-data.js +1 -1
- package/cjs/navbar/navbar-logo-data.js.map +1 -1
- package/cjs/theme/index.js +1 -1
- package/cjs/theme/types.js +1 -1
- package/cjs/theme/types.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 +2 -0
- package/file-download/file-list-card/file-list-card.styles.js +1 -1
- package/file-download/file-list-card/file-list-card.styles.js.map +1 -1
- package/file-download/file-list-card/file-list-card.styles_lzbqkk.css +18 -0
- package/file-download/file-list-card/types.d.ts +1 -0
- package/file-download/types.d.ts +13 -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/footer/footer-disclaimer-links-data.js +1 -1
- package/footer/footer-disclaimer-links-data.js.map +1 -1
- package/footer/footer.styles.js +1 -1
- package/footer/footer.styles.js.map +1 -1
- package/footer/{footer.styles_1msorhc.css → footer.styles_14hnlcq.css} +4 -4
- 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/types.d.ts +37 -0
- package/index.js +1 -1
- package/masthead/sgds-day.css +0 -1
- package/masthead/sgds-night.css +0 -1
- package/navbar/navbar-logo-data.js +1 -1
- package/navbar/navbar-logo-data.js.map +1 -1
- package/package.json +1 -1
- package/theme/index.js +1 -1
- package/theme/styles/sportsg-orange.css +779 -0
- package/theme/theme-provider/preset.d.ts +2 -0
- package/theme/types.d.ts +9 -3
- package/theme/types.js +1 -1
- package/theme/types.js.map +1 -1
- package/cjs/file-download/file-list-card/file-list-card.styles_18j2gut.css +0 -16
- package/file-download/file-list-card/file-list-card.styles_18j2gut.css +0 -16
|
@@ -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 clsx from \"clsx\";\nimport {\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n ReactZoomPanPinchContentRef,\n ReactZoomPanPinchRef,\n} from \"react-zoom-pan-pinch\";\nimport { TransformComponent, TransformWrapper } from \"react-zoom-pan-pinch\";\n\nimport { ModalV2 } from \"../modal-v2\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { useStateCallback } from \"../shared/hooks\";\nimport { ImagePlaceholder } from \"../shared/image-placeholder\";\nimport { formatUnitValue, useApplyStyle } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { useEventListener } from \"../util\";\nimport * as styles from \"./fullscreen-image-carousel.styles\";\nimport { StatefulImage } from \"./stateful-image\";\nimport type {\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 topActionButtonsRef = useRef<HTMLDivElement>(null);\n const prevArrowButtonRef = useRef<HTMLButtonElement>(null);\n const nextArrowButtonRef = useRef<HTMLButtonElement>(null);\n const thumbnailContainerRef = 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 useApplyStyle(topActionButtonsRef, {\n [styles.tokens.topActionButtons.insetTop]: formatUnitValue(\n insets?.top,\n \"px\"\n ),\n [styles.tokens.topActionButtons.insetLeft]: formatUnitValue(\n insets?.left,\n \"px\"\n ),\n [styles.tokens.topActionButtons.insetRight]: formatUnitValue(\n insets?.right,\n \"px\"\n ),\n });\n\n useApplyStyle(prevArrowButtonRef, {\n [styles.tokens.arrowButton.insetLeft]: formatUnitValue(\n insets?.left,\n \"px\"\n ),\n });\n\n useApplyStyle(nextArrowButtonRef, {\n [styles.tokens.arrowButton.insetRight]: formatUnitValue(\n insets?.right,\n \"px\"\n ),\n });\n\n useApplyStyle(thumbnailContainerRef, {\n [styles.tokens.thumbnailContainer.insetBottom]: formatUnitValue(\n insets?.bottom,\n \"px\"\n ),\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 <div\n className={styles.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 <div\n className={styles.imageGallerySlide}\n key={index}\n data-testid=\"slide-item\"\n >\n <div\n className={styles.focusableImageRegion}\n ref={isActive ? imageRef : null}\n tabIndex={isActive ? 0 : -1}\n >\n {isCustomItem(item) ? (\n isActiveOrAdjacent ? (\n item.renderContent()\n ) : (\n <ImagePlaceholder\n className={\n styles.slidePlaceholderImage\n }\n />\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 <StatefulImage\n className={styles.slideImage}\n src={item.src}\n alt={getItemAriaLabel(index)}\n placeholder={\n <ImagePlaceholder\n className={\n styles.slidePlaceholderImage\n }\n />\n }\n fit=\"scale-down\"\n retrieveImageDimension\n setDimension={setDimension}\n />\n </TransformComponent>\n </TransformWrapper>\n )}\n </div>\n </div>\n );\n })}\n </div>\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 <div\n className={clsx(\n styles.fileInfoTextWrapper,\n !trimmedSize && styles.fileInfoTextWrapperCentered\n )}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n data-testid=\"file-info-bar\"\n >\n {trimmedName && (\n <Typography.BodyBL\n className={styles.fileInfoFileName}\n weight=\"semibold\"\n data-testid=\"file-info-name\"\n >\n {trimmedName}\n </Typography.BodyBL>\n )}\n {trimmedSize && (\n <Typography.BodyMD\n className={styles.fileInfoFileSize}\n data-testid=\"file-info-size\"\n >\n {trimmedSize}\n </Typography.BodyMD>\n )}\n </div>\n );\n };\n\n const renderThumbnails = () => {\n return (\n <div\n className={styles.thumbnailContainer}\n ref={thumbnailContainerRef}\n aria-hidden=\"true\"\n data-testid=\"thumbnail-container\"\n >\n <div className={styles.thumbnailWrapper}>\n {items.map((item, index) => {\n const src = isCustomItem(item)\n ? item.thumbnailSrc\n : item.thumbnailSrc ?? item.src;\n return (\n <div\n className={styles.thumbnailItemContainer}\n key={index}\n >\n <div\n className={styles.thumbnailItem}\n data-active={index === currentSlide}\n data-testid=\"thumbnail-item\"\n onClick={() => goToSlide(index)}\n ref={(el) =>\n (thumbnailRefs.current[index] = el)\n }\n >\n {src ? (\n <StatefulImage\n className={styles.thumbnailImage}\n src={src}\n alt={`Thumbnail ${index + 1}`}\n fit=\"cover\"\n />\n ) : (\n <ImagePlaceholder\n className={\n styles.slidePlaceholderImage\n }\n />\n )}\n </div>\n </div>\n );\n })}\n </div>\n </div>\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 <div className={styles.carouselModalContent}>\n <div className={styles.imageGalleryContainer}>\n <div className={styles.imageGalleryWrapper}>\n <div\n className={styles.imageGallerySwipe}\n ref={containerRef}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n {renderSlides()}\n </div>\n\n {!hideNavigation && (\n <>\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.arrowButton,\n styles.arrowButtonLeft\n )}\n ref={prevArrowButtonRef}\n aria-label={`Previous ${carouselItemNoun}`}\n data-testid=\"prev-btn\"\n onClick={goToPrevSlide}\n >\n <ChevronLeftIcon aria-hidden />\n </ClickableIcon>\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.arrowButton,\n styles.arrowButtonRight\n )}\n ref={nextArrowButtonRef}\n aria-label={`Next ${carouselItemNoun}`}\n data-testid=\"forward-btn\"\n onClick={goToNextSlide}\n >\n <ChevronRightIcon aria-hidden />\n </ClickableIcon>\n </>\n )}\n\n {!hideCounter && (\n <div className={styles.boxChip} aria-hidden=\"true\">\n <Typography.BodyXS\n className={styles.chip}\n weight=\"semibold\"\n data-testid=\"carousel-counter\"\n >{`${currentSlide + 1}/${\n items.length\n }`}</Typography.BodyXS>\n </div>\n )}\n </div>\n\n {!hideThumbnail && renderThumbnails()}\n </div>\n <div\n className={styles.topActionButtons}\n ref={topActionButtonsRef}\n data-has-file-info={hasFileInfo}\n >\n {hasFileInfo && renderFileInfo()}\n {!hideMagnifier && !isCustomItem(currentItem) && (\n <ClickableIcon\n className={styles.iconButton}\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 </ClickableIcon>\n )}\n\n {onDelete && (\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.iconButtonError\n )}\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 </ClickableIcon>\n )}\n\n <ClickableIcon\n className={styles.iconButton}\n aria-label={\n hasAnyItemLabel\n ? \"Close carousel\"\n : \"Close image carousel\"\n }\n onClick={onClose}\n >\n <CrossIcon aria-hidden />\n </ClickableIcon>\n </div>\n </div>\n </ModalV2>\n );\n};\n\n// @catalog\n/**\n * A fullscreen modal carousel for browsing images and custom media items.\n *\n * Use to present a collection of images or custom content in an overlay with\n * navigation controls, zoom support, and an optional thumbnail strip.\n * The top info bar is rendered only when at least one item provides some file metadata.\n * @keywords carousel, gallery, image, lightbox, media, overlay\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","topActionButtonsRef","prevArrowButtonRef","nextArrowButtonRef","thumbnailContainerRef","diff","currentItem","hasAnyItemLabel","some","itemLabel","trim","carouselItemNoun","hasFileInfo","useMemo","fileName","fileSize","_b","useApplyStyle","styles.tokens","topActionButtons","insetTop","formatUnitValue","top","insetLeft","left","insetRight","right","arrowButton","thumbnailContainer","insetBottom","bottom","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","_jsxs","className","styles.carouselModalContent","children","styles.imageGalleryContainer","styles.imageGalleryWrapper","styles.imageGallerySwipe","onTouchStart","touches","clientX","onTouchMove","onTouchEnd","Math","abs","offsetWidth","undefined","styles.imageGallerySlides","style","transform","map","isActive","isActiveOrAdjacent","styles.imageGallerySlide","styles.focusableImageRegion","tabIndex","renderContent","ImagePlaceholder","styles.slidePlaceholderImage","TransformWrapper","el","panning","disabled","initialScale","onZoom","onZoomStop","onWheel","TransformComponent","StatefulImage","styles.slideImage","placeholder","fit","retrieveImageDimension","_Fragment","ClickableIcon","clsx","styles.iconButton","styles.arrowButton","styles.arrowButtonLeft","onClick","ChevronLeftIcon","styles.arrowButtonRight","ChevronRightIcon","styles.boxChip","Typography","BodyXS","styles.chip","weight","styles.thumbnailContainer","styles.thumbnailWrapper","thumbnailSrc","styles.thumbnailItemContainer","styles.thumbnailItem","styles.thumbnailImage","styles.topActionButtons","trimmedName","trimmedSize","styles.fileInfoTextWrapper","styles.fileInfoTextWrapperCentered","BodyBL","styles.fileInfoFileName","BodyMD","styles.fileInfoFileSize","renderFileInfo","zoomRatio","centerView","_d","_c","MagnifierPlusIcon","MagnifierMinusIcon","styles.iconButtonError","BinIcon","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 clsx from \"clsx\";\nimport {\n cloneElement,\n forwardRef,\n useCallback,\n useEffect,\n useImperativeHandle,\n useMemo,\n useRef,\n useState,\n} from \"react\";\nimport type {\n ReactZoomPanPinchContentRef,\n ReactZoomPanPinchRef,\n} from \"react-zoom-pan-pinch\";\nimport { TransformComponent, TransformWrapper } from \"react-zoom-pan-pinch\";\n\nimport { ModalV2 } from \"../modal-v2\";\nimport { ClickableIcon } from \"../shared/clickable-icon\";\nimport { useStateCallback } from \"../shared/hooks\";\nimport { ImagePlaceholder } from \"../shared/image-placeholder\";\nimport { formatUnitValue, useApplyStyle } from \"../theme\";\nimport { Typography } from \"../typography\";\nimport { mergeRefs, useEventListener } from \"../util\";\nimport * as styles from \"./fullscreen-image-carousel.styles\";\nimport { StatefulImage } from \"./stateful-image\";\nimport type {\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 /*\n * The top bar's element is held in state rather than a ref so that its mount\n * causes a render. Overlay keeps its portal target in state and mounts these\n * children, so the layout effect below would otherwise run while a ref was\n * still null and never write the inset custom properties.\n */\n const [topActionButtons, setTopActionButtons] =\n useState<HTMLDivElement | null>(null);\n const topActionButtonsRef = useMemo(\n () => ({ current: topActionButtons }),\n [topActionButtons]\n );\n const mergedTopBarRef = useMemo(\n () => mergeRefs(setTopActionButtons, topBarRef),\n [topBarRef]\n );\n const prevArrowButtonRef = useRef<HTMLButtonElement>(null);\n const nextArrowButtonRef = useRef<HTMLButtonElement>(null);\n const thumbnailContainerRef = 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 useApplyStyle(topActionButtonsRef, {\n [styles.tokens.topActionButtons.insetTop]: formatUnitValue(\n insets?.top,\n \"px\"\n ),\n [styles.tokens.topActionButtons.insetLeft]: formatUnitValue(\n insets?.left,\n \"px\"\n ),\n [styles.tokens.topActionButtons.insetRight]: formatUnitValue(\n insets?.right,\n \"px\"\n ),\n });\n\n useApplyStyle(prevArrowButtonRef, {\n [styles.tokens.arrowButton.insetLeft]: formatUnitValue(\n insets?.left,\n \"px\"\n ),\n });\n\n useApplyStyle(nextArrowButtonRef, {\n [styles.tokens.arrowButton.insetRight]: formatUnitValue(\n insets?.right,\n \"px\"\n ),\n });\n\n useApplyStyle(thumbnailContainerRef, {\n [styles.tokens.thumbnailContainer.insetBottom]: formatUnitValue(\n insets?.bottom,\n \"px\"\n ),\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 <div\n className={styles.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 <div\n className={styles.imageGallerySlide}\n key={index}\n data-testid=\"slide-item\"\n >\n <div\n className={styles.focusableImageRegion}\n ref={isActive ? imageRef : null}\n tabIndex={isActive ? 0 : -1}\n >\n {isCustomItem(item) ? (\n isActiveOrAdjacent ? (\n item.renderContent()\n ) : (\n <ImagePlaceholder\n className={\n styles.slidePlaceholderImage\n }\n />\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 <StatefulImage\n className={styles.slideImage}\n src={item.src}\n alt={getItemAriaLabel(index)}\n placeholder={\n <ImagePlaceholder\n className={\n styles.slidePlaceholderImage\n }\n />\n }\n fit=\"scale-down\"\n retrieveImageDimension\n setDimension={setDimension}\n />\n </TransformComponent>\n </TransformWrapper>\n )}\n </div>\n </div>\n );\n })}\n </div>\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 <div\n className={clsx(\n styles.fileInfoTextWrapper,\n !trimmedSize && styles.fileInfoTextWrapperCentered\n )}\n aria-live=\"polite\"\n aria-atomic=\"true\"\n data-testid=\"file-info-bar\"\n >\n {trimmedName && (\n <Typography.BodyBL\n className={styles.fileInfoFileName}\n weight=\"semibold\"\n data-testid=\"file-info-name\"\n >\n {trimmedName}\n </Typography.BodyBL>\n )}\n {trimmedSize && (\n <Typography.BodyMD\n className={styles.fileInfoFileSize}\n data-testid=\"file-info-size\"\n >\n {trimmedSize}\n </Typography.BodyMD>\n )}\n </div>\n );\n };\n\n const renderThumbnails = () => {\n return (\n <div\n className={styles.thumbnailContainer}\n ref={thumbnailContainerRef}\n aria-hidden=\"true\"\n data-testid=\"thumbnail-container\"\n >\n <div className={styles.thumbnailWrapper}>\n {items.map((item, index) => {\n const src = isCustomItem(item)\n ? item.thumbnailSrc\n : item.thumbnailSrc ?? item.src;\n return (\n <div\n className={styles.thumbnailItemContainer}\n key={index}\n >\n <div\n className={styles.thumbnailItem}\n data-active={index === currentSlide}\n data-testid=\"thumbnail-item\"\n onClick={() => goToSlide(index)}\n ref={(el) =>\n (thumbnailRefs.current[index] = el)\n }\n >\n {src ? (\n <StatefulImage\n className={styles.thumbnailImage}\n src={src}\n alt={`Thumbnail ${index + 1}`}\n fit=\"cover\"\n />\n ) : (\n <ImagePlaceholder\n className={\n styles.slidePlaceholderImage\n }\n />\n )}\n </div>\n </div>\n );\n })}\n </div>\n </div>\n );\n };\n\n const renderTopActions = () => {\n return (\n <div\n className={styles.topActionButtons}\n ref={mergedTopBarRef}\n data-has-file-info={hasFileInfo}\n >\n {hasFileInfo && renderFileInfo()}\n\n {resolvedCustomActions.map((action, index) => (\n <ClickableIcon\n key={index}\n className={styles.iconButton}\n aria-label={action.ariaLabel}\n data-testid={action[\"data-testid\"]}\n onClick={() => handleCustomAction(action)}\n >\n {cloneElement(action.icon, { \"aria-hidden\": true })}\n </ClickableIcon>\n ))}\n\n {!hideMagnifier && !isCustomItem(currentItem) && (\n <ClickableIcon\n className={styles.iconButton}\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 </ClickableIcon>\n )}\n\n {onDelete && (\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.iconButtonError\n )}\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 </ClickableIcon>\n )}\n\n <ClickableIcon\n className={styles.iconButton}\n aria-label={\n hasAnyItemLabel\n ? \"Close carousel\"\n : \"Close image carousel\"\n }\n onClick={onClose}\n >\n <CrossIcon aria-hidden />\n </ClickableIcon>\n </div>\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 <div className={styles.carouselModalContent}>\n <div className={styles.imageGalleryContainer}>\n <div className={styles.imageGalleryWrapper}>\n <div\n className={styles.imageGallerySwipe}\n ref={containerRef}\n onTouchStart={handleTouchStart}\n onTouchMove={handleTouchMove}\n onTouchEnd={handleTouchEnd}\n >\n {renderSlides()}\n </div>\n\n {!hideNavigation && (\n <>\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.arrowButton,\n styles.arrowButtonLeft\n )}\n ref={prevArrowButtonRef}\n aria-label={`Previous ${carouselItemNoun}`}\n data-testid=\"prev-btn\"\n onClick={goToPrevSlide}\n >\n <ChevronLeftIcon aria-hidden />\n </ClickableIcon>\n <ClickableIcon\n className={clsx(\n styles.iconButton,\n styles.arrowButton,\n styles.arrowButtonRight\n )}\n ref={nextArrowButtonRef}\n aria-label={`Next ${carouselItemNoun}`}\n data-testid=\"forward-btn\"\n onClick={goToNextSlide}\n >\n <ChevronRightIcon aria-hidden />\n </ClickableIcon>\n </>\n )}\n\n {!hideCounter && (\n <div className={styles.boxChip} aria-hidden=\"true\">\n <Typography.BodyXS\n className={styles.chip}\n weight=\"semibold\"\n data-testid=\"carousel-counter\"\n >{`${currentSlide + 1}/${\n items.length\n }`}</Typography.BodyXS>\n </div>\n )}\n </div>\n\n {!hideThumbnail && renderThumbnails()}\n </div>\n {renderTopActions()}\n </div>\n </ModalV2>\n );\n};\n\n// @catalog\n/**\n * A fullscreen modal carousel for browsing images and custom media items.\n *\n * Use to present a collection of images or custom content in an overlay with\n * navigation controls, zoom support, and an optional thumbnail strip.\n * The top info bar is rendered only when at least one item provides some file metadata.\n * @keywords carousel, gallery, image, lightbox, media, overlay\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","topActionButtons","setTopActionButtons","topActionButtonsRef","useMemo","current","mergedTopBarRef","mergeRefs","prevArrowButtonRef","nextArrowButtonRef","thumbnailContainerRef","diff","currentItem","resolvedCustomActions","_c","_b","hasAnyItemLabel","some","itemLabel","trim","carouselItemNoun","hasFileInfo","fileName","fileSize","useApplyStyle","styles.tokens","insetTop","formatUnitValue","top","insetLeft","left","insetRight","right","arrowButton","thumbnailContainer","insetBottom","bottom","getItemAriaLabel","useCallback","index","itemTypeLabel","prefix","alt","positionLabel","length","useImperativeHandle","currentItemIndex","setCurrentItem","goToSlide","goToPrevItem","goToPrevSlide","goToNextItem","goToNextSlide","useEventListener","e","key","useEffect","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","className","clsx","styles.fileInfoTextWrapper","styles.fileInfoTextWrapperCentered","children","_jsx","Typography","BodyBL","styles.fileInfoFileName","weight","BodyMD","styles.fileInfoFileSize","ModalV2","disableInitialFocus","styles.carouselModalContent","styles.imageGalleryContainer","styles.imageGalleryWrapper","styles.imageGallerySwipe","onTouchStart","touches","clientX","onTouchMove","onTouchEnd","Math","abs","offsetWidth","undefined","styles.imageGallerySlides","style","transform","map","isActive","isActiveOrAdjacent","styles.imageGallerySlide","styles.focusableImageRegion","tabIndex","renderContent","ImagePlaceholder","styles.slidePlaceholderImage","TransformWrapper","el","panning","disabled","initialScale","onZoom","onZoomStop","onWheel","TransformComponent","StatefulImage","styles.slideImage","placeholder","fit","retrieveImageDimension","_Fragment","ClickableIcon","styles.iconButton","styles.arrowButton","styles.arrowButtonLeft","onClick","ChevronLeftIcon","styles.arrowButtonRight","ChevronRightIcon","styles.boxChip","BodyXS","styles.chip","styles.thumbnailContainer","styles.thumbnailWrapper","thumbnailSrc","styles.thumbnailItemContainer","styles.thumbnailItem","styles.thumbnailImage","styles.topActionButtons","action","ariaLabel","handleCustomAction","cloneElement","icon","MagnifierPlusIcon","MagnifierMinusIcon","styles.iconButtonError","BinIcon","CrossIcon","renderTopActions","FullscreenImageCarousel","forwardRef"],"mappings":"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"}
|
package/cjs/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("./accordion/accordion.js"),r=require("./alert/alert.js"),t=require("./animations/loading-dots/loading-dots.js"),i=require("./animations/loading-dots-spinner/loading-dots-spinner.js"),o=require("./animations/loading-spinner/loading-spinner.js"),s=require("./animations/themed-loading-spinner/themed-loading-spinner.js"),n=require("./avatar/avatar.js"),a=require("./badge/badge.js"),p=require("./box-container/box-container.js"),u=require("./breadcrumb/breadcrumb.js"),l=require("./button/button.js"),d=require("./calendar/calendar.js"),x=require("./card/card.js"),m=require("./checkbox/checkbox.js"),g=require("./countdown-timer/countdown-timer.js"),c=require("./dashed-border/dashed-border.js"),q=require("./data-table/data-table.js"),j=require("./date-input/date-input.js"),b=require("./date-navigator/date-navigator.js"),h=require("./date-range-input/date-range-input.js"),T=require("./divider/divider.js"),
|
|
1
|
+
"use strict";var e=require("./accordion/accordion.js"),r=require("./alert/alert.js"),t=require("./animations/loading-dots/loading-dots.js"),i=require("./animations/loading-dots-spinner/loading-dots-spinner.js"),o=require("./animations/loading-spinner/loading-spinner.js"),s=require("./animations/themed-loading-spinner/themed-loading-spinner.js"),n=require("./avatar/avatar.js"),a=require("./badge/badge.js"),p=require("./box-container/box-container.js"),u=require("./breadcrumb/breadcrumb.js"),l=require("./button/button.js"),d=require("./calendar/calendar.js"),x=require("./card/card.js"),m=require("./checkbox/checkbox.js"),g=require("./countdown-timer/countdown-timer.js"),c=require("./dashed-border/dashed-border.js"),q=require("./data-table/data-table.js"),j=require("./date-input/date-input.js"),b=require("./date-navigator/date-navigator.js"),h=require("./date-range-input/date-range-input.js"),T=require("./divider/divider.js"),S=require("./drawer/drawer.js"),k=require("./e-signature/e-signature.js"),v=require("./error-display/error-display.js"),I=require("./error-display/helper.js"),y=require("./feedback-rating/feedback-rating.js"),B=require("./file-download/file-download.js"),M=require("./file-upload/file-upload.js"),w=require("./filter/filter.js"),P=require("./footer/footer.js"),D=require("./form/index.js"),f=require("./fullscreen-image-carousel/fullscreen-image-carousel.js"),C=require("./histogram-slider/histogram-slider.js"),E=require("./image-button/image-button.js"),F=require("./input/input.js"),N=require("./input-group/input-group.js"),R=require("./input-multi-select/input-multi-select.js"),L=require("./input-nested-multi-select/input-nested-multi-select.js"),A=require("./input-nested-select/input-nested-select.js"),H=require("./input-range-select/input-range-select.js"),O=require("./input-range-slider/input-range-slider.js"),Q=require("./input-select/input-select.js"),U=require("./input-slider/input-slider.js"),V=require("./input-textarea/textarea.js"),W=require("./language-switcher/language-switcher.js"),_=require("./layout/index.js"),G=require("./link-list/link-list.js"),Y=require("./markup/markup.js"),z=require("./masked-input/masked-input.js"),J=require("./masthead/masthead.js"),K=require("./menu/menu.js"),X=require("./modal/index.js"),Z=require("./modal-v2/modal-v2.js"),$=require("./navbar/navbar.js"),ee=require("./notification-banner/notification-banner.js"),re=require("./notification-banner/notification-banner-hoc.js"),te=require("./otp-input/otp-input.js"),ie=require("./overlay/overlay.js"),oe=require("./pagination/pagination.js"),se=require("./phone-number-input/phone-number-input.js"),ne=require("./pill/pill.js"),ae=require("./popover/popover.js"),pe=require("./popover/popover-inline/popover-inline.js"),ue=require("./popover/popover-trigger.js"),le=require("./predictive-text-input/predictive-text-input.js"),de=require("./progress-indicator/progress-indicator.js"),xe=require("./radio-button/radio-button.js"),me=require("./select-histogram/select-histogram.js"),ge=require("./sidenav/sidenav.js"),ce=require("./singpass-button/singpass-button.js"),qe=require("./smart-app-banner/smart-app-banner.js"),je=require("./tab/tab.js"),be=require("./table/table.js"),he=require("./tag/tag.js"),Te=require("./text-list/index.js"),Se=require("./theme/theme-provider/index.js"),ke=require("./theme/theme-provider/hooks.js"),ve=require("./theme/tokens/border.js"),Ie=require("./theme/tokens/breakpoint.js"),ye=require("./theme/tokens/colour.js"),Be=require("./theme/tokens/component.js"),Me=require("./theme/tokens/font.js"),we=require("./theme/tokens/media-query.js"),Pe=require("./theme/tokens/motion.js"),De=require("./theme/tokens/radius.js"),fe=require("./theme/tokens/shadow.js"),Ce=require("./theme/tokens/spacing.js"),Ee=require("./theme/types.js"),Fe=require("./theme/utils/css-variable.js"),Ne=require("./theme/utils/use-apply-styles.js"),Re=require("./theme/utils/use-design-token.js"),Le=require("./theme/utils/use-media-query.js"),Ae=require("./time-range-picker/time-range-picker.js"),He=require("./time-slot-bar/time-slot-bar.js"),Oe=require("./time-slot-bar-week/time-slot-bar-week.js"),Qe=require("./time-slot-week-view/time-slot-week-view.js"),Ue=require("./timeline/timeline.js"),Ve=require("./timepicker/timepicker.js"),We=require("./timetable/timetable.js"),_e=require("./toast/toast.js"),Ge=require("./toggle/toggle.js"),Ye=require("./typography/index.js"),ze=require("./uneditable-section/index.js"),Je=require("./unit-number/unit-number-input.js");exports.Accordion=e.Accordion,exports.Alert=r.Alert,exports.LoadingDots=t.LoadingDots,exports.LoadingDotsSpinner=i.LoadingDotsSpinner,exports.LoadingSpinner=o.LoadingSpinner,exports.ThemedLoadingSpinner=s.ThemedLoadingSpinner,exports.Avatar=n.Avatar,exports.Badge=a.Badge,exports.BoxContainer=p.BoxContainer,exports.Breadcrumb=u.Breadcrumb,exports.Button=l.Button,exports.Calendar=d.Calendar,exports.Card=x.Card,exports.Checkbox=m.Checkbox,exports.CountdownTimer=g.CountdownTimer,exports.DashedBorder=c.DashedBorder,exports.DataTable=q.DataTable,exports.DateInput=j.DateInput,exports.DateNavigator=b.DateNavigator,exports.DateRangeInput=h.DateRangeInput,exports.Divider=T.Divider,exports.Drawer=S.Drawer,exports.ESignature=k.ESignature,exports.ErrorDisplay=v.ErrorDisplay,exports.ErrorDisplayHelper=I.ErrorDisplayHelper,exports.FeedbackRating=y.FeedbackRating,exports.FileDownload=B.FileDownload,exports.FileUpload=M.FileUpload,exports.Filter=w.Filter,exports.Footer=P.Footer,exports.Form=D.Form,exports.Component=f.Component,exports.FullscreenImageCarousel=f.FullscreenImageCarousel,exports.HistogramSlider=C.HistogramSlider,exports.ImageButton=E.ImageButton,exports.Input=F.Input,exports.InputGroup=N.InputGroup,exports.InputMultiSelect=R.InputMultiSelect,exports.InputNestedMultiSelect=L.InputNestedMultiSelect,exports.InputNestedSelect=A.InputNestedSelect,exports.InputRangeSelect=H.InputRangeSelect,exports.InputRangeSlider=O.InputRangeSlider,exports.InputSelect=Q.InputSelect,exports.InputSlider=U.InputSlider,exports.Textarea=V.Textarea,exports.LanguageSwitcher=W.LanguageSwitcher,exports.Layout=_.Layout,exports.LinkList=G.LinkList,exports.Markup=Y.Markup,exports.MaskedInput=z.MaskedInput,exports.Masthead=J.Masthead,exports.Menu=K.Menu,exports.MenuTrigger=K.MenuTrigger,exports.Modal=X.Modal,exports.ModalV2=Z.ModalV2,exports.Navbar=$.Navbar,exports.NBComponent=ee.NBComponent,exports.NotificationBanner=ee.NotificationBanner,exports.withNotificationBanner=re.withNotificationBanner,exports.OtpInput=te.OtpInput,exports.Overlay=ie.Overlay,exports.Pagination=oe.Pagination,exports.PhoneNumberInput=se.PhoneNumberInput,exports.Pill=ne.Pill,exports.Popover=ae.Popover,exports.PopoverInline=pe.PopoverInline,exports.PopoverTrigger=ue.PopoverTrigger,exports.PredictiveTextInput=le.PredictiveTextInput,exports.ProgressIndicator=de.ProgressIndicator,exports.RadioButton=xe.RadioButton,exports.SelectHistogram=me.SelectHistogram,exports.Sidenav=ge.Sidenav,exports.SingpassButton=ce.SingpassButton,exports.SmartAppBanner=qe.SmartAppBanner,exports.Tab=je.Tab,exports.Table=be.Table,exports.Tag=he.Tag,exports.TextList=Te.TextList,exports.ThemeProvider=Se.ThemeProvider,exports.useInheritedThemeScope=ke.useInheritedThemeScope,exports.useTheme=ke.useTheme,exports.Border=ve.Border,exports.BorderStyle=ve.BorderStyle,exports.BorderThickness=ve.BorderThickness,exports.Breakpoint=Ie.Breakpoint,exports.Colour=ye.Colour,exports.PrimitiveColours=ye.PrimitiveColours,exports.SemanticColours=ye.SemanticColours,exports.ComponentToken=Be.ComponentToken,exports.Font=Me.Font,exports.FontSpec=Me.FontSpec,exports.MediaQuery=we.MediaQuery,exports.Motion=Pe.Motion,exports.Radius=De.Radius,exports.Shadow=fe.Shadow,exports.Spacing=Ce.Spacing,exports.THEME_FONT_PRESETS=Ee.THEME_FONT_PRESETS,exports.THEME_TYPES=Ee.THEME_TYPES,exports.formatUnitValue=Fe.formatUnitValue,exports.parsePxOrRemValue=Fe.parsePxOrRemValue,exports.useApplyStyle=Ne.useApplyStyle,exports.useDesignToken=Re.useDesignToken,exports.useMaxWidthMediaQuery=Le.useMaxWidthMediaQuery,exports.useMediaQuery=Le.useMediaQuery,exports.useMinWidthMediaQuery=Le.useMinWidthMediaQuery,exports.useResolvedBreakpointToken=Le.useResolvedBreakpointToken,exports.TimeRangePicker=Ae.TimeRangePicker,exports.TimeSlotBar=He.TimeSlotBar,exports.TimeSlotBarWeek=Oe.TimeSlotBarWeek,exports.TimeSlotWeekView=Qe.TimeSlotWeekView,exports.Timeline=Ue.Timeline,exports.Timepicker=Ve.Timepicker,exports.TimeTable=We.TimeTable,exports.Toast=_e.Toast,exports.Toggle=Ge.Toggle,exports.Typography=Ye.Typography,exports.UneditableSection=ze.UneditableSection,exports.UnitNumberInput=Je.UnitNumberInput;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";const
|
|
1
|
+
"use strict";const s={primary:{brandName:"LifeSG",logoSrc:"https://assets.life.gov.sg/lifesg/logo-lifesg.svg"}},e={primary:{brandName:"BookingSG",logoSrc:"https://www.booking.gov.sg/logo.svg"}},o={primary:{brandName:"CCube",logoSrc:"https://assets.life.gov.sg/ccube/logo-ccube.svg"}},g={primary:{brandName:"IMDA",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/imda-logo.svg"}},r={primary:{brandName:"MyLegacy",logoSrc:"https://mylegacy.life.gov.sg/images/site-logo.png"}},t={primary:{brandName:"SPF",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/spf-logo.png"}},a={primary:{brandName:"SportSG",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/sportsg-logo.svg"}},i={primary:{brandName:"SupportGoWhere",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/sgw-logo.png"}},l={primary:{brandName:"Tote Board",logoSrc:"https://assets.life.gov.sg/react-design-system/img/logo/tote-board-logo.svg"}};exports.getDefaultResourceLogo=c=>{switch(c){case"bookingsg":return e;case"mylegacy":return r;case"ccube":return o;case"spf":return t;case"supportgowhere":case"sgw-digital-lobby":return i;case"imda":return g;case"tote-board":return l;case"sportsg-orange":return a;default:return s}};
|
|
2
2
|
//# sourceMappingURL=navbar-logo-data.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"navbar-logo-data.js","sources":["../../../src/navbar/navbar-logo-data.ts"],"sourcesContent":["import type { ThemeType } from \"../theme/types\";\nimport type { NavbarResourcesProps } from \"./types\";\n\nconst DEFAULT_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"LifeSG\",\n logoSrc: \"https://assets.life.gov.sg/lifesg/logo-lifesg.svg\",\n },\n};\n\nconst BOOKINGSG_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"BookingSG\",\n logoSrc: \"https://www.booking.gov.sg/logo.svg\",\n },\n};\n\nconst CCUBE_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"CCube\",\n logoSrc: \"https://assets.life.gov.sg/ccube/logo-ccube.svg\",\n },\n};\n\nconst IMDA_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"IMDA\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/imda-logo.svg\",\n },\n};\n\nconst MYLEGACY_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"MyLegacy\",\n logoSrc: \"https://mylegacy.life.gov.sg/images/site-logo.png\",\n },\n};\n\nconst SPF_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"SPF\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/spf-logo.png\",\n },\n};\n\nconst SUPPORTGOWHERE_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"SupportGoWhere\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/sgw-logo.png\",\n },\n};\n\nconst TOTEBOARD_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"Tote Board\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/tote-board-logo.svg\",\n },\n};\n\nexport const getDefaultResourceLogo = (resourceScheme?: ThemeType) => {\n switch (resourceScheme) {\n case \"bookingsg\":\n return BOOKINGSG_RESOURCES_LOGO;\n case \"mylegacy\":\n return MYLEGACY_RESOURCES_LOGO;\n case \"ccube\":\n return CCUBE_RESOURCES_LOGO;\n case \"spf\":\n return SPF_RESOURCE_LOGO;\n case \"supportgowhere\":\n case \"sgw-digital-lobby\":\n return SUPPORTGOWHERE_RESOURCE_LOGO;\n case \"imda\":\n return IMDA_RESOURCE_LOGO;\n case \"tote-board\":\n return TOTEBOARD_RESOURCES_LOGO;\n default:\n return DEFAULT_RESOURCES_LOGO;\n }\n};\n"],"names":["DEFAULT_RESOURCES_LOGO","primary","brandName","logoSrc","BOOKINGSG_RESOURCES_LOGO","CCUBE_RESOURCES_LOGO","IMDA_RESOURCE_LOGO","MYLEGACY_RESOURCES_LOGO","SPF_RESOURCE_LOGO","SUPPORTGOWHERE_RESOURCE_LOGO","TOTEBOARD_RESOURCES_LOGO","resourceScheme"],"mappings":"aAGA,MAAMA,EAA+C,CACjDC,QAAS,CACLC,UAAW,SACXC,QAAS,sDAIXC,EAAiD,CACnDH,QAAS,CACLC,UAAW,YACXC,QAAS,wCAIXE,EAA6C,CAC/CJ,QAAS,CACLC,UAAW,QACXC,QAAS,oDAIXG,EAA2C,CAC7CL,QAAS,CACLC,UAAW,OACXC,QACI,0EAINI,EAAgD,CAClDN,QAAS,CACLC,UAAW,WACXC,QAAS,sDAIXK,EAA0C,CAC5CP,QAAS,CACLC,UAAW,MACXC,QACI,yEAINM,EAAqD,
|
|
1
|
+
{"version":3,"file":"navbar-logo-data.js","sources":["../../../src/navbar/navbar-logo-data.ts"],"sourcesContent":["import type { ThemeType } from \"../theme/types\";\nimport type { NavbarResourcesProps } from \"./types\";\n\nconst DEFAULT_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"LifeSG\",\n logoSrc: \"https://assets.life.gov.sg/lifesg/logo-lifesg.svg\",\n },\n};\n\nconst BOOKINGSG_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"BookingSG\",\n logoSrc: \"https://www.booking.gov.sg/logo.svg\",\n },\n};\n\nconst CCUBE_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"CCube\",\n logoSrc: \"https://assets.life.gov.sg/ccube/logo-ccube.svg\",\n },\n};\n\nconst IMDA_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"IMDA\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/imda-logo.svg\",\n },\n};\n\nconst MYLEGACY_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"MyLegacy\",\n logoSrc: \"https://mylegacy.life.gov.sg/images/site-logo.png\",\n },\n};\n\nconst SPF_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"SPF\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/spf-logo.png\",\n },\n};\n\nconst SPORTSG_ORANGE_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"SportSG\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/sportsg-logo.svg\",\n },\n};\n\nconst SUPPORTGOWHERE_RESOURCE_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"SupportGoWhere\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/sgw-logo.png\",\n },\n};\n\nconst TOTEBOARD_RESOURCES_LOGO: NavbarResourcesProps = {\n primary: {\n brandName: \"Tote Board\",\n logoSrc:\n \"https://assets.life.gov.sg/react-design-system/img/logo/tote-board-logo.svg\",\n },\n};\n\nexport const getDefaultResourceLogo = (resourceScheme?: ThemeType) => {\n switch (resourceScheme) {\n case \"bookingsg\":\n return BOOKINGSG_RESOURCES_LOGO;\n case \"mylegacy\":\n return MYLEGACY_RESOURCES_LOGO;\n case \"ccube\":\n return CCUBE_RESOURCES_LOGO;\n case \"spf\":\n return SPF_RESOURCE_LOGO;\n case \"supportgowhere\":\n case \"sgw-digital-lobby\":\n return SUPPORTGOWHERE_RESOURCE_LOGO;\n case \"imda\":\n return IMDA_RESOURCE_LOGO;\n case \"tote-board\":\n return TOTEBOARD_RESOURCES_LOGO;\n case \"sportsg-orange\":\n return SPORTSG_ORANGE_RESOURCES_LOGO;\n default:\n return DEFAULT_RESOURCES_LOGO;\n }\n};\n"],"names":["DEFAULT_RESOURCES_LOGO","primary","brandName","logoSrc","BOOKINGSG_RESOURCES_LOGO","CCUBE_RESOURCES_LOGO","IMDA_RESOURCE_LOGO","MYLEGACY_RESOURCES_LOGO","SPF_RESOURCE_LOGO","SPORTSG_ORANGE_RESOURCES_LOGO","SUPPORTGOWHERE_RESOURCE_LOGO","TOTEBOARD_RESOURCES_LOGO","resourceScheme"],"mappings":"aAGA,MAAMA,EAA+C,CACjDC,QAAS,CACLC,UAAW,SACXC,QAAS,sDAIXC,EAAiD,CACnDH,QAAS,CACLC,UAAW,YACXC,QAAS,wCAIXE,EAA6C,CAC/CJ,QAAS,CACLC,UAAW,QACXC,QAAS,oDAIXG,EAA2C,CAC7CL,QAAS,CACLC,UAAW,OACXC,QACI,0EAINI,EAAgD,CAClDN,QAAS,CACLC,UAAW,WACXC,QAAS,sDAIXK,EAA0C,CAC5CP,QAAS,CACLC,UAAW,MACXC,QACI,yEAINM,EAAsD,CACxDR,QAAS,CACLC,UAAW,UACXC,QACI,6EAINO,EAAqD,CACvDT,QAAS,CACLC,UAAW,iBACXC,QACI,yEAINQ,EAAiD,CACnDV,QAAS,CACLC,UAAW,aACXC,QACI,+GAI2BS,IACnC,OAAQA,GACJ,IAAK,YACD,OAAOR,EACX,IAAK,WACD,OAAOG,EACX,IAAK,QACD,OAAOF,EACX,IAAK,MACD,OAAOG,EACX,IAAK,iBACL,IAAK,oBACD,OAAOE,EACX,IAAK,OACD,OAAOJ,EACX,IAAK,aACD,OAAOK,EACX,IAAK,iBACD,OAAOF,EACX,QACI,OAAOT"}
|
package/cjs/theme/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("./theme-provider/index.js"),r=require("./theme-provider/hooks.js"),s=require("./tokens/border.js"),o=require("./tokens/breakpoint.js"),t=require("./tokens/colour.js"),i=require("./tokens/component.js"),u=require("./tokens/font.js"),
|
|
1
|
+
"use strict";var e=require("./theme-provider/index.js"),r=require("./theme-provider/hooks.js"),s=require("./tokens/border.js"),o=require("./tokens/breakpoint.js"),t=require("./tokens/colour.js"),i=require("./tokens/component.js"),u=require("./tokens/font.js"),p=require("./tokens/media-query.js"),n=require("./tokens/motion.js"),a=require("./tokens/radius.js"),d=require("./tokens/shadow.js"),x=require("./tokens/spacing.js"),l=require("./types.js"),k=require("./utils/css-variable.js"),T=require("./utils/use-apply-styles.js"),m=require("./utils/use-design-token.js"),h=require("./utils/use-media-query.js");exports.ThemeProvider=e.ThemeProvider,exports.useInheritedThemeScope=r.useInheritedThemeScope,exports.useTheme=r.useTheme,exports.Border=s.Border,exports.BorderStyle=s.BorderStyle,exports.BorderThickness=s.BorderThickness,exports.Breakpoint=o.Breakpoint,exports.Colour=t.Colour,exports.PrimitiveColours=t.PrimitiveColours,exports.SemanticColours=t.SemanticColours,exports.ComponentToken=i.ComponentToken,exports.Font=u.Font,exports.FontSpec=u.FontSpec,exports.MediaQuery=p.MediaQuery,exports.Motion=n.Motion,exports.Radius=a.Radius,exports.Shadow=d.Shadow,exports.Spacing=x.Spacing,exports.THEME_FONT_PRESETS=l.THEME_FONT_PRESETS,exports.THEME_TYPES=l.THEME_TYPES,exports.formatUnitValue=k.formatUnitValue,exports.parsePxOrRemValue=k.parsePxOrRemValue,exports.useApplyStyle=T.useApplyStyle,exports.useDesignToken=m.useDesignToken,exports.useMaxWidthMediaQuery=h.useMaxWidthMediaQuery,exports.useMediaQuery=h.useMediaQuery,exports.useMinWidthMediaQuery=h.useMinWidthMediaQuery,exports.useResolvedBreakpointToken=h.useResolvedBreakpointToken;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/cjs/theme/types.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";exports.THEME_TYPES=["a11y-playground","bookingsg","careercompass","ccube","imda","lifesg","mylegacy","oneservice","pa","rbs","sgw-digital-lobby","smgs","spf","supportgowhere","tote-board","vica","websg","wise","wogaa"];
|
|
1
|
+
"use strict";exports.THEME_FONT_PRESETS=["wise-public","wise-admin","sportsg-gms"],exports.THEME_TYPES=["a11y-playground","bookingsg","careercompass","ccube","imda","lifesg","mylegacy","oneservice","pa","rbs","sgw-digital-lobby","smgs","spf","sportsg-orange","supportgowhere","tote-board","vica","websg","wise","wogaa"];
|
|
2
2
|
//# sourceMappingURL=types.js.map
|
package/cjs/theme/types.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.js","sources":["../../../src/theme/types.ts"],"sourcesContent":["import type { ValueOf } from \"../util/utility-types\";\nimport type {\n Border,\n Breakpoint,\n ComponentToken,\n FontSpec,\n Motion,\n PrimitiveColours,\n Radius,\n SemanticColours,\n Shadow,\n Spacing,\n} from \"./tokens\";\n\n/** All available theme names. */\nexport const THEME_TYPES = [\n \"a11y-playground\",\n \"bookingsg\",\n \"careercompass\",\n \"ccube\",\n \"imda\",\n \"lifesg\",\n \"mylegacy\",\n \"oneservice\",\n \"pa\",\n \"rbs\",\n \"sgw-digital-lobby\",\n \"smgs\",\n \"spf\",\n \"supportgowhere\",\n \"tote-board\",\n \"vica\",\n \"websg\",\n \"wise\",\n \"wogaa\",\n] as const;\n\n/** Union of all supported theme names. */\nexport type ThemeType = (typeof THEME_TYPES)[number];\n\n
|
|
1
|
+
{"version":3,"file":"types.js","sources":["../../../src/theme/types.ts"],"sourcesContent":["import type { ValueOf } from \"../util/utility-types\";\nimport type {\n Border,\n Breakpoint,\n ComponentToken,\n FontSpec,\n Motion,\n PrimitiveColours,\n Radius,\n SemanticColours,\n Shadow,\n Spacing,\n} from \"./tokens\";\n\n/** All available theme names. */\nexport const THEME_TYPES = [\n \"a11y-playground\",\n \"bookingsg\",\n \"careercompass\",\n \"ccube\",\n \"imda\",\n \"lifesg\",\n \"mylegacy\",\n \"oneservice\",\n \"pa\",\n \"rbs\",\n \"sgw-digital-lobby\",\n \"smgs\",\n \"spf\",\n \"sportsg-orange\",\n \"supportgowhere\",\n \"tote-board\",\n \"vica\",\n \"websg\",\n \"wise\",\n \"wogaa\",\n] as const;\n\n/** Union of all supported theme names. */\nexport type ThemeType = (typeof THEME_TYPES)[number];\n\n/**\n * All available theme presets.\n * For WISE product themes: wise, vica, websg, wogaa\n * For SportSG product themes: sportsg-orange\n * */\nexport const THEME_FONT_PRESETS = [\n \"wise-public\",\n \"wise-admin\",\n \"sportsg-gms\",\n] as const;\n\n/** Union of all supported font presets. */\nexport type ThemeFontPreset = (typeof THEME_FONT_PRESETS)[number];\n\n/**\n * Colour mode accepted by `ThemeProvider`.\n * — `\"auto\"` follows OS preference.\n * - `\"light\"` light mode.\n * - `\"dark\"` dark mode.\n */\nexport type ThemeMode = \"light\" | \"dark\" | \"auto\";\n\n/** Resolved colour mode. */\nexport type ResolvedThemeMode = \"light\" | \"dark\";\n\n/** Available typography size presets. */\nexport type FontSize =\n | \"heading-xxl\"\n | \"heading-xl\"\n | \"heading-lg\"\n | \"heading-md\"\n | \"heading-sm\"\n | \"heading-xs\"\n | \"body-baseline\"\n | \"body-md\"\n | \"body-sm\"\n | \"body-xs\"\n | \"form-label\"\n | \"form-description\";\n\n/** Available typography weight presets. */\nexport type FontWeight = \"light\" | \"regular\" | \"semibold\" | \"bold\";\n\n/** Accepted breakpoint CSS variable strings. */\nexport type BreakpointCSSVariableString = ValueOf<typeof Breakpoint>;\n/** Accepted border CSS variable strings. */\nexport type BorderCSSVariableString = ValueOf<typeof Border>;\n/** Accepted component-scoped CSS variable strings. */\nexport type ComponentTokenCSSVariableString =\n | ValueOf<typeof ComponentToken.Animation>\n | ValueOf<typeof ComponentToken.Button>\n | ValueOf<typeof ComponentToken.Footer>\n | ValueOf<typeof ComponentToken.Navbar>;\n/** Accepted font CSS variable strings. */\nexport type FontSpecCSSVariableString = ValueOf<typeof FontSpec>;\n/** Accepted motion CSS variable strings. */\nexport type MotionCSSVariableString = ValueOf<typeof Motion>;\n/** Accepted primitive colour CSS variable strings. */\nexport type PrimitiveColourCSSVariableString = ValueOf<typeof PrimitiveColours>;\n/** Accepted radius CSS variable strings. */\nexport type RadiusCSSVariableString = ValueOf<typeof Radius>;\n/** Accepted semantic colour CSS variable strings. */\nexport type SemanticColourCSSVariableString = ValueOf<typeof SemanticColours>;\n/** Accepted colour CSS variable strings. */\nexport type ColourCSSVariableString =\n | PrimitiveColourCSSVariableString\n | SemanticColourCSSVariableString;\n/** Accepted shadow CSS variable strings. */\nexport type ShadowCSSVariableString = ValueOf<typeof Shadow>;\n/** Accepted spacing and layout CSS variable strings. */\nexport type SpacingCSSVariableString = ValueOf<typeof Spacing>;\n\n/** Union of all design-token CSS variable string literals. */\nexport type CSSVariableString =\n | BreakpointCSSVariableString\n | BorderCSSVariableString\n | ColourCSSVariableString\n | ComponentTokenCSSVariableString\n | FontSpecCSSVariableString\n | MotionCSSVariableString\n | RadiusCSSVariableString\n | ShadowCSSVariableString\n | SpacingCSSVariableString;\n"],"names":[],"mappings":"wCA8CkC,CAC9B,cACA,aACA,mCAlCuB,CACvB,kBACA,YACA,gBACA,QACA,OACA,SACA,WACA,aACA,KACA,MACA,oBACA,OACA,MACA,iBACA,iBACA,aACA,OACA,QACA,OACA"}
|
|
@@ -6,4 +6,4 @@ import type { FileDownloadProps } from "./types";
|
|
|
6
6
|
* Each file item renders as a card with file metadata and a download trigger.
|
|
7
7
|
* @keywords attachment, document, download, file
|
|
8
8
|
*/
|
|
9
|
-
export declare const FileDownload: ({ id, fileItems, title, description, onDownload, "data-testid": testId, className, styleType, }: FileDownloadProps) => import("react/jsx-runtime").JSX.Element;
|
|
9
|
+
export declare const FileDownload: ({ id, fileItems, title, description, onDownload, onClick, "data-testid": testId, className, styleType, }: FileDownloadProps) => import("react/jsx-runtime").JSX.Element;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__awaiter as e}from"../_virtual/_tslib.js";import{jsxs as r,jsx as t}from"react/jsx-runtime";import i from"clsx";import{DashedBorder as o}from"../dashed-border/dashed-border.js";import{Markup as s}from"../markup/markup.js";import"../theme/theme-provider/index.js";import"react";import"../theme/theme-provider/context.js";import{Border as m}from"../theme/tokens/border.js";import{Colour as d}from"../theme/tokens/colour.js";import"../theme/tokens/font.js";import"../theme/tokens/media-query.js";import{Radius as l}from"../theme/tokens/radius.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import"../theme/utils/use-media-query.js";import{textContainer as a,listWrapper as n,container as p,containerBordered as c,title as h,titleContainer as f,description as u,descriptionContainer as j}from"./file-download.styles.js";import{FileListCard as b}from"./file-list-card/file-list-card.js";const y=({id:y,fileItems:
|
|
1
|
+
import{__awaiter as e}from"../_virtual/_tslib.js";import{jsxs as r,jsx as t}from"react/jsx-runtime";import i from"clsx";import{DashedBorder as o}from"../dashed-border/dashed-border.js";import{Markup as s}from"../markup/markup.js";import"../theme/theme-provider/index.js";import"react";import"../theme/theme-provider/context.js";import{Border as m}from"../theme/tokens/border.js";import{Colour as d}from"../theme/tokens/colour.js";import"../theme/tokens/font.js";import"../theme/tokens/media-query.js";import{Radius as l}from"../theme/tokens/radius.js";import"../util/calendar-helper.js";import"../external/dayjs/dayjs.min.js";import"../util/simple-id-generator.js";import"../util/string-helper.js";import"@react-aria/live-announcer";import"../theme/utils/use-media-query.js";import{textContainer as a,listWrapper as n,container as p,containerBordered as c,title as h,titleContainer as f,description as u,descriptionContainer as j}from"./file-download.styles.js";import{FileListCard as b}from"./file-list-card/file-list-card.js";const y=({id:y,fileItems:k,title:x,description:v,onDownload:N,onClick:g,"data-testid":w,className:T,styleType:q="bordered"})=>{const z=r=>e(void 0,void 0,void 0,(function*(){N&&(yield N(r))})),C="bordered"===q;return r(o,{id:y?`${y}-file-download`:"file-download",className:i(p,C&&c,T),"data-testid":w,enabled:C,thickness:m["width-040"],radius:l.sm,colour:d.border,children:[(x||v)&&r("div",{className:a,children:[x?"string"==typeof x?t("p",{className:h,children:x}):t(s,{className:f,baseTextSize:"heading-xs",children:x}):null,v?"string"==typeof v?t("p",{className:u,children:v}):t(s,{className:j,baseTextSize:"body-md",children:v}):null]}),t("ul",{className:n,children:k&&k.length>0&&k.map((e=>t(b,{fileItem:e,onDownload:z,onClick:g},e.id)))})]})};export{y as FileDownload};
|
|
2
2
|
//# sourceMappingURL=file-download.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-download.js","sources":["../../src/file-download/file-download.tsx"],"sourcesContent":["import clsx from \"clsx\";\n\nimport { DashedBorder } from \"../dashed-border\";\nimport { Markup } from \"../markup\";\nimport { Border, Colour, Radius } from \"../theme\";\nimport * as styles from \"./file-download.styles\";\nimport { FileListCard } from \"./file-list-card\";\nimport type { FileDownloadProps, FileItemDownloadProps } from \"./types\";\n\n// @catalog\n/**\n * Displays a list of downloadable files, optionally grouped under a title and description.\n *\n * Use `FileDownload` to present one or more files that users can download individually.\n * Each file item renders as a card with file metadata and a download trigger.\n * @keywords attachment, document, download, file\n */\nexport const FileDownload = ({\n id,\n fileItems,\n title,\n description,\n onDownload,\n \"data-testid\": testId,\n className,\n styleType = \"bordered\",\n}: FileDownloadProps) => {\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleDownloadItem = async (item: FileItemDownloadProps) => {\n if (onDownload) {\n await onDownload(item);\n }\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderTitle = () => {\n if (!title) {\n return null;\n }\n\n if (typeof title === \"string\") {\n return <p className={styles.title}>{title}</p>;\n }\n\n return (\n <Markup className={styles.titleContainer} baseTextSize=\"heading-xs\">\n {title}\n </Markup>\n );\n };\n\n const renderDescription = () => {\n if (!description) {\n return null;\n }\n\n if (typeof description === \"string\") {\n return <p className={styles.description}>{description}</p>;\n }\n\n return (\n <Markup\n className={styles.descriptionContainer}\n baseTextSize=\"body-md\"\n >\n {description}\n </Markup>\n );\n };\n\n const isBordered = styleType === \"bordered\";\n\n return (\n <DashedBorder\n id={id ? `${id}-file-download` : \"file-download\"}\n className={clsx(\n styles.container,\n isBordered && styles.containerBordered,\n className\n )}\n data-testid={testId}\n enabled={isBordered}\n thickness={Border[\"width-040\"]}\n radius={Radius[\"sm\"]}\n colour={Colour[\"border\"]}\n >\n {(title || description) && (\n <div className={styles.textContainer}>\n {renderTitle()}\n {renderDescription()}\n </div>\n )}\n <ul className={styles.listWrapper}>\n {fileItems &&\n fileItems.length > 0 &&\n fileItems.map((item) => (\n <FileListCard\n key={item.id}\n fileItem={item}\n onDownload={handleDownloadItem}\n />\n ))}\n </ul>\n </DashedBorder>\n );\n};\n"],"names":["FileDownload","id","fileItems","title","description","onDownload","testId","className","styleType","handleDownloadItem","item","__awaiter","isBordered","_jsxs","DashedBorder","clsx","styles.container","styles.containerBordered","enabled","thickness","Border","radius","Radius","colour","Colour","children","styles.textContainer","_jsx","styles.title","Markup","styles.titleContainer","baseTextSize","styles.description","styles.descriptionContainer","styles.listWrapper","length","map","FileListCard","fileItem"],"mappings":"ogCAiBO,MAAMA,EAAe,EACxBC,KACAC,YAASC,MACTA,EAAKC,YACLA,EACAC,
|
|
1
|
+
{"version":3,"file":"file-download.js","sources":["../../src/file-download/file-download.tsx"],"sourcesContent":["import clsx from \"clsx\";\n\nimport { DashedBorder } from \"../dashed-border\";\nimport { Markup } from \"../markup\";\nimport { Border, Colour, Radius } from \"../theme\";\nimport * as styles from \"./file-download.styles\";\nimport { FileListCard } from \"./file-list-card\";\nimport type { FileDownloadProps, FileItemDownloadProps } from \"./types\";\n\n// @catalog\n/**\n * Displays a list of downloadable files, optionally grouped under a title and description.\n *\n * Use `FileDownload` to present one or more files that users can download individually.\n * Each file item renders as a card with file metadata and a download trigger.\n * @keywords attachment, document, download, file\n */\nexport const FileDownload = ({\n id,\n fileItems,\n title,\n description,\n onDownload,\n onClick,\n \"data-testid\": testId,\n className,\n styleType = \"bordered\",\n}: FileDownloadProps) => {\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleDownloadItem = async (item: FileItemDownloadProps) => {\n if (onDownload) {\n await onDownload(item);\n }\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderTitle = () => {\n if (!title) {\n return null;\n }\n\n if (typeof title === \"string\") {\n return <p className={styles.title}>{title}</p>;\n }\n\n return (\n <Markup className={styles.titleContainer} baseTextSize=\"heading-xs\">\n {title}\n </Markup>\n );\n };\n\n const renderDescription = () => {\n if (!description) {\n return null;\n }\n\n if (typeof description === \"string\") {\n return <p className={styles.description}>{description}</p>;\n }\n\n return (\n <Markup\n className={styles.descriptionContainer}\n baseTextSize=\"body-md\"\n >\n {description}\n </Markup>\n );\n };\n\n const isBordered = styleType === \"bordered\";\n\n return (\n <DashedBorder\n id={id ? `${id}-file-download` : \"file-download\"}\n className={clsx(\n styles.container,\n isBordered && styles.containerBordered,\n className\n )}\n data-testid={testId}\n enabled={isBordered}\n thickness={Border[\"width-040\"]}\n radius={Radius[\"sm\"]}\n colour={Colour[\"border\"]}\n >\n {(title || description) && (\n <div className={styles.textContainer}>\n {renderTitle()}\n {renderDescription()}\n </div>\n )}\n <ul className={styles.listWrapper}>\n {fileItems &&\n fileItems.length > 0 &&\n fileItems.map((item) => (\n <FileListCard\n key={item.id}\n fileItem={item}\n onDownload={handleDownloadItem}\n onClick={onClick}\n />\n ))}\n </ul>\n </DashedBorder>\n );\n};\n"],"names":["FileDownload","id","fileItems","title","description","onDownload","onClick","testId","className","styleType","handleDownloadItem","item","__awaiter","isBordered","_jsxs","DashedBorder","clsx","styles.container","styles.containerBordered","enabled","thickness","Border","radius","Radius","colour","Colour","children","styles.textContainer","_jsx","styles.title","Markup","styles.titleContainer","baseTextSize","styles.description","styles.descriptionContainer","styles.listWrapper","length","map","FileListCard","fileItem"],"mappings":"ogCAiBO,MAAMA,EAAe,EACxBC,KACAC,YAASC,MACTA,EAAKC,YACLA,EACAC,aACAC,UACA,cAAeC,EACfC,YACAC,YAAY,eAKZ,MAAMC,EAA4BC,GAA+BC,OAAA,OAAA,OAAA,GAAA,YACzDP,UACMA,EAAWM,GAEzB,IAwCME,EAA2B,aAAdJ,EAEnB,OACIK,EAACC,GACGd,GAAIA,EAAK,GAAGA,kBAAqB,gBACjCO,UAAWQ,EACPC,EACAJ,GAAcK,EACdV,GACH,cACYD,EACbY,QAASN,EACTO,UAAWC,EAAO,aAClBC,OAAQC,EAAW,GACnBC,OAAQC,EAAe,OAACC,SAAA,EAEtBvB,GAASC,IACPU,SAAKN,UAAWmB,YAnDnBxB,EAIgB,iBAAVA,EACAyB,EAAA,IAAA,CAAGpB,UAAWqB,EAAYH,SAAGvB,IAIpCyB,EAACE,EAAM,CAACtB,UAAWuB,EAAuBC,aAAa,sBAClD7B,IATE,KAeNC,EAIsB,iBAAhBA,EACAwB,EAAA,IAAA,CAAGpB,UAAWyB,EAAkBP,SAAGtB,IAI1CwB,EAACE,EAAM,CACHtB,UAAW0B,EACXF,aAAa,mBAEZ5B,IAZE,QAuCPwB,QAAIpB,UAAW2B,WACVjC,GACGA,EAAUkC,OAAS,GACnBlC,EAAUmC,KAAK1B,GACXiB,EAACU,EAAY,CAETC,SAAU5B,EACVN,WAAYK,EACZJ,QAASA,GAHJK,EAAKV,UAOf"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
import type { FileListItemProps } from "./types";
|
|
2
|
-
export declare const FileListCard: import("react").MemoExoticComponent<({ fileItem, onDownload }: FileListItemProps) => import("react/jsx-runtime").JSX.Element>;
|
|
2
|
+
export declare const FileListCard: import("react").MemoExoticComponent<({ fileItem, onDownload, onClick }: FileListItemProps) => import("react/jsx-runtime").JSX.Element>;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{__awaiter as e}from"../../_virtual/_tslib.js";import{jsx as
|
|
1
|
+
import{__awaiter as e}from"../../_virtual/_tslib.js";import{jsx as t,jsxs as i,Fragment as r}from"react/jsx-runtime";import{DownloadIcon as a}from"@lifesg/react-icons";import{ExclamationCircleFillIcon as l}from"@lifesg/react-icons/exclamation-circle-fill";import o from"clsx";import{memo as s,useState as n,useRef as m,useEffect as c}from"react";import{Button as d}from"../../button/button.js";import{FileUploadHelper as p}from"../../file-upload/helper.js";import{VisuallyHidden as h}from"../../shared/accessibility/index.js";import{ImageWithFallback as u}from"../../shared/image-with-fallback/image-with-fallback.js";import"../../theme/theme-provider/index.js";import"../../theme/theme-provider/context.js";import"../../theme/tokens/border.js";import"../../theme/tokens/colour.js";import"../../theme/tokens/font.js";import"../../theme/tokens/media-query.js";import"../../util/calendar-helper.js";import"../../external/dayjs/dayjs.min.js";import"../../util/simple-id-generator.js";import{StringHelper as f}from"../../util/string-helper.js";import"@react-aria/live-announcer";import{useMaxWidthMediaQuery as y}from"../../theme/utils/use-media-query.js";import{item as b,box as j,boxError as g,extendedNameSection as v,contentSection as N,contentSectionHasThumbnail as k,cardButton as w,actionContainer as x,iconButton as C,thumbnailContainer as T,thumbnail as D,thumbnailPdf as $,nameSection as _,fileSizeSection as z,mobileErrorMessage as I,errorIcon as L,itemNameText as P,desktopErrorMessage as S}from"./file-list-card.styles.js";const q=s((({fileItem:s,onDownload:q,onClick:F})=>{const{id:R,name:U,mimeType:B,size:M,errorMessage:O,thumbnailImageDataUrl:A,truncateText:E=!0,ready:G=!0,clickLabel:H}=s,[J,K]=n(!1),[Q,V]=n(!1),W=p.formatFileSizeDisplay(M),X=p.resolveThumbnailDisplay(B,A),Y="none"!==X.type,Z=y("sm"),[ee,te]=n(),ie=m(null);c((()=>{ie.current&&te(Z?se(U):U)}),[U,Z]);const re=()=>e(void 0,void 0,void 0,(function*(){if(G&&!J){K(!0);try{V(!1),yield q(s)}catch(e){V(!0)}finally{K(!1)}}})),ae=()=>{G&&(F?F(s):re())},le=e=>{e.stopPropagation(),ae()},oe=e=>{e.stopPropagation(),re()},se=e=>{if(!E)return e;const t=ie&&ie.current?ie.current.getBoundingClientRect().width:0;return f.truncateTwoLines(e,t,16,1.5)},ne=()=>{if("none"===X.type)return null;const e="pdf-icon"===X.type;return t("div",{className:T,"data-testid":`${R}-thumbnail`,children:t(u,{className:o(D,e&&$),"data-testid":`${R}-thumbnail-image`,src:e?p.PDF_ICON_URL:X.src})})},me=()=>i(r,{children:[t("div",{className:_,children:i(r,{children:[t("div",{className:P,ref:ie,children:ee}),Q&&i("div",{className:S,children:[t(l,{className:L}),O||"Something went wrong"]})]})}),t("div",{className:z,children:W||"-"}),Q&&i("div",{className:I,children:[t(l,{className:L}),O||"Something went wrong"]})]});return t("li",{className:b,"data-testid":R,children:i("div",{className:o(j,Q&&g),onClick:ae,children:[i("div",{className:o(N,Y&&k),children:[ne(),Y?t("div",{className:v,children:me()}):me()]}),F?t(h,{children:t("button",{type:"button",className:w,"data-testid":`${R}-card-button`,"aria-label":null!=H?H:U,disabled:!G,onClick:le})}):null,t("div",{className:x,children:t(d,{className:C,"data-testid":`${R}-download-button`,type:"button",styleType:"light",sizeType:"small","aria-label":`download ${U}`,loading:J||!G,icon:t(a,{}),onClick:oe})})]})})}));export{q as FileListCard};
|
|
2
2
|
//# sourceMappingURL=file-list-card.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-list-card.js","sources":["../../../src/file-download/file-list-card/file-list-card.tsx"],"sourcesContent":["import { DownloadIcon } from \"@lifesg/react-icons\";\nimport { ExclamationCircleFillIcon } from \"@lifesg/react-icons/exclamation-circle-fill\";\nimport clsx from \"clsx\";\nimport { memo, useEffect, useRef, useState } from \"react\";\n\nimport { Button } from \"../../button\";\nimport { FileUploadHelper } from \"../../file-upload/helper\";\nimport { ImageWithFallback } from \"../../shared/image-with-fallback/image-with-fallback\";\nimport { useMaxWidthMediaQuery } from \"../../theme\";\nimport { StringHelper } from \"../../util\";\nimport * as styles from \"./file-list-card.styles\";\nimport type { FileListItemProps } from \"./types\";\n\nconst Component = ({ fileItem, onDownload }: FileListItemProps) => {\n // =========================================================================\n // CONST, STATE, REFS\n // =========================================================================\n const {\n id,\n name,\n size,\n errorMessage,\n thumbnailImageDataUrl,\n truncateText = true,\n ready = true,\n } = fileItem;\n\n // Local variables\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [isError, setIsError] = useState<boolean>(false);\n const fileSize = FileUploadHelper.formatFileSizeDisplay(size);\n const isMobile = useMaxWidthMediaQuery(\"sm\");\n const [displayText, setDisplayText] = useState<string>();\n const containerRef = useRef<HTMLDivElement>(null);\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n if (!containerRef.current) return;\n if (isMobile) {\n setDisplayText(getTruncatedText(name));\n } else {\n setDisplayText(name);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [name, isMobile]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleDownload = async () => {\n if (!ready || isLoading) {\n return;\n }\n\n setIsLoading(true);\n try {\n setIsError(false);\n await onDownload(fileItem);\n } catch {\n setIsError(true);\n } finally {\n setIsLoading(false);\n }\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const getTruncatedText = (value: string) => {\n if (!truncateText) return value;\n\n const widthOfElement =\n containerRef && containerRef.current\n ? containerRef.current.getBoundingClientRect().width\n : 0;\n\n return StringHelper.truncateTwoLines(value, widthOfElement, 16, 1.5);\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderNameDescription = () => (\n <>\n <div className={styles.itemNameText} ref={containerRef}>\n {displayText}\n </div>\n {isError && (\n <div className={styles.desktopErrorMessage}>\n <ExclamationCircleFillIcon className={styles.errorIcon} />\n {errorMessage ? errorMessage : \"Something went wrong\"}\n </div>\n )}\n </>\n );\n\n const renderWithThumbnail = (thumbnailSrc: string) => (\n <>\n <div\n className={styles.thumbnailContainer}\n data-testid={`${id}-thumbnail`}\n >\n <ImageWithFallback\n className={styles.thumbnail}\n data-testid={`${id}-thumbnail-image`}\n src={thumbnailSrc}\n />\n </div>\n <div className={styles.extendedNameSection}>\n <div className={styles.nameSection}>\n {renderNameDescription()}\n </div>\n <div className={styles.fileSizeSection}>\n {fileSize ? fileSize : \"-\"}\n </div>\n {isError && (\n <div className={styles.mobileErrorMessage}>\n <ExclamationCircleFillIcon\n className={styles.errorIcon}\n />\n {errorMessage ? errorMessage : \"Something went wrong\"}\n </div>\n )}\n </div>\n </>\n );\n\n const renderDefault = () => (\n <>\n <div className={styles.nameSection}>{renderNameDescription()}</div>\n <div className={styles.fileSizeSection}>\n {fileSize ? fileSize : \"-\"}\n </div>\n {isError && (\n <div className={styles.mobileErrorMessage}>\n <ExclamationCircleFillIcon className={styles.errorIcon} />\n {errorMessage ? errorMessage : \"Something went wrong\"}\n </div>\n )}\n </>\n );\n\n const renderContents = () => {\n let content: JSX.Element;\n\n if (thumbnailImageDataUrl) {\n content = renderWithThumbnail(thumbnailImageDataUrl);\n } else {\n content = renderDefault();\n }\n\n return (\n <div\n className={clsx(\n styles.contentSection,\n !!thumbnailImageDataUrl && styles.contentSectionHasThumbnail\n )}\n >\n {content}\n </div>\n );\n };\n\n const renderActions = () => {\n return (\n <div className={styles.actionContainer}>\n <Button\n className={styles.iconButton}\n data-testid={`${id}-download-button`}\n type=\"button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-label={`download ${name}`}\n loading={isLoading || !ready}\n icon={<DownloadIcon />}\n />\n </div>\n );\n };\n\n return (\n <li className={styles.item} data-testid={id}>\n <div\n className={clsx(styles.box, isError && styles.boxError)}\n onClick={handleDownload}\n >\n {renderContents()}\n {renderActions()}\n </div>\n </li>\n );\n};\n\nexport const FileListCard = memo(Component);\n"],"names":["FileListCard","memo","fileItem","onDownload","id","name","size","errorMessage","thumbnailImageDataUrl","truncateText","ready","isLoading","setIsLoading","useState","isError","setIsError","fileSize","FileUploadHelper","formatFileSizeDisplay","isMobile","useMaxWidthMediaQuery","displayText","setDisplayText","containerRef","useRef","useEffect","current","getTruncatedText","value","widthOfElement","getBoundingClientRect","width","StringHelper","truncateTwoLines","renderNameDescription","_jsxs","_Fragment","children","_jsx","className","styles.itemNameText","ref","styles.desktopErrorMessage","ExclamationCircleFillIcon","styles.errorIcon","styles.item","clsx","styles.box","styles.boxError","onClick","__awaiter","_a","content","styles.thumbnailContainer","ImageWithFallback","styles.thumbnail","src","styles.extendedNameSection","styles.nameSection","styles.fileSizeSection","styles.mobileErrorMessage","styles.contentSection","styles.contentSectionHasThumbnail","renderContents","styles.actionContainer","Button","styles.iconButton","type","styleType","sizeType","loading","icon","DownloadIcon"],"mappings":"q5CAaA,MAsLaA,EAAeC,GAtLV,EAAGC,WAAUC,iBAI3B,MAAMC,GACFA,EAAEC,KACFA,EAAIC,KACJA,EAAIC,aACJA,EAAYC,sBACZA,EAAqBC,aACrBA,GAAe,EAAIC,MACnBA,GAAQ,GACRR,GAGGS,EAAWC,GAAgBC,GAAkB,IAC7CC,EAASC,GAAcF,GAAkB,GAC1CG,EAAWC,EAAiBC,sBAAsBZ,GAClDa,EAAWC,EAAsB,OAChCC,EAAaC,GAAkBT,IAChCU,EAAeC,EAAuB,MAK5CC,GAAU,KACDF,EAAaG,SAEdJ,EADAH,EACeQ,EAAiBtB,GAEjBA,EACnB,GAED,CAACA,EAAMc,IAKV,MAmBMQ,EAAoBC,IACtB,IAAKnB,EAAc,OAAOmB,EAE1B,MAAMC,EACFN,GAAgBA,EAAaG,QACvBH,EAAaG,QAAQI,wBAAwBC,MAC7C,EAEV,OAAOC,EAAaC,iBAAiBL,EAAOC,EAAgB,GAAI,IAAI,EAMlEK,EAAwB,IAC1BC,EAAAC,EAAA,CAAAC,SAAA,CACIC,EAAA,MAAA,CAAKC,UAAWC,EAAqBC,IAAKlB,EAAYc,SACjDhB,IAEJP,GACGqB,EAAA,MAAA,CAAKI,UAAWG,EAA0BL,SAAA,CACtCC,EAACK,EAAyB,CAACJ,UAAWK,IACrCrC,GAA8B,6BA0F/C,OACI+B,EAAA,KAAA,CAAIC,UAAWM,EAAW,cAAezC,EAAEiC,SACvCF,SACII,UAAWO,EAAKC,EAAYjC,GAAWkC,GACvCC,QAvIW,IAAWC,OAAA,OAAA,OAAA,GAAA,YAC9B,GAAKxC,IAASC,EAAd,CAIAC,GAAa,GACb,IACIG,GAAW,SACLZ,EAAWD,EACrB,CAAE,MAAAiD,GACEpC,GAAW,EACf,SACIH,GAAa,EACjB,CAVA,CAWJ,IAyHmCyB,SAAA,CA1CZ,MACnB,IAAIe,EAQJ,OALIA,EAjDJjB,EAAAC,EAgDI5B,EAhDJ,CAAA6B,SAAA,CACIC,EAAA,MAAA,CACIC,UAAWc,EAAyB,cACvB,GAAGjD,uBAEhBkC,EAACgB,EAAiB,CACdf,UAAWgB,EAAgB,cACd,GAAGnD,oBAChBoD,IAyCsBhD,MAtC9B2B,EAAA,MAAA,CAAKI,UAAWkB,EAA0BpB,SAAA,CACtCC,EAAA,MAAA,CAAKC,UAAWmB,EAAkBrB,SAC7BH,MAELI,EAAA,MAAA,CAAKC,UAAWoB,EAAsBtB,SACjCrB,GAAsB,MAE1BF,GACGqB,EAAA,MAAA,CAAKI,UAAWqB,EAAyBvB,SAAA,CACrCC,EAACK,EAAyB,CACtBJ,UAAWK,IAEdrC,GAA8B,+BAQ/C,CAAA8B,SAAA,CACIC,EAAA,MAAA,CAAKC,UAAWmB,WAAqBxB,MACrCI,EAAA,MAAA,CAAKC,UAAWoB,EAAsBtB,SACjCrB,GAAsB,MAE1BF,GACGqB,EAAA,MAAA,CAAKI,UAAWqB,EAAyBvB,SAAA,CACrCC,EAACK,EAAyB,CAACJ,UAAWK,IACrCrC,GAA8B,6BAgBvC+B,SACIC,UAAWO,EACPe,IACErD,GAAyBsD,GAC9BzB,SAEAe,GACC,EA2BDW,GArBLzB,EAAA,MAAA,CAAKC,UAAWyB,EAAsB3B,SAClCC,EAAC2B,EAAM,CACH1B,UAAW2B,EAAiB,cACf,GAAG9D,oBAChB+D,KAAK,SACLC,UAAU,QACVC,SAAS,QAAO,aACJ,YAAYhE,IACxBiE,QAAS3D,IAAcD,EACvB6D,KAAMjC,EAACkC,EAAY,CAAA,WAe1B"}
|
|
1
|
+
{"version":3,"file":"file-list-card.js","sources":["../../../src/file-download/file-list-card/file-list-card.tsx"],"sourcesContent":["import { DownloadIcon } from \"@lifesg/react-icons\";\nimport { ExclamationCircleFillIcon } from \"@lifesg/react-icons/exclamation-circle-fill\";\nimport clsx from \"clsx\";\nimport { memo, useEffect, useRef, useState } from \"react\";\n\nimport { Button } from \"../../button\";\nimport { FileUploadHelper } from \"../../file-upload/helper\";\nimport { VisuallyHidden } from \"../../shared/accessibility\";\nimport { ImageWithFallback } from \"../../shared/image-with-fallback/image-with-fallback\";\nimport { useMaxWidthMediaQuery } from \"../../theme\";\nimport { StringHelper } from \"../../util\";\nimport * as styles from \"./file-list-card.styles\";\nimport type { FileListItemProps } from \"./types\";\n\nconst Component = ({ fileItem, onDownload, onClick }: FileListItemProps) => {\n // =========================================================================\n // CONST, STATE, REFS\n // =========================================================================\n const {\n id,\n name,\n mimeType,\n size,\n errorMessage,\n thumbnailImageDataUrl,\n truncateText = true,\n ready = true,\n clickLabel,\n } = fileItem;\n\n // Local variables\n const [isLoading, setIsLoading] = useState<boolean>(false);\n const [isError, setIsError] = useState<boolean>(false);\n const fileSize = FileUploadHelper.formatFileSizeDisplay(size);\n const thumbnailDisplay = FileUploadHelper.resolveThumbnailDisplay(\n mimeType,\n thumbnailImageDataUrl\n );\n const hasThumbnail = thumbnailDisplay.type !== \"none\";\n const isMobile = useMaxWidthMediaQuery(\"sm\");\n const [displayText, setDisplayText] = useState<string>();\n const containerRef = useRef<HTMLDivElement>(null);\n\n // =========================================================================\n // EFFECTS\n // =========================================================================\n useEffect(() => {\n if (!containerRef.current) return;\n if (isMobile) {\n setDisplayText(getTruncatedText(name));\n } else {\n setDisplayText(name);\n }\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [name, isMobile]);\n\n // =========================================================================\n // EVENT HANDLERS\n // =========================================================================\n const handleDownload = async () => {\n if (!ready || isLoading) {\n return;\n }\n\n setIsLoading(true);\n try {\n setIsError(false);\n await onDownload(fileItem);\n } catch {\n setIsError(true);\n } finally {\n setIsLoading(false);\n }\n };\n\n const handleCardClick = () => {\n if (!ready) {\n return;\n }\n\n if (onClick) {\n onClick(fileItem);\n return;\n }\n\n handleDownload();\n };\n\n const handleCardButtonClick = (\n event: React.MouseEvent<HTMLButtonElement>\n ) => {\n /*\n * The button sits inside the container, which handles clicks too.\n * Without this both handlers fire and the action runs twice.\n */\n event.stopPropagation();\n handleCardClick();\n };\n\n const handleDownloadButtonClick = (\n event: React.MouseEvent<HTMLButtonElement>\n ) => {\n // Same reason: the container's handler must not also run.\n event.stopPropagation();\n handleDownload();\n };\n\n // =========================================================================\n // HELPER FUNCTIONS\n // =========================================================================\n const getTruncatedText = (value: string) => {\n if (!truncateText) return value;\n\n const widthOfElement =\n containerRef && containerRef.current\n ? containerRef.current.getBoundingClientRect().width\n : 0;\n\n return StringHelper.truncateTwoLines(value, widthOfElement, 16, 1.5);\n };\n\n // =========================================================================\n // RENDER FUNCTIONS\n // =========================================================================\n const renderNameDescription = () => (\n <>\n <div className={styles.itemNameText} ref={containerRef}>\n {displayText}\n </div>\n {isError && (\n <div className={styles.desktopErrorMessage}>\n <ExclamationCircleFillIcon className={styles.errorIcon} />\n {errorMessage ? errorMessage : \"Something went wrong\"}\n </div>\n )}\n </>\n );\n\n const renderThumbnail = () => {\n if (thumbnailDisplay.type === \"none\") {\n return null;\n }\n\n const isPdfBadge = thumbnailDisplay.type === \"pdf-icon\";\n\n return (\n <div\n className={styles.thumbnailContainer}\n data-testid={`${id}-thumbnail`}\n >\n <ImageWithFallback\n className={clsx(\n styles.thumbnail,\n isPdfBadge && styles.thumbnailPdf\n )}\n data-testid={`${id}-thumbnail-image`}\n src={\n isPdfBadge\n ? FileUploadHelper.PDF_ICON_URL\n : thumbnailDisplay.src\n }\n />\n </div>\n );\n };\n\n const renderNameSizeError = () => (\n <>\n <div className={styles.nameSection}>{renderNameDescription()}</div>\n <div className={styles.fileSizeSection}>\n {fileSize ? fileSize : \"-\"}\n </div>\n {isError && (\n <div className={styles.mobileErrorMessage}>\n <ExclamationCircleFillIcon className={styles.errorIcon} />\n {errorMessage ? errorMessage : \"Something went wrong\"}\n </div>\n )}\n </>\n );\n\n const renderContents = () => (\n <div\n className={clsx(\n styles.contentSection,\n hasThumbnail && styles.contentSectionHasThumbnail\n )}\n >\n {renderThumbnail()}\n {hasThumbnail ? (\n <div className={styles.extendedNameSection}>\n {renderNameSizeError()}\n </div>\n ) : (\n renderNameSizeError()\n )}\n </div>\n );\n\n const renderCardButton = () => {\n if (!onClick) {\n return null;\n }\n\n return (\n <VisuallyHidden>\n <button\n type=\"button\"\n className={styles.cardButton}\n data-testid={`${id}-card-button`}\n aria-label={clickLabel ?? name}\n disabled={!ready}\n onClick={handleCardButtonClick}\n />\n </VisuallyHidden>\n );\n };\n\n const renderActions = () => {\n return (\n <div className={styles.actionContainer}>\n <Button\n className={styles.iconButton}\n data-testid={`${id}-download-button`}\n type=\"button\"\n styleType=\"light\"\n sizeType=\"small\"\n aria-label={`download ${name}`}\n loading={isLoading || !ready}\n icon={<DownloadIcon />}\n onClick={handleDownloadButtonClick}\n />\n </div>\n );\n };\n\n return (\n <li className={styles.item} data-testid={id}>\n <div\n className={clsx(styles.box, isError && styles.boxError)}\n onClick={handleCardClick}\n >\n {renderContents()}\n {renderCardButton()}\n {renderActions()}\n </div>\n </li>\n );\n};\n\nexport const FileListCard = memo(Component);\n"],"names":["FileListCard","memo","fileItem","onDownload","onClick","id","name","mimeType","size","errorMessage","thumbnailImageDataUrl","truncateText","ready","clickLabel","isLoading","setIsLoading","useState","isError","setIsError","fileSize","FileUploadHelper","formatFileSizeDisplay","thumbnailDisplay","resolveThumbnailDisplay","hasThumbnail","type","isMobile","useMaxWidthMediaQuery","displayText","setDisplayText","containerRef","useRef","useEffect","current","getTruncatedText","handleDownload","__awaiter","_a","handleCardClick","handleCardButtonClick","event","stopPropagation","handleDownloadButtonClick","value","widthOfElement","getBoundingClientRect","width","StringHelper","truncateTwoLines","renderThumbnail","isPdfBadge","_jsx","className","styles.thumbnailContainer","children","ImageWithFallback","clsx","styles.thumbnail","styles.thumbnailPdf","src","PDF_ICON_URL","renderNameSizeError","_jsxs","_Fragment","styles.nameSection","styles.itemNameText","ref","styles.desktopErrorMessage","ExclamationCircleFillIcon","styles.errorIcon","styles.fileSizeSection","styles.mobileErrorMessage","styles.item","styles.box","styles.boxError","styles.contentSection","styles.contentSectionHasThumbnail","styles.extendedNameSection","VisuallyHidden","styles.cardButton","disabled","styles.actionContainer","Button","styles.iconButton","styleType","sizeType","loading","icon","DownloadIcon"],"mappings":"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"}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export declare const item: import("@linaria/core").LinariaClassName;
|
|
2
|
+
export declare const cardButton: import("@linaria/core").LinariaClassName;
|
|
2
3
|
export declare const box: import("@linaria/core").LinariaClassName;
|
|
3
4
|
export declare const boxError: import("@linaria/core").LinariaClassName;
|
|
4
5
|
export declare const contentSection: import("@linaria/core").LinariaClassName;
|
|
@@ -14,3 +15,4 @@ export declare const actionContainer: import("@linaria/core").LinariaClassName;
|
|
|
14
15
|
export declare const iconButton: import("@linaria/core").LinariaClassName;
|
|
15
16
|
export declare const thumbnailContainer: import("@linaria/core").LinariaClassName;
|
|
16
17
|
export declare const thumbnail: import("@linaria/core").LinariaClassName;
|
|
18
|
+
export declare const thumbnailPdf: import("@linaria/core").LinariaClassName;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import"./file-list-card.
|
|
1
|
+
import"./file-list-card.styles_lzbqkk.css";const t="ifkrwze",i="c7grm6i",l="b1ryf4f4",e="basceiz",f="c83cih3",c="c13wqyhg",o="nthi1vt",d="ef8ofzq",r="fytzo9z",s="i4y82lx",z="ega23xt",a="d1qdniby",q="m1xq0zd",y="a18nltf5",k="impqdeo",n="t4orgj8",b="t96jkl",g="t1l7ztkl";export{y as actionContainer,l as box,e as boxError,i as cardButton,f as contentSection,c as contentSectionHasThumbnail,a as desktopErrorMessage,z as errorIcon,d as extendedNameSection,r as fileSizeSection,k as iconButton,t as item,s as itemNameText,q as mobileErrorMessage,o as nameSection,b as thumbnail,n as thumbnailContainer,g as thumbnailPdf};
|
|
2
2
|
//# sourceMappingURL=file-list-card.styles.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-list-card.styles.js","sources":["../../../src/file-download/file-list-card/file-list-card.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { lineClampCss } from \"../../shared/styles\";\nimport { Border, Colour, Font, MediaQuery, Radius, Spacing } from \"../../theme\";\n\n// =============================================================================\n// STYLING\n// =============================================================================\nexport const item = css`\n display: flex;\n align-items: center;\n\n width: 100%;\n border: none;\n\n &:not(:last-child) {\n margin-bottom: ${Spacing[\"spacing-16\"]};\n }\n`;\n\nexport const box = css`\n display: flex;\n align-items: center;\n\n width: 100%;\n padding: ${Spacing[\"spacing-16\"]} ${Spacing[\"spacing-32\"]};\n cursor: pointer;\n\n background: ${Colour[\"bg-primary-subtlest\"]};\n border: ${Border[\"width-010\"]} ${Border[\"solid\"]} ${Colour[\"border\"]};\n border-radius: ${Radius[\"sm\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n padding: ${Spacing[\"spacing-16\"]};\n }\n\n &:hover {\n background: ${Colour[\"bg-hover\"]};\n }\n`;\n\nexport const boxError = css`\n background: ${Colour[\"bg-error\"]};\n border-color: ${Colour[\"border-error\"]};\n\n &:hover {\n background: ${Colour[\"bg-error\"]};\n }\n`;\n\nexport const contentSection = css`\n display: flex;\n flex: 1;\n align-items: center;\n\n ${MediaQuery.MaxWidth.lg} {\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n }\n`;\n\nexport const contentSectionHasThumbnail = css`\n ${MediaQuery.MaxWidth.lg} {\n flex-direction: row;\n align-items: center;\n }\n`;\n\nexport const nameSection = css`\n display: flex;\n flex: 1;\n flex-direction: column;\n\n width: 100%;\n\n overflow-wrap: break-word;\n word-break: break-all;\n white-space: normal;\n`;\n\nexport const extendedNameSection = css`\n display: flex;\n flex: 1;\n align-items: center;\n\n ${MediaQuery.MaxWidth.lg} {\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n }\n`;\n\nexport const fileSizeSection = css`\n display: flex;\n justify-content: flex-end;\n\n width: 5rem;\n margin-left: ${Spacing[\"spacing-8\"]};\n\n ${Font[\"body-md-regular\"]}\n color: ${Colour[\"text\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n justify-content: flex-start;\n\n width: 100%;\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-8\"]};\n\n ${lineClampCss(2)}\n }\n`;\n\nexport const itemNameText = css`\n ${Font[\"body-md-regular\"]}\n color: ${Colour[\"text\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n ${lineClampCss(2)}\n }\n`;\n\nexport const errorIcon = css`\n height: 1lh;\n width: 1em;\n flex-shrink: 0;\n color: ${Colour[\"icon-error-strong\"]};\n`;\n\nconst baseErrorMessage = `\n ${Font[\"body-sm-semibold\"]}\n color: ${Colour[\"text-error\"]};\n`;\n\nexport const desktopErrorMessage = css`\n ${baseErrorMessage}\n margin-top: ${Spacing[\"spacing-8\"]};\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n display: none;\n visibility: hidden;\n }\n`;\n\nexport const mobileErrorMessage = css`\n ${baseErrorMessage}\n display: none;\n visibility: hidden;\n\n ${MediaQuery.MaxWidth.lg} {\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n visibility: visible;\n margin-top: ${Spacing[\"spacing-8\"]};\n }\n`;\n\nexport const actionContainer = css`\n display: flex;\n justify-content: flex-end;\n align-items: center;\n\n margin-left: ${Spacing[\"spacing-32\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n margin-left: ${Spacing[\"spacing-16\"]};\n }\n`;\n\nexport const iconButton = css`\n min-width: unset;\n\n &:not(:last-child) {\n margin-right: ${Spacing[\"spacing-16\"]};\n }\n`;\n\nexport const thumbnailContainer = css`\n width: auto;\n margin-right: ${Spacing[\"spacing-32\"]};\n\n display: flex;\n flex-shrink: 0;\n flex-direction: column;\n justify-content: center;\n\n ${MediaQuery.MaxWidth.lg} {\n margin-right: ${Spacing[\"spacing-16\"]};\n }\n`;\n\nexport const thumbnail = css`\n border-radius: ${Radius[\"sm\"]};\n border: ${Border[\"width-010\"]} ${Border[\"solid\"]} ${Colour[\"border\"]};\n\n width: 96px;\n height: 96px;\n aspect-ratio: 1;\n object-fit: cover;\n\n ${MediaQuery.MaxWidth.lg} {\n width: 64px;\n height: 64px;\n }\n`;\n"],"names":["item","box","boxError","contentSection","contentSectionHasThumbnail","nameSection","extendedNameSection","fileSizeSection","itemNameText","errorIcon","desktopErrorMessage","mobileErrorMessage","actionContainer","iconButton","thumbnailContainer","thumbnail"],"mappings":"
|
|
1
|
+
{"version":3,"file":"file-list-card.styles.js","sources":["../../../src/file-download/file-list-card/file-list-card.styles.ts"],"sourcesContent":["import { css } from \"@linaria/core\";\n\nimport { lineClampCss } from \"../../shared/styles\";\nimport { Border, Colour, Font, MediaQuery, Radius, Spacing } from \"../../theme\";\n\n// =============================================================================\n// STYLING\n// =============================================================================\nexport const item = css`\n display: flex;\n align-items: center;\n\n width: 100%;\n border: none;\n\n &:not(:last-child) {\n margin-bottom: ${Spacing[\"spacing-16\"]};\n }\n`;\n\nexport const cardButton = css`\n appearance: none;\n padding: 0;\n background: none;\n border: none;\n`;\n\nexport const box = css`\n position: relative;\n display: flex;\n align-items: center;\n\n width: 100%;\n padding: ${Spacing[\"spacing-16\"]} ${Spacing[\"spacing-32\"]};\n cursor: pointer;\n\n background: ${Colour[\"bg-primary-subtlest\"]};\n border: ${Border[\"width-010\"]} ${Border[\"solid\"]} ${Colour[\"border\"]};\n border-radius: ${Radius[\"sm\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n padding: ${Spacing[\"spacing-16\"]};\n }\n\n &:hover {\n background: ${Colour[\"bg-hover\"]};\n }\n\n @supports selector(:has(*)) {\n &:has(.${cardButton}:focus-visible) {\n outline: 2px solid ${Colour[\"focus-ring\"]};\n outline-offset: -2px;\n }\n }\n`;\n\nexport const boxError = css`\n background: ${Colour[\"bg-error\"]};\n border-color: ${Colour[\"border-error\"]};\n\n &:hover {\n background: ${Colour[\"bg-error\"]};\n }\n\n @supports selector(:has(*)) {\n &:has(.${cardButton}:focus-visible) {\n outline-color: ${Colour[\"border-error-focus\"]};\n }\n }\n`;\n\nexport const contentSection = css`\n display: flex;\n flex: 1;\n align-items: center;\n\n ${MediaQuery.MaxWidth.lg} {\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n }\n`;\n\nexport const contentSectionHasThumbnail = css`\n ${MediaQuery.MaxWidth.lg} {\n flex-direction: row;\n align-items: center;\n }\n`;\n\nexport const nameSection = css`\n display: flex;\n flex: 1;\n flex-direction: column;\n\n width: 100%;\n\n overflow-wrap: break-word;\n word-break: break-all;\n white-space: normal;\n`;\n\nexport const extendedNameSection = css`\n display: flex;\n flex: 1;\n align-items: center;\n\n ${MediaQuery.MaxWidth.lg} {\n flex-direction: column;\n align-items: flex-start;\n width: 100%;\n }\n`;\n\nexport const fileSizeSection = css`\n display: flex;\n justify-content: flex-end;\n\n width: 5rem;\n margin-left: ${Spacing[\"spacing-8\"]};\n\n ${Font[\"body-md-regular\"]}\n color: ${Colour[\"text\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n justify-content: flex-start;\n\n width: 100%;\n margin-left: 0;\n margin-top: ${Spacing[\"spacing-8\"]};\n\n ${lineClampCss(2)}\n }\n`;\n\nexport const itemNameText = css`\n ${Font[\"body-md-regular\"]}\n color: ${Colour[\"text\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n ${lineClampCss(2)}\n }\n`;\n\nexport const errorIcon = css`\n height: 1lh;\n width: 1em;\n flex-shrink: 0;\n color: ${Colour[\"icon-error-strong\"]};\n`;\n\nconst baseErrorMessage = `\n ${Font[\"body-sm-semibold\"]}\n color: ${Colour[\"text-error\"]};\n`;\n\nexport const desktopErrorMessage = css`\n ${baseErrorMessage}\n margin-top: ${Spacing[\"spacing-8\"]};\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n display: none;\n visibility: hidden;\n }\n`;\n\nexport const mobileErrorMessage = css`\n ${baseErrorMessage}\n display: none;\n visibility: hidden;\n\n ${MediaQuery.MaxWidth.lg} {\n display: flex;\n gap: ${Spacing[\"spacing-4\"]};\n visibility: visible;\n margin-top: ${Spacing[\"spacing-8\"]};\n }\n`;\n\nexport const actionContainer = css`\n display: flex;\n justify-content: flex-end;\n align-items: center;\n\n margin-left: ${Spacing[\"spacing-32\"]};\n\n ${MediaQuery.MaxWidth.lg} {\n margin-left: ${Spacing[\"spacing-16\"]};\n }\n`;\n\nexport const iconButton = css`\n min-width: unset;\n\n &:not(:last-child) {\n margin-right: ${Spacing[\"spacing-16\"]};\n }\n`;\n\nexport const thumbnailContainer = css`\n width: auto;\n margin-right: ${Spacing[\"spacing-32\"]};\n\n display: flex;\n flex-shrink: 0;\n flex-direction: column;\n justify-content: center;\n\n ${MediaQuery.MaxWidth.lg} {\n margin-right: ${Spacing[\"spacing-16\"]};\n }\n`;\n\nexport const thumbnail = css`\n border-radius: ${Radius[\"sm\"]};\n border: ${Border[\"width-010\"]} ${Border[\"solid\"]} ${Colour[\"border\"]};\n\n width: 96px;\n height: 96px;\n aspect-ratio: 1;\n object-fit: cover;\n\n ${MediaQuery.MaxWidth.lg} {\n width: 64px;\n height: 64px;\n }\n`;\n\nexport const thumbnailPdf = css`\n border: none;\n`;\n"],"names":["item","cardButton","box","boxError","contentSection","contentSectionHasThumbnail","nameSection","extendedNameSection","fileSizeSection","itemNameText","errorIcon","desktopErrorMessage","mobileErrorMessage","actionContainer","iconButton","thumbnailContainer","thumbnail","thumbnailPdf"],"mappings":"uFAQO,MAAMA,EAAI,UAYJC,EAAU,UAOVC,EAAG,WA6BHC,EAAQ,UAeRC,EAAc,UAYdC,EAA0B,WAO1BC,EAAW,UAYXC,EAAmB,UAYnBC,EAAe,UAqBfC,EAAY,UASZC,EAAS,UAYTC,EAAmB,WAYnBC,EAAkB,UAalBC,EAAe,WAYfC,EAAU,UAQVC,EAAkB,UAclBC,EAAS,SAeTC,EAAY"}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
@layer fds{.ifkrwze{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;border:none;}.ifkrwze:not(:last-child){margin-bottom:var(--fds-spacing-16);}
|
|
2
|
+
.c7grm6i{-webkit-appearance:none;-moz-appearance:none;-ms-appearance:none;appearance:none;padding:0;background:none;border:none;}
|
|
3
|
+
.b1ryf4f4{position:relative;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;width:100%;padding:var(--fds-spacing-16) var(--fds-spacing-32);cursor:pointer;background:var(--fds-colour-bg-primary-subtlest);border:var(--fds-border-width-010) var(--fds-border-style-solid) var(--fds-colour-border);border-radius:var(--fds-radius-sm);}:where(body.fds-breakpoint-lg-max) .b1ryf4f4{padding:var(--fds-spacing-16);}.b1ryf4f4:hover{background:var(--fds-colour-bg-hover);}@supports selector(:has(*)){.b1ryf4f4:has(.c7grm6i:focus-visible){outline:2px solid var(--fds-colour-focus-ring);outline-offset:-2px;}}
|
|
4
|
+
.basceiz{background:var(--fds-colour-bg-error);border-color:var(--fds-colour-border-error);}.basceiz:hover{background:var(--fds-colour-bg-error);}@supports selector(:has(*)){.basceiz:has(.c7grm6i:focus-visible){outline-color:var(--fds-colour-border-error-focus);}}
|
|
5
|
+
.c83cih3{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}:where(body.fds-breakpoint-lg-max) .c83cih3{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;width:100%;}
|
|
6
|
+
:where(body.fds-breakpoint-lg-max) .c13wqyhg{-webkit-flex-direction:row;-ms-flex-direction:row;flex-direction:row;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}
|
|
7
|
+
.nthi1vt{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;width:100%;overflow-wrap:break-word;word-break:break-all;white-space:normal;}
|
|
8
|
+
.ef8ofzq{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex:1;-ms-flex:1;flex:1;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;}:where(body.fds-breakpoint-lg-max) .ef8ofzq{-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-align-items:flex-start;-webkit-box-align:flex-start;-ms-flex-align:flex-start;align-items:flex-start;width:100%;}
|
|
9
|
+
.fytzo9z{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;width:5rem;margin-left:var(--fds-spacing-8);font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-md);font-weight:var(--fds-font-weight-regular);line-height:var(--fds-font-body-lh-md);letter-spacing:var(--fds-font-body-ls-md);color:var(--fds-colour-text);}:where(body.fds-breakpoint-lg-max) .fytzo9z{-webkit-box-pack:start;-ms-flex-pack:start;-webkit-justify-content:flex-start;justify-content:flex-start;width:100%;margin-left:0;margin-top:var(--fds-spacing-8);display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
|
|
10
|
+
.i4y82lx{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-md);font-weight:var(--fds-font-weight-regular);line-height:var(--fds-font-body-lh-md);letter-spacing:var(--fds-font-body-ls-md);color:var(--fds-colour-text);}:where(body.fds-breakpoint-lg-max) .i4y82lx{display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;}
|
|
11
|
+
.ega23xt{height:1lh;width:1em;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;color:var(--fds-colour-icon-error-strong);}
|
|
12
|
+
.d1qdniby{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-sm);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-body-lh-sm);letter-spacing:var(--fds-font-body-ls-sm);color:var(--fds-colour-text-error);margin-top:var(--fds-spacing-8);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:var(--fds-spacing-4);}:where(body.fds-breakpoint-lg-max) .d1qdniby{display:none;visibility:hidden;}
|
|
13
|
+
.m1xq0zd{font-family:var(--fds-font-family-body);font-variant:var(--fds-font-variant);font-size:var(--fds-font-body-size-sm);font-weight:var(--fds-font-weight-semibold);line-height:var(--fds-font-body-lh-sm);letter-spacing:var(--fds-font-body-ls-sm);color:var(--fds-colour-text-error);display:none;visibility:hidden;}:where(body.fds-breakpoint-lg-max) .m1xq0zd{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;gap:var(--fds-spacing-4);visibility:visible;margin-top:var(--fds-spacing-8);}
|
|
14
|
+
.a18nltf5{display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-box-pack:end;-ms-flex-pack:end;-webkit-justify-content:flex-end;justify-content:flex-end;-webkit-align-items:center;-webkit-box-align:center;-ms-flex-align:center;align-items:center;margin-left:var(--fds-spacing-32);}:where(body.fds-breakpoint-lg-max) .a18nltf5{margin-left:var(--fds-spacing-16);}
|
|
15
|
+
.impqdeo{min-width:unset;}.impqdeo:not(:last-child){margin-right:var(--fds-spacing-16);}
|
|
16
|
+
.t4orgj8{width:auto;margin-right:var(--fds-spacing-32);display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex;-webkit-flex-shrink:0;-ms-flex-negative:0;flex-shrink:0;-webkit-flex-direction:column;-ms-flex-direction:column;flex-direction:column;-webkit-box-pack:center;-ms-flex-pack:center;-webkit-justify-content:center;justify-content:center;}:where(body.fds-breakpoint-lg-max) .t4orgj8{margin-right:var(--fds-spacing-16);}
|
|
17
|
+
.t96jkl{border-radius:var(--fds-radius-sm);border:var(--fds-border-width-010) var(--fds-border-style-solid) var(--fds-colour-border);width:96px;height:96px;aspect-ratio:1;object-fit:cover;}:where(body.fds-breakpoint-lg-max) .t96jkl{width:64px;height:64px;}
|
|
18
|
+
.t1l7ztkl{border:none;}}
|