Input component
Installation
npx shadcn@latest add @caprice/inputnpm install @caprice-ui/reactInstall the following dependencies:
npm install @base-ui/react lucide-reactAdd a cn helper
import { defineConfig, type VariantProps } from 'cva';import { twMerge } from 'tailwind-merge';export const { compose, cva, cx: cn,} = defineConfig({ hooks: { onComplete: (className: string) => twMerge(className), },});export type { VariantProps };Copy and paste the following code into your project.
import { mergePropsN } from '@base-ui/react';import { Input as InputPrimitive } from '@base-ui/react/input';import type * as React from 'react';import { useFocusRing } from 'react-aria';import { cva, type VariantProps } from '@/lib/utils';export const inputVariants = cva({ base: [ 'w-full min-w-0 rounded-md border border-input bg-transparent shadow-xs outline-none selection:bg-primary selection:text-primary-foreground placeholder:text-muted-foreground disabled:pointer-events-none disabled:cursor-not-allowed disabled:opacity-50 dark:bg-input/30', // Transition 'transition-[color,background-color,box-shadow]', // Hover state 'hover:not-focus-within:border-input/30 hover:not-focus-within:bg-input/30 hover:not-focus-within:placeholder:text-current', // File 'file:inline-flex file:h-7 file:border-0 file:bg-transparent file:font-medium file:text-foreground file:text-sm', // Focus state, using focus instead of focus-visible to avoid confusion with data-focus-visible 'focus:border-ring focus:ring-[3px] focus:ring-ring/50 focus:placeholder:text-current', // Real "focus-visible", only visible when interacting with a keyboard. // ref: https://react-spectrum.adobe.com/react-aria/useFocusRing.html 'data-focus-visible:ring-2 data-focus-visible:ring-foreground data-focus-visible:ring-offset-2', // Invalid state 'aria-invalid:border-destructive aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40', ], variants: { size: { sm: '', md: 'h-9 px-3 py-1 text-base md:text-sm', lg: '', }, }, defaultVariants: { size: 'md', },});/** * A native input element that automatically works with [Field](https://base-ui.com/react/components/field). * Renders an `<input>` element. * * Documentation: [Caprice UI Input](https://caprice-ui.com/docs/components/input) * * API Reference: [Base UI Input](https://base-ui.com/react/components/input) */export namespace Input { export type State = InputPrimitive.State; export type Props = Omit<React.ComponentProps<typeof InputPrimitive>, 'size'> & { size?: VariantProps<typeof inputVariants>['size'] | number; }; export type ChangeEventDetails = InputPrimitive.ChangeEventDetails; export type ChangeEventReason = InputPrimitive.ChangeEventReason;}export function Input({ className, size, ...props }: Input.Props) { const { isFocusVisible, focusProps } = useFocusRing({ isTextInput: true }); const inputProps = mergePropsN<'input'>([focusProps, props]); return ( <InputPrimitive className={inputVariants({ size: typeof size === 'string' ? size : undefined, className })} data-focus-visible={isFocusVisible ? '' : undefined} data-slot="input" size={typeof size === 'number' ? size : undefined} {...inputProps} /> );}Update the import paths to match your project setup.
Usage
import { Input } from "@/components/caprice-ui/input"import { Input } from "@caprice-ui/react/input"