EXITN

Input

플로팅 라벨, 애니메이션, 다양한 변형을 가진 향상된 입력 컴포넌트

Input

Input 컴포넌트는 플로팅 라벨, 부드러운 애니메이션, 유효성 검사 상태, 다양한 스타일링 변형을 제공하는 포괄적인 텍스트 입력 솔루션입니다.

설치

pnpm dlx shadcn@latest add https://n-exit.io/r/input.json

기능

  • 플로팅 라벨: 입력 필드 위로 떠오르는 부드러운 라벨 애니메이션
  • 다양한 변형: 기본, 채우기, 아웃라인, 밑줄, 페이드 스타일
  • 유효성 검사 상태: 애니메이션과 함께 성공, 오류, 경고 상태
  • 아이콘 지원: 애니메이션과 함께 왼쪽 및 오른쪽 아이콘 지원
  • 지우기 기능: 부드러운 전환과 함께 내장된 지우기 버튼
  • 비밀번호 토글: 비밀번호 표시/숨김 기능
  • 라벨 배치: 유연한 라벨 위치 옵션
  • 접근성: 완전한 ARIA 지원 및 키보드 내비게이션

기본 사용법

import { Input } from '@/nexit-ui/components/ui/input'

export function BasicInput() {
  return <Input placeholder="이름을 입력하세요" />
}

라벨 변형

외부 라벨 (기본)

<Input 
  label="이메일 주소" 
  placeholder="이메일을 입력하세요"
  labelPlacement="outside"
/>

플로팅 라벨 (내부)

<Input 
  label="전체 이름"
  labelPlacement="inside"
/>

외부 왼쪽 라벨

<Input 
  label="사용자명"
  placeholder="사용자명 입력"
  labelPlacement="outside-left"
/>

Input Variants

Default

<Input 
  label="Default Input"
  placeholder="Default style"
  variant="default"
/>

Filled

<Input 
  label="Filled Input"
  placeholder="Filled background"
  variant="filled"
/>

Outlined

<Input 
  label="Outlined Input"
  placeholder="Outlined border"
  variant="outlined"
/>

Underlined

<Input 
  label="Underlined Input"
  placeholder="Bottom border only"
  variant="underlined"
/>

Faded

<Input 
  label="Faded Input"
  placeholder="Subtle background"
  variant="faded"
/>

Sizes

<Input size="sm" label="Small" placeholder="Small input" />
<Input size="default" label="Default" placeholder="Default input" />
<Input size="lg" label="Large" placeholder="Large input" />
<Input size="xl" label="Extra Large" placeholder="Extra large input" />

With Icons

Left Icon

<Input 
  label="Email"
  placeholder="Enter email"
  leftIcon={<MailIcon className="h-4 w-4" />}
/>

Right Icon

<Input 
  label="Password"
  type="password"
  placeholder="Enter password"
  rightIcon={<EyeIcon className="h-4 w-4" />}
/>

Both Icons

<Input 
  label="Search"
  placeholder="Search..."
  leftIcon={<SearchIcon className="h-4 w-4" />}
  rightIcon={<FilterIcon className="h-4 w-4" />}
/>

Validation States

Success State

<Input 
  label="Valid Input"
  placeholder="This looks good"
  state="success"
  description="Great! This input is valid."
/>

Error State

<Input 
  label="Invalid Input"
  placeholder="Something's wrong"
  state="error"
  errorMessage="This field is required."
/>

Warning State

<Input 
  label="Warning Input"
  placeholder="Be careful"
  state="warning"
  description="This might need attention."
/>

Required Fields

<Input 
  label="Required Field"
  placeholder="This field is required"
  isRequired
/>

Clear Functionality

<Input 
  label="Clearable Input"
  placeholder="Type something..."
  isClearable
  onClear={() => console.log('Input cleared')}
/>

Password Toggle

<Input 
  label="Password"
  type="password"
  showPasswordToggle
  placeholder="Enter password"
/>

<Input 
  label="Password with Clear"
  type="password"
  showPasswordToggle
  isClearable
  placeholder="Enter password"
