@yamada-ui/react
Version:
React UI components of the Yamada, by the Yamada, for the Yamada built with React and Emotion
136 lines (132 loc) • 4.06 kB
JavaScript
"use client";
const require_rolldown_runtime = require('../../_virtual/rolldown_runtime.cjs');
const require_effect = require('../../utils/effect.cjs');
const require_ref = require('../../utils/ref.cjs');
const require_utils_index = require('../../utils/index.cjs');
let react = require("react");
react = require_rolldown_runtime.__toESM(react);
//#region src/components/textarea/use-autosize.ts
const SIZING_STYLE_PROPERTIES = [
"borderBottomWidth",
"borderLeftWidth",
"borderRightWidth",
"borderTopWidth",
"boxSizing",
"fontFamily",
"fontSize",
"fontStyle",
"fontWeight",
"letterSpacing",
"lineHeight",
"paddingBottom",
"paddingLeft",
"paddingRight",
"paddingTop",
"tabSize",
"textIndent",
"textRendering",
"textTransform",
"width",
"wordBreak"
];
const HIDDEN_STYLE = {
height: "0",
"max-height": "none",
"min-height": "0",
overflow: "hidden",
position: "absolute",
right: "0",
top: "0",
visibility: "hidden",
"z-index": "-1000"
};
const getSizingStyle = (el) => {
const style = window.getComputedStyle(el);
if (style == null) return null;
const computedStyle = (0, require_utils_index.utils_exports.pickObject)(style, SIZING_STYLE_PROPERTIES);
if (computedStyle.boxSizing === "") return null;
const padding = parseFloat(computedStyle.paddingBottom) + parseFloat(computedStyle.paddingTop);
return {
style: computedStyle,
border: parseFloat(computedStyle.borderBottomWidth) + parseFloat(computedStyle.borderTopWidth),
padding,
rowHeight: parseFloat(computedStyle.lineHeight)
};
};
const setHiddenStyle = (el) => {
Object.keys(HIDDEN_STYLE).forEach((key) => {
el.style.setProperty(key, HIDDEN_STYLE[key], "important");
});
};
const calcRows = (el, sizingStyle, value, maxRows, minRows) => {
const cloneEl = el.cloneNode();
Object.assign(cloneEl.style, sizingStyle.style);
setHiddenStyle(cloneEl);
cloneEl.value = value;
document.body.appendChild(cloneEl);
let rows;
if (cloneEl.scrollHeight) {
const rowHeight = sizingStyle.rowHeight;
rows = Math.min(maxRows, Math.max(minRows, Math.floor(cloneEl.scrollHeight / rowHeight)));
} else {
const lineBreaks = (value.match(/\n/g) || []).length;
rows = Math.min(maxRows, Math.max(minRows, lineBreaks + 1));
}
document.body.removeChild(cloneEl);
return rows;
};
const useAutosize = ({ disabled = false, maxRows = Infinity, minRows = 2 } = {}) => {
const ref = (0, react.useRef)(null);
const beforeValueRef = (0, react.useRef)(null);
const value = ref.current?.value ?? "";
const onResizeTextarea = (0, react.useCallback)(() => {
const el = ref.current;
if (!el) return;
let { placeholder, value: value$1 } = el;
if (value$1 === beforeValueRef.current) return;
beforeValueRef.current = value$1;
value$1 ||= placeholder || "x";
const sizingStyle = getSizingStyle(el);
if (!sizingStyle) return;
el.rows = calcRows(el, sizingStyle, value$1, maxRows, minRows);
}, [
ref,
maxRows,
minRows
]);
const getTextareaProps = (0, react.useCallback)((props = {}) => ({
...props,
ref: require_ref.mergeRefs(props.ref, ref),
style: {
resize: !disabled ? "none" : void 0,
...props.style
},
onChange: (0, require_utils_index.utils_exports.handlerAll)(props.onChange, !disabled ? onResizeTextarea : require_utils_index.utils_exports.noop)
}), [
ref,
onResizeTextarea,
disabled
]);
require_effect.useSafeLayoutEffect(() => {
if (!(0, require_utils_index.utils_exports.createdDom)() || disabled) return;
onResizeTextarea();
const unsubscribeResize = (0, require_utils_index.utils_exports.addDomEvent)(window, "resize", onResizeTextarea);
const unsubscribeLoadingdone = (0, require_utils_index.utils_exports.addDomEvent)(document.fonts, "loadingdone", onResizeTextarea);
return () => {
unsubscribeResize();
unsubscribeLoadingdone();
};
}, []);
require_effect.useUpdateEffect(() => {
if (disabled) return;
onResizeTextarea();
}, [value]);
return {
ref,
getTextareaProps,
onResizeTextarea
};
};
//#endregion
exports.useAutosize = useAutosize;
//# sourceMappingURL=use-autosize.cjs.map