import * as React from "react"; import { useImperativeHandle, useRef } from "react"; import { cn } from "~/utils/cn"; import { Icon, type RenderIcon } from "./Icon"; const containerBase = "has-focus-visible:outline-hidden has-focus-visible:ring-1 has-focus-visible:ring-border-bright has-focus-visible:ring-offset-0 has-[:focus]:border-ring has-focus:outline-hidden has-focus:ring-1 has-[:focus]:ring-ring has-disabled:cursor-not-allowed has-disabled:opacity-50 ring-offset-background transition cursor-text"; const inputBase = "h-full w-full text-text-bright bg-transparent file:border-0 file:bg-transparent file:text-base file:font-medium placeholder:text-muted-foreground focus-visible:outline-hidden focus-visible:ring-0 disabled:cursor-not-allowed outline-hidden ring-0 border-none [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none [&::-webkit-outer-spin-button]:m-0 [&::-webkit-inner-spin-button]:m-0 [&]:[-moz-appearance:textfield]"; const variants = { large: { container: "px-1 w-full h-10 rounded-[3px] border border-background-bright bg-background-hover hover:border-border-bright hover:bg-secondary", input: "px-2 text-sm", iconSize: "size-4 ml-1", accessory: "pr-1", }, medium: { container: "px-1 h-8 w-full rounded border border-background-bright bg-background-hover hover:border-border-bright hover:bg-secondary", input: "px-1.5 rounded text-sm", iconSize: "size-4 ml-0.5", accessory: "pr-1", }, small: { container: "px-1 h-6 w-full rounded border border-background-bright bg-background-hover hover:border-border-bright hover:bg-secondary", input: "px-1 rounded text-xs", iconSize: "size-3 ml-0.5", accessory: "pr-0.5", }, tertiary: { container: "px-1 h-6 w-full rounded hover:bg-background-hover", input: "px-1 rounded text-xs", iconSize: "size-3 ml-0.5", accessory: "pr-0.5", }, "secondary-small": { container: "px-1 h-6 w-full rounded border border-border-bright hover:border-border-brighter bg-grid-dimmed hover:bg-secondary", input: "px-1 rounded text-xs", iconSize: "size-3 ml-0.5", accessory: "pr-0.5", }, "outline/large": { container: "px-1 h-10 w-full rounded border border-grid-bright hover:border-border-brighter", input: "px-2 rounded text-sm", iconSize: "size-4 ml-1", accessory: "pr-1", }, "outline/medium": { container: "px-1 h-8 w-full rounded border border-grid-bright hover:border-border-brighter", input: "px-1 rounded text-sm", iconSize: "size-4 ml-0.5", accessory: "pr-1", }, "outline/small": { container: "px-1 h-6 w-full rounded border border-grid-bright hover:border-border-brighter", input: "px-1 rounded text-xs", iconSize: "size-3 ml-0.5", accessory: "pr-0.5", }, }; export type InputProps = React.InputHTMLAttributes & { variant?: keyof typeof variants; icon?: RenderIcon; iconClassName?: string; accessory?: React.ReactNode; fullWidth?: boolean; containerClassName?: string; }; const Input = React.forwardRef( ( { className, type, accessory, fullWidth = true, variant = "medium", icon, iconClassName, containerClassName, ...props }, ref ) => { const innerRef = useRef(null); useImperativeHandle(ref, () => innerRef.current as HTMLInputElement); const variantContainerClassName = variants[variant].container; const inputClassName = variants[variant].input; const variantIconClassName = variants[variant].iconSize; return (
innerRef.current && innerRef.current.focus()} > {icon && (
)} {accessory &&
{accessory}
}
); } ); Input.displayName = "Input"; export { Input };