Skip to content

Commit ee27a06

Browse files
committed
feat(textarea): added auto-size prop
closes #37
1 parent c501e3e commit ee27a06

File tree

8 files changed

+54
-43
lines changed

8 files changed

+54
-43
lines changed
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
<template>
2+
<ATextarea auto-size />
3+
</template>

docs/guide/components/textarea.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,17 @@ You can adjust the height of ATextarea component by providing `height` prop with
4848

4949
::::
5050

51+
<!-- 👉 Auto Size -->
52+
::::card Auto Size
53+
54+
You can use `auto-size` prop to automatically update the height of ATextarea depending on the content.
55+
56+
:::code DemoTextareaAutoSize
57+
<<< @/components/demos/textarea/DemoTextareaAutoSize.vue{3}
58+
:::
59+
60+
::::
61+
5162
<!-- 👉 API -->
5263
## API
5364

docs/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,9 @@
2828
},
2929
"dependencies": {
3030
"@anu-vue/preset-theme-default": "workspace:*",
31-
"@vueuse/core": "^9.12.0",
31+
"@vueuse/core": "10.0.0-beta.2",
3232
"anu-vue": "workspace:*",
3333
"vee-validate": "^4.7.3",
3434
"vue": "^3.2.47"
3535
}
36-
}
36+
}

packages/anu-vue/src/components/base-input/ABaseInput.vue

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<script lang="ts" setup>
2-
import { baseInputProps } from './props'
3-
import type { baseInputSlots } from './slots'
42
import { ALoader } from '@/components/loader'
53
import { useConfigurable } from '@/composables/useConfigurable'
64
import TransitionExpand from '@/transitions/TransitionExpand.vue'
5+
import { baseInputProps } from './props'
6+
import type { baseInputSlots } from './slots'
77
88
// TODO: Provide a way to attach classes to root element
99
const props = defineProps(baseInputProps)
@@ -29,10 +29,12 @@ const elementId = _elementIdToken ? `a-input-${_elementIdToken}-${Math.random().
2929
3030
const refRoot = ref()
3131
const refInputContainer = ref()
32+
const refInputWrapper = ref()
3233
3334
defineExpose({
3435
refRoot,
3536
refInputContainer,
37+
refInputWrapper,
3638
})
3739
</script>
3840

@@ -76,6 +78,7 @@ defineExpose({
7678
<!-- SECTION Input Wrapper -->
7779
<!-- ❗ relative class is required for loader on `.a-base-input-input-wrapper` -->
7880
<div
81+
ref="refInputWrapper"
7982
:class="[props.inputWrapperClasses, props.error ? 'border-danger' : 'focus-within:border-primary']"
8083
class="a-base-input-input-wrapper cursor-text em:spacing:px-4 spacing:gap-x-2 relative i:focus-within:text-primary items-center border border-solid border-a-border w-full"
8184
@click="$emit('click:inputWrapper')"
Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1-
export { default as ABaseInput } from './ABaseInput.vue'
21
export * from './props'
32
export * from './slots'
3+
export { ABaseInput }
4+
5+
import ABaseInput from './ABaseInput.vue'
6+
7+
export type ABaseInput = InstanceType<typeof ABaseInput>

packages/anu-vue/src/components/textarea/ATextarea.vue

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
<script lang="ts" setup>
2-
import { defu } from 'defu'
3-
import type { ExtractPropTypes } from 'vue'
4-
import { ABaseInput, baseInputProps } from '@/components/base-input'
2+
import { ABaseInput, baseInputProps } from '@/components/base-input';
3+
import { defu } from 'defu';
4+
import type { ExtractPropTypes } from 'vue';
55
66
const props = defineProps(defu({
77
modelValue: String,
88
height: String,
9+
autoSize: Boolean,
910
}, baseInputProps))
1011
1112
const emit = defineEmits<{
@@ -17,21 +18,36 @@ defineOptions({
1718
inheritAttrs: false,
1819
})
1920
21+
const textareaValue = useVModel(props, 'modelValue', emit, { defaultValue: '', passive: true })
22+
2023
const _baseInputProps = reactivePick(props, Object.keys(baseInputProps) as Array<keyof typeof baseInputProps>)
2124
2225
const textarea = ref<HTMLTextAreaElement>()
2326
2427
const handleInputWrapperClick = () => {
2528
textarea.value?.focus()
2629
}
30+
31+
32+
const refBaseInput = ref<ABaseInput>()
33+
if (props.autoSize) {
34+
const refInputWrapper = computed(() => refBaseInput.value?.refInputWrapper)
35+
useTextareaAutosize({
36+
element: textarea,
37+
input: textareaValue,
38+
styleTarget: refInputWrapper
39+
})
40+
}
2741
</script>
2842

2943
<template>
3044
<!-- ℹ️ `overflow-hidden` on input wrapper will prevent square edge when textarea will have scrollbar -->
3145
<ABaseInput
46+
ref="refBaseInput"
3247
v-bind="{ ..._baseInputProps, class: $attrs.class }"
33-
:input-wrapper-classes="['min-h-32 overflow-hidden', props.height, props.inputWrapperClasses]"
48+
:input-wrapper-classes="['h-32 overflow-hidden', props.height, props.inputWrapperClasses]"
3449
class="a-textarea !pointer-events-auto"
50+
:class="[props.autoSize && 'a-textarea-auto-size']"
3551
@click:inputWrapper="handleInputWrapperClick"
3652
>
3753
<!-- ℹ️ Recursively pass down slots to child -->
@@ -50,8 +66,7 @@ const handleInputWrapperClick = () => {
5066
v-bind="{ ...$attrs, ...slotProps }"
5167
ref="textarea"
5268
class="a-textarea-textarea bg-transparent resize-none"
53-
:value="props.modelValue"
54-
@input="emit('update:modelValue', ($event.target as HTMLInputElement).value)"
69+
v-model="textareaValue"
5570
/>
5671
</template>
5772
</ABaseInput>

packages/preset-theme-default/src/shortcuts.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ const shortcuts: Exclude<Preset['shortcuts'], undefined | StaticShortcutMap> = [
175175
'a-tabs-navigation-arrow-next': 'i-bx-right-arrow-alt',
176176

177177
// 👉 Textarea
178-
'a-textarea': '[&_.a-base-input-input-wrapper]-px-0',
178+
'a-textarea': '[&_.a-base-input-input-wrapper]-px-0 [&_.a-base-input-input-wrapper]-box-content',
179179
'a-textarea-textarea': 'em:spacing:py-4 overflow-x-hidden em:spacing:px-4',
180180

181181
// 👉 Tooltip

pnpm-lock.yaml

Lines changed: 6 additions & 31 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)