mirror of
https://github.com/acid-info/Kurate.git
synced 2025-01-13 01:14:12 +00:00
feat: textarea resizes as text is added/removed (#209)
Co-authored-by: Barbara Gomes <barbara@barbaragomes.com>
This commit is contained in:
parent
9d939b78a5
commit
73ca7d72d8
@ -1,8 +1,41 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import { onDestroy, onMount } from 'svelte'
|
||||||
|
|
||||||
export let value = ''
|
export let value = ''
|
||||||
export let placeholder = ''
|
export let placeholder = ''
|
||||||
export let label = ''
|
export let label = ''
|
||||||
|
|
||||||
let placeholderHeight: number
|
let placeholderHeight: number
|
||||||
|
let textarea: HTMLTextAreaElement
|
||||||
|
|
||||||
|
const resizeEvents = ['change']
|
||||||
|
const delayedResizeEvents = ['cut', 'paste', 'drop', 'keydown']
|
||||||
|
|
||||||
|
function resize() {
|
||||||
|
textarea.style.height = 'auto'
|
||||||
|
textarea.style.height = `${Math.max(placeholderHeight, textarea.scrollHeight)}px`
|
||||||
|
}
|
||||||
|
|
||||||
|
function delayedResize() {
|
||||||
|
setTimeout(resize, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
// The resize mechanism is heavily inspired by https://stackoverflow.com/a/5346855
|
||||||
|
onMount(() => {
|
||||||
|
resizeEvents.forEach((eventName) => textarea.addEventListener(eventName, resize))
|
||||||
|
delayedResizeEvents.forEach((eventName) => textarea.addEventListener(eventName, delayedResize))
|
||||||
|
resize()
|
||||||
|
})
|
||||||
|
|
||||||
|
// This cleans up all the listeners from the textarea element when the component is about to be destroyed
|
||||||
|
onDestroy(() => {
|
||||||
|
if (!textarea) return
|
||||||
|
|
||||||
|
resizeEvents.forEach((eventName) => textarea.removeEventListener(eventName, resize))
|
||||||
|
delayedResizeEvents.forEach((eventName) =>
|
||||||
|
textarea.removeEventListener(eventName, delayedResize),
|
||||||
|
)
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<label>
|
<label>
|
||||||
@ -14,11 +47,7 @@
|
|||||||
>
|
>
|
||||||
{placeholder}
|
{placeholder}
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
<textarea bind:value bind:this={textarea} class={value != '' ? 'content' : ''} />
|
||||||
bind:value
|
|
||||||
class={value != '' ? 'content' : ''}
|
|
||||||
style={`${value != '' ? 'min-height: ' + placeholderHeight : ''}px;`}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</label>
|
</label>
|
||||||
|
|
||||||
@ -35,11 +64,13 @@
|
|||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
|
|
||||||
.placeholder-text {
|
.placeholder-text {
|
||||||
font-size: var(--font-size-lg);
|
font-size: var(--font-size-lg);
|
||||||
color: var(--grey-300);
|
color: var(--grey-300);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: fit-content;
|
height: fit-content;
|
||||||
|
|
||||||
&.hide {
|
&.hide {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
@ -55,9 +86,12 @@
|
|||||||
|
|
||||||
&:focus,
|
&:focus,
|
||||||
&.content {
|
&.content {
|
||||||
background-color: #ffffff;
|
background-color: #000;
|
||||||
transition: background-color 0.2s;
|
transition: background-color 0.2s;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
@media (prefers-color-scheme: light) {
|
||||||
|
background-color: #ffffff;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.content {
|
&.content {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user