@trap_stevo/legendarybuilderproreact-ui
Version:
The legendary UI & utility API that makes your application a legendary application. ~ Created by Steven Compton
382 lines • 18.6 kB
JavaScript
import _slicedToArray from "@babel/runtime/helpers/slicedToArray";
import _defineProperty from "@babel/runtime/helpers/defineProperty";
function _createForOfIteratorHelper(o, allowArrayLike) { var it = typeof Symbol !== "undefined" && o[Symbol.iterator] || o["@@iterator"]; if (!it) { if (Array.isArray(o) || (it = _unsupportedIterableToArray(o)) || allowArrayLike && o && typeof o.length === "number") { if (it) o = it; var i = 0; var F = function F() {}; return { s: F, n: function n() { if (i >= o.length) return { done: true }; return { done: false, value: o[i++] }; }, e: function e(_e) { throw _e; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var normalCompletion = true, didErr = false, err; return { s: function s() { it = it.call(o); }, n: function n() { var step = it.next(); normalCompletion = step.done; return step; }, e: function e(_e2) { didErr = true; err = _e2; }, f: function f() { try { if (!normalCompletion && it["return"] != null) it["return"](); } finally { if (didErr) throw err; } } }; }
function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
import React, { useState, useEffect, useRef, useMemo, useCallback } from "react";
var baseListConfigurationSettings = {
position: "relative",
display: "flex",
flexDirection: "column",
overflow: "auto",
boxSizing: "border-box",
height: "100%",
width: "100%"
};
var clamp = function clamp(n, lo, hi) {
return Math.max(lo, Math.min(hi, n));
};
var VirtualListItem = /*#__PURE__*/React.memo(function VirtualListItem(_ref) {
var indexSpecificHoverConfigurationSettings = _ref.indexSpecificHoverConfigurationSettings,
indexSpecificClickConfigurationSettings = _ref.indexSpecificClickConfigurationSettings,
clickAnimationConfigurationSettings = _ref.clickAnimationConfigurationSettings,
hoverAnimationConfigurationSettings = _ref.hoverAnimationConfigurationSettings,
indexSpecificConfigurationSettings = _ref.indexSpecificConfigurationSettings,
cellConfigurationSettings = _ref.cellConfigurationSettings,
observeRef = _ref.observeRef,
onContext = _ref.onContext,
onDouble = _ref.onDouble,
onEnter = _ref.onEnter,
onLeave = _ref.onLeave,
_onClick = _ref.onClick,
renderCellStable = _ref.renderCellStable,
transitionDuration = _ref.transitionDuration,
verticalList = _ref.verticalList,
hovered = _ref.hovered,
clicked = _ref.clicked,
index = _ref.index,
item = _ref.item;
var setNode = useCallback(function (node) {
return observeRef(index, node);
}, [observeRef, index]);
var style = useMemo(function () {
var base = {
pointerEvents: "auto",
userSelect: "none",
cursor: "pointer",
transition: "all ".concat(transitionDuration, " ease"),
width: verticalList ? "100%" : "auto"
};
var cellBase = typeof cellConfigurationSettings === "function" ? cellConfigurationSettings(item, index) : cellConfigurationSettings || {};
var idxBase = (indexSpecificConfigurationSettings === null || indexSpecificConfigurationSettings === void 0 ? void 0 : indexSpecificConfigurationSettings[index]) || {};
var hoverBase = hovered ? typeof hoverAnimationConfigurationSettings === "function" ? hoverAnimationConfigurationSettings(index) : hoverAnimationConfigurationSettings || {} : {};
var hoverIdx = hovered ? (indexSpecificHoverConfigurationSettings === null || indexSpecificHoverConfigurationSettings === void 0 ? void 0 : indexSpecificHoverConfigurationSettings[index]) || {} : {};
var clickBase = clicked ? typeof clickAnimationConfigurationSettings === "function" ? clickAnimationConfigurationSettings(index) : clickAnimationConfigurationSettings || {} : {};
var clickIdx = clicked ? (indexSpecificClickConfigurationSettings === null || indexSpecificClickConfigurationSettings === void 0 ? void 0 : indexSpecificClickConfigurationSettings[index]) || {} : {};
return _objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread(_objectSpread({}, base), cellBase), idxBase), hoverBase), hoverIdx), clickBase), clickIdx);
}, [indexSpecificHoverConfigurationSettings, indexSpecificClickConfigurationSettings, clickAnimationConfigurationSettings, hoverAnimationConfigurationSettings, indexSpecificConfigurationSettings, cellConfigurationSettings, transitionDuration, verticalList, hovered, clicked, item, index]);
return /*#__PURE__*/React.createElement("div", {
ref: setNode,
style: style,
onContextMenu: function onContextMenu(e) {
return onContext(item, index, e);
},
onDoubleClick: function onDoubleClick() {
return onDouble(item, index);
},
onMouseEnter: function onMouseEnter() {
return onEnter(item, index);
},
onMouseLeave: function onMouseLeave() {
return onLeave(item, index);
},
onClick: function onClick() {
return _onClick(item, index);
}
}, renderCellStable(item, index, hovered ? index : null, clicked ? index : null));
});
function HUDVirtualList(_ref2) {
var _ref2$indexSpecificHo = _ref2.indexSpecificHoverConfigurationSettings,
indexSpecificHoverConfigurationSettings = _ref2$indexSpecificHo === void 0 ? {} : _ref2$indexSpecificHo,
_ref2$indexSpecificCl = _ref2.indexSpecificClickConfigurationSettings,
indexSpecificClickConfigurationSettings = _ref2$indexSpecificCl === void 0 ? {} : _ref2$indexSpecificCl,
_ref2$hoverAnimationC = _ref2.hoverAnimationConfigurationSettings,
hoverAnimationConfigurationSettings = _ref2$hoverAnimationC === void 0 ? {} : _ref2$hoverAnimationC,
_ref2$clickAnimationC = _ref2.clickAnimationConfigurationSettings,
clickAnimationConfigurationSettings = _ref2$clickAnimationC === void 0 ? {} : _ref2$clickAnimationC,
_ref2$indexSpecificCo = _ref2.indexSpecificConfigurationSettings,
indexSpecificConfigurationSettings = _ref2$indexSpecificCo === void 0 ? {} : _ref2$indexSpecificCo,
_ref2$listConfigurati = _ref2.listConfigurationSettings,
listConfigurationSettings = _ref2$listConfigurati === void 0 ? {} : _ref2$listConfigurati,
_ref2$cellConfigurati = _ref2.cellConfigurationSettings,
cellConfigurationSettings = _ref2$cellConfigurati === void 0 ? {} : _ref2$cellConfigurati,
_ref2$keyExtractor = _ref2.keyExtractor,
keyExtractor = _ref2$keyExtractor === void 0 ? function (item, index) {
return index;
} : _ref2$keyExtractor,
onCellDoubleClick = _ref2.onCellDoubleClick,
onCellRightClick = _ref2.onCellRightClick,
onCellHover = _ref2.onCellHover,
onCellClick = _ref2.onCellClick,
renderCell = _ref2.renderCell,
_ref2$fallbackCellVir = _ref2.fallbackCellVirtualHeight,
fallbackCellVirtualHeight = _ref2$fallbackCellVir === void 0 ? 40 : _ref2$fallbackCellVir,
_ref2$transitionDurat = _ref2.transitionDuration,
transitionDuration = _ref2$transitionDurat === void 0 ? "0.369s" : _ref2$transitionDurat,
_ref2$initiallyClicke = _ref2.initiallyClicked,
initiallyClicked = _ref2$initiallyClicke === void 0 ? -1 : _ref2$initiallyClicke,
_ref2$listType = _ref2.listType,
listType = _ref2$listType === void 0 ? "vertical" : _ref2$listType,
_ref2$overscan = _ref2.overscan,
overscan = _ref2$overscan === void 0 ? 3 : _ref2$overscan,
_ref2$gap = _ref2.gap,
gap = _ref2$gap === void 0 ? 10 : _ref2$gap,
items = _ref2.items;
var _useState = useState({
start: 0,
end: 20
}),
_useState2 = _slicedToArray(_useState, 2),
visibleRange = _useState2[0],
setVisibleRange = _useState2[1];
var _useState3 = useState(null),
_useState4 = _slicedToArray(_useState3, 2),
hoveredIndex = _useState4[0],
setHoveredIndex = _useState4[1];
var _useState5 = useState(null),
_useState6 = _slicedToArray(_useState5, 2),
clickedIndex = _useState6[0],
setClickedIndex = _useState6[1];
var _useState7 = useState({}),
_useState8 = _slicedToArray(_useState7, 2),
cellHeights = _useState8[0],
setCellHeights = _useState8[1];
var resizeObservers = useRef(new Map());
var renderCellRef = useRef(renderCell);
var itemRefs = useRef(new Map());
var rafScrollId = useRef(null);
var scrollRef = useRef(null);
var verticalList = useMemo(function () {
return listType === "vertical";
}, [listType]);
var sizeAt = useCallback(function (i) {
var _cellHeights$i;
return (_cellHeights$i = cellHeights[i]) !== null && _cellHeights$i !== void 0 ? _cellHeights$i : fallbackCellVirtualHeight;
}, [cellHeights, fallbackCellVirtualHeight]);
var prefix = useMemo(function () {
var arr = new Array(items.length + 1);
arr[0] = 0;
for (var i = 0; i < items.length; i++) {
arr[i + 1] = arr[i] + sizeAt(i);
}
return arr;
}, [items.length, sizeAt]);
var offsetForIndex = useCallback(function (i) {
return i <= 0 ? 0 : prefix[i] + i * gap;
}, [prefix, gap]);
var totalScrollArea = useMemo(function () {
return prefix[items.length] + Math.max(0, items.length - 1) * gap;
}, [prefix, items.length, gap]);
var scrollOffset = useMemo(function () {
return offsetForIndex(visibleRange.start);
}, [visibleRange.start, offsetForIndex]);
var visibleItems = useMemo(function () {
var start = visibleRange.start,
end = visibleRange.end;
return items.slice(start, end + 1);
}, [items, visibleRange]);
var containerStyle = useMemo(function () {
return _objectSpread(_objectSpread(_objectSpread({}, baseListConfigurationSettings), listConfigurationSettings), {}, {
flexDirection: verticalList ? "column" : "row",
overflowY: verticalList ? "auto" : "hidden",
overflowX: verticalList ? "hidden" : "auto"
});
}, [listConfigurationSettings, verticalList]);
var trackStyle = useMemo(function () {
return {
position: "relative",
boxSizing: "border-box",
height: verticalList ? "".concat(totalScrollArea, "px") : "100%",
width: verticalList ? "100%" : "".concat(totalScrollArea, "px")
};
}, [verticalList, totalScrollArea]);
var windowStyle = useMemo(function () {
return {
position: "absolute",
display: "flex",
flexDirection: verticalList ? "column" : "row",
transform: verticalList ? "translateY(".concat(scrollOffset, "px)") : "translateX(".concat(scrollOffset, "px)"),
height: verticalList ? "auto" : "100%",
width: verticalList ? "100%" : "auto",
gap: gap
};
}, [verticalList, scrollOffset, gap]);
var findStartIndex = useCallback(function (scrollPos) {
var lo = 0,
hi = items.length;
while (lo < hi) {
var mid = lo + hi >> 1;
var endPos = offsetForIndex(mid + 1);
if (endPos <= scrollPos) {
lo = mid + 1;
} else {
hi = mid;
}
}
return Math.max(0, lo - 1);
}, [items.length, offsetForIndex]);
var findEndIndex = useCallback(function (scrollPos, viewSize) {
var target = scrollPos + viewSize;
var lo = 0,
hi = items.length;
while (lo < hi) {
var mid = lo + hi >> 1;
var startPos = offsetForIndex(mid);
if (startPos < target) {
lo = mid + 1;
} else {
hi = mid;
}
}
return Math.max(0, lo - 1);
}, [items.length, offsetForIndex]);
var scheduleRangeUpdate = useCallback(function () {
if (!scrollRef.current) {
return;
}
if (rafScrollId.current) {
cancelAnimationFrame(rafScrollId.current);
}
rafScrollId.current = requestAnimationFrame(function () {
var viewSize = verticalList ? scrollRef.current.clientHeight : scrollRef.current.clientWidth;
var scrollPos = verticalList ? scrollRef.current.scrollTop : scrollRef.current.scrollLeft;
var startCore = findStartIndex(scrollPos);
var endCore = findEndIndex(scrollPos, viewSize);
var start = clamp(startCore - overscan, 0, items.length - 1);
var end = clamp(endCore + overscan, 0, items.length - 1);
setVisibleRange(function (prev) {
return prev.start === start && prev.end === end ? prev : {
start: start,
end: end
};
});
});
}, [verticalList, findStartIndex, findEndIndex, overscan, items.length]);
var observeNodeSize = useCallback(function (index, node) {
itemRefs.current.set(index, node);
var prev = resizeObservers.current.get(index);
if (prev) {
prev.disconnect();
resizeObservers.current["delete"](index);
}
if (!node) {
return;
}
var ro = new ResizeObserver(function (entries) {
var _iterator = _createForOfIteratorHelper(entries),
_step;
try {
var _loop = function _loop() {
var _entry$borderBoxSize;
var entry = _step.value;
var box = ((_entry$borderBoxSize = entry.borderBoxSize) === null || _entry$borderBoxSize === void 0 ? void 0 : _entry$borderBoxSize[0]) || entry.contentRect;
var measured = verticalList ? box.blockSize || entry.contentRect.height : box.inlineSize || entry.contentRect.width;
setCellHeights(function (prev) {
return prev[index] === measured ? prev : _objectSpread(_objectSpread({}, prev), {}, _defineProperty({}, index, measured));
});
};
for (_iterator.s(); !(_step = _iterator.n()).done;) {
_loop();
}
} catch (err) {
_iterator.e(err);
} finally {
_iterator.f();
}
});
ro.observe(node);
resizeObservers.current.set(index, ro);
}, [verticalList]);
var handleRightClick = useCallback(function (item, index, e) {
e.preventDefault();
onCellRightClick === null || onCellRightClick === void 0 || onCellRightClick(item, index);
}, [onCellRightClick]);
var handleDoubleClick = useCallback(function (item, index) {
onCellDoubleClick === null || onCellDoubleClick === void 0 || onCellDoubleClick(item, index);
}, [onCellDoubleClick]);
var handleMouseEnter = useCallback(function (item, index) {
setHoveredIndex(index);
onCellHover === null || onCellHover === void 0 || onCellHover(item, index, true);
}, [onCellHover]);
var handleMouseLeave = useCallback(function (item, index) {
setHoveredIndex(null);
onCellHover === null || onCellHover === void 0 || onCellHover(item, index, false);
}, [onCellHover]);
var handleClick = useCallback(function (item, index) {
setClickedIndex(index);
onCellClick === null || onCellClick === void 0 || onCellClick(item, index);
}, [onCellClick]);
useEffect(function () {
var el = scrollRef.current;
if (!el) {
return;
}
scheduleRangeUpdate();
var opts = {
passive: true
};
el.addEventListener("scroll", scheduleRangeUpdate, opts);
return function () {
el.removeEventListener("scroll", scheduleRangeUpdate, opts);
if (rafScrollId.current) {
cancelAnimationFrame(rafScrollId.current);
}
};
}, [scheduleRangeUpdate]);
useEffect(function () {
renderCellRef.current = renderCell;
}, [renderCell]);
useEffect(function () {
return function () {
var _iterator2 = _createForOfIteratorHelper(resizeObservers.current),
_step2;
try {
for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
var _step2$value = _slicedToArray(_step2.value, 2),
ro = _step2$value[1];
ro.disconnect();
}
} catch (err) {
_iterator2.e(err);
} finally {
_iterator2.f();
}
resizeObservers.current.clear();
itemRefs.current.clear();
};
}, []);
useEffect(function () {
if (initiallyClicked >= 0 && items[initiallyClicked]) {
setClickedIndex(initiallyClicked);
}
}, [initiallyClicked, items]);
return /*#__PURE__*/React.createElement("div", {
ref: scrollRef,
style: containerStyle
}, /*#__PURE__*/React.createElement("div", {
style: trackStyle
}, /*#__PURE__*/React.createElement("div", {
style: windowStyle
}, visibleItems.map(function (item, localIdx) {
var index = visibleRange.start + localIdx;
var key = keyExtractor(item, index);
return /*#__PURE__*/React.createElement(VirtualListItem, {
key: key,
indexSpecificHoverConfigurationSettings: indexSpecificHoverConfigurationSettings,
indexSpecificClickConfigurationSettings: indexSpecificClickConfigurationSettings,
clickAnimationConfigurationSettings: clickAnimationConfigurationSettings,
hoverAnimationConfigurationSettings: hoverAnimationConfigurationSettings,
indexSpecificConfigurationSettings: indexSpecificConfigurationSettings,
cellConfigurationSettings: cellConfigurationSettings,
onContext: handleRightClick,
onDouble: handleDoubleClick,
onEnter: handleMouseEnter,
onLeave: handleMouseLeave,
onClick: handleClick,
renderCellStable: function renderCellStable(it, idx, h, c) {
return renderCellRef.current ? renderCellRef.current(it, idx, h, c) : it;
},
transitionDuration: transitionDuration,
hovered: hoveredIndex === index,
clicked: clickedIndex === index,
observeRef: observeNodeSize,
verticalList: verticalList,
index: index,
item: item
});
}))));
}
;
export default HUDVirtualList;