From 7bf0984698e43b9aa2dd879f65951318ed410390 Mon Sep 17 00:00:00 2001 From: Maze <167211895+mazeincoding@users.noreply.github.com> Date: Sat, 31 Jan 2026 00:20:04 +0100 Subject: codebase overhaul (#697) --- apps/web/src/components/ui/input.tsx | 225 ++++++++++++++++++++--------------- 1 file changed, 127 insertions(+), 98 deletions(-) (limited to 'apps/web/src/components/ui/input.tsx') diff --git a/apps/web/src/components/ui/input.tsx b/apps/web/src/components/ui/input.tsx index 8f195a50..9be4bca2 100644 --- a/apps/web/src/components/ui/input.tsx +++ b/apps/web/src/components/ui/input.tsx @@ -1,113 +1,142 @@ "use client"; import { Eye, EyeOff, X } from "lucide-react"; -import { cn } from "../../lib/utils"; +import { cva, type VariantProps } from "class-variance-authority"; +import { cn } from "@/utils/ui"; import { Button } from "./button"; -import { forwardRef, ComponentProps } from "react"; +import { forwardRef, type ComponentProps } from "react"; import { useState } from "react"; -interface InputProps extends ComponentProps<"input"> { - showPassword?: boolean; - onShowPasswordChange?: (show: boolean) => void; - showClearIcon?: boolean; - onClear?: () => void; - containerClassName?: string; +const inputVariants = cva( + "file:text-foreground placeholder:text-muted-foreground border-border bg-background flex w-full min-w-0 rounded-md border shadow-xs outline-none file:inline-flex file:border-0 file:bg-transparent file:font-medium disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 focus-visible:ring-4 aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive", + { + variants: { + variant: { + default: "selection:bg-primary selection:text-primary-foreground focus-visible:border-primary focus-visible:ring-primary/10", + destructive: "selection:bg-destructive selection:text-destructive-foreground focus-visible:border-destructive focus-visible:ring-destructive/10", + }, + size: { + default: + "h-9 px-3 py-1 text-base file:h-7 file:text-sm md:text-sm", + sm: "h-8 px-3 text-xs file:h-6 file:text-xs", + lg: "h-10 px-4 text-base file:h-8 file:text-sm md:text-sm", + }, + }, + defaultVariants: { + size: "default", + variant: "default", + }, + }, +); + +interface InputProps + extends Omit, "size">, + VariantProps { + showPassword?: boolean; + onShowPasswordChange?: (show: boolean) => void; + showClearIcon?: boolean; + onClear?: () => void; + containerClassName?: string; } const Input = forwardRef( - ( - { - className, - type, - containerClassName, - showPassword, - onShowPasswordChange, - showClearIcon, - onClear, - value, - onFocus, - onBlur, - ...props - }, - ref - ) => { - const [isFocused, setIsFocused] = useState(false); + ( + { + className, + type, + size, + variant, + containerClassName, + showPassword, + onShowPasswordChange, + showClearIcon, + onClear, + value, + onFocus, + onBlur, + ...props + }, + ref, + ) => { + const [isFocused, setIsFocused] = useState(false); - const isPassword = type === "password"; - const showPasswordToggle = isPassword && onShowPasswordChange; - const showClear = - showClearIcon && - onClear && - value && - String(value).length > 0 && - isFocused; - const inputType = isPassword && showPassword ? "text" : type; + const isPassword = type === "password"; + const showPasswordToggle = isPassword && onShowPasswordChange; + const showClear = + showClearIcon && + onClear && + value && + String(value).length > 0 && + isFocused; + const inputType = isPassword && showPassword ? "text" : type; - const hasIcons = showPasswordToggle || showClear; - const iconCount = Number(showPasswordToggle) + Number(showClear); - const paddingRight = - iconCount === 2 ? "pr-20" : iconCount === 1 ? "pr-10" : ""; + const hasIcons = showPasswordToggle || showClear; + const iconCount = Number(showPasswordToggle) + Number(showClear); + const paddingRight = + iconCount === 2 ? "pr-20" : iconCount === 1 ? "pr-10" : ""; - return ( -
- { - setIsFocused(true); - onFocus?.(e); - }} - onBlur={(e) => { - setIsFocused(false); - onBlur?.(e); - }} - {...props} - /> - {showClear && ( - - )} - {showPasswordToggle && ( - - )} -
- ); - } + return ( +
+ { + setIsFocused(true); + onFocus?.(e); + }} + onBlur={(e) => { + setIsFocused(false); + onBlur?.(e); + }} + {...props} + /> + {showClear && ( + + )} + {showPasswordToggle && ( + + )} +
+ ); + }, ); Input.displayName = "Input"; -- cgit v1.3.1