UNPKG

@nutui/nutui-react-taro

Version:

京东风格的轻量级移动端 React 组件库,支持一套代码生成 H5 和小程序

120 lines (119 loc) 4.03 kB
import { _ as __rest } from "./tslib.es6-iWu3F_1J.js"; import React__default, { useState, useEffect, useRef } from "react"; import classNames from "classnames"; import Taro from "@tarojs/taro"; import { C as ComponentDefaults } from "./typings-DV9RBfhj.js"; import { a as useRtl } from "./configprovider.taro-DpK4IiCE.js"; import { u as useUuid } from "./use-uuid-BvqmbYZ7.js"; const defaultProps = Object.assign(Object.assign({}, ComponentDefaults), { percent: 0, showText: false, animated: false, lazy: false, delay: 0 }); const Progress = (props) => { const rtl = useRtl(); const _a = Object.assign(Object.assign({}, defaultProps), props), { className, style, percent, background, color, strokeWidth, showText, animated, children, lazy, delay } = _a, rest = __rest(_a, ["className", "style", "percent", "background", "color", "strokeWidth", "showText", "animated", "children", "lazy", "delay"]); const classPrefix = "nut-progress"; const classesInner = classNames({ [`${classPrefix}-inner`]: true, [`${classPrefix}-active`]: animated }); const stylesOuter = { height: `${strokeWidth}px`, background }; const [displayPercent, setDispalyPercent] = useState(0); const stylesInner = { width: `${displayPercent}%`, background: color }; const handlePercent = () => { let timer = null; if (delay) { setDispalyPercent(0); timer = setTimeout(() => { setDispalyPercent(percent); }, delay); } return () => { lazy && resetObserver(Taro.getEnv()); timer && clearTimeout(timer); }; }; useEffect(() => { setDispalyPercent(percent); }, [percent]); const [intersecting, setIntersecting] = useState(false); const progressRef = useRef(null); const webObserver = useRef(null); const uuid = useUuid(); const selector = `${classPrefix}-lazy-${uuid}`; const resetObserver = (env, observer = null) => { if (env === "WEB") { webObserver.current.disconnect && webObserver.current.disconnect(); } else { observer && observer.disconnect(); } }; useEffect(() => { if (lazy) { setTimeout(() => { if (intersecting) { setDispalyPercent(percent); } else { setDispalyPercent(0.01); } }, delay); } }, [intersecting]); const handleWebObserver = () => { if (lazy) { webObserver.current = new IntersectionObserver((entires, self) => { entires.forEach((item) => { setIntersecting(item.isIntersecting); }); }, { threshold: [0], rootMargin: "0px" }); webObserver.current.observe(progressRef.current); } handlePercent(); }; const handleOtherObserver = () => { let observer = null; if (lazy) { observer = Taro.createIntersectionObserver(Taro.getCurrentInstance().page, { thresholds: [0], observeAll: true }); observer.relativeToViewport({ top: 0 }).observe(`#${selector}`, (res) => { setIntersecting(res.intersectionRatio > 0); }); } handlePercent(); }; useEffect(() => { if (Taro.getEnv() === "WEB") { handleWebObserver(); } else { handleOtherObserver(); } }, []); return React__default.createElement( "div", Object.assign({ ref: progressRef, id: selector, className: classNames(classPrefix, className), style }, rest), React__default.createElement( "div", { className: `${classPrefix}-outer`, style: stylesOuter }, React__default.createElement("div", { className: classesInner, style: stylesInner }, showText && React__default.createElement("div", { className: `${classPrefix}-text`, style: rtl ? { right: `${displayPercent}%` } : { left: `${displayPercent}%` } }, children || React__default.createElement( "div", { className: `${classPrefix}-text-inner`, style: { background: color } }, percent, "%" ))) ) ); }; Progress.displayName = "NutProgress"; export { Progress as P };