Skip to content

Commit

Permalink
feat(useTextareaAutosize): allow configuring styleProp to support n…
Browse files Browse the repository at this point in the history
…ative `rows` attribute (#3552)

Co-authored-by: alexander.kudinov <ka@modumlab.com>
Co-authored-by: Anthony Fu <github@antfu.me>
Co-authored-by: Anthony Fu <anthonyfu117@hotmail.com>
  • Loading branch information
4 people authored Feb 20, 2024
1 parent cf29c4c commit 5025e3a
Show file tree
Hide file tree
Showing 2 changed files with 45 additions and 3 deletions.
39 changes: 39 additions & 0 deletions packages/core/useTextareaAutosize/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Automatically update the height of a textarea depending on the content.

## Usage

### Simple example

```vue
<script setup lang="ts">
const { textarea, input } = useTextareaAutosize()
Expand All @@ -22,3 +24,40 @@ const { textarea, input } = useTextareaAutosize()
/>
</template>
```

::: info

It's recommended to reset the scrollbar styles for the textarea element to avoid incorrect height values for large amounts of text.

```css
textarea {
-ms-overflow-style: none;
scrollbar-width: none;
}

textarea::-webkit-scrollbar {
display: none;
}
```

:::

### With `rows` attribute

If you need support for the rows attribute on a textarea element, then you should set the `styleProp` option to `minHeight`.

```vue
<script setup lang="ts">
const { textarea, input } = useTextareaAutosize({ styleProp: 'minHeight' })
</script>
<template>
<textarea
ref="textarea"
v-model="input"
class="resize-none"
placeholder="What's on your mind?"
rows="3"
/>
</template>
```
9 changes: 6 additions & 3 deletions packages/core/useTextareaAutosize/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@ export interface UseTextareaAutosizeOptions {
onResize?: () => void
/** Specify style target to apply the height based on textarea content. If not provided it will use textarea it self. */
styleTarget?: MaybeRef<HTMLElement>
/** Specify the style property that will be used to manipulate height. Can be `height | minHeight`. Default value is `height`. */
styleProp?: 'height' | 'minHeight'
}

export function useTextareaAutosize(options?: UseTextareaAutosizeOptions) {
const textarea = ref<HTMLTextAreaElement>(options?.element as any)
const input = ref<string>(options?.input as any)
const styleProp = options?.styleProp ?? 'height'
const textareaScrollHeight = ref(1)

function triggerResize() {
Expand All @@ -28,17 +31,17 @@ export function useTextareaAutosize(options?: UseTextareaAutosizeOptions) {

let height = ''

textarea.value!.style.height = '1px'
textarea.value.style[styleProp] = '1px'
textareaScrollHeight.value = textarea.value?.scrollHeight

// If style target is provided update its height
if (options?.styleTarget)
toValue(options.styleTarget).style.height = `${textareaScrollHeight.value}px`
toValue(options.styleTarget).style[styleProp] = `${textareaScrollHeight.value}px`
// else update textarea's height by updating height variable
else
height = `${textareaScrollHeight.value}px`

textarea.value!.style.height = height
textarea.value.style[styleProp] = height

options?.onResize?.()
}
Expand Down

0 comments on commit 5025e3a

Please sign in to comment.