refac: textarea

This commit is contained in:
Timothy Jaeryang Baek 2025-01-31 23:49:25 -08:00
parent 4e375c892a
commit af10f87075

View File

@ -3,68 +3,49 @@
export let value = ''; export let value = '';
export let placeholder = ''; export let placeholder = '';
export let rows = 1;
export let required = false;
export let className = export let className =
'w-full rounded-lg px-3 py-2 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none resize-none h-full'; 'w-full rounded-lg px-3 py-2 text-sm bg-gray-50 dark:text-gray-300 dark:bg-gray-850 outline-none h-full';
export let onKeydown: Function = () => {};
let textareaElement; let textareaElement;
$: if (textareaElement) {
if (textareaElement.innerText !== value && value !== '') {
textareaElement.innerText = value ?? '';
}
}
// Adjust height on mount and after setting the element. // Adjust height on mount and after setting the element.
onMount(async () => { onMount(async () => {
await tick(); await tick();
resize();
requestAnimationFrame(() => {
// setInterveal to cehck until textareaElement is set
const interval = setInterval(() => {
if (textareaElement) {
clearInterval(interval);
resize();
}
}, 100);
});
}); });
// Handle paste event to ensure only plaintext is pasted const resize = () => {
function handlePaste(event: ClipboardEvent) { if (textareaElement) {
event.preventDefault(); // Prevent the default paste action textareaElement.style.height = '';
const clipboardData = event.clipboardData?.getData('text/plain'); // Get plaintext from clipboard textareaElement.style.height = `${textareaElement.scrollHeight}px`;
// Insert plaintext into the textarea
document.execCommand('insertText', false, clipboardData);
} }
};
</script> </script>
<div <textarea
contenteditable="true"
bind:this={textareaElement} bind:this={textareaElement}
class="{className} whitespace-pre-wrap relative {value bind:value
? !value.trim() {placeholder}
? 'placeholder' class={className}
: '' style="field-sizing: content;"
: 'placeholder'}" {rows}
style="field-sizing: content; -moz-user-select: text !important;" {required}
on:input={() => { on:input={(e) => {
const text = textareaElement.innerText; resize();
if (text === '\n') { }}
value = ''; on:focus={() => {
return; resize();
}
value = text;
}} }}
on:paste={handlePaste}
on:keydown={onKeydown}
data-placeholder={placeholder}
/> />
<style>
.placeholder::before {
/* absolute */
position: absolute;
content: attr(data-placeholder);
color: #adb5bd;
overflow: hidden;
display: -webkit-box;
-webkit-box-orient: vertical;
-webkit-line-clamp: 1;
pointer-events: none;
touch-action: none;
}
</style>