{"version":3,"file":"VizRepeater.cjs","sources":["../../../../src/components/VizRepeater/VizRepeater.tsx"],"sourcesContent":["import { clamp } from 'lodash';\nimport { PureComponent, CSSProperties, type JSX } from 'react';\nimport * as React from 'react';\n\nimport { VizOrientation } from '@grafana/data';\n\nimport { calculateGridDimensions } from '../../utils/squares';\n\ninterface Props<V, D> {\n  /**\n   * Optionally precalculate dimensions to support consistent behavior between repeated\n   * values.  Two typical patterns are:\n   * 1) Calculate raw values like font size etc and pass them to each vis\n   * 2) find the maximum input values and pass that to the vis\n   */\n  getAlignmentFactors?: (values: V[], width: number, height: number) => D;\n\n  /**\n   * Render a single value\n   */\n  renderValue: (props: VizRepeaterRenderValueProps<V, D>) => JSX.Element;\n  height: number;\n  width: number;\n  source: unknown; // If this changes, new values will be requested\n  getValues: () => V[];\n  renderCounter: number; // force update of values & render\n  orientation: VizOrientation;\n  itemSpacing?: number;\n  /** When orientation is set to auto layout items in a grid */\n  autoGrid?: boolean;\n  minVizWidth?: number;\n  minVizHeight?: number;\n  maxVizHeight?: number;\n}\n\nexport interface VizRepeaterRenderValueProps<V, D = {}> {\n  value: V;\n  width: number;\n  height: number;\n  orientation: VizOrientation;\n  alignmentFactors: D;\n  /**\n   * Total number of values being shown in repeater\n   */\n  count: number;\n}\n\ninterface DefaultProps {\n  itemSpacing: number;\n}\n\ntype PropsWithDefaults<V, D> = Props<V, D> & DefaultProps;\n\ninterface State<V> {\n  values: V[];\n}\n\nexport class VizRepeater<V, D = {}> extends PureComponent<PropsWithDefaults<V, D>, State<V>> {\n  static defaultProps: DefaultProps = {\n    itemSpacing: 8,\n  };\n\n  constructor(props: PropsWithDefaults<V, D>) {\n    super(props);\n\n    this.state = {\n      values: props.getValues(),\n    };\n  }\n\n  componentDidUpdate(prevProps: Props<V, D>) {\n    const { renderCounter, source } = this.props;\n    if (renderCounter !== prevProps.renderCounter || source !== prevProps.source) {\n      this.setState({ values: this.props.getValues() });\n    }\n  }\n\n  getOrientation(): VizOrientation {\n    const { orientation, width, height } = this.props;\n\n    if (orientation === VizOrientation.Auto) {\n      if (width > height) {\n        return VizOrientation.Vertical;\n      } else {\n        return VizOrientation.Horizontal;\n      }\n    }\n\n    return orientation;\n  }\n\n  renderGrid() {\n    const { renderValue, height, width, itemSpacing, getAlignmentFactors, orientation } = this.props;\n\n    const { values } = this.state;\n    const grid = calculateGridDimensions(width, height, itemSpacing, values.length);\n    const alignmentFactors = getAlignmentFactors ? getAlignmentFactors(values, grid.width, grid.height) : ({} as D);\n\n    let xGrid = 0;\n    let yGrid = 0;\n    let items: JSX.Element[] = [];\n\n    for (let i = 0; i < values.length; i++) {\n      const value = values[i];\n      const isLastRow = yGrid === grid.yCount - 1;\n\n      const itemWidth = isLastRow ? grid.widthOnLastRow : grid.width;\n      const itemHeight = grid.height;\n\n      const xPos = xGrid * itemWidth + itemSpacing * xGrid;\n      const yPos = yGrid * itemHeight + itemSpacing * yGrid;\n\n      const itemStyles: CSSProperties = {\n        position: 'absolute',\n        left: xPos,\n        top: yPos,\n        width: `${itemWidth}px`,\n        height: `${itemHeight}px`,\n      };\n\n      items.push(\n        <div key={i} style={itemStyles}>\n          {renderValue({\n            value,\n            width: itemWidth,\n            height: itemHeight,\n            alignmentFactors,\n            orientation,\n            count: values.length,\n          })}\n        </div>\n      );\n\n      xGrid++;\n\n      if (xGrid === grid.xCount) {\n        xGrid = 0;\n        yGrid++;\n      }\n    }\n\n    return <div style={{ position: 'relative', width: '100%', height: '100%' }}>{items}</div>;\n  }\n\n  render() {\n    const {\n      renderValue,\n      height,\n      width,\n      itemSpacing,\n      getAlignmentFactors,\n      autoGrid,\n      orientation,\n      maxVizHeight,\n      minVizWidth,\n      minVizHeight,\n    } = this.props;\n    const { values } = this.state;\n\n    if (autoGrid && orientation === VizOrientation.Auto) {\n      return this.renderGrid();\n    }\n\n    const itemStyles: React.CSSProperties = {\n      display: 'flex',\n    };\n\n    const repeaterStyle: React.CSSProperties = {\n      display: 'flex',\n      overflowX: `${minVizWidth ? 'auto' : 'hidden'}`,\n      overflowY: `${minVizHeight ? 'auto' : 'hidden'}`,\n    };\n\n    let vizHeight = height;\n    let vizWidth = width;\n\n    const resolvedOrientation = this.getOrientation();\n\n    switch (resolvedOrientation) {\n      case VizOrientation.Horizontal:\n        const defaultVizHeight = (height + itemSpacing) / values.length - itemSpacing;\n        repeaterStyle.flexDirection = 'column';\n        repeaterStyle.height = `${height}px`;\n        repeaterStyle.overflowX = 'hidden';\n        repeaterStyle.scrollbarWidth = 'thin';\n        itemStyles.marginBottom = `${itemSpacing}px`;\n        vizWidth = width;\n        vizHeight = clamp(defaultVizHeight, minVizHeight ?? 0, maxVizHeight ?? defaultVizHeight);\n        break;\n      case VizOrientation.Vertical:\n        repeaterStyle.flexDirection = 'row';\n        repeaterStyle.justifyContent = 'space-between';\n        repeaterStyle.overflowY = 'hidden';\n        itemStyles.marginRight = `${itemSpacing}px`;\n        vizHeight = height;\n        vizWidth = Math.max(width / values.length - itemSpacing + itemSpacing / values.length, minVizWidth ?? 0);\n    }\n\n    itemStyles.width = `${vizWidth}px`;\n    itemStyles.height = `${vizHeight}px`;\n\n    const alignmentFactors = getAlignmentFactors ? getAlignmentFactors(values, vizWidth, vizHeight) : ({} as D);\n\n    return (\n      <div style={repeaterStyle}>\n        {values.map((value, index) => {\n          return (\n            <div key={index} style={getItemStylesForIndex(itemStyles, index, values.length)}>\n              {renderValue({\n                value,\n                width: vizWidth,\n                height: vizHeight,\n                alignmentFactors,\n                orientation: resolvedOrientation,\n                count: values.length,\n              })}\n            </div>\n          );\n        })}\n      </div>\n    );\n  }\n}\n\n/*\n * Removes any padding on the last item\n */\nfunction getItemStylesForIndex(itemStyles: CSSProperties, index: number, length: number): CSSProperties {\n  if (index === length - 1) {\n    return {\n      ...itemStyles,\n      marginRight: 0,\n      marginBottom: 0,\n    };\n  }\n  return itemStyles;\n}\n"],"names":["PureComponent","VizOrientation","calculateGridDimensions","jsx","clamp"],"mappings":"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"}