npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@sanghee01/card-field-hooks

v0.0.11

Published

A set of hooks for managing card fields in React

Readme

Card Field Hooks

신용카드 정보를 입력하는 데 필요한 다양한 React Custom Hook과 유틸리티를 제공하는 npm 패키지입니다.


🚀 설치 방법

npm install @sanghee01/card-field-hooks

🛠️ 제공되는 훅

이 패키지는 신용카드 입력 필드를 관리하기 위한 다음과 같은 커스텀 훅을 제공합니다.

useCardNumberField

  • 카드 번호 입력 관리
  • 입력값 자동 포맷팅 (VISA, MasterCard, AMEX, Diners, UnionPay 등 카드사별 포맷)
  • 카드 브랜드 자동 감지 기능
  • 카드사별 유효성 검사 자동 처리
  • 카드 종류에 따른 최대 입력 길이 자동 설정
const {
  cardNumbers, // 숫자만 포함된 원본 카드 번호 (예: "4111111111111111")
  formattedCardNumber, // 포맷팅된 카드 번호 (예: "4111 1111 1111 1111")
  cardBrand, // 감지된 카드 브랜드 (visa, master, amex, diners, unionpay 등)
  handleCardNumberChange, // 카드 번호 변경 핸들러 함수
  cardNumberErrors, // 유효성 검사 오류 메시지
  isCardNumberValid, // 카드 번호 유효한지 여부 (boolean)
  maxCardLength, // 카드 종류에 따른 최대 입력 길이 (공백 포함)
} = useCardNumberField();

사용 예시

import React from 'react';
import { useCardNumberField } from '@sanghee01/card-field-hooks';

function CardNumberInput() {
  const {
    cardNumbers,
    formattedCardNumber,
    cardBrand,
    handleCardNumberChange,
    cardNumberErrors,
    isCardNumberValid,
    maxCardLength,
  } = useCardNumberField();

  return (
    <div>
      <label htmlFor="cardNumber">카드 번호</label>
      <input
        type="text"
        name="cardNumber"
        value={formattedCardNumber}
        onChange={(e) => handleCardNumberChange(e.target.value)}
        placeholder="카드 번호를 입력해주세요."
        maxLength={maxCardLength}
      />
      {!isCardNumberValid && <p className="error">{cardNumberErrors}</p>}
      {cardBrand && <p>카드 종류: {cardBrand.toUpperCase()}</p>}
    </div>
  );
}

useExpirationDateField

  • 카드 유효기간 입력 관리
  • MM/YY 형식 자동 처리 및 유효성 검사
const {
  cardExpiration, // { month: string, year: string } 형태의 객체
  handleCardExpirationChange, // 카드 유효기간 변경 핸들러 함수
  cardExpirationError, // { month: string, year: string } 형태의 오류 메시지
  isCardExpirationValid, // 유효기간이 유효한지 여부 (boolean)
} = useExpirationDateField();

useCardPasswordField

  • 카드 비밀번호 입력 관리 (앞 2자리)
  • 유효성 검사 및 마스킹 처리
const {
  cardPassword, // 카드 비밀번호 값 (string)
  handleCardPasswordChange, // 비밀번호 변경 핸들러 함수
  cardPasswordError, // 비밀번호 오류 메시지
  isCardPasswordValid, // 비밀번호가 유효한지 여부 (boolean)
} = useCardPasswordField();

useCvcField

  • 카드 CVC 입력 관리
  • 입력값 유효성 검사 자동 처리
const {
  cvc, // CVC 값 (string)
  handleCvcChange, // CVC 변경 핸들러 함수
  cvcError, // CVC 오류 메시지
  isCvcValid, // CVC가 유효한지 여부 (boolean)
} = useCvcField();

useCardCompanyField

  • 카드 회사 선택 관리
const {
  cardCompany, // 선택된 카드 회사 (string)
  handleSelectChange, // 카드 회사 선택 변경 핸들러 함수
} = useCardCompanyField();

📦 유틸리티

  • 카드 유효성 검사: 카드 번호, 유효기간, 비밀번호, CVC 입력에 대한 유효성 검사 로직을 제공합니다.
  • 카드 브랜드 감지: 카드 번호를 기반으로 카드 브랜드를 자동으로 감지합니다.
  • 포맷팅: 카드 번호, 유효기간 등의 입력값을 적절한 형식으로 자동 포맷팅합니다.
