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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@omergulcicek/forms

v1.4.0

Published

Seamlessly integrate smart masking and robust validation into your react-hook-form inputs. Get clean, unmasked values with full TypeScript support, built to work perfectly with shadcn/ui.

Downloads

473

Readme

@omergulcicek/forms

Seamlessly integrate smart masking and robust validation into your react-hook-form inputs. Get clean, unmasked values with full TypeScript support, built to work perfectly with shadcn/ui.

npm bundlephobia types license npm downloads

🚀 Live Demo

Try the interactive demo: omergulcicek-forms.vercel.app

See all input types with real-time validation, masking, and shadcn/ui integration in action.

Installation

npm install @omergulcicek/forms

Peer Dependencies

This package requires the following dependencies:

npm install react react-hook-form use-mask-input

Features

Keyboard Input Validation: Numeric fields only accept numbers
Smart Masking: Automatic formatting for phone, card numbers, etc.
Pattern Validation: Built-in regex validation
Value Access: Get both masked and unmasked field values
TypeScript Support: Full type safety
shadcn/ui Compatible: Works seamlessly with shadcn/ui components

Usage

import { useForm } from "react-hook-form"
import { useMaskedFormFields } from "@omergulcicek/forms"

export default function MyForm() {
  const form = useForm()

  const { cardNumber, expiryDate, cvv, tckn, phone, email, url, alpha, password, details } =
    useMaskedFormFields({
      form,
      fields: [
        // 💳 Payment Fields
        { name: "cardNumber", type: "cardNumber" },
        { name: "expiryDate", type: "expiryDate" },
        { name: "cvv", type: "cvv" },

        // 🇹🇷 Turkish Specific
        { name: "tckn", type: "tckn" },
        { name: "phone", type: "phone" },

        // 📧 Contact & Web
        { name: "email", type: "email" },
        { name: "url", type: "url" },

        // 📝 Text Fields
        { name: "alpha", type: "alpha" },
        { name: "password", type: "password" },
        { name: "details", type: "text" },
      ],
    })

  // Access field values
  console.log(cardNumber.value) // "1234567890123456" (unmasked)
  console.log(cardNumber.maskedValue) // "1234 5678 9012 3456" (masked)

  return (
    <form onSubmit={form.handleSubmit(console.log)}>
      {/* Payment */}
      <input {...cardNumber} placeholder="**** **** **** ****" />
      <input {...expiryDate} placeholder="MM/YY" />
      <input {...cvv} placeholder="***" />

      {/* Turkish */}
      <input {...tckn} placeholder="12345678950" />
      <input {...phone} placeholder="(5xx) xxx xx xx" />

      {/* Contact */}
      <input {...email} placeholder="[email protected]" />
      <input {...url} placeholder="https://example.com/" />

      {/* Text */}
      <input {...alpha} placeholder="Ömer Gülçiçek" />
      <input {...password} placeholder="••••••••" />
      <input {...details} placeholder="Additional details..." />

      <button type="submit">Submit</button>
    </form>
  )
}

💡 Value Access

Each field object provides both masked and unmasked values:

const { cardNumber, phone } = useMaskedFormFields({
  form,
  fields: [
    { name: "cardNumber", type: "cardNumber" },
    { name: "phone", type: "phone" },
  ],
})

// Unmasked values (clean)
console.log(cardNumber.value)  // "1234567890123456"
console.log(phone.value)       // "5551234567"

// Masked values (formatted)
console.log(cardNumber.maskedValue)  // "1234 5678 9012 3456"
console.log(phone.maskedValue)       // "(555) 123 45 67"

// Use in JSX
<div>
  <span>Clean: {cardNumber.value}</span>
  <span>Formatted: {cardNumber.maskedValue}</span>
</div>

🎭 Custom Mask & Pattern

You can override the built-in masks and regex patterns per field using mask and pattern on each field config.

Custom mask for numeric fields

import { useForm } from "react-hook-form"
import { useMaskedFormFields } from "@omergulcicek/forms"

type FormValues = {
  altCard: string
  trPhone: string
}

const form = useForm<FormValues>()

const { altCard, trPhone } = useMaskedFormFields<FormValues>({
  form,
  fields: [
    {
      name: "altCard",
      type: "cardNumber",
      // default: "9999 9999 9999 9999"
      mask: "9999-9999-9999-9999",
    },
    {
      name: "trPhone",
      type: "phone",
      // default: "(999) 999 99 99"
      mask: "+90 (999) 999 99 99",
    },
  ],
})

Custom pattern (regex) override

