import type { MaybeRef, MultiWatchSources, Ref, WatchSource } from 'vue'; import { nextTick, toRef, toValue, watch } from 'vue'; import type { VoidFunction } from '@robonen/stdlib'; import { noop } from '@robonen/stdlib'; import type { ConfigurableWindow } from '@/types'; import { defaultWindow } from '@/types'; import { useEventListener } from '@/composables/browser/useEventListener'; import { useResizeObserver } from '@/composables/elements/useResizeObserver'; export interface UseTextareaAutosizeOptions extends ConfigurableWindow { /** * The textarea element to autosize. May also be bound via the returned `textarea` ref */ element?: MaybeRef; /** * The textarea content. May also be bound via the returned `input` ref */ input?: MaybeRef; /** * Cap the resulting height (in pixels). Beyond this the textarea scrolls */ maxHeight?: number; /** * Additional reactive sources that should trigger a resize when they change */ watch?: WatchSource | MultiWatchSources; /** * Invoked after each resize once the textarea height settles * * @default noop */ onResize?: VoidFunction; /** * Apply the computed height to this element instead of the textarea itself. * Useful when the textarea is wrapped (e.g. for a CSS grid auto-grow trick) */ styleTarget?: MaybeRef; /** * Which style property carries the computed height * * @default 'height' */ styleProp?: 'height' | 'minHeight'; } export interface UseTextareaAutosizeReturn { /** * The textarea element being autosized. Bind it with `ref` in the template */ textarea: Ref; /** * Two-way bound textarea content */ input: Ref; /** * Force a resize on demand (e.g. after a programmatic value change) */ triggerResize: VoidFunction; } /** * @name useTextareaAutosize * @category Browser * @description Auto-resizes a `