map • Lines: 1{"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 *\n * @default 200 x 200\n */\n minItemSize?: Size;\n /**\n * The maximum item size.\n *\n * @default Infinity\n */\n maxItemSize?: Size;\n /**\n * The minimum space required between items.\n *\n * @default 18 x 18\n */\n minSpace?: Size;\n /**\n * The maximum allowed horizontal space between items.\n *\n * @default Infinity\n */\n maxHorizontalSpace?: number;\n /**\n * The maximum number of columns.\n *\n * @default Infinity\n */\n maxColumns?: number;\n /**\n * The thickness of the drop indicator.\n *\n * @default 2\n */\n dropIndicatorThickness?: number;\n /**\n * The fixed height of a loader element in px. This loader is specifically for \"load more\"\n * elements rendered when loading more rows at the root level or inside nested row/sections.\n *\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<\n T extends object,\n O extends WaterfallLayoutOptions = WaterfallLayoutOptions\n>\n extends Layout<Node<T>, O>\n implements LayoutDelegate, DropTargetDelegate\n{\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 (\n newOptions.maxColumns !== oldOptions.maxColumns ||\n newOptions.dropIndicatorThickness !== oldOptions.dropIndicatorThickness ||\n !(newOptions.minItemSize || DEFAULT_OPTIONS.minItemSize).equals(\n oldOptions.minItemSize || DEFAULT_OPTIONS.minItemSize\n ) ||\n !(newOptions.maxItemSize || DEFAULT_OPTIONS.maxItemSize).equals(\n oldOptions.maxItemSize || DEFAULT_OPTIONS.maxItemSize\n ) ||\n !(newOptions.minSpace || DEFAULT_OPTIONS.minSpace).equals(\n oldOptions.minSpace || DEFAULT_OPTIONS.minSpace\n ) ||\n newOptions.maxHorizontalSpace !== oldOptions.maxHorizontalSpace ||\n newOptions.loaderHeight !== oldOptions.loaderHeight\n );\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(\n Math.max(maxHorizontalSpace, minSpace.width),\n Math.floor((virtualizerWidth - numColumns * itemWidth) / (numColumns + 1))\n );\n this.margin = Math.floor(\n (virtualizerWidth - numColumns * itemWidth - horizontalSpacing * (numColumns + 1)) / 2\n );\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 =\n invalidationContext.sizeChanged ||\n oldLayoutInfo.estimatedSize ||\n 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 =\n numColumns === this.numColumns &&\n oldLayoutInfo &&\n oldLayoutInfo.index === index &&\n oldLayoutInfo.rect.y < this.virtualizer!.visibleRect.maxY\n ? oldLayoutInfo.column\n : undefined;\n let column =\n prevColumn ??\n 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 =\n 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 (\n layoutInfo.rect.intersects(rect) ||\n this.virtualizer!.isPersistedKey(layoutInfo.key) ||\n layoutInfo.type === 'loader'\n ) {\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(\n layoutInfo.rect.maxX,\n layoutInfo.rect.y,\n this.virtualizer!.visibleRect.maxX - layoutInfo.rect.maxX,\n layoutInfo.rect.height\n );\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"}