HextaUI

useInvalidShake

Lässt ein Formularelement wackeln, wenn ein Absendeversuch es als ungültig findet, und nie, während noch getippt wird.

Submit without choosing.
"use client"

import * as React from "react"

import { Button } from "@/components/ui/button"
import { useInvalidShake } from "@/hooks/use-invalid-shake"

export function UseInvalidShakeDemo() {
  const ref = React.useRef<HTMLSelectElement>(null)
  const [sent, setSent] = React.useState<string>()
  useInvalidShake(ref)

  return (
    <form
      className="flex w-full max-w-xs flex-col gap-3"
      onSubmit={(event) => {
        event.preventDefault()
        setSent(String(new FormData(event.currentTarget).get("plan")))
      }}
    >
      <label className="flex flex-col gap-2 text-sm font-medium">
        Plan
        <select
          ref={ref}
          name="plan"
          required
          defaultValue=""
          className="h-9 rounded-md bg-muted px-2.5 text-sm font-normal outline-none focus-visible:ring-3 focus-visible:ring-focus-ring focus-visible:outline-hidden data-shake:motion-safe:animate-button-shake pointer-coarse:text-touch [&:user-invalid]:ring-2 [&:user-invalid]:ring-destructive/40"
        >
          <option value="" disabled>
            Choose a plan
          </option>
          <option value="hobby">Hobby</option>
          <option value="pro">Pro</option>
        </select>
      </label>
      <Button type="submit" size="sm">
        Continue
      </Button>
      <output className="text-sm text-muted-foreground">
        {sent ? `plan=${sent}` : "Submit without choosing."}
      </output>
    </form>
  )
}
pnpm dlx shadcn@latest add https://hextaui.com/r/use-invalid-shake.json

Fügt den Hook und alles, wovon er abhängt, zu deinem Projekt hinzu.

import { useInvalidShake } from "@/hooks/use-invalid-shake"
const ref = React.useRef<HTMLSelectElement>(null)
useInvalidShake(ref)

<form>
  <select
    ref={ref}
    required
    className="data-shake:motion-safe:animate-button-shake"
  >
    …
  </select>
  <button type="submit">Continue</button>
</form>

Der Hook setzt nur ein data-shake-Attribut. Die Bewegung kommt vom animate-button-shake des Themes, das du mit data-shake:motion-safe:animate-button-shake anhängst. Input, Textarea, Native select und Input group von HextaUI enthalten diese Klasse bereits und rufen den Hook auf. Nutze ihn direkt für eigene Steuerelemente.

Ein Wackeln beantwortet eine Frage: Warum hat mein Absenden nicht funktioniert? Deshalb wackelt der Hook nur direkt nach einem Absendeversuch und nie, während jemand das Formular noch ausfüllt.

EventBeschreibung
Submit attemptEin Klick auf einen Submit-Button, Enter in einem Input des Formulars oder das submit-Event des Formulars.
Invalid within 600msDas Steuerelement löst invalid aus oder hat aria-invalid="true", data-invalid oder :user-invalid. Das deckt native Validierung, Base-UI-Fields und Serverfehler ab, die direkt nach dem Absenden gesetzt werden.
Shakedata-shake wird für 400ms gesetzt. Es wackelt einmal pro Versuch, egal wie viele dieser Signale eintreffen.
  • In einer InputGroup wackelt die ganze Gruppe, nicht nur das innere Steuerelement.
  • Bei reduzierter Bewegung wird nichts gesetzt. Kombiniere das Wackeln in jedem Fall mit einer sichtbaren Fehlermeldung, da das Wackeln ein Hinweis ist, nicht die Meldung.
  • Der Hook braucht ein Steuerelement, das zu einem <form> gehört. Ohne eines tut er nichts.
  • Schalte es pro Steuerelement mit dem Argument enabled oder mit shake={false} an den Inputs von HextaUI ab.
  • Das Neustarten des Attributs startet die Animation neu, sodass ein zweiter fehlgeschlagener Versuch erneut wackelt, auch wenn der erste noch läuft.
  • Die native Validierung fokussiert beim Absenden das erste ungültige Steuerelement. Das Wackeln fügt nur Bewegung hinzu und verschiebt nie den Fokus.
PropTypStandard
refDas Formular-Steuerelement, das beobachtet wird.
RefObject<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement | null>–
enabledOb gewackelt wird.
booleantrue
AttributBeschreibung
data-shakeVorhanden für 400ms nach einem fehlgeschlagenen Absendeversuch, am Steuerelement oder seiner InputGroup.

Input, Textarea, NativeSelect und InputGroup.