Repository: h2oai/wave
File: ui/src/parts/lightbox.tsx (TypeScript)

Code before:
          alt={title}
          data-src={getImageSrc(image)}
          onClick={() => setActiveImageIdx(idx)}
        />
      </div>
    ) : undefined

  React.useEffect(() => {
    // Set initial scroll position.
    if (isGallery) navImgRefs[activeImageIdx].current!.scrollIntoView({ behavior: 'auto', inline: 'center', block: 'center' })
    // Add keyboard events listener.
    if (visible) window.addEventListener("keydown", handleKeyDown)
    else window.removeEventListener("keydown", handleKeyDown)
    return () => window.removeEventListener("keydown", handleKeyDown)
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [visible])

  // Handle image navigation scroll.
  React.useEffect(() => {
    if (isGallery) navImgRefs[activeImageIdx].current!.scrollIntoView({
      behavior: (activeImageIdx === 0 || activeImageIdx === images.length - 1) ? 'auto' : 'smooth',
      inline: 'center',
      block: 'center'
    })
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeImageIdx, images.length, navImgRefs])

  React.useLayoutEffect(() => {
    // Initialize intersection observer for lazy images.
    const lazyImages = [].slice.call(document.querySelectorAll(".lazy"))
    lazyImages.forEach(lazyImage => lazyImageObserver.observe(lazyImage))
  }, [])

  if (images.length === 0) throw new Error('No images passed to image lightbox component.')
  if (activeImageIdx >= images.length) throw new Error(`Image with defaultImageIdx:${activeImageIdx} does not exist.`)

  return (
    <div className={css.body} style={visible ? undefined : { display: 'none' }}>
      <div className={css.header}>
        <CloseButton onClose={onClose} />
      </div>
      <div className={css.content} style={{ height: `calc(100% - ${isGallery ? '262px' : '100px'})` }}>
        <img className={css.img} alt={title} src={src} />
        {isGallery && <ArrowControls activeImageIdx={activeImageIdx} setActiveImageIdx={setActiveImageIdx} images={images} />}
      </div>
      <div className={css.footer} style={{ height: isGallery ? '260px' : '60px' }}>
        <div className={css.imgCaptions}>
          <div title={title} className={clas(css.text, css.title)}>{title}</div>
          <div title={description} className={clas(css.text, css.description)}>{description || ''}</div>
        </div>
        {isGallery && <div className={css.imageNav} ref={imageNavRef}>{imageNav}</div>}

Review comment (suggestion):
Is `navImgRefs` necessary here? It seems like it's only initialized once and then just mutated so shouldn't trigger the useEffect anyway.
```suggestion
  }, [activeImageIdx, images.length])
```

Code after:
          styles={iconStyles}
          onClick={() => lightboxB(null)}
          iconProps={{ iconName: 'Cancel', style: styles.icon }}
        />
      </div>
      <div className={css.content} style={{ height: `calc(100% - ${HEADER_HEIGHT + FOOTER_HEIGHT}px)` }}>
        <img className={css.img} alt={title} src={getImageSrc(images[activeImageIdx])} />
        {isGallery &&
          <>
            <Fluent.ActionButton
              styles={iconStyles}
              className={css.iconStylesRootArrow}
              style={{ left: 0 }}
              onClick={() => setActiveImageIdx(prevIdx => prevIdx === 0 ? images.length - 1 : prevIdx - 1)}
              iconProps={{ iconName: 'ChevronLeft', style: styles.icon }}
            />
            <Fluent.ActionButton
              styles={iconStyles}
              className={css.iconStylesRootArrow}
              style={{ right: 0 }}
              onClick={() => setActiveImageIdx(prevIdx => prevIdx === images.length - 1 ? 0 : prevIdx + 1)}
              iconProps={{ iconName: 'ChevronRight', style: styles.icon }}
            />
          </>
        }
      </div>
      <div className={css.footer} style={{ height: FOOTER_HEIGHT }}>
        <div className={css.imgCaptions}>
          <div title={title} className={clas(css.text, css.title)}>{title}</div>
          <div title={description} className={clas(css.text, css.description)}>{description || ''}</div>
        </div>
        {isGallery &&
          <div className={css.imageNav} ref={imageNavRef}>
            {images.map((image, idx) =>
              <div key={idx} className={css.navImgContainer}>
                <img
                  className={clas(css.img, css.navImg, 'lazy', style({ $nest: { '&:hover': imageHighlightStyle } }))}
                  style={activeImageIdx === idx ? imageHighlightStyle : undefined}
                  alt={title}
                  data-src={getImageSrc(image)}
                  onClick={() => setActiveImageIdx(idx)}
                />
              </div>
            )}
          </div>
        }
      </div>
    </div>
  )
}