/>

Descriptions and Help Text

<Input 
  label="Username"
  placeholder="Enter username"
  description="Username must be 3-20 characters long"
/>

<Input 
  label="Password"
  type="password"
  placeholder="Enter password"
  errorMessage="Password must be at least 8 characters"
/>

Radius Options

<Input radius="none" label="No Radius" />
<Input radius="sm" label="Small Radius" />
<Input radius="default" label="Default Radius" />
<Input radius="lg" label="Large Radius" />
<Input radius="xl" label="Extra Large Radius" />
<Input radius="full" label="Full Radius" />

Disabled State

<Input 
  label="Disabled Input"
  placeholder="Cannot type here"
  disabled
/>

Animation Controls

{/* Disable animations */}
<Input 
  label="No Animation"
  placeholder="Static input"
  disableAnimation
/>

API Reference

Input Props

PropTypeDefaultDescription
variantstring"default"Input style variant
sizestring"default"Input size
radiusstring"default"Border radius
statestring"default"Validation state
labelstring-Input label text
descriptionstring-Help text below input
errorMessagestring-Error message text
leftIconReactNode-Icon on the left side
rightIconReactNode-Icon on the right side
labelPlacementstring"outside"Label positioning
isRequiredbooleanfalseShow required indicator
isClearablebooleanfalseShow clear button
disableAnimationbooleanfalseDisable animations
onClearfunction-Clear button callback
showPasswordTogglebooleanfalseShow password visibility toggle

Variant Options

VariantDescription
defaultStandard border with background
filledFilled background style
outlinedThick border, no background
underlinedBottom border only
fadedSubtle background tint

Size Options

SizeDescription
smSmall input (36px height)
defaultDefault input (44px height)
lgLarge input (52px height)
xlExtra large input (60px height)

State Options

StateDescription
defaultNormal state
successValid/success state (green)
errorError state (red)
warningWarning state (yellow)

Label Placement Options

PlacementDescription
outsideLabel above input (default)
insideFloating label inside input
outside-leftLabel to the left of input

Examples

Login Form

import { useState } from 'react'
import { Input } from '@/nexit-ui/components/ui/input'
import { Button } from '@/nexit-ui/components/ui/button'

export function LoginForm() {
  const [email, setEmail] = useState('')
  const [password, setPassword] = useState('')

  return (
    <form className="space-y-4">
      <Input
        label="Email"
        type="email"
        placeholder="Enter your email"
        value={email}
        onChange={(e) => setEmail(e.target.value)}
        leftIcon={<MailIcon className="h-4 w-4" />}
        isRequired
      />
      
      <Input
        label="Password"
        type="password"
        placeholder="Enter your password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        leftIcon={<LockIcon className="h-4 w-4" />}
        isRequired
      />
      
      <Button type="submit" variant="primary" className="w-full">
        Sign In
      </Button>
    </form>
  )
}

Search Input

export function SearchInput() {
  const [query, setQuery] = useState('')

  return (
    <Input
      placeholder="Search anything..."
      value={query}
      onChange={(e) => setQuery(e.target.value)}
      leftIcon={<SearchIcon className="h-4 w-4" />}
      isClearable
      onClear={() => setQuery('')}
      variant="filled"
    />
  )
}

Form Validation

export function ValidatedInput() {
  const [email, setEmail] = useState('')
  const [error, setError] = useState('')

  const validateEmail = (value: string) => {
    const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
    if (!value) {
      setError('Email is required')
    } else if (!emailRegex.test(value)) {
      setError('Please enter a valid email')
    } else {
      setError('')
    }
  }

  return (
    <Input
      label="Email Address"
      type="email"
      placeholder="Enter your email"
      value={email}
      onChange={(e) => {
        setEmail(e.target.value)
        validateEmail(e.target.value)
      }}
      state={error ? 'error' : email ? 'success' : 'default'}
      errorMessage={error}
      isRequired
    />
  )
}

The Input component provides a comprehensive solution for text input needs with beautiful animations and excellent user experience.