{"mappings":"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","sources":["packages/react-stately/src/layout/WaterfallLayout.ts"],"sourcesContent":["/*\n * Copyright 2024 Adobe. All rights reserved.\n * This file is licensed to you under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License. You may obtain a copy\n * of the License at http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software distributed under\n * the License is distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR REPRESENTATIONS\n * OF ANY KIND, either express or implied. See the License for the specific language\n * governing permissions and limitations under the License.\n */\n\nimport {DropTarget, DropTargetDelegate, Key, LayoutDelegate, Node} from '@react-types/shared';\nimport {InvalidationContext} from '../virtualizer/types';\nimport {Layout} from '../virtualizer/Layout';\nimport {LayoutInfo} from '../virtualizer/LayoutInfo';\nimport {Point} from '../virtualizer/Point';\nimport {Rect} from '../virtualizer/Rect';\nimport {Size} from '../virtualizer/Size';\n\nexport interface WaterfallLayoutOptions {\n  /**\n   * The minimum item size.\n   * @default 200 x 200\n   */\n  minItemSize?: Size,\n  /**\n   * The maximum item size.\n   * @default Infinity\n   */\n  maxItemSize?: Size,\n  /**\n   * The minimum space required between items.\n   * @default 18 x 18\n   */\n  minSpace?: Size,\n  /**\n   * The maximum allowed horizontal space between items.\n   * @default Infinity\n   */\n  maxHorizontalSpace?: number,\n  /**\n   * The maximum number of columns.\n   * @default Infinity\n   */\n  maxColumns?: number,\n  /**\n   * The thickness of the drop indicator.\n   * @default 2\n   */\n  dropIndicatorThickness?: number,\n  /**\n   * The fixed height of a loader element in px. This loader is specifically for\n   * \"load more\" elements rendered when loading more rows at the root level or inside nested row/sections.\n   * @default 48\n   */\n  loaderHeight?: number\n}\n\nclass WaterfallLayoutInfo extends LayoutInfo {\n  column = 0;\n  index = 0;\n\n  copy(): WaterfallLayoutInfo {\n    let res = super.copy() as WaterfallLayoutInfo;\n    res.column = this.column;\n    res.index = this.index;\n    return res;\n  }\n}\n\nconst DEFAULT_OPTIONS = {\n  minItemSize: new Size(200, 200),\n  maxItemSize: new Size(Infinity, Infinity),\n  minSpace: new Size(18, 18),\n  maxSpace: Infinity,\n  maxColumns: Infinity,\n  dropIndicatorThickness: 2,\n  loaderHeight: 48\n};\n\nexport class WaterfallLayout<T extends object, O extends WaterfallLayoutOptions = WaterfallLayoutOptions> extends Layout<Node<T>, O> implements LayoutDelegate, DropTargetDelegate {\n  private contentSize: Size = new Size();\n  private layoutInfos: Map<Key, WaterfallLayoutInfo> = new Map();\n  protected numColumns = 0;\n  protected dropIndicatorThickness = 2;\n  private margin: number = 0;\n\n  shouldInvalidateLayoutOptions(newOptions: O, oldOptions: O): boolean {\n    return newOptions.maxColumns !== oldOptions.maxColumns\n      || newOptions.dropIndicatorThickness !== oldOptions.dropIndicatorThickness\n      || (!(newOptions.minItemSize || DEFAULT_OPTIONS.minItemSize).equals(oldOptions.minItemSize || DEFAULT_OPTIONS.minItemSize))\n      || (!(newOptions.maxItemSize || DEFAULT_OPTIONS.maxItemSize).equals(oldOptions.maxItemSize || DEFAULT_OPTIONS.maxItemSize))\n      || (!(newOptions.minSpace || DEFAULT_OPTIONS.minSpace).equals(oldOptions.minSpace || DEFAULT_OPTIONS.minSpace))\n      || (newOptions.maxHorizontalSpace !== oldOptions.maxHorizontalSpace)\n      || newOptions.loaderHeight !== oldOptions.loaderHeight;\n  }\n\n  update(invalidationContext: InvalidationContext<O>): void {\n    let {\n      minItemSize = DEFAULT_OPTIONS.minItemSize,\n      maxItemSize = DEFAULT_OPTIONS.maxItemSize,\n      minSpace = DEFAULT_OPTIONS.minSpace,\n      maxHorizontalSpace = DEFAULT_OPTIONS.maxSpace,\n      maxColumns = DEFAULT_OPTIONS.maxColumns,\n      dropIndicatorThickness = DEFAULT_OPTIONS.dropIndicatorThickness,\n      loaderHeight = DEFAULT_OPTIONS.loaderHeight\n    } = invalidationContext.layoutOptions || {};\n    this.dropIndicatorThickness = dropIndicatorThickness;\n    let virtualizerWidth = this.virtualizer!.size.width;\n\n    // The max item width is always the entire viewport.\n    // If the max item height is infinity, scale in proportion to the max width.\n    let maxItemWidth = Math.min(maxItemSize.width, virtualizerWidth);\n    let maxItemHeight = Number.isFinite(maxItemSize.height)\n      ? maxItemSize.height\n      : Math.floor((minItemSize.height / minItemSize.width) * maxItemWidth);\n\n    // Compute the number of rows and columns needed to display the content\n    let columns = Math.floor(virtualizerWidth / (minItemSize.width + minSpace.width));\n    let numColumns = Math.max(1, Math.min(maxColumns, columns));\n\n    // Compute the available width (minus the space between items)\n    let width = virtualizerWidth - (minSpace.width * Math.max(0, numColumns));\n\n    // Compute the item width based on the space available\n    let itemWidth = Math.floor(width / numColumns);\n    itemWidth = Math.max(minItemSize.width, Math.min(maxItemWidth, itemWidth));\n\n    // Compute the item height, which is proportional to the item width\n    let t = ((itemWidth - minItemSize.width) / Math.max(1, maxItemWidth - minItemSize.width));\n    let itemHeight = minItemSize.height +  Math.floor((maxItemHeight - minItemSize.height) * t);\n    itemHeight = Math.max(minItemSize.height, Math.min(maxItemHeight, itemHeight));\n\n    // Compute the horizontal spacing, content height and horizontal margin\n    let horizontalSpacing = Math.min(Math.max(maxHorizontalSpace, minSpace.width), Math.floor((virtualizerWidth - numColumns * itemWidth) / (numColumns + 1)));\n    this.margin = Math.floor((virtualizerWidth - numColumns * itemWidth - horizontalSpacing * (numColumns + 1)) / 2);\n\n    // Setup an array of column heights\n    let columnHeights = Array(numColumns).fill(minSpace.height);\n    let newLayoutInfos = new Map();\n    let index = 0;\n    let addNode = (key: Key, node: Node<T>) => {\n      let oldLayoutInfo = this.layoutInfos.get(key);\n      let height = itemHeight;\n      let estimatedSize = true;\n      if (oldLayoutInfo) {\n        height = oldLayoutInfo.rect.height / oldLayoutInfo.rect.width * itemWidth;\n        estimatedSize = invalidationContext.sizeChanged || oldLayoutInfo.estimatedSize || oldLayoutInfo.content !== node;\n      }\n\n      // Figure out which column to place the item in, and compute its position.\n      // Preserve the previous column index so items don't jump around during resizing unless the number of columns changed.\n      let prevColumn = numColumns === this.numColumns && oldLayoutInfo && oldLayoutInfo.index === index && oldLayoutInfo.rect.y < this.virtualizer!.visibleRect.maxY ? oldLayoutInfo.column : undefined;\n      let column = prevColumn ?? columnHeights.reduce((minIndex, h, i) => h < columnHeights[minIndex] ? i : minIndex, 0);\n      let x = horizontalSpacing + column * (itemWidth + horizontalSpacing) + this.margin;\n      let y = columnHeights[column];\n\n      let rect = new Rect(x, y, itemWidth, height);\n      let layoutInfo = new WaterfallLayoutInfo(node.type, key, rect);\n      layoutInfo.estimatedSize = estimatedSize;\n      layoutInfo.allowOverflow = true;\n      layoutInfo.content = node;\n      layoutInfo.column = column;\n      layoutInfo.index = index++;\n      newLayoutInfos.set(key, layoutInfo);\n\n      columnHeights[column] += layoutInfo.rect.height + minSpace.height;\n    };\n\n    let collection = this.virtualizer!.collection;\n    let skeletonCount = 0;\n    for (let node of collection) {\n      if (node.type === 'skeleton') {\n        // Add skeleton cards until every column has at least one, and we fill the viewport.\n        let startingHeights = [...columnHeights];\n        while (\n          !columnHeights.every((h, i) => h !== startingHeights[i]) ||\n          Math.min(...columnHeights) < this.virtualizer!.size.height\n        ) {\n          let key = `${node.key}-${skeletonCount++}`;\n          let content = this.layoutInfos.get(key)?.content || {...node};\n          addNode(key, content);\n        }\n        break;\n      } else if (node.type !== 'loader') {\n        addNode(node.key, node);\n      }\n    }\n\n    // Reset all columns to the maximum for the next section. If loading, set to 0 so virtualizer doesn't render its body since there aren't items to render,\n    // except if we are performing skeleton loading\n    let isEmptyOrLoading = collection?.size === 0 && collection.getItem(collection.getFirstKey()!)?.type !== 'skeleton';\n    let maxHeight = isEmptyOrLoading ? 0 : Math.max(...columnHeights);\n\n    // Always add the loader sentinel if present in the collection so we can make sure it is never virtualized out.\n    // Add it under the first column for simplicity\n    let lastNode = collection.getItem(collection.getLastKey()!);\n    if (lastNode?.type === 'loader') {\n      if (skeletonCount > 0 || !lastNode.props.isLoading) {\n        loaderHeight = 0;\n      }\n      const loaderWidth = virtualizerWidth - horizontalSpacing * 2;\n      // Note that if the user provides isLoading to their sentinel during a case where they only want to render the emptyState, this will reserve\n      // room for the loader alongside rendering the emptyState\n      let rect = new Rect(horizontalSpacing, maxHeight, loaderWidth, loaderHeight);\n      let layoutInfo = new LayoutInfo('loader', lastNode.key, rect);\n      newLayoutInfos.set(lastNode.key, layoutInfo);\n      maxHeight = layoutInfo.rect.maxY;\n    }\n\n    this.contentSize = new Size(this.virtualizer!.size.width, maxHeight);\n    this.layoutInfos = newLayoutInfos;\n    this.numColumns = numColumns;\n  }\n\n  getLayoutInfo(key: Key): LayoutInfo {\n    return this.layoutInfos.get(key)!;\n  }\n\n  getContentSize(): Size {\n    return this.contentSize;\n  }\n\n  getVisibleLayoutInfos(rect: Rect): LayoutInfo[] {\n    let layoutInfos: LayoutInfo[] = [];\n    for (let layoutInfo of this.layoutInfos.values()) {\n      if (layoutInfo.rect.intersects(rect) || this.virtualizer!.isPersistedKey(layoutInfo.key) || layoutInfo.type === 'loader') {\n        layoutInfos.push(layoutInfo);\n      }\n    }\n    return layoutInfos;\n  }\n\n  updateItemSize(key: Key, size: Size): boolean {\n    let layoutInfo = this.layoutInfos.get(key);\n    if (!size || !layoutInfo) {\n      return false;\n    }\n\n    if (size.height !== layoutInfo.rect.height) {\n      let newLayoutInfo = layoutInfo.copy();\n      newLayoutInfo.rect.height = size.height;\n      newLayoutInfo.estimatedSize = false;\n      this.layoutInfos.set(key, newLayoutInfo);\n      return true;\n    }\n\n    return false;\n  }\n\n  // Override keyboard navigation to work spatially.\n  getKeyRightOf(key: Key): Key | null {\n    let layoutInfo = this.getLayoutInfo(key);\n    if (!layoutInfo) {\n      return null;\n    }\n\n    let rect = new Rect(layoutInfo.rect.maxX, layoutInfo.rect.y, this.virtualizer!.visibleRect.maxX - layoutInfo.rect.maxX, layoutInfo.rect.height);\n    let layoutInfos = this.getVisibleLayoutInfos(rect);\n    let bestKey: Key | null = null;\n    let bestDistance = Infinity;\n    for (let candidate of layoutInfos) {\n      if (candidate.key === key) {\n        continue;\n      }\n\n      // Find the closest item in the x direction with the most overlap in the y direction.\n      let deltaX = candidate.rect.x - rect.x;\n      let overlapY = Math.min(candidate.rect.maxY, rect.maxY) - Math.max(candidate.rect.y, rect.y);\n      let distance = deltaX - overlapY;\n      if (distance < bestDistance) {\n        bestDistance = distance;\n        bestKey = candidate.key;\n      }\n    }\n\n    return bestKey;\n  }\n\n  getKeyLeftOf(key: Key): Key | null {\n    let layoutInfo = this.getLayoutInfo(key);\n    if (!layoutInfo) {\n      return null;\n    }\n\n    let rect = new Rect(0, layoutInfo.rect.y, layoutInfo.rect.x, layoutInfo.rect.height);\n    let layoutInfos = this.getVisibleLayoutInfos(rect);\n    let bestKey: Key | null = null;\n    let bestDistance = Infinity;\n    for (let candidate of layoutInfos) {\n      if (candidate.key === key) {\n        continue;\n      }\n\n      // Find the closest item in the x direction with the most overlap in the y direction.\n      let deltaX = rect.maxX - candidate.rect.maxX;\n      let overlapY = Math.min(candidate.rect.maxY, rect.maxY) - Math.max(candidate.rect.y, rect.y);\n      let distance = deltaX - overlapY;\n      if (distance < bestDistance) {\n        bestDistance = distance;\n        bestKey = candidate.key;\n      }\n    }\n\n    return bestKey;\n  }\n\n  // This overrides the default behavior of shift selection to work spatially\n  // rather than following the order of the items in the collection (which may appear unpredictable).\n  getKeyRange(from: Key, to: Key): Key[] {\n    let fromLayoutInfo = this.getLayoutInfo(from);\n    let toLayoutInfo = this.getLayoutInfo(to);\n    if (!fromLayoutInfo || !toLayoutInfo) {\n      return [];\n    }\n\n    // Find items where half of the area intersects the rectangle\n    // formed from the first item to the last item in the range.\n    let rect = fromLayoutInfo.rect.union(toLayoutInfo.rect);\n    let keys: Key[] = [];\n    for (let layoutInfo of this.layoutInfos.values()) {\n      if (rect.intersection(layoutInfo.rect).area > layoutInfo.rect.area / 2) {\n        keys.push(layoutInfo.key);\n      }\n    }\n    return keys;\n  }\n\n  getDropTargetFromPoint(x: number, y: number): DropTarget {\n    if (this.layoutInfos.size === 0) {\n      return {type: 'root'};\n    }\n\n    x += this.virtualizer!.visibleRect.x;\n    y += this.virtualizer!.visibleRect.y;\n    let key = this.virtualizer!.keyAtPoint(new Point(x, y));\n    if (key == null) {\n      return {type: 'root'};\n    }\n\n    // Only support \"on\" drop position in waterfall layout.\n    // Reordering doesn't make sense because the items don't have a deterministic order.\n    return {\n      type: 'item',\n      key,\n      dropPosition: 'on'\n    };\n  }\n}\n"],"names":[],"version":3,"file":"WaterfallLayout.cjs.map"}