Highly ambitious ATProtocol AppView service and sdks
at fix-postgres 44 lines 1.5 kB view raw
1import type { JSX } from "preact"; 2import { cn } from "../../utils/cn.ts"; 3 4type TextareaSize = "sm" | "md" | "lg"; 5 6export interface TextareaProps 7 extends Omit<JSX.IntrinsicElements['textarea'], 'size'> { 8 label?: string; 9 error?: string; 10 size?: TextareaSize; 11} 12 13export function Textarea(props: TextareaProps): JSX.Element { 14 const { class: classProp, label, error, size = "lg", ...rest } = props; 15 16 const sizeClasses = { 17 sm: "px-2.5 py-0.5 text-xs", 18 md: "px-3 py-1 text-sm", 19 lg: "px-4 py-2 text-sm", 20 }; 21 22 const className = cn( 23 "block w-full border border-zinc-200 dark:border-zinc-700 rounded-md bg-white dark:bg-zinc-900 text-zinc-900 dark:text-white placeholder:text-zinc-500 dark:placeholder:text-zinc-400 focus:outline-none focus:ring-2 focus:border-transparent", 24 sizeClasses[size], 25 error 26 ? "border-red-500 dark:border-red-400 focus:ring-red-500 dark:focus:ring-red-400" 27 : "focus:ring-blue-500 dark:focus:ring-blue-400", 28 props.disabled && "bg-zinc-50 dark:bg-zinc-800 text-zinc-500 dark:text-zinc-400 cursor-not-allowed", 29 classProp, 30 ); 31 32 return ( 33 <div> 34 {label && ( 35 <label className="block text-sm font-medium text-zinc-700 dark:text-zinc-300 mb-2"> 36 {label} 37 {props.required && <span className="text-red-500 dark:text-red-400 ml-1">*</span>} 38 </label> 39 )} 40 <textarea class={className} {...rest} /> 41 {error && <p className="mt-1 text-sm text-red-600 dark:text-red-400">{error}</p>} 42 </div> 43 ); 44}