import {
  validateNumberError,
  validateCardBrandLength,
  validateMonthRangeError,
  validateYearLengthError,
  validateCardPasswordLengthError,
  validateCvcLengthError,
} from '@sanghee01/card-field-hooks';

// 예시 사용법
const isNumberValid = !validateNumberError('1234'); // true

📌 사용 예시

import React from 'react';
import {
  useCardNumberField,
  useExpirationDateField,
  useCardPasswordField,
  useCvcField,
  useCardCompanyField,
  CardCompany,
} from '@sanghee01/card-field-hooks';

const CardForm = () => {
  // 카드 번호 관리
  const { cardNumbers, formattedCardNumber, handleCardNumberChange, cardNumberErrors, isCardNumberValid } =
    useCardNumberField();

  // 유효기간 관리
  const { cardExpiration, handleCardExpirationChange, cardExpirationError, isCardExpirationValid } =
    useExpirationDateField();

  // 비밀번호 관리
  const { cardPassword, handleCardPasswordChange, cardPasswordError, isCardPasswordValid } = useCardPasswordField();

  // CVC 관리
  const { cvc, handleCvcChange, cvcError, isCvcValid } = useCvcField();

  // 카드 회사 관리
  const { cardCompany, handleSelectChange } = useCardCompanyField();

  const handleSubmit = (e) => {
    e.preventDefault();

    // 모든 입력값이 유효한지 확인
    if (isCardNumberValid && isCardExpirationValid && isCardPasswordValid && isCvcValid && cardCompany) {
      console.log('카드 정보 제출:', {
        cardNumbers,
        expirationMonth: cardExpiration.month,
        expirationYear: cardExpiration.year,
        cardPassword,
        cvc,
        cardCompany,
      });
      // 결제 처리 로직...
    } else {
      console.log('유효하지 않은 카드 정보가 있습니다.');
    }
  };

  return (
    <form onSubmit={handleSubmit}>
      <div>
        <label htmlFor="cardNumber">카드 번호</label>
        <input
          id="cardNumber"
          value={formattedCardNumber}
          onChange={(e) => handleCardNumberChange(e.target.value)}
          placeholder="카드 번호를 입력해주세요"
        />
        {!isCardNumberValid && <p className="error">{cardNumberErrors}</p>}
      </div>

      <div>
        <label htmlFor="expirationMonth">유효기간 (월)</label>
        <input
          id="expirationMonth"
          value={cardExpiration.month}
          onChange={(e) => handleCardExpirationChange('month', e.target.value)}
          placeholder="MM"
          maxLength={2}
        />
        {cardExpirationError.month && <p className="error">{cardExpirationError.month}</p>}
      </div>

      <div>
        <label htmlFor="expirationYear">유효기간 (년)</label>
        <input
          id="expirationYear"
          value={cardExpiration.year}
          onChange={(e) => handleCardExpirationChange('year', e.target.value)}
          placeholder="YY"
          maxLength={2}
        />
        {cardExpirationError.year && <p className="error">{cardExpirationError.year}</p>}
      </div>

      <div>
        <label htmlFor="cardPassword">비밀번호 앞 2자리</label>
        <input
          id="cardPassword"
          type="password"
          value={cardPassword}
          onChange={(e) => handleCardPasswordChange(e.target.value)}
          placeholder="앞 2자리"
          maxLength={2}
        />
        {!isCardPasswordValid && <p className="error">{cardPasswordError}</p>}
      </div>

      <div>
        <label htmlFor="cvc">CVC</label>
        <input id="cvc" value={cvc} onChange={(e) => handleCvcChange(e.target.value)} placeholder="CVC" maxLength={4} />
        {!isCvcValid && <p className="error">{cvcError}</p>}
      </div>

      <div>
        <label htmlFor="cardCompany">카드 회사</label>
        <select
          id="cardCompany"
          value={cardCompany}
          onChange={(e) => handleSelectChange(e.target.value as CardCompany)}
        >
          <option value="">카드사 선택</option>
          <option value="BC카드">BC카드</option>
          <option value="신한카드">신한카드</option>
          <option value="카카오뱅크">카카오뱅크</option>
          <option value="현대카드">현대카드</option>
          <option value="우리카드">우리카드</option>
          <option value="롯데카드">롯데카드</option>
          <option value="하나카드">하나카드</option>
          <option value="국민카드">국민카드</option>
        </select>
      </div>

      <button type="submit">결제하기</button>
    </form>
  );
};