|
@@ -3,68 +3,49 @@
|
|
|
|
|
|
export let value = '';
|
|
|
export let placeholder = '';
|
|
|
+ export let rows = 1;
|
|
|
+ export let required = false;
|
|
|
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';
|
|
|
-
|
|
|
- export let onKeydown: Function = () => {};
|
|
|
+ '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';
|
|
|
|
|
|
let textareaElement;
|
|
|
|
|
|
- $: if (textareaElement) {
|
|
|
- if (textareaElement.innerText !== value && value !== '') {
|
|
|
- textareaElement.innerText = value ?? '';
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
// Adjust height on mount and after setting the element.
|
|
|
onMount(async () => {
|
|
|
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
|
|
|
- function handlePaste(event: ClipboardEvent) {
|
|
|
- event.preventDefault(); // Prevent the default paste action
|
|
|
- const clipboardData = event.clipboardData?.getData('text/plain'); // Get plaintext from clipboard
|
|
|
-
|
|
|
- // Insert plaintext into the textarea
|
|
|
- document.execCommand('insertText', false, clipboardData);
|
|
|
- }
|
|
|
+ const resize = () => {
|
|
|
+ if (textareaElement) {
|
|
|
+ textareaElement.style.height = '';
|
|
|
+ textareaElement.style.height = `${textareaElement.scrollHeight}px`;
|
|
|
+ }
|
|
|
+ };
|
|
|
</script>
|
|
|
|
|
|
-<div
|
|
|
- contenteditable="true"
|
|
|
+<textarea
|
|
|
bind:this={textareaElement}
|
|
|
- class="{className} whitespace-pre-wrap relative {value
|
|
|
- ? !value.trim()
|
|
|
- ? 'placeholder'
|
|
|
- : ''
|
|
|
- : 'placeholder'}"
|
|
|
- style="field-sizing: content; -moz-user-select: text !important;"
|
|
|
- on:input={() => {
|
|
|
- const text = textareaElement.innerText;
|
|
|
- if (text === '\n') {
|
|
|
- value = '';
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- value = text;
|
|
|
+ bind:value
|
|
|
+ {placeholder}
|
|
|
+ class={className}
|
|
|
+ style="field-sizing: content;"
|
|
|
+ {rows}
|
|
|
+ {required}
|
|
|
+ on:input={(e) => {
|
|
|
+ resize();
|
|
|
+ }}
|
|
|
+ on:focus={() => {
|
|
|
+ resize();
|
|
|
}}
|
|
|
- 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>
|