{"version":3,"file":"Carousel.mjs","sources":["../../../../src/components/Carousel/Carousel.tsx"],"sourcesContent":["import { css, cx } from '@emotion/css';\nimport { useState, useEffect } from 'react';\n\nimport { GrafanaTheme2 } from '@grafana/data';\n\nimport { useStyles2 } from '../../themes';\nimport { t } from '../../utils/i18n';\nimport { Alert } from '../Alert/Alert';\nimport { IconButton } from '../IconButton/IconButton';\n\n// Define the image item interface\nexport interface CarouselImage {\n  path: string;\n  name: string;\n}\n\nexport interface CarouselProps {\n  images: CarouselImage[];\n}\n\nexport const Carousel: React.FC<CarouselProps> = ({ images }) => {\n  const [selectedIndex, setSelectedIndex] = useState<number | null>(null);\n  const [imageErrors, setImageErrors] = useState<Record<string, boolean>>({});\n  const [validImages, setValidImages] = useState<CarouselImage[]>(images);\n\n  const styles = useStyles2(getStyles());\n\n  const handleImageError = (path: string) => {\n    setImageErrors((prev) => ({\n      ...prev,\n      [path]: true,\n    }));\n  };\n\n  useEffect(() => {\n    const filteredImages = images.filter((image) => !imageErrors[image.path]);\n    setValidImages(filteredImages);\n  }, [imageErrors, images]);\n\n  const openPreview = (index: number) => {\n    setSelectedIndex(index);\n  };\n\n  const closePreview = () => {\n    setSelectedIndex(null);\n  };\n\n  const goToNext = () => {\n    if (selectedIndex !== null && validImages.length > 0) {\n      setSelectedIndex((selectedIndex + 1) % validImages.length);\n    }\n  };\n\n  const goToPrevious = () => {\n    if (selectedIndex !== null && validImages.length > 0) {\n      setSelectedIndex((selectedIndex - 1 + validImages.length) % validImages.length);\n    }\n  };\n\n  const handleKeyDown = (event: React.KeyboardEvent) => {\n    if (selectedIndex === null) {\n      return;\n    }\n\n    switch (event.key) {\n      case 'ArrowRight':\n        goToNext();\n        break;\n      case 'ArrowLeft':\n        goToPrevious();\n        break;\n      case 'Escape':\n        closePreview();\n        break;\n      default:\n        break;\n    }\n  };\n\n  if (validImages.length === 0) {\n    return (\n      <Alert\n        title={t('carousel.error', 'Something went wrong loading images')}\n        severity=\"warning\"\n        data-testid=\"alert-warning\"\n      />\n    );\n  }\n\n  return (\n    <div onKeyDown={handleKeyDown} tabIndex={0}>\n      <div className={cx(styles.imageGrid)}>\n        {validImages.map((image, index) => (\n          <div key={image.path} onClick={() => openPreview(index)} style={{ cursor: 'pointer' }}>\n            <img src={image.path} alt={image.name} onError={() => handleImageError(image.path)} />\n            <p>{image.name}</p>\n          </div>\n        ))}\n      </div>\n\n      {selectedIndex !== null && (\n        <div className={cx(styles.fullScreenDiv)} onClick={closePreview} data-testid=\"carousel-full-screen\">\n          <IconButton\n            name=\"times\"\n            aria-label={t('carousel.close', 'Close')}\n            size=\"xl\"\n            onClick={closePreview}\n            className={cx(styles.closeButton)}\n          />\n\n          <IconButton\n            size=\"xl\"\n            name=\"angle-left\"\n            aria-label={t('carousel.previous', 'Previous')}\n            onClick={(e) => {\n              e.stopPropagation();\n              goToPrevious();\n            }}\n            className={cx(styles.navigationButton, styles.previousButton)}\n            data-testid=\"previous-button\"\n          />\n\n          <div\n            style={{ position: 'relative', maxWidth: '90%', maxHeight: '90%' }}\n            onClick={(e) => e.stopPropagation()}\n            data-testid=\"carousel-full-image\"\n          >\n            <img\n              src={validImages[selectedIndex].path}\n              alt={validImages[selectedIndex].name}\n              onError={() => handleImageError(validImages[selectedIndex].path)}\n            />\n          </div>\n\n          <IconButton\n            size=\"xl\"\n            name=\"angle-right\"\n            aria-label={t('carousel.next', 'Next')}\n            onClick={(e) => {\n              e.stopPropagation();\n              goToNext();\n            }}\n            className={cx(styles.navigationButton, styles.nextButton)}\n            data-testid=\"next-button\"\n          />\n        </div>\n      )}\n    </div>\n  );\n};\n\nconst getStyles = () => (theme: GrafanaTheme2) => ({\n  imageGrid: css({\n    display: 'grid',\n    gridTemplateColumns: `repeat(auto-fill, minmax(200px, 1fr))`,\n    gap: '16px',\n    marginBottom: '20px',\n\n    '& img': {\n      width: '100%',\n      height: '150px',\n      objectFit: 'cover',\n      border: theme.colors.border.strong,\n      borderRadius: theme.shape.radius.default,\n      boxShadow: theme.shadows.z1,\n    },\n    '& p': {\n      margin: '4px 0',\n      fontWeight: theme.typography.fontWeightMedium,\n      color: theme.colors.text.primary,\n    },\n  }),\n  fullScreenDiv: css({\n    position: 'fixed',\n    zIndex: theme.zIndex.modalBackdrop,\n    top: 0,\n    right: 0,\n    bottom: 0,\n    left: 0,\n    backgroundColor: theme.components.overlay.background,\n    alignItems: 'center',\n    justifyContent: 'center',\n    display: 'flex',\n\n    '& img': {\n      maxWidth: '100%',\n      maxHeight: '80vh',\n      objectFit: 'contain',\n    },\n  }),\n  closeButton: css({\n    position: 'absolute',\n    top: '20px',\n    right: '20px',\n    backgroundColor: 'transparent',\n    color: theme.colors.text.primary,\n  }),\n  navigationButton: css({\n    position: 'absolute',\n    backgroundColor: 'transparent',\n    color: theme.colors.text.primary,\n    cursor: 'pointer',\n    display: 'flex',\n    alignItems: 'center',\n    justifyContent: 'center',\n  }),\n  nextButton: css({\n    right: '20px',\n  }),\n  previousButton: css({\n    left: '20px',\n  }),\n});\n"],"names":[],"mappings":"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"}