1 | {"version":3,"file":"TilesContainer.js","sources":["../../../src/tile-layout/TilesContainer.tsx"],"sourcesContent":["import React, { useEffect, useMemo, useRef, useState } from 'react';\nimport { useTileTable } from './useTileTable';\nimport { useMeasure } from 'react-use';\nimport styles from './TilesContainer.module.css';\nimport { useComposeRef } from '../utils/useComposedRef';\nimport { jc } from '../utils/joinclasses';\nimport { isEqual } from 'lodash-es';\nimport {\n TileInfo,\n RenderTileFunction,\n RenderInsertIndicatorFunction,\n RenderTileProps,\n} from './model';\n\nexport interface TilesContainerBaseProps<T> {\n /**\n * width/height ration\n */\n data: T[];\n renderTile: RenderTileFunction<T>;\n renderInsertIndicator?: RenderInsertIndicatorFunction;\n ratio?: number;\n forceTileHeight?: number;\n acceptsDrop?: (source: T, target: T) => boolean;\n onTileDrop?: (source: T, target: T) => boolean;\n tileSize?: (data: T) => { rowSpan: number; colSpan: number };\n disabled?: boolean;\n onReorderTiles?: (reorderedData: T[]) => void;\n activeBorderSize?: number;\n strategy?: 'reorder' | 'move';\n}\n\nexport interface TilesContainerColsProps<T> extends TilesContainerBaseProps<T> {\n columns: number;\n}\n\nexport interface TilesContainerForcedSizeProps<T>\n extends TilesContainerBaseProps<T> {\n forceTileWidth: number;\n}\n\nconst TileUI = React.memo(\n <T,>({\n renderTile,\n ...props\n }: { renderTile: RenderTileFunction<T> } & RenderTileProps<T>) => {\n return renderTile(props);\n }\n);\n\nconst isTilesContainerForcedSizeProps = <T,>(\n props: TilesContainerBaseProps<T>\n): props is TilesContainerForcedSizeProps<T> => !!(props as any).forceTileWidth;\n\nconst isTilesContainerColsProps = <T,>(\n props: TilesContainerBaseProps<T>\n): props is TilesContainerColsProps<T> => !!(props as any).columns;\n\nexport type TilesContainerProps<T> =\n | TilesContainerColsProps<T>\n | TilesContainerForcedSizeProps<T>;\n\nconst defaultTileSize = () => ({ rowSpan: 1, colSpan: 1 });\n\ntype DataWithKeys<T> = {\n item: T;\n key: number;\n};\n\nlet lastKey = 0;\nconst dataWithKeys = <T,>(\n data: T[],\n dataWithKeys: DataWithKeys<T>[]\n): DataWithKeys<T>[] => {\n return data.map(item => {\n const existingItem = dataWithKeys.find(k => k.item === item);\n return existingItem || { item, key: lastKey++ };\n });\n};\n\nexport const TilesContainer = <T,>(props: TilesContainerProps<T>) => {\n const containerRef = useRef<HTMLDivElement>(null);\n const [measureRef, measure] = useMeasure<HTMLDivElement>();\n\n const forceTileWidth = isTilesContainerForcedSizeProps(props)\n ? props.forceTileWidth\n : 0;\n const columns = isTilesContainerColsProps(props)\n ? props.columns\n : forceTileWidth\n ? Math.floor(measure.width / forceTileWidth)\n : 4;\n const {\n onReorderTiles,\n ratio = 1,\n forceTileHeight,\n data: propsData,\n acceptsDrop,\n onTileDrop,\n tileSize = defaultTileSize,\n renderTile,\n renderInsertIndicator,\n activeBorderSize = 24,\n disabled,\n strategy = 'move',\n } = props;\n\n const tileWidth = forceTileWidth || measure.width / columns;\n const tileHeight = forceTileHeight || tileWidth / ratio;\n\n const [data, setData] = useState<DataWithKeys<T>[]>(() =>\n dataWithKeys(propsData, [])\n );\n useEffect(\n () => setData(curr => dataWithKeys(propsData, curr)),\n [propsData, setData]\n );\n\n //extract the tiles from the props\n const propsTiles = useMemo(() => {\n const tiles: TileInfo<T>[] = [];\n data.forEach(({ item: tile, key }) =>\n tiles.push({\n key,\n ...tileSize(tile),\n data: tile,\n })\n );\n return tiles;\n }, [data, tileSize]);\n\n const { bind, renderTileProps, tableHeight, insertIndicatorPosition } =\n useTileTable({\n columns,\n strategy,\n enabled: !disabled,\n elementHeight: tileHeight,\n elementWidth: tileWidth,\n activeBorderSize,\n currentTiles: propsTiles,\n canAcceptDrop: (source, target) => {\n return acceptsDrop ? acceptsDrop(source.data, target.data) : false;\n },\n changeTilesOrder: tiles => {\n const newData = tiles.map(tile => tile.data);\n const actualData = data.map(tile => tile.item);\n if (!isEqual(actualData, newData)) {\n setData(curr => dataWithKeys(newData, curr));\n onReorderTiles && onReorderTiles(newData);\n }\n },\n didDrop: (source, target) => {\n setData(tiles => tiles.filter(tile => tile.item !== source.data));\n onTileDrop && onTileDrop(source.data, target.data);\n },\n });\n\n const insertIndicator = useMemo(() => {\n if (!insertIndicatorPosition || !renderInsertIndicator) {\n return null;\n }\n const { x, y } = insertIndicatorPosition;\n return (\n <div\n className={styles.indicator}\n style={{\n top: `${y}px`,\n left: `${x}px`,\n height: `${tileHeight}px`,\n width: `${tileWidth}px`,\n }}\n >\n {renderInsertIndicator()}\n </div>\n );\n }, [insertIndicatorPosition, renderInsertIndicator, tileHeight, tileWidth]);\n\n const tiles = useMemo(\n () =>\n renderTileProps.map(({ x, y, key, ...props }) => (\n <div\n className={jc(styles.tile, props.isDragging && styles.dragging)}\n key={`K-${key}`}\n style={{\n top: `${y}px`,\n left: `${x}px`,\n width: `${props.colSpan * tileWidth}px`,\n height: `${props.rowSpan * tileHeight}px`,\n }}\n {...bind(props.data)}\n >\n <TileUI {...props} renderTile={renderTile as any} />\n </div>\n )),\n [renderTileProps, renderTile, bind, tileWidth, tileHeight]\n );\n\n return (\n <div\n className={styles.container}\n ref={useComposeRef(containerRef, measureRef)}\n style={{ height: `${tableHeight}px`, minWidth: `${tileWidth}px` }}\n >\n {insertIndicator}\n {tiles}\n </div>\n );\n};\n"],"names":[],"mappings":"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"} |
---|