UNPKG

@wix/design-system

Version:

@wix/design-system

190 lines (187 loc) 8.12 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof = require("@babel/runtime/helpers/typeof"); exports.__esModule = true; exports["default"] = void 0; var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _slicedToArray2 = _interopRequireDefault(require("@babel/runtime/helpers/slicedToArray")); var _react = _interopRequireWildcard(require("react")); var _classnames = _interopRequireDefault(require("classnames")); var _Item = _interopRequireDefault(require("./Item")); var _utils = require("./utils"); var _jsxFileName = "/home/builduser/work/57e038ea7326c1ec/packages/wix-design-system/dist/cjs/NestableListBase/VirtualContainer.jsx"; function _interopRequireWildcard(e, t) { if ("function" == typeof WeakMap) var r = new WeakMap(), n = new WeakMap(); return (_interopRequireWildcard = function _interopRequireWildcard(e, t) { if (!t && e && e.__esModule) return e; var o, i, f = { __proto__: null, "default": e }; if (null === e || "object" != _typeof(e) && "function" != typeof e) return f; if (o = t ? n : r) { if (o.has(e)) return o.get(e); o.set(e, f); } for (var _t in e) "default" !== _t && {}.hasOwnProperty.call(e, _t) && ((i = (o = Object.defineProperty) && Object.getOwnPropertyDescriptor(e, _t)) && (i.get || i.set) ? o(f, _t, i) : f[_t] = e[_t]); return f; })(e, t); } 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) { (0, _defineProperty2["default"])(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; } // Resolve childrenStyle.marginLeft to a numeric per-depth indent for the // absolute layout. Accepts both numbers and "{n}px" strings. function parseIndentPx(childrenStyle) { var ml = childrenStyle && childrenStyle.marginLeft; if (typeof ml === 'number' && Number.isFinite(ml)) { return ml; } if (typeof ml === 'string') { var n = parseInt(ml, 10); return Number.isFinite(n) ? n : 0; } return 0; } var VirtualContainer = /*#__PURE__*/_react["default"].forwardRef(function VirtualContainer(_ref, containerRef) { var _this = this; var items = _ref.items, childrenProperty = _ref.childrenProperty, childrenStyle = _ref.childrenStyle, renderAction = _ref.renderAction, isRenderDraggingChildren = _ref.isRenderDraggingChildren, theme = _ref.theme, itemHeight = _ref.itemHeight, viewportHeight = _ref.viewportHeight, _ref$offscreenRowCoun = _ref.offscreenRowCount, offscreenRowCount = _ref$offscreenRowCoun === void 0 ? 5 : _ref$offscreenRowCoun, pinnedItemId = _ref.pinnedItemId; var _useState = (0, _react.useState)(0), _useState2 = (0, _slicedToArray2["default"])(_useState, 2), scrollTop = _useState2[0], setScrollTop = _useState2[1]; // Memoizing the row stream is what makes scrolling cheap. The action-row // entries store truthiness only (no rendered React node), so this cache // stays valid across drag-state changes — action-row styling depends on // isDragging, but action-row *existence* depends only on stable props // (actions/addItemLabel/maxDepth). We re-invoke renderAction at render // time per visible action row to pick up live styling. var rows = (0, _react.useMemo)(function () { return (0, _utils.flattenVisible)({ items: items, renderAction: renderAction, childrenProperty: childrenProperty }); }, [items, renderAction, childrenProperty]); var indentPx = parseIndentPx(childrenStyle); var totalHeight = rows.length * itemHeight; var firstWindowIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - offscreenRowCount); var lastWindowIndex = Math.min(rows.length, Math.ceil((scrollTop + viewportHeight) / itemHeight) + offscreenRowCount); var handleScroll = (0, _react.useCallback)(function (e) { setScrollTop(e.currentTarget.scrollTop); }, []); var containerClass = (0, _classnames["default"])('nestable-container', 'nestable-top-container', theme && theme.topContainer); var visible = []; for (var i = firstWindowIndex; i < lastWindowIndex; i++) { visible.push({ row: rows[i], absoluteIndex: i }); } // Pin the focused/keyboard-moved row in the slice so its keyboard handlers // survive scroll. Without this, arrow-key reorder across viewport edge // unmounts the focused Item and onKeyUp dies. if (pinnedItemId) { var alreadyVisible = visible.some(function (v) { return v.row.kind === 'item' && v.row.item.id === pinnedItemId; }); if (!alreadyVisible) { var pinnedIdx = rows.findIndex(function (r) { return r.kind === 'item' && r.item.id === pinnedItemId; }); if (pinnedIdx !== -1) { visible.push({ row: rows[pinnedIdx], absoluteIndex: pinnedIdx }); } } } return /*#__PURE__*/_react["default"].createElement("div", { ref: containerRef, className: containerClass, onScroll: handleScroll, style: { height: viewportHeight, overflowY: 'auto', position: 'relative' }, __self: this, __source: { fileName: _jsxFileName, lineNumber: 92, columnNumber: 5 } }, /*#__PURE__*/_react["default"].createElement("div", { style: { height: totalHeight, position: 'relative' }, __self: this, __source: { fileName: _jsxFileName, lineNumber: 102, columnNumber: 7 } }, visible.map(function (_ref2) { var row = _ref2.row, absoluteIndex = _ref2.absoluteIndex; var top = absoluteIndex * itemHeight; var left = (row.kind === 'item' ? row.treeDepth - 1 : row.depth - 1) * indentPx; var positionStyle = { position: 'absolute', top: top, left: left, right: 0, minHeight: itemHeight }; if (row.kind === 'item') { var itemForRender = row.isParentLocked ? _objectSpread(_objectSpread({}, row.item), {}, { isParentLocked: true, draggable: false }) : row.item; return /*#__PURE__*/_react["default"].createElement("div", { key: "item-".concat(row.item.id), style: positionStyle, __self: _this, __source: { fileName: _jsxFileName, lineNumber: 121, columnNumber: 15 } }, /*#__PURE__*/_react["default"].createElement(_Item["default"], { id: row.item.id, item: itemForRender, index: row.index, isVeryLastItem: row.isVeryLastItem, siblings: row.siblings, isRenderDraggingChildren: isRenderDraggingChildren, position: row.position, depth: (0, _utils.getDepth)(row.item, childrenProperty), theme: theme, __self: _this, __source: { fileName: _jsxFileName, lineNumber: 122, columnNumber: 17 } })); } // Re-invoke renderAction at render time to pick up live styling // (depends on state.isDragging in the consumer). var actionNode = renderAction({ siblings: row.siblings, item: row.parentItem, isRootAction: row.isRootAction, veryLastItem: row.veryLastItem, depth: row.depth }); if (!actionNode) { return null; } return /*#__PURE__*/_react["default"].createElement("div", { key: "action-".concat(row.parentItem.id), style: positionStyle, __self: _this, __source: { fileName: _jsxFileName, lineNumber: 150, columnNumber: 13 } }, actionNode); }))); }); var _default = exports["default"] = VirtualContainer;