react-fast-masonry
Version:
A fast masonry infinite-scrolling component using the intersection api
115 lines (114 loc) • 5.11 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const jsx_runtime_1 = require("react/jsx-runtime");
const react_1 = __importStar(require("react"));
const index_1 = __importDefault(require("../../../index"));
const defaultStyles = {
display: "flex",
justifyContent: "center",
alignItems: "center",
color: "white",
fontSize: "24px",
fontWeight: "bold",
fontFamily: `"Helvetica Neue", Helvetica, Arial, sans-serif`
};
const colors = [
"cornflowerblue",
"tomato",
"steelblue",
"slategrey",
"turquoise",
"teal",
"darkcyan",
"darkseagreen",
"coral"
];
const randomInt = (min, max) => {
min = Math.ceil(min);
max = Math.floor(max);
// The maximum is inclusive and the minimum is inclusive
return Math.floor(Math.random() * (max - min + 1)) + min;
};
const randomItems = (n = 20) => new Array(n).fill(0).map(() => ({
width: 300,
height: randomInt(100, 1000),
backgroundColor: colors[randomInt(0, colors.length - 1)]
}));
const concatRandomItems = (items, type = "append") => {
const randomItemList = randomItems();
return type === "append"
? [...items, ...randomItemList]
: [...randomItemList, ...items];
};
function closestScrollArea(element) {
if (element instanceof HTMLElement &&
element.scroll &&
element.scrollHeight > 0) {
return element;
}
return (element === null || element === void 0 ? void 0 : element.parentNode) ? closestScrollArea(element.parentNode) : null;
}
function MyMasonry() {
const container = (0, react_1.useRef)(undefined);
const [items, setItems] = react_1.default.useState([]);
const [scrollTarget, setScrollTarget] = react_1.default.useState(null);
(0, react_1.useLayoutEffect)(() => {
setTimeout(() => {
console.log({ scrollTarget });
scrollTarget === null || scrollTarget === void 0 ? void 0 : scrollTarget.scrollIntoView(true);
}, 10);
}, [items]);
return ((0, jsx_runtime_1.jsx)("div", Object.assign({ ref: r => {
if (!r)
return;
container.current = r;
}, style: {
transform: `rotate(180deg)`
} }, { children: (0, jsx_runtime_1.jsx)(index_1.default, { pack: true, sizes: [
{ columns: 1, gutter: 0, columnWidth: "100%" },
{ cq: 768, columns: 2, gutter: 20, columnWidth: 300 },
{ cq: 1024, columns: 3, gutter: 20, columnWidth: 400 }
], items: items, renderItem: ({ columnWidth }, index, key) => ((0, jsx_runtime_1.jsx)("div", Object.assign({ style: Object.assign(Object.assign(Object.assign({ transform: `rotate(-180deg)` }, items[index]), defaultStyles), { width: columnWidth }) }, { children: index }), key)), loadMore: () => {
if (!container.current)
return;
const masonryEl = container.current.querySelector(".masonry");
let scrollTarget2 = masonryEl === null || masonryEl === void 0 ? void 0 : masonryEl.lastChild;
// Get the last HTMLElement (this will grab the sentinel)
while (!(scrollTarget2 instanceof HTMLElement)) {
scrollTarget2 = scrollTarget2 === null || scrollTarget2 === void 0 ? void 0 : scrollTarget2.previousSibling;
}
// Get the last HTMLElement besides the sentinel.
scrollTarget2 = scrollTarget2 === null || scrollTarget2 === void 0 ? void 0 : scrollTarget2.previousSibling;
while (!(scrollTarget2 instanceof HTMLElement)) {
scrollTarget2 = scrollTarget2 === null || scrollTarget2 === void 0 ? void 0 : scrollTarget2.previousSibling;
}
if (scrollTarget2) {
setScrollTarget(scrollTarget2);
console.log({ scrollTarget2 });
}
setItems([...items, ...randomItems()]);
}, awaitMore: true, pageSize: 20, className: "masonry" }, void 0) }), void 0));
}
exports.default = MyMasonry;