UNPKG

react-responsive-scale

Version:

A React component for responsive scaling of data dashboards

331 lines (330 loc) 12 kB
(function(global2, factory) { typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("react"), require("react/jsx-runtime")) : typeof define === "function" && define.amd ? define(["exports", "react", "react/jsx-runtime"], factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, factory(global2.ReactResponsiveScale = {}, global2.React, global2.jsxRuntime)); })(this, function(exports2, react, jsxRuntime) { "use strict"; const ScaleContext = react.createContext(null); function isObject(value) { var type = typeof value; return value != null && (type == "object" || type == "function"); } var freeGlobal = typeof global == "object" && global && global.Object === Object && global; var freeSelf = typeof self == "object" && self && self.Object === Object && self; var root = freeGlobal || freeSelf || Function("return this")(); var now = function() { return root.Date.now(); }; var reWhitespace = /\s/; function trimmedEndIndex(string) { var index = string.length; while (index-- && reWhitespace.test(string.charAt(index))) { } return index; } var reTrimStart = /^\s+/; function baseTrim(string) { return string ? string.slice(0, trimmedEndIndex(string) + 1).replace(reTrimStart, "") : string; } var Symbol$1 = root.Symbol; var objectProto$1 = Object.prototype; var hasOwnProperty = objectProto$1.hasOwnProperty; var nativeObjectToString$1 = objectProto$1.toString; var symToStringTag$1 = Symbol$1 ? Symbol$1.toStringTag : void 0; function getRawTag(value) { var isOwn = hasOwnProperty.call(value, symToStringTag$1), tag = value[symToStringTag$1]; try { value[symToStringTag$1] = void 0; var unmasked = true; } catch (e) { } var result = nativeObjectToString$1.call(value); if (unmasked) { if (isOwn) { value[symToStringTag$1] = tag; } else { delete value[symToStringTag$1]; } } return result; } var objectProto = Object.prototype; var nativeObjectToString = objectProto.toString; function objectToString(value) { return nativeObjectToString.call(value); } var nullTag = "[object Null]", undefinedTag = "[object Undefined]"; var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : void 0; function baseGetTag(value) { if (value == null) { return value === void 0 ? undefinedTag : nullTag; } return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value); } function isObjectLike(value) { return value != null && typeof value == "object"; } var symbolTag = "[object Symbol]"; function isSymbol(value) { return typeof value == "symbol" || isObjectLike(value) && baseGetTag(value) == symbolTag; } var NAN = 0 / 0; var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; var reIsBinary = /^0b[01]+$/i; var reIsOctal = /^0o[0-7]+$/i; var freeParseInt = parseInt; function toNumber(value) { if (typeof value == "number") { return value; } if (isSymbol(value)) { return NAN; } if (isObject(value)) { var other = typeof value.valueOf == "function" ? value.valueOf() : value; value = isObject(other) ? other + "" : other; } if (typeof value != "string") { return value === 0 ? value : +value; } value = baseTrim(value); var isBinary = reIsBinary.test(value); return isBinary || reIsOctal.test(value) ? freeParseInt(value.slice(2), isBinary ? 2 : 8) : reIsBadHex.test(value) ? NAN : +value; } var FUNC_ERROR_TEXT = "Expected a function"; var nativeMax = Math.max, nativeMin = Math.min; function debounce(func, wait, options) { var lastArgs, lastThis, maxWait, result, timerId, lastCallTime, lastInvokeTime = 0, leading = false, maxing = false, trailing = true; if (typeof func != "function") { throw new TypeError(FUNC_ERROR_TEXT); } wait = toNumber(wait) || 0; if (isObject(options)) { leading = !!options.leading; maxing = "maxWait" in options; maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait; trailing = "trailing" in options ? !!options.trailing : trailing; } function invokeFunc(time) { var args = lastArgs, thisArg = lastThis; lastArgs = lastThis = void 0; lastInvokeTime = time; result = func.apply(thisArg, args); return result; } function leadingEdge(time) { lastInvokeTime = time; timerId = setTimeout(timerExpired, wait); return leading ? invokeFunc(time) : result; } function remainingWait(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime, timeWaiting = wait - timeSinceLastCall; return maxing ? nativeMin(timeWaiting, maxWait - timeSinceLastInvoke) : timeWaiting; } function shouldInvoke(time) { var timeSinceLastCall = time - lastCallTime, timeSinceLastInvoke = time - lastInvokeTime; return lastCallTime === void 0 || timeSinceLastCall >= wait || timeSinceLastCall < 0 || maxing && timeSinceLastInvoke >= maxWait; } function timerExpired() { var time = now(); if (shouldInvoke(time)) { return trailingEdge(time); } timerId = setTimeout(timerExpired, remainingWait(time)); } function trailingEdge(time) { timerId = void 0; if (trailing && lastArgs) { return invokeFunc(time); } lastArgs = lastThis = void 0; return result; } function cancel() { if (timerId !== void 0) { clearTimeout(timerId); } lastInvokeTime = 0; lastArgs = lastCallTime = lastThis = timerId = void 0; } function flush() { return timerId === void 0 ? result : trailingEdge(now()); } function debounced() { var time = now(), isInvoking = shouldInvoke(time); lastArgs = arguments; lastThis = this; lastCallTime = time; if (isInvoking) { if (timerId === void 0) { return leadingEdge(lastCallTime); } if (maxing) { clearTimeout(timerId); timerId = setTimeout(timerExpired, wait); return invokeFunc(lastCallTime); } } if (timerId === void 0) { timerId = setTimeout(timerExpired, wait); } return result; } debounced.cancel = cancel; debounced.flush = flush; return debounced; } function ReactResponsiveScale(props) { const { rootValue = 16, precision = 5, rootWidth = 1920, rootHeight = 1080, wait = 300, backgroundColor, backgroundImage, style, children } = props; const rootRef = react.useRef(null); const [rootSize, setRootSize] = react.useState(null); react.useEffect(() => { const computeSize = (size2) => { if (!size2 || !size2.width || !size2.height) { return { width: 0, height: 0, rootFontSize: Math.round(rootValue * 10 ** precision) / 10 ** precision }; } const aspectRatio = rootWidth / rootHeight; let width = 0; let height = 0; if (size2 && size2.width && size2.height) { const wrapperWPH = size2.width / size2.height; if (wrapperWPH > aspectRatio) { height = size2.height; width = Math.round(height * aspectRatio * 10 ** precision) / 10 ** precision; } else if (wrapperWPH < aspectRatio) { width = size2.width; height = Math.round(width / aspectRatio * 10 ** precision) / 10 ** precision; } else { width = size2.width; height = size2.height; } } return { width, height, rootFontSize: Math.round(width / (rootWidth / rootValue) * 10 ** precision) / 10 ** precision }; }; const { clientWidth, clientHeight } = rootRef.current; const size = computeSize({ width: clientWidth, height: clientHeight }); setRootSize(size); const onResize = debounce( () => { const { clientWidth: clientWidth2, clientHeight: clientHeight2 } = rootRef.current; const size2 = computeSize({ width: clientWidth2, height: clientHeight2 }); setRootSize(size2); }, wait // { leading: false, trailing: true } ); window.addEventListener("resize", onResize, true); return () => { window.removeEventListener("resize", onResize, true); }; }, [rootValue, precision, rootWidth, rootHeight, wait]); const calcWidth = react.useCallback( (percent) => { if (typeof rootSize?.width !== "number" || typeof percent !== "number" || percent < 0 || percent > 100) { return 0; } return Math.round(rootSize.width * (percent / 100) * 10 ** precision) / 10 ** precision; }, [rootSize?.width, precision] ); const calcHeight = react.useCallback( (percent) => { if (typeof rootSize?.height !== "number" || typeof percent !== "number" || percent < 0 || percent > 100) { return 0; } return Math.round(rootSize.height * (percent / 100) * 10 ** precision) / 10 ** precision; }, [rootSize?.height, precision] ); const calcPx = react.useCallback( (px) => { if (typeof rootSize?.rootFontSize !== "number" || typeof px !== "number") { return px; } return Math.round(px * rootSize.rootFontSize / rootValue * 10 ** precision) / 10 ** precision; }, [rootSize?.rootFontSize, rootValue, precision] ); const calcRem = react.useCallback( (px) => { if (typeof px !== "number") { return "0rem"; } return Math.round(px / rootValue * 10 ** precision) / 10 ** precision + "rem"; }, [rootValue, precision] ); const ScaleContextValue = react.useMemo( () => ({ rootWidth: rootSize?.width || 0, rootHeight: rootSize?.height || 0, rootValue: rootSize?.rootFontSize || 0, calcWidth, calcHeight, calcPx, calcRem }), [rootSize?.width, rootSize?.height, rootSize?.rootFontSize, calcWidth, calcHeight, calcPx, calcRem] ); react.useEffect(() => { const fontSize = rootSize?.rootFontSize ?? rootValue; document.documentElement.style.fontSize = fontSize + "px"; }, [rootValue, rootSize?.rootFontSize]); return /* @__PURE__ */ jsxRuntime.jsx(ScaleContext.Provider, { value: ScaleContextValue, children: /* @__PURE__ */ jsxRuntime.jsxs( "div", { ref: rootRef, style: { width: "100vw", height: "100vh", position: "fixed", left: 0, top: 0, display: "flex", alignItems: "center", justifyContent: "center", overflow: "hidden", backgroundColor, ...style }, children: [ backgroundImage ? /* @__PURE__ */ jsxRuntime.jsx( "div", { style: { position: "absolute", width: "100%", height: "100%", top: 0, left: 0, backgroundImage, backgroundSize: "cover", backgroundRepeat: "no-repeat", backgroundPosition: "center", filter: "blur(10px)", zIndex: -1 } } ) : null, /* @__PURE__ */ jsxRuntime.jsx("div", { style: { width: rootSize?.width, height: rootSize?.height, position: "relative" }, children: rootSize ? children : null }) ] } ) }); } exports2.ResponsiveScale = ReactResponsiveScale; exports2.ScaleContext = ScaleContext; exports2.default = ReactResponsiveScale; Object.defineProperties(exports2, { __esModule: { value: true }, [Symbol.toStringTag]: { value: "Module" } }); });