feat(filter): add auto resize for filter query input

This commit is contained in:
kolaente 2023-12-15 19:01:08 +01:00
parent 8313bb8a9b
commit bcfd2d5392
Signed by: konrad
GPG Key ID: F40E70337AB24C9B
3 changed files with 25 additions and 10 deletions

View File

@ -1,5 +1,6 @@
<script setup lang="ts"> <script setup lang="ts">
import {computed, ref, watch} from 'vue' import {computed, ref, watch} from 'vue'
import {useAutoHeightTextarea} from '@/composables/useAutoHeightTextarea'
const { const {
modelValue, modelValue,
@ -8,6 +9,10 @@ const {
}>() }>()
const filterQuery = ref('') const filterQuery = ref('')
const {
textarea: filterInput,
height,
} = useAutoHeightTextarea(filterQuery)
watch( watch(
() => modelValue, () => modelValue,
@ -88,14 +93,19 @@ function escapeHtml(unsafe: string): string {
spellcheck="false" spellcheck="false"
v-model="filterQuery" v-model="filterQuery"
class="input" class="input"
ref="filterInput"
></textarea> ></textarea>
<div class="filter-input-highlight" v-html="highlightedFilterQuery"></div> <div
class="filter-input-highlight"
:style="{'height': height}"
v-html="highlightedFilterQuery"
></div>
</div> </div>
</div> </div>
</template> </template>
<style lang="scss"> <style lang="scss">
.filter-input-highlight span { .filter-input-highlight span {
&.filter-query__field { &.filter-query__field {
color: #faf594; color: #faf594;
} }
@ -113,18 +123,20 @@ function escapeHtml(unsafe: string): string {
<style lang="scss" scoped> <style lang="scss" scoped>
.filter-input { .filter-input {
position: relative; position: relative;
textarea { textarea {
position: absolute; position: absolute;
text-fill-color: transparent; text-fill-color: transparent;
-webkit-text-fill-color: transparent; -webkit-text-fill-color: transparent;
background: transparent !important; background: transparent !important;
resize: none;
} }
.filter-input-highlight { .filter-input-highlight {
height: 2.5em; height: 2.5em;
line-height: 1.5; line-height: 1.5;
padding: .5em .75em; padding: .5em .75em;
word-break: break-word;
} }
} }
</style> </style>

View File

@ -71,7 +71,7 @@ const props = defineProps({
const emit = defineEmits(['taskAdded']) const emit = defineEmits(['taskAdded'])
const newTaskTitle = ref('') const newTaskTitle = ref('')
const newTaskInput = useAutoHeightTextarea(newTaskTitle) const {textarea: newTaskInput} = useAutoHeightTextarea(newTaskTitle)
const {t} = useI18n({useScope: 'global'}) const {t} = useI18n({useScope: 'global'})
const authStore = useAuthStore() const authStore = useAuthStore()

View File

@ -6,6 +6,7 @@ import {debouncedWatch, tryOnMounted, useWindowSize, type MaybeRef} from '@vueus
export function useAutoHeightTextarea(value: MaybeRef<string>) { export function useAutoHeightTextarea(value: MaybeRef<string>) {
const textarea = ref<HTMLTextAreaElement | null>(null) const textarea = ref<HTMLTextAreaElement | null>(null)
const minHeight = ref(0) const minHeight = ref(0)
const height = ref('')
// adapted from https://github.com/LeaVerou/stretchy/blob/47f5f065c733029acccb755cae793009645809e2/src/stretchy.js#L34 // adapted from https://github.com/LeaVerou/stretchy/blob/47f5f065c733029acccb755cae793009645809e2/src/stretchy.js#L34
function resize(textareaEl: HTMLTextAreaElement | null) { function resize(textareaEl: HTMLTextAreaElement | null) {
@ -23,14 +24,13 @@ export function useAutoHeightTextarea(value: MaybeRef<string>) {
textareaEl.style.minHeight = '' textareaEl.style.minHeight = ''
textareaEl.style.height = '0' textareaEl.style.height = '0'
const offset = textareaEl.offsetHeight - parseFloat(cs.paddingTop) - parseFloat(cs.paddingBottom) height.value = textareaEl.scrollHeight + 'px'
const height = textareaEl.scrollHeight + offset + 'px'
textareaEl.style.height = height textareaEl.style.height = height.value
// calculate min-height for the first time // calculate min-height for the first time
if (!minHeight.value) { if (!minHeight.value) {
minHeight.value = parseFloat(height) minHeight.value = parseFloat(height.value)
} }
textareaEl.style.minHeight = minHeight.value.toString() textareaEl.style.minHeight = minHeight.value.toString()
@ -68,5 +68,8 @@ export function useAutoHeightTextarea(value: MaybeRef<string>) {
}, },
) )
return textarea return {
textarea,
height,
}
} }