UNPKG

@z-cloud/virtual-taro

Version:

一个基于React + TS开发的虚拟列表,支持瀑布流、grid的组件。

89 lines (88 loc) 2.71 kB
import { jsxs, jsx } from "react/jsx-runtime"; import { View } from "@tarojs/components"; import Taro, { getCurrentInstance } from "@tarojs/taro"; import { useState, useLayoutEffect } from "react"; import { getRectSizeAsync } from "../utils/index.js"; const flexStyle = { position: "absolute", width: 1, height: 1, zIndex: -10, visibility: "hidden", pointerEvents: "none" }; function Resizable({ children, className, style, emitWhenMounted, listId, onResize }) { const [rect, setRect] = useState({ width: 0, height: 0 }); const resizeId = `resize-${listId}`; const resizeFlexClass = `resize-flex-${listId}`; const [instance] = useState(() => getCurrentInstance()); useLayoutEffect(() => { let observer; const init = async () => { const res = await getRectSizeAsync(resizeId); if (res) { setRect({ width: res.width, height: res.height }); if (emitWhenMounted) { onResize == null ? void 0 : onResize(res); } observer = Taro.createIntersectionObserver(instance.page, { observeAll: true, // @ts-ignore nativeMode: true }); observer.relativeTo(`#${resizeId}`).observe(`.${resizeFlexClass}`, (res2) => { if (!res2.relativeRect) { return; } const nextRect = { width: Math.ceil(res2.relativeRect.right - res2.relativeRect.left), height: Math.ceil(res2.relativeRect.bottom - res2.relativeRect.top) }; setRect((prevRect) => { if (nextRect.width !== prevRect.width || nextRect.height !== prevRect.height) { onResize == null ? void 0 : onResize({ ...res2.relativeRect, width: nextRect.width, height: nextRect.height }); return nextRect; } return prevRect; }); }); } }; init(); return () => { observer == null ? void 0 : observer.disconnect(); observer = null; }; }, []); const { width, height } = rect; return /* @__PURE__ */ jsxs( View, { id: resizeId, className, style: { position: "relative", width: "fit-content", ...style }, children: [ children, /* @__PURE__ */ jsx( View, { className: resizeFlexClass, style: { ...flexStyle, left: width - 2, top: height - 2 } } ), /* @__PURE__ */ jsx(View, { className: resizeFlexClass, style: { ...flexStyle, left: width - 1, top: height } }), /* @__PURE__ */ jsx(View, { className: resizeFlexClass, style: { ...flexStyle, left: width, top: height - 1 } }) ] } ); } export { Resizable };