import { useDialogComposition } from "@/components/ui/dialog"; import { useComposition } from "@/hooks/useComposition"; import { cn } from "@/lib/utils"; import * as React from "react"; function Textarea({ className, onKeyDown, onCompositionStart, onCompositionEnd, ...props }: React.ComponentProps<"textarea">) { // Get dialog composition context if available (will be no-op if not inside Dialog) const dialogComposition = useDialogComposition(); // Add composition event handlers to support input method editor (IME) for CJK languages. const { onCompositionStart: handleCompositionStart, onCompositionEnd: handleCompositionEnd, onKeyDown: handleKeyDown, } = useComposition({ onKeyDown: (e) => { // Check if this is an Enter key that should be blocked const isComposing = (e.nativeEvent as any).isComposing || dialogComposition.justEndedComposing(); // If Enter key is pressed while composing or just after composition ended, // don't call the user's onKeyDown (this blocks the business logic) // Note: For textarea, Shift+Enter should still work for newlines if (e.key === "Enter" && !e.shiftKey && isComposing) { return; } // Otherwise, call the user's onKeyDown onKeyDown?.(e); }, onCompositionStart: e => { dialogComposition.setComposing(true); onCompositionStart?.(e); }, onCompositionEnd: e => { // Mark that composition just ended - this helps handle the Enter key that confirms input dialogComposition.markCompositionEnd(); // Delay setting composing to false to handle Safari's event order // In Safari, compositionEnd fires before the ESC keydown event setTimeout(() => { dialogComposition.setComposing(false); }, 100); onCompositionEnd?.(e); }, }); return (