@vimeo/iris
Version:
Vimeo Design System
73 lines (70 loc) • 3.81 kB
JavaScript
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 };