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 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 | 'use client'; import { type AnyFieldApi } from '@tanstack/react-form'; import { FormInput } from '@/components/shared'; import { getHintMessage } from '@/lib/auth/utils'; import { cn } from '@/lib/utils'; interface AvailabilityButtonProps { onClick: () => void; disabled: boolean; } type NicknameCheck = { hint?: string; state: { status: 'idle' | 'checking' | 'available' | 'unavailable' | 'error' }; isChecking: boolean; check: (value: string) => void | Promise<void>; reset: () => void; }; interface Props { field: AnyFieldApi; nicknameCheck: NicknameCheck; } const AvailabilityButton = ({ onClick, disabled }: AvailabilityButtonProps) => { return ( <button className={cn( 'text-text-xs-semibold absolute top-4 right-5 rounded-lg bg-gray-100 px-3 py-1 text-gray-800', disabled && '!cursor-not-allowed', )} aria-disabled={disabled} aria-label='닉네임 중복 확인' disabled={disabled} type='button' onClick={onClick} > 중복 확인 </button> ); }; export const NicknameField = ({ field, nicknameCheck }: Props) => { const hintMessage = getHintMessage(field); const trimmedValue = field.state.value.trim(); const hasValidationError = field.state.meta.errors.length > 0; const availabilityButtonDisabled = !trimmedValue || hasValidationError || nicknameCheck.isChecking; const iconButton = ( <AvailabilityButton disabled={availabilityButtonDisabled} onClick={() => { void nicknameCheck.check(trimmedValue); }} /> ); return ( <FormInput availabilityHint={nicknameCheck.hint} availabilityStatus={nicknameCheck.state} hintMessage={hintMessage} inputProps={{ type: 'text', autoComplete: 'nickname', placeholder: '닉네임을 입력해주세요', value: field.state.value, iconButton: iconButton, onChange: (e) => { field.handleChange(e.target.value); nicknameCheck.reset(); }, }} labelName='닉네임' /> ); }; |