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

Code before:
      else if (scrollLeftActiveImage > scrollLeftMiddle) navRef.scrollTo({ left: scrollLeftActiveImage - scrollLeftMiddle, behavior: scrollBehavior })
      else navRef.scrollTo({ left: 0, behavior: scrollBehavior })

      if (!defaultScrollSetRef.current) defaultScrollSetRef.current = true
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeImageIdx])

  return (
    <div className={css.body}>
      <div className={css.header}>
        <Fluent.ActionButton
          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(activeImageIdx === 0 ? images.length - 1 : activeImageIdx - 1)}
              iconProps={{ iconName: 'ChevronLeft', style: styles.icon }}
            />
            <Fluent.ActionButton
              styles={iconStyles}
              className={css.iconStylesRootArrow}
              style={{ right: 0 }}
              onClick={() => setActiveImageIdx(activeImageIdx === images.length - 1 ? 0 : activeImageIdx + 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}

Review comment (suggestion):
Since next state for `activeImageIdx` depends on the previous one, let's use the value provided by the setState callback rather than the closure one as we discussed. Same for the other button.

Code after:
      else if (scrollLeftActiveImage > scrollLeftMiddle) navRef.scrollTo({ left: scrollLeftActiveImage - scrollLeftMiddle, behavior: scrollBehavior })
      else navRef.scrollTo({ left: 0, behavior: scrollBehavior })

      if (!defaultScrollSetRef.current) defaultScrollSetRef.current = true
    }
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [activeImageIdx])

  return (
    <div className={css.body} onKeyDown={handleKeyDown} tabIndex={0} ref={rootElementRef}>
      <div className={css.header}>
        <Fluent.ActionButton
          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}