UNPKG

@vimeo/iris

Version:
73 lines (70 loc) 3.81 kB
import { b as __rest, _ as __read, c as __assign } from '../../tslib.es6-7f0e734f.js'; import React__default, { useReducer, useRef, useImperativeHandle, useEffect, cloneElement } from 'react'; import { Styled } from './Grid.style.esm.js'; import { reducer, initialState } from './Grid.state.esm.js'; import { withIris } from '../../utils/HOCs/withIris.esm.js'; import { useMeasure } from '../../utils/hooks/useMeasure.esm.js'; import 'styled-components'; import 'polished'; import 'react-dom'; import '../../utils/DOM/createPortalOutlet.esm.js'; import '../../utils/DOM/SSR.esm.js'; import '../../utils/DOM/createElement.esm.js'; import '../../utils/DOM/geometry.esm.js'; import '../../utils/DOM/removeElementByID.esm.js'; var Grid = withIris(GridComponent); function GridComponent(_a) { var _b; var children = _a.children, masonry = _a.masonry, _c = _a.columns, columns = _c === void 0 ? 4 : _c, featured = _a.featured, forwardRef = _a.forwardRef, props = __rest(_a, ["children", "masonry", "columns", "featured", "forwardRef"]); var _d = __read(useReducer(reducer, initialState()), 2), state = _d[0], dispatch = _d[1]; var gridGap = state.gridGap; var ref = useRef(null); useImperativeHandle(forwardRef, function () { return ref.current; }, [ref]); var _e = __read(useMeasure(React__default.createElement("div", null, children), { depth: 1 }), 2), measuredGridItems = _e[0], data = _e[1]; useEffect(function () { var _a, _b, _c; var lastGap = gridGap; var gap = parseInt((_c = (_b = (_a = ref.current) === null || _a === void 0 ? void 0 : _a.style) === null || _b === void 0 ? void 0 : _b.gap.slice(0, -2)) !== null && _c !== void 0 ? _c : 0); var gapChanged = !Number.isNaN(gap) && gap !== lastGap && gap > 0; if (gapChanged) dispatch({ type: 'SET_GRID_GAP', payload: gap }); }, [gridGap]); function applyGridStyles(_a, i, height) { var style = _a.props.style; var gridColumn = featured === i ? '1/-1' : ''; if (!masonry) return __assign(__assign({}, style), { gridColumn: gridColumn }); // masonry requires us to calculate `grid-row-end` for each // child based upon the child's height var marginBottom = gridGap; var gridRowEnd = 'span ' + (height + gridGap + 1); return __assign(__assign({}, style), { gridRowEnd: gridRowEnd, marginBottom: marginBottom, gridColumn: gridColumn }); } function cloneWithStyles(heights) { return function (child, i) { var style = applyGridStyles(child, i, heights[i]); return cloneElement(child, { style: style }); }; } function rebuildChildren() { var _a; // if useMeasure returns a portal to perform a measure if (measuredGridItems.type !== 'div') return children; // if useMeasure returns the component(s) with the measurements if (measuredGridItems.type === 'div') { var heights = (_a = data === null || data === void 0 ? void 0 : data.children) === null || _a === void 0 ? void 0 : _a.map(function (_a) { var height = _a.height; return height; }); var children_1 = measuredGridItems.props.children; var gridItems = children_1.map(cloneWithStyles(heights)); return gridItems; } } children = ((_b = measuredGridItems === null || measuredGridItems === void 0 ? void 0 : measuredGridItems.props) === null || _b === void 0 ? void 0 : _b.children) ? rebuildChildren() : measuredGridItems; return (React__default.createElement(Styled, __assign({ columns: columns, masonry: masonry, gridGap: gridGap, ref: ref, stagger: false }, props), children)); } export { Grid };