components/elements/InfoGridWidget/InfoGridWidget.jsxjavascript
import "./InfoGridWidget.scss";

/**
 * Labelled text box (or image) next to a grid of short labels ("infoGridWidget"
 * element type), e.g. a nodule example paired with its measurable attributes.
 * When `textboxImage` is set, it replaces the head/text box entirely.
 *
 * @param {Object} props
 * @param {string} [props.select] - Small caption above the text/image box (e.g. "Example").
 * @param {string} [props.textboxHead] - Headline inside the text box; ignored when `textboxImage` is set.
 * @param {string} [props.textboxImage] - Image URL shown instead of the text box.
 * @param {Array<{item: string}>} props.textboxText - Body lines inside the text box; ignored when `textboxImage` is set.
 * @param {Array<{item: string}>} props.grid - Grid tiles, one headline each.
 */
export const InfoGridWidget = ({ select, textboxHead, textboxImage, textboxText, grid }) => {
  return (
    <div className="infogrid">
      <div className="infogrid__select">
        <div className="infogrid-select__text">{select}</div>
      </div>
      <div>
        {textboxImage ? (
          <img src={textboxImage} alt="" />
        ) : (
          <div className="infogrid__textbox">
            <div className="infogrid-textbox__text infogrid-textbox__text--head">
              {" "}
              {textboxHead}
            </div>
            <div className="textbox__space--1"></div>
            {textboxText.map((text, index) => (
              <div
                key={index}
                className={`infogrid-textbox__text infogrid-textbox__text--text ${textboxText.length - 1 > index ? "textbox__space--2" : ""}`}>
                {text.item}
              </div>
            ))}
          </div>
        )}
      </div>
      <div className="infogrid__grid">
        {grid.map((item, index) => (
          <div key={index} className="infogrid-grid__item">
            <h3>{item.item}</h3>
          </div>
        ))}
      </div>
    </div>
  );
};