mirror of
https://github.com/robonen/lorem-blog.git
synced 2026-03-20 10:54:38 +00:00
feat(ui): add Input, Textarea, Button, and Badge components with styles and props
This commit is contained in:
68
src/shared/composables/useTextAreaAutosize.ts
Normal file
68
src/shared/composables/useTextAreaAutosize.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { clamp } from '@robonen/stdlib';
|
||||
import { nextTick, onMounted, onUnmounted, ref, type TemplateRef, watch } from 'vue';
|
||||
|
||||
export function useTextAreaAutosize(textareaRef: TemplateRef<HTMLTextAreaElement | null>) {
|
||||
const minHeight = ref(0);
|
||||
const maxHeight = ref(Infinity);
|
||||
|
||||
const resize = () => nextTick(() => {
|
||||
const textarea = textareaRef.value;
|
||||
if (!textarea)
|
||||
return;
|
||||
|
||||
textarea.style.height = 'auto';
|
||||
|
||||
const newHeight = clamp(textarea.scrollHeight, minHeight.value, maxHeight.value);
|
||||
|
||||
textarea.style.height = `${newHeight}px`;
|
||||
|
||||
textarea.style.overflowY = newHeight >= maxHeight.value ? 'auto' : 'hidden';
|
||||
});
|
||||
|
||||
const handleInput = () => {
|
||||
resize();
|
||||
};
|
||||
|
||||
onMounted(() => {
|
||||
const textarea = textareaRef.value;
|
||||
if (textarea) {
|
||||
minHeight.value = textarea.offsetHeight;
|
||||
|
||||
textarea.addEventListener('input', handleInput);
|
||||
textarea.addEventListener('paste', handleInput);
|
||||
|
||||
resize();
|
||||
}
|
||||
});
|
||||
|
||||
onUnmounted(() => {
|
||||
const textarea = textareaRef.value;
|
||||
if (textarea) {
|
||||
textarea.removeEventListener('input', handleInput);
|
||||
textarea.removeEventListener('paste', handleInput);
|
||||
}
|
||||
});
|
||||
|
||||
watch(textareaRef, (newTextarea) => {
|
||||
if (newTextarea) {
|
||||
minHeight.value = newTextarea.offsetHeight;
|
||||
resize();
|
||||
}
|
||||
});
|
||||
|
||||
const setMinHeight = (height: number) => {
|
||||
minHeight.value = height;
|
||||
resize();
|
||||
};
|
||||
|
||||
const setMaxHeight = (height: number) => {
|
||||
maxHeight.value = height;
|
||||
resize();
|
||||
};
|
||||
|
||||
return {
|
||||
resize,
|
||||
setMinHeight,
|
||||
setMaxHeight,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user