const { trPhone } = useMaskedFormFields<FormValues>({
  form,
  fields: [
    {
      name: "trPhone",
      type: "phone",
      mask: "+90 (999) 999 99 99",
      pattern: /^\+90\s\d{3}\s\d{3}\s\d{2}\s\d{2}$/,
    },
  ],
})

Fully custom text field

type FormValues = { iban: string }

const form = useForm<FormValues>()

const { iban } = useMaskedFormFields<FormValues>({
  form,
  fields: [
    {
      name: "iban",
      type: "text",
      pattern: /^TR\d{2}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{4}\s?\d{2}$/,
      inputMode: "text",
    },
  ],
})

🎨 shadcn/ui Integration

This package works seamlessly with shadcn/ui components. Here's how to use it:

With shadcn Input Component

import { useForm } from "react-hook-form"
import { useMaskedFormFields } from "@omergulcicek/forms"
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { Button } from "@/components/ui/button"

export default function ShadcnForm() {
  const form = useForm()

  const { cardNumber, phone, email, tckn } = useMaskedFormFields({
    form,
    fields: [
      { name: "cardNumber", type: "cardNumber" },
      { name: "phone", type: "phone" },
      { name: "email", type: "email" },
      { name: "tckn", type: "tckn" },
    ],
  })

  return (
    <form onSubmit={form.handleSubmit(console.log)} className="space-y-4">
      <div>
        <Label htmlFor="cardNumber">Card Number</Label>
        <Input {...cardNumber} placeholder="**** **** **** ****" />
      </div>
      
      <div>
        <Label htmlFor="phone">Phone</Label>
        <Input {...phone} placeholder="(5xx) xxx xx xx" />
      </div>
      
      <div>
        <Label htmlFor="email">Email</Label>
        <Input {...email} placeholder="[email protected]" />
      </div>
      
      <div>
        <Label htmlFor="tckn">Turkish ID</Label>
        <Input {...tckn} placeholder="12345678950" />
      </div>

      <Button type="submit">Submit</Button>
    </form>
  )
}

With shadcn Form Components (Advanced)

Use the basic example for quick setup, or go with the advanced version for full form control with validation, error handling, and accessibility via shadcn/ui form components.

import { zodResolver } from "@hookform/resolvers/zod"
import { useForm } from "react-hook-form"
import { useMaskedFormFields } from "@omergulcicek/forms"
import * as z from "zod"

import {
  Form,
  FormControl,
  FormDescription,
  FormField,
  FormItem,
  FormLabel,
  FormMessage,
} from "@/components/ui/form"
import { Input } from "@/components/ui/input"
import { Button } from "@/components/ui/button"

const formSchema = z.object({
  cardNumber: z.string().min(1, "Card number is required"),
  phone: z.string().min(1, "Phone is required"),
  email: z.string().email("Invalid email address"),
})

export default function AdvancedShadcnForm() {
  const form = useForm<z.infer<typeof formSchema>>({
    resolver: zodResolver(formSchema),
  })

  const { cardNumber, phone, email } = useMaskedFormFields({
    form,
    fields: [
      { name: "cardNumber", type: "cardNumber" },
      { name: "phone", type: "phone" },
      { name: "email", type: "email" },
    ],
  })

  return (
    <Form {...form}>
      <form onSubmit={form.handleSubmit(console.log)} className="space-y-6">
        <FormField
          control={form.control}
          name="cardNumber"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Card Number</FormLabel>
              <FormControl>
                <Input {...field} {...cardNumber} placeholder="**** **** **** ****" />
              </FormControl>
              <FormDescription>Enter your 16-digit card number</FormDescription>
              <FormMessage />
            </FormItem>
          )}
        />

        <FormField
          control={form.control}
          name="phone"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Phone Number</FormLabel>
              <FormControl>
                <Input {...field} {...phone} placeholder="(5xx) xxx xx xx" />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        <FormField
          control={form.control}
          name="email"
          render={({ field }) => (
            <FormItem>
              <FormLabel>Email</FormLabel>
              <FormControl>
                <Input {...field} {...email} placeholder="[email protected]" />
              </FormControl>
              <FormMessage />
            </FormItem>
          )}
        />

        <Button type="submit">Submit</Button>
      </form>
    </Form>
  )
}

Key Benefits with shadcn/ui

Perfect Integration: Works seamlessly with Input, Label, and Form components
Automatic Styling: Inherits shadcn's beautiful design system
Validation Support: Compatible with Zod and form validation
Accessibility: Maintains shadcn's accessibility features
TypeScript First: Full type safety with shadcn components

Note: All input types (cardNumber, phone, email, tckn, etc.) work perfectly with shadcn/ui components.

Contributors