Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | 69x 69x 69x 69x 1x | import { cn } from "../../lib/utils";
type CharCountTextareaProps = {
value: string;
onChange: (value: string) => void;
maxLength: number;
rows?: number;
placeholder?: string;
id?: string;
className?: string;
disabled?: boolean;
};
export function CharCountTextarea({
value,
onChange,
maxLength,
rows = 4,
placeholder,
id,
className,
disabled,
}: CharCountTextareaProps) {
const remaining = maxLength - value.length;
const isNearLimit = remaining <= Math.ceil(maxLength * 0.1);
const isAtLimit = remaining <= 0;
return (
<div>
<textarea
id={id}
value={value}
onChange={(e) => onChange(e.target.value)}
maxLength={maxLength}
rows={rows}
placeholder={placeholder}
disabled={disabled}
className={cn(
"w-full px-3 py-2 text-sm rounded-md border border-border-default bg-background-elevated text-foreground-default focus:ring-2 focus:ring-primary-500 focus:border-transparent resize-none",
className,
)}
/>
<div className="flex justify-end mt-1">
<span
className={cn(
"text-xs",
isAtLimit
? "text-error"
: isNearLimit
? "text-warning"
: "text-foreground-subtle",
)}
>
{value.length}/{maxLength}
</span>
</div>
</div>
);
}
|