UNPKG

@mantine/core

Version:

React components library focused on usability, accessibility and developer experience

143 lines (142 loc) 5.01 kB
"use client"; const require_runtime = require("../../_virtual/_rolldown/runtime.cjs"); let react = require("react"); react = require_runtime.__toESM(react); let _mantine_hooks = require("@mantine/hooks"); let react_jsx_runtime = require("react/jsx-runtime"); //#region packages/@mantine/core/src/components/Textarea/Autosize.tsx const SIZING_STYLE_KEYS = [ "borderBottomWidth", "borderLeftWidth", "borderRightWidth", "borderTopWidth", "boxSizing", "fontFamily", "fontSize", "fontStyle", "fontWeight", "letterSpacing", "lineHeight", "paddingBottom", "paddingLeft", "paddingRight", "paddingTop", "tabSize", "textIndent", "textRendering", "textTransform", "width", "wordBreak", "wordSpacing", "scrollbarGutter" ]; const HIDDEN_TEXTAREA_STYLE = { "min-height": "0", "max-height": "none", height: "0", visibility: "hidden", overflow: "hidden", position: "absolute", "z-index": "-1000", top: "0", right: "0", display: "block" }; function forceHiddenStyles(node) { Object.keys(HIDDEN_TEXTAREA_STYLE).forEach((key) => { node.style.setProperty(key, HIDDEN_TEXTAREA_STYLE[key], "important"); }); } function getSizingData(node) { const style = window.getComputedStyle(node); if (style === null) return null; const sizingStyle = {}; for (const key of SIZING_STYLE_KEYS) sizingStyle[key] = style[key]; if (sizingStyle.boxSizing === "") return null; return { sizingStyle, paddingSize: parseFloat(sizingStyle.paddingBottom) + parseFloat(sizingStyle.paddingTop), borderSize: parseFloat(sizingStyle.borderBottomWidth) + parseFloat(sizingStyle.borderTopWidth) }; } let hiddenTextarea = null; function calculateNodeHeight(sizingData, value, minRows = 1, maxRows = Infinity) { if (!hiddenTextarea) { hiddenTextarea = document.createElement("textarea"); hiddenTextarea.setAttribute("tabindex", "-1"); hiddenTextarea.setAttribute("aria-hidden", "true"); hiddenTextarea.setAttribute("aria-label", "autosize measurement"); forceHiddenStyles(hiddenTextarea); } if (hiddenTextarea.parentNode === null) document.body.appendChild(hiddenTextarea); const { paddingSize, borderSize, sizingStyle } = sizingData; const { boxSizing } = sizingStyle; Object.keys(sizingStyle).forEach((key) => { hiddenTextarea.style[key] = sizingStyle[key]; }); forceHiddenStyles(hiddenTextarea); hiddenTextarea.value = value; let height = boxSizing === "border-box" ? hiddenTextarea.scrollHeight + borderSize : hiddenTextarea.scrollHeight - paddingSize; hiddenTextarea.value = value; height = boxSizing === "border-box" ? hiddenTextarea.scrollHeight + borderSize : hiddenTextarea.scrollHeight - paddingSize; hiddenTextarea.value = "x"; const rowHeight = hiddenTextarea.scrollHeight - paddingSize; let minHeight = rowHeight * minRows; if (boxSizing === "border-box") minHeight = minHeight + paddingSize + borderSize; height = Math.max(minHeight, height); let maxHeight = rowHeight * maxRows; if (boxSizing === "border-box") maxHeight = maxHeight + paddingSize + borderSize; height = Math.min(maxHeight, height); return [height, rowHeight]; } function TextareaAutosize({ maxRows, minRows, onChange, ref: userRef, ...props }) { const isControlled = props.value !== void 0; const libRef = (0, react.useRef)(null); const ref = (0, _mantine_hooks.useMergedRef)(libRef, userRef); const heightRef = (0, react.useRef)(0); const resizeTextarea = () => { const node = libRef.current; const nodeSizingData = getSizingData(node); if (!nodeSizingData) return; const [height] = calculateNodeHeight(nodeSizingData, node.value || node.placeholder || "x", minRows, maxRows); if (heightRef.current !== height) { heightRef.current = height; node.style.setProperty("height", `${height}px`, "important"); } }; const handleChange = (event) => { if (!isControlled) resizeTextarea(); onChange?.(event); }; (0, react.useLayoutEffect)(resizeTextarea); (0, react.useEffect)(() => { const handleResize = () => resizeTextarea(); window.addEventListener("resize", handleResize); return () => window.removeEventListener("resize", handleResize); }, []); (0, react.useEffect)(() => { const handleFontsLoaded = () => resizeTextarea(); document.fonts.addEventListener("loadingdone", handleFontsLoaded); return () => document.fonts.removeEventListener("loadingdone", handleFontsLoaded); }, []); (0, react.useEffect)(() => { const handleReset = (event) => { if (libRef.current?.form === event.target && !isControlled) { const currentValue = libRef.current.value; requestAnimationFrame(() => { if (libRef.current && currentValue !== libRef.current.value) resizeTextarea(); }); } }; document.body.addEventListener("reset", handleReset); return () => document.body.removeEventListener("reset", handleReset); }, [isControlled]); return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", { ...props, onChange: handleChange, ref }); } //#endregion exports.TextareaAutosize = TextareaAutosize; //# sourceMappingURL=Autosize.cjs.map