HextaUI

useAutosize

Bir textarea'yı yazdıklarınıza göre en küçük ve en büyük yüksekliği arasında büyütür; metne hiç dokunmadan her değişikliği canlandırır.

"use client"

import * as React from "react"

import { useAutosize } from "@/hooks/use-autosize"

export function UseAutosizeDemo() {
  const ref = React.useRef<HTMLTextAreaElement>(null)
  useAutosize(ref, true, undefined)

  return (
    <textarea
      ref={ref}
      rows={1}
      aria-label="Note"
      placeholder="Write a note. It grows up to six lines."
      className="max-h-[calc(6lh+1rem)] min-h-[calc(1lh+1rem)] w-full max-w-sm resize-none rounded-lg bg-muted px-3 py-2 text-sm/6 outline-none placeholder:text-muted-foreground focus-visible:ring-3 focus-visible:ring-focus-ring focus-visible:outline-hidden pointer-coarse:text-touch"
    />
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/use-autosize.json

Hook'u ve bağımlı olduğu her şeyi projenize ekler.

import { useAutosize } from "@/hooks/use-autosize"
const ref = React.useRef<HTMLTextAreaElement>(null)
useAutosize(ref, true, value)

<textarea
  ref={ref}
  rows={1}
  value={value}
  onChange={(event) => setValue(event.target.value)}
  className="min-h-[calc(1lh+1rem)] max-h-[calc(8lh+1rem)] resize-none"
/>

<Textarea autoResize> bu hook'u zaten kullanır. Sohbet yazma alanı veya satır içi düzenleyici gibi kendi <textarea> bileşeninizi işlerken onu kendiniz çağırın.

Her değişiklikte hook yüksekliği auto yapar, doğal scrollHeight değerini okur ve öğenin kendi CSS min-height ve max-height değerlerine sıkıştırır. Hepsi boyamadan önce olur, bu yüzden daralmış kareyi asla görmezsiniz. Sınırlar CSS'inizde kalır; böylece duyarlı olabilir veya satırları saymak için lh kullanabilir.

min-h-[calc(2lh+1rem)]   at least two lines plus the vertical padding
max-h-[calc(8lh+1rem)]   then scroll after eight
max-h-64                 or any fixed length
  • Yükseklik değişiklikleri 180ms'de animasyonlanır ve animasyon sırasında gelen bir değişiklik geçerli yükseklikten başlar; böylece hızlı yazma asla zıplamaz. Azaltılmış harekette yükseklik anında değişir.
  • max-height aşıldığında textarea kayar. Aksi halde kaydırma çubuğu gizli kalır; böylece her yeni satırda çakmaz.
  • Genişlik değiştiğinde yeniden uyum sağlar, çünkü farklı sarılan metin yüksekliği değiştirir.
  • window üzerinde input olayını dinler ve yalnızca ölçer. Değeri asla okumaz veya yazmaz; böylece tuş vuruşları hiç gecikmez veya düşmez.

Kontrollü değerler

Yazmak input tetikler ama koddan value ayarlamak tetiklemez. Değeri üçüncü argüman olarak verin; bir şablon eklediğinizde veya temizlediğinizde textarea yeniden uyum sağlar.

"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { useAutosize } from "@/hooks/use-autosize"

const template = `Hi team,

The release is out. Highlights:
- Faster search
- Offline drafts
- New keyboard shortcuts

Thanks!`

export function UseAutosizeControlled() {
  const ref = React.useRef<HTMLTextAreaElement>(null)
  const [value, setValue] = React.useState("")
  useAutosize(ref, true, value)

  return (
    <div className="flex w-full max-w-sm flex-col gap-3">
      <textarea
        ref={ref}
        rows={1}
        aria-label="Message"
        value={value}
        onChange={(event) => setValue(event.target.value)}
        placeholder="Message"
        className="max-h-[calc(8lh+1rem)] min-h-[calc(2lh+1rem)] w-full resize-none rounded-lg bg-muted px-3 py-2 text-sm/6 outline-none placeholder:text-muted-foreground focus-visible:ring-3 focus-visible:ring-focus-ring focus-visible:outline-hidden pointer-coarse:text-touch"
      />
      <div className="flex gap-2">
        <Button variant="outline" size="sm" onClick={() => setValue(template)}>
          Insert template
        </Button>
        <Button variant="ghost" size="sm" onClick={() => setValue("")}>
          Clear
        </Button>
      </div>
    </div>
  )
}
  • rows={1} ve resize-none ayarlayın. Elle yeniden boyutlandırma tutamacı otomatik yükseklikle çatışır.
  • enabled'ı kapatmak veya unmount etmek satır içi yüksekliği ve taşmayı kaldırır, boyutu CSS'inize geri verir.
  • Dokunmatik ekranlarda textarea'da en az 16px metin kullanın; aksi halde odaklanınca iOS yakınlaştırır.
PropTürVarsayılan
refBoyutlandırılacak textarea.
RefObject<HTMLTextAreaElement | null>–
enabledOtomatik boyutlandırılıp boyutlandırılmayacağı.
boolean–
valueKontrollü değer. Kontrolsüz textarea'lar için undefined verin.
unknown–

Textarea ve InputGroupTextarea.