diff --git a/build_examples/demo.js b/build_examples/demo.js index 5cc3338..9b7e030 100644 --- a/build_examples/demo.js +++ b/build_examples/demo.js @@ -32,51 +32,116 @@ const react_1 = __importStar(require("react")); const client_1 = __importDefault(require("react-dom/client")); const __1 = require(".."); const utils_1 = require("../utils"); -const simple_1 = require("../simple"); -const Item = ({ item }) => { - return (0, jsx_runtime_1.jsx)("div", { style: { height: '40px' }, children: item }); -}; -function ListWithHook({ items }) { +const fixed_list_y_1 = require("../fixed-list-y"); +const fixed_grid_1 = require("../fixed-grid"); +const itemsLine = Array.from({ length: 300 }).map((_, i) => `item ${i}`); +const itemsGrid = Array.from({ length: 300 }).map((_, iy) => Array.from({ length: 300 }).map((_, ix) => `item ${ix} ${iy}`)); +function ListWithHookExample() { + const items = itemsLine; const containerRef = (0, react_1.useRef)(undefined); const itemHeight = 40; - const rendered = (0, __1.useVirtualOverflowV)({ + const { renderedItems, updateViewRect } = (0, __1.useVirtualOverflowY)({ containerRef, itemHeight, - itemsLength: items.length, + itemsLengthY: items.length, overscanItemsCount: 3, calcVisibleRect: utils_1.virtualOverflowUtils.calcVisibleRectOverflowed, - renderItem: (itemIndex, offsetTop, item = items[itemIndex]) => ((0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', top: `${offsetTop}px` }, children: (0, jsx_runtime_1.jsx)(Item, { item: item }) }, item)), + renderItem: (itemIndex, offsetTop, item = items[itemIndex]) => ((0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', top: `${offsetTop}px` }, children: (0, jsx_runtime_1.jsx)("div", { style: { height: '40px' }, children: item }) }, item)), }); - return ((0, jsx_runtime_1.jsx)("div", { style: { overflowY: 'scroll', height: '300px', background: 'lightgreen' }, children: (0, jsx_runtime_1.jsx)("div", { ref: containerRef, style: { position: 'relative', height: `${itemHeight * items.length}px` }, children: rendered }) })); + (0, react_1.useEffect)(() => { + setInterval(() => updateViewRect(), 8); + }, []); + return ((0, jsx_runtime_1.jsx)("div", { style: { overflowY: 'scroll', height: '300px', background: 'lightgreen' }, children: (0, jsx_runtime_1.jsx)("div", { ref: containerRef, style: { position: 'relative', height: `${itemHeight * items.length}px` }, children: renderedItems }) })); +} +function VerticalListExample() { + const items = itemsLine; + return ((0, jsx_runtime_1.jsx)("div", { style: { overflowY: 'scroll', height: '300px', background: 'lightgreen' }, children: (0, jsx_runtime_1.jsx)(fixed_list_y_1.VirtualListY, { items: items, itemHeight: 40, itemKey: x => x, renderItem: item => (0, jsx_runtime_1.jsx)("div", { style: { height: '40px' }, children: item }) }) })); } -function ListSimple(props) { - const items = props.items; - return ((0, jsx_runtime_1.jsx)("div", { style: { overflowY: 'scroll', height: '300px', background: 'lightgreen' }, children: (0, jsx_runtime_1.jsx)(simple_1.SimpleVirtualListV, { items: items, itemHeight: 40, itemKey: x => x, renderItem: item => (0, jsx_runtime_1.jsx)("div", { style: { height: '40px' }, children: item }) }) })); +function GridExample() { + const items = itemsGrid; + return ((0, jsx_runtime_1.jsx)("div", { style: { overflowY: 'scroll', height: '300px', background: 'lightgreen' }, children: (0, jsx_runtime_1.jsx)(fixed_grid_1.VirtualGrid, { items: items, columnsNum: 300, itemWidth: 40, itemHeight: 80, itemKey: x => x, overscanItemsCount: 3, renderItem: item => (0, jsx_runtime_1.jsx)("div", { style: { width: '40px', height: '80px' }, children: item }) }) })); } -const items = Array.from({ length: 300 }).map((_, i) => `item ${i}`); function App() { - const [, forceUpd] = react_1.default.useState(0); - const r = (0, react_1.useRef)(undefined); - return ((0, jsx_runtime_1.jsxs)("div", { ref: r, children: [(0, jsx_runtime_1.jsx)("div", { style: { height: '700px' } }), (0, jsx_runtime_1.jsxs)("div", { style: { overflowY: 'scroll', height: '600px', background: 'blue' }, children: [(0, jsx_runtime_1.jsx)("div", { style: { height: '700px' } }), (0, jsx_runtime_1.jsx)(ListSimple, { items: items })] }), (0, jsx_runtime_1.jsx)("div", { style: { height: '700px' } })] })); + return ((0, jsx_runtime_1.jsxs)("div", { children: [(0, jsx_runtime_1.jsx)("div", { style: { + height: '700px', fontSize: '60px', + color: 'black' + }, children: "Scroll me down" }), (0, jsx_runtime_1.jsxs)("div", { style: { overflowY: 'scroll', height: '600px', background: 'blue' }, children: [(0, jsx_runtime_1.jsx)("div", { style: { + height: '700px', fontSize: '60px', + color: 'white' + }, children: "Scroll me down" }), (0, jsx_runtime_1.jsx)(VerticalListExample, {})] }), (0, jsx_runtime_1.jsx)("div", { style: { height: '700px' } })] })); } const rootElement = document.getElementById("demo"); const root = client_1.default.createRoot(rootElement); root.render((0, jsx_runtime_1.jsx)(react_1.default.StrictMode, { children: (0, jsx_runtime_1.jsx)(App, {}) })); -},{"..":2,"../simple":3,"../utils":4,"react":14,"react-dom/client":8,"react/jsx-runtime":15}],2:[function(require,module,exports){ +},{"..":4,"../fixed-grid":2,"../fixed-list-y":3,"../utils":5,"react":15,"react-dom/client":9,"react/jsx-runtime":16}],2:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.VirtualGrid = void 0; +const jsx_runtime_1 = require("react/jsx-runtime"); +const react_1 = require("react"); +const _1 = require("."); +function VirtualGrid(props) { + const containerRef = (0, react_1.useRef)(undefined); + const { renderedItems } = (0, _1.useVirtualOverflowGrid)({ + containerRef, + itemsLengthY: props.items.length, + itemsLengthX: props.columnsNum, + itemWidth: props.itemWidth, + itemHeight: props.itemHeight, + overscanItemsCount: props.overscanItemsCount, + calcVisibleRect: props.calcVisibleRect, + renderItem: (itemIndexX, leftOffsetPx, itemIndexY, topOffsetPx) => { + const item = props.items[itemIndexY][itemIndexX]; + if (!item) + return null; + return ((0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', top: `${topOffsetPx}px`, left: `${leftOffsetPx}px` }, children: props.renderItem(item, itemIndexX, leftOffsetPx, itemIndexY, topOffsetPx) }, props.itemKey(item, itemIndexX, itemIndexY))); + } + }, [props.items, props.itemHeight]); + return ((0, jsx_runtime_1.jsx)("div", { ref: containerRef, style: { width: `${props.columnsNum * props.itemWidth}px`, height: `${props.items.length * props.itemHeight}px`, position: 'relative' }, children: renderedItems })); +} +exports.VirtualGrid = VirtualGrid; + +},{".":4,"react":15,"react/jsx-runtime":16}],3:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.useVirtualOverflowV = exports.virtualOverflowCalcItemsV = exports.virtualOverflowCalcVisibleRect = void 0; +exports.VirtualListY = void 0; +const jsx_runtime_1 = require("react/jsx-runtime"); +const react_1 = require("react"); +const _1 = require("."); +function VirtualListY(props) { + const containerRef = (0, react_1.useRef)(undefined); + const { renderedItems } = (0, _1.useVirtualOverflowY)({ + containerRef, + itemsLengthY: props.items.length, + itemHeight: props.itemHeight, + overscanItemsCount: props.overscanItemsCount, + calcVisibleRect: props.calcVisibleRect, + renderItem: (itemIndex, topOffset) => { + const item = props.items[itemIndex]; + if (!item) + return null; + return ((0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', top: `${topOffset}px` }, children: props.renderItem(item, itemIndex, topOffset) }, props.itemKey(item, itemIndex))); + } + }, [props.items, props.itemHeight]); + return ((0, jsx_runtime_1.jsx)("div", { ref: containerRef, style: { height: `${props.items.length * props.itemHeight}px`, position: 'relative' }, children: renderedItems })); +} +exports.VirtualListY = VirtualListY; + +},{".":4,"react":15,"react/jsx-runtime":16}],4:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +exports.useVirtualOverflowGrid = exports.useVirtualOverflowX = exports.useVirtualOverflowY = exports.useCalcVirtualOverflow = exports.virtualOverflowCalcItems = exports.virtualOverflowCalcVisibleRect = void 0; const react_1 = require("react"); function debounceAnimationFrame(func) { let frameRequest = 0; - return [ - () => { + return { + requestFrame: () => { cancelAnimationFrame(frameRequest); frameRequest = requestAnimationFrame((frameTime) => func.call(undefined, frameTime)); }, - () => cancelAnimationFrame(frameRequest) - ]; + cancelFrame: () => cancelAnimationFrame(frameRequest) + }; } function virtualOverflowCalcVisibleRect(element) { const elementRect = element.getBoundingClientRect(); @@ -115,26 +180,47 @@ function virtualOverflowCalcVisibleRect(element) { }; } exports.virtualOverflowCalcVisibleRect = virtualOverflowCalcVisibleRect; -function virtualOverflowCalcItemsV(visibleRect, itemHeight, overscanItemsCount, itemsLength) { - let itemStart = Math.floor(visibleRect.contentOffsetTop / itemHeight); - let itemLen = Math.ceil(visibleRect.contentVisibleHeight / itemHeight); +// contentOffsetStart = visibleRect.contentOffsetTop +// contentVisibleSize = visibleRect.contentVisibleHeight +function virtualOverflowCalcItems(contentOffsetStart, contentVisibleSize, itemSize, overscanItemsCount, itemsLength) { + let itemStart = Math.floor(contentOffsetStart / itemSize); + let itemLen = Math.ceil(contentVisibleSize / itemSize); itemStart = Math.max(0, itemStart - overscanItemsCount); itemLen = Math.max(0, Math.min(itemsLength - itemStart, itemLen + overscanItemsCount + overscanItemsCount)); - return [itemStart, itemLen]; -} -exports.virtualOverflowCalcItemsV = virtualOverflowCalcItemsV; -function useVirtualOverflowV(params, deps = []) { - const { renderItem, containerRef, itemsLength, itemHeight, overscanItemsCount = 3, calcVisibleRect = virtualOverflowCalcVisibleRect } = params; - const [[itemStart, itemLength], setItemSlice] = (0, react_1.useState)([0, 0]); - (0, react_1.useLayoutEffect)(() => { + return { itemStart, itemLen }; +} +exports.virtualOverflowCalcItems = virtualOverflowCalcItems; +function useCalcVirtualOverflow(params, deps) { + const { containerRef, itemsLengthX, itemsLengthY, itemWidth, itemHeight, overscanItemsCount = 3, calcVisibleRect = virtualOverflowCalcVisibleRect } = params; + const [itemSlice, setItemSlice] = (0, react_1.useState)({ + topStartIndex: 0, + lengthY: 0, + leftStartIndex: 0, + lengthX: 0, + }); + const { requestFrame: updateViewRect, cancelFrame } = (0, react_1.useMemo)(() => debounceAnimationFrame((frameTime) => { if (!containerRef.current) - return () => { }; - const containerEl = containerRef.current; - const [updateViewRect, cancelFrame] = debounceAnimationFrame((frameTime) => { - const visibleRect = calcVisibleRect(containerEl, frameTime); - const itemSlicePos = virtualOverflowCalcItemsV(visibleRect, itemHeight, overscanItemsCount, itemsLength); - setItemSlice(itemSlicePos); - }); + return; + const visibleRect = calcVisibleRect(containerRef.current, frameTime); + const newItemSlice = { + topStartIndex: 0, + lengthY: 1, + leftStartIndex: 0, + lengthX: 1, + }; + if (itemHeight !== undefined && itemsLengthY !== undefined) { + const verticalSlice = virtualOverflowCalcItems(visibleRect.contentOffsetTop, visibleRect.contentVisibleHeight, itemHeight, overscanItemsCount, itemsLengthY); + newItemSlice.topStartIndex = verticalSlice.itemStart; + newItemSlice.lengthY = verticalSlice.itemLen; + } + if (itemWidth !== undefined && itemsLengthX !== undefined) { + const horizontalSlice = virtualOverflowCalcItems(visibleRect.contentOffsetLeft, visibleRect.contentVisibleWidth, itemWidth, overscanItemsCount, itemsLengthX); + newItemSlice.leftStartIndex = horizontalSlice.itemStart; + newItemSlice.lengthX = horizontalSlice.itemLen; + } + setItemSlice(newItemSlice); + }), [containerRef.current, itemsLengthX, itemsLengthY, itemWidth, itemHeight, ...deps]); + (0, react_1.useLayoutEffect)(() => { window.addEventListener('scroll', updateViewRect, { capture: true, passive: true }); window.addEventListener('resize', updateViewRect, { capture: true, passive: true }); window.addEventListener('orientationchange', updateViewRect, { capture: true, passive: true }); @@ -145,41 +231,52 @@ function useVirtualOverflowV(params, deps = []) { window.removeEventListener('resize', updateViewRect); window.removeEventListener('orientationchange', updateViewRect); }; - }, [containerRef.current, itemsLength, itemHeight, ...deps]); - const outLength = itemStart + itemLength; - const renderedItems = Array.from({ length: outLength }); - for (let i = itemStart; i < outLength; ++i) { - renderedItems[i - itemStart] = renderItem(i, i * itemHeight); + }, [containerRef.current, itemsLengthX, itemsLengthY, itemWidth, itemHeight, ...deps]); + return { itemSlice, updateViewRect }; +} +exports.useCalcVirtualOverflow = useCalcVirtualOverflow; +function utilRenderItems1D(itemStart, itemsLength, itemSize, renderItem) { + const itemEnd = itemStart + itemsLength; + const renderedItems = Array.from({ length: itemsLength }); + for (let i = itemStart; i < itemEnd; ++i) { + renderedItems[i - itemStart] = renderItem(i, i * itemSize); } return renderedItems; } -exports.useVirtualOverflowV = useVirtualOverflowV; - -},{"react":14}],3:[function(require,module,exports){ -"use strict"; -Object.defineProperty(exports, "__esModule", { value: true }); -exports.SimpleVirtualListV = void 0; -const jsx_runtime_1 = require("react/jsx-runtime"); -const react_1 = require("react"); -const _1 = require("."); -function SimpleVirtualListV(props) { - const containerRef = (0, react_1.useRef)(undefined); - const rendered = (0, _1.useVirtualOverflowV)({ - containerRef, - itemsLength: props.items.length, - itemHeight: props.itemHeight, - renderItem: (itemIndex, topOffset) => { - const item = props.items[itemIndex]; - if (!item) - return null; - return ((0, jsx_runtime_1.jsx)("div", { style: { position: 'absolute', top: `${topOffset}px` }, children: props.renderItem(item, itemIndex, topOffset) }, props.itemKey(item, itemIndex))); +function useVirtualOverflowY(params, deps = []) { + const { itemSlice, updateViewRect } = useCalcVirtualOverflow(params, deps); + return { + renderedItems: utilRenderItems1D(itemSlice.topStartIndex, itemSlice.lengthY, params.itemHeight, params.renderItem), + updateViewRect, + }; +} +exports.useVirtualOverflowY = useVirtualOverflowY; +function useVirtualOverflowX(params, deps = []) { + const { itemSlice, updateViewRect } = useCalcVirtualOverflow(params, deps); + return { + renderedItems: utilRenderItems1D(itemSlice.leftStartIndex, itemSlice.lengthX, params.itemWidth, params.renderItem), + updateViewRect, + }; +} +exports.useVirtualOverflowX = useVirtualOverflowX; +function useVirtualOverflowGrid(params, deps = []) { + const { itemSlice, updateViewRect } = useCalcVirtualOverflow(params, deps); + const renderedItems = Array.from({ length: itemSlice.lengthX * itemSlice.lengthY }); + for (let iy = 0; iy < itemSlice.lengthY; ++iy) { + for (let ix = 0; ix < itemSlice.lengthX; ++ix) { + const realXindex = itemSlice.leftStartIndex + ix; + const realYindex = itemSlice.topStartIndex + iy; + renderedItems[ix + iy * itemSlice.lengthX] = params.renderItem(realXindex, realXindex * params.itemWidth, realYindex, realYindex * params.itemHeight); } - }, [props.items, props.itemHeight]); - return ((0, jsx_runtime_1.jsx)("div", { ref: containerRef, style: { height: `${props.items.length * props.itemHeight}px`, position: 'relative' }, children: rendered })); + } + return { + renderedItems, + updateViewRect + }; } -exports.SimpleVirtualListV = SimpleVirtualListV; +exports.useVirtualOverflowGrid = useVirtualOverflowGrid; -},{".":2,"react":14,"react/jsx-runtime":15}],4:[function(require,module,exports){ +},{"react":15}],5:[function(require,module,exports){ "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.virtualOverflowUtils = void 0; @@ -268,7 +365,7 @@ var virtualOverflowUtils; virtualOverflowUtils.calcVisibleRectOverflowed = calcVisibleRectOverflowed; })(virtualOverflowUtils || (exports.virtualOverflowUtils = virtualOverflowUtils = {})); -},{}],5:[function(require,module,exports){ +},{}],6:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; @@ -454,7 +551,7 @@ process.chdir = function (dir) { }; process.umask = function() { return 0; }; -},{}],6:[function(require,module,exports){ +},{}],7:[function(require,module,exports){ (function (process){(function (){ /** * @license React @@ -30326,7 +30423,7 @@ if ( } }).call(this)}).call(this,require('_process')) -},{"_process":5,"react":14,"scheduler":18}],7:[function(require,module,exports){ +},{"_process":6,"react":15,"scheduler":19}],8:[function(require,module,exports){ /** * @license React * react-dom.production.min.js @@ -30651,7 +30748,7 @@ exports.hydrateRoot=function(a,b,c){if(!ol(a))throw Error(p(405));var d=null!=c& e);return new nl(b)};exports.render=function(a,b,c){if(!pl(b))throw Error(p(200));return sl(null,a,b,!1,c)};exports.unmountComponentAtNode=function(a){if(!pl(a))throw Error(p(40));return a._reactRootContainer?(Sk(function(){sl(null,null,a,!1,function(){a._reactRootContainer=null;a[uf]=null})}),!0):!1};exports.unstable_batchedUpdates=Rk; exports.unstable_renderSubtreeIntoContainer=function(a,b,c,d){if(!pl(c))throw Error(p(200));if(null==a||void 0===a._reactInternals)throw Error(p(38));return sl(a,b,c,!1,d)};exports.version="18.2.0-next-9e3b772b8-20220608"; -},{"react":14,"scheduler":18}],8:[function(require,module,exports){ +},{"react":15,"scheduler":19}],9:[function(require,module,exports){ (function (process){(function (){ 'use strict'; @@ -30680,7 +30777,7 @@ if (process.env.NODE_ENV === 'production') { } }).call(this)}).call(this,require('_process')) -},{"_process":5,"react-dom":9}],9:[function(require,module,exports){ +},{"_process":6,"react-dom":10}],10:[function(require,module,exports){ (function (process){(function (){ 'use strict'; @@ -30722,7 +30819,7 @@ if (process.env.NODE_ENV === 'production') { } }).call(this)}).call(this,require('_process')) -},{"./cjs/react-dom.development.js":6,"./cjs/react-dom.production.min.js":7,"_process":5}],10:[function(require,module,exports){ +},{"./cjs/react-dom.development.js":7,"./cjs/react-dom.production.min.js":8,"_process":6}],11:[function(require,module,exports){ (function (process){(function (){ /** * @license React @@ -32040,7 +32137,7 @@ exports.jsxs = jsxs; } }).call(this)}).call(this,require('_process')) -},{"_process":5,"react":14}],11:[function(require,module,exports){ +},{"_process":6,"react":15}],12:[function(require,module,exports){ /** * @license React * react-jsx-runtime.production.min.js @@ -32053,7 +32150,7 @@ exports.jsxs = jsxs; 'use strict';var f=require("react"),k=Symbol.for("react.element"),l=Symbol.for("react.fragment"),m=Object.prototype.hasOwnProperty,n=f.__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED.ReactCurrentOwner,p={key:!0,ref:!0,__self:!0,__source:!0}; function q(c,a,g){var b,d={},e=null,h=null;void 0!==g&&(e=""+g);void 0!==a.key&&(e=""+a.key);void 0!==a.ref&&(h=a.ref);for(b in a)m.call(a,b)&&!p.hasOwnProperty(b)&&(d[b]=a[b]);if(c&&c.defaultProps)for(b in a=c.defaultProps,a)void 0===d[b]&&(d[b]=a[b]);return{$$typeof:k,type:c,key:e,ref:h,props:d,_owner:n.current}}exports.Fragment=l;exports.jsx=q;exports.jsxs=q; -},{"react":14}],12:[function(require,module,exports){ +},{"react":15}],13:[function(require,module,exports){ (function (process){(function (){ /** * @license React @@ -34796,7 +34893,7 @@ if ( } }).call(this)}).call(this,require('_process')) -},{"_process":5}],13:[function(require,module,exports){ +},{"_process":6}],14:[function(require,module,exports){ /** * @license React * react.production.min.js @@ -34824,7 +34921,7 @@ exports.useCallback=function(a,b){return U.current.useCallback(a,b)};exports.use exports.useInsertionEffect=function(a,b){return U.current.useInsertionEffect(a,b)};exports.useLayoutEffect=function(a,b){return U.current.useLayoutEffect(a,b)};exports.useMemo=function(a,b){return U.current.useMemo(a,b)};exports.useReducer=function(a,b,e){return U.current.useReducer(a,b,e)};exports.useRef=function(a){return U.current.useRef(a)};exports.useState=function(a){return U.current.useState(a)};exports.useSyncExternalStore=function(a,b,e){return U.current.useSyncExternalStore(a,b,e)}; exports.useTransition=function(){return U.current.useTransition()};exports.version="18.2.0"; -},{}],14:[function(require,module,exports){ +},{}],15:[function(require,module,exports){ (function (process){(function (){ 'use strict'; @@ -34835,7 +34932,7 @@ if (process.env.NODE_ENV === 'production') { } }).call(this)}).call(this,require('_process')) -},{"./cjs/react.development.js":12,"./cjs/react.production.min.js":13,"_process":5}],15:[function(require,module,exports){ +},{"./cjs/react.development.js":13,"./cjs/react.production.min.js":14,"_process":6}],16:[function(require,module,exports){ (function (process){(function (){ 'use strict'; @@ -34846,7 +34943,7 @@ if (process.env.NODE_ENV === 'production') { } }).call(this)}).call(this,require('_process')) -},{"./cjs/react-jsx-runtime.development.js":10,"./cjs/react-jsx-runtime.production.min.js":11,"_process":5}],16:[function(require,module,exports){ +},{"./cjs/react-jsx-runtime.development.js":11,"./cjs/react-jsx-runtime.production.min.js":12,"_process":6}],17:[function(require,module,exports){ (function (process,setImmediate){(function (){ /** * @license React @@ -35484,7 +35581,7 @@ if ( } }).call(this)}).call(this,require('_process'),require("timers").setImmediate) -},{"_process":5,"timers":19}],17:[function(require,module,exports){ +},{"_process":6,"timers":20}],18:[function(require,module,exports){ (function (setImmediate){(function (){ /** * @license React @@ -35507,7 +35604,7 @@ exports.unstable_scheduleCallback=function(a,b,c){var d=exports.unstable_now();" exports.unstable_shouldYield=M;exports.unstable_wrapCallback=function(a){var b=y;return function(){var c=y;y=b;try{return a.apply(this,arguments)}finally{y=c}}}; }).call(this)}).call(this,require("timers").setImmediate) -},{"timers":19}],18:[function(require,module,exports){ +},{"timers":20}],19:[function(require,module,exports){ (function (process){(function (){ 'use strict'; @@ -35518,7 +35615,7 @@ if (process.env.NODE_ENV === 'production') { } }).call(this)}).call(this,require('_process')) -},{"./cjs/scheduler.development.js":16,"./cjs/scheduler.production.min.js":17,"_process":5}],19:[function(require,module,exports){ +},{"./cjs/scheduler.development.js":17,"./cjs/scheduler.production.min.js":18,"_process":6}],20:[function(require,module,exports){ (function (setImmediate,clearImmediate){(function (){ var nextTick = require('process/browser.js').nextTick; var apply = Function.prototype.apply; @@ -35597,4 +35694,4 @@ exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : delete immediateIds[id]; }; }).call(this)}).call(this,require("timers").setImmediate,require("timers").clearImmediate) -},{"process/browser.js":5,"timers":19}]},{},[1]); +},{"process/browser.js":6,"timers":20}]},{},[1]); diff --git a/package.json b/package.json index 4c57d3b..51b2c16 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "react-virtual-overflow", - "version": "1.0.3", + "version": "1.1.0", "description": "virtual scroll without headache", "main": "lib/index.cjs.js", "module": "lib/index.esm.js", @@ -45,7 +45,7 @@ }, "size-limit": [ { - "path": "lib/index.esm.js", + "path": "lib/fixed-list-y.js", "limit": "1 kB", "gzip": true } diff --git a/readme.md b/readme.md index 9ef9d6f..a1ad8c4 100644 --- a/readme.md +++ b/readme.md @@ -10,14 +10,16 @@ Similar to [react-virtualized](https://github.com/bvaughn/react-virtualized), bu - No magical divs will wrap your list with position: absolute and height: 0 - No scroll syncing problems - No AutoWindow over AutoSize with VerticalSpecialList +- Full rendering controll - It just works -- <1kb gzipped +- ~0.5kb gzipped -Currently only vertical list supported with fixed item's height, but will add horizontal & grid soon +Currently only fixed item sizes supported, but will dynamic sizing later. -Components & hooks in this library will automatically find all containers with overflows and render only visible items. +Components & hooks in this library will automatically find all containers with overflows and render only visible items. +So you could stack and wrap your list in anyway you want, everything will work. -So you could stack/wrap/move your list in anyway you want, everything will work. +You also could use some parts of this library for example to calculate only visible on screen rect of element.  @@ -27,10 +29,10 @@ npm i react-virtual-overflow [demo app code](src/examples/demo.tsx) -## Simple +## Simple example ```tsx -import { SimpleVirtualListV } from "react-virtual-overflow/lib/simple"; +import { VirtualListY } from "react-virtual-overflow/lib/fixed-list-y"; function MyApp() { const items = Array.from({ length: 300 }).map((_, i) => `item ${i}`); @@ -43,7 +45,7 @@ function MyApp() { return (