Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/satnaing/pin-input

A modular, style-agnostic PinInput component for React
https://github.com/satnaing/pin-input

component otp-input pin-input react shadcn-ui

Last synced: 2 months ago
JSON representation

A modular, style-agnostic PinInput component for React

Awesome Lists containing this project

README

        

# Pin Input (React)

A modular, style-agnostic PinInput component for React, ready to use with just a copy-paste—no extra libraries needed.

![Pin Input by Sat Naing](public/pin-input-social-card.png)

## Features

- No additional library required.
- Supports both controlled and uncontrolled components.
- Compatible with form libraries.
- Simple & Accessible\_ support copy-paste, mask, auto-focus, onComplete, onIncomplete etc

## Get Started

1. Copy & paste [pin-input.tsx](src/components/ui/pin-input.tsx) into your project.
2. Use the component as needed, refering to the usage section for guidance.
3. That's it—enjoy the simplicity!

## Note

> You don’t need to install a component or CSS library. However, feel free to use one to enhance and customize the component to your needs.

## Usage

### Controlled PinInput

```tsx
function ControlledPinInput() {
const [pinInput, setPinInput] = useState("");

return (
console.log("completed", str)}
>
{Array.from({ length: 4 }, (_, i) => (

))}

);
}
```

### Uncontrolled PinInput

```tsx
function ControlledPinInput() {
return (
console.log("completed", str)}
autoFocus
>






);
}
```

### React-hook-form with Zod

```tsx
import { z } from "zod";
import { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { cn } from "@/lib/utils";
import {
Form,
FormControl,
FormField,
FormItem,
FormMessage,
} from "@/components/ui/form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { PinInput, PinInputField } from "@/components/ui/pin-input";

const formSchema = z.object({
otp: z.string().min(1, { message: "Please enter your otp code." }),
});

export default function MyComponent() {
const [isLoading, setIsLoading] = useState(false);
const [disabledBtn, setDisabledBtn] = useState(true);

const form = useForm>({
resolver: zodResolver(formSchema),
defaultValues: { otp: "" },
});

function onSubmit(data: z.infer) {
setIsLoading(true);
console.log({ data });

setTimeout(() => {
form.reset();
setIsLoading(false);
}, 2000);
}

return (



(


setDisabledBtn(false)}
onIncomplete={() => setDisabledBtn(true)}
placeholder="◯"
>
{Array.from({ length: 7 }, (_, i) => {
if (i === 3)
return ;
return (

);
})}




)}
/>

Verify




);
}
```

## Examples

- [PinInput (ShadcnUI + React Hook Form)](https://stackblitz.com/edit/pin-input-shadcn-react-hook-form?file=src%2FApp.tsx)
- [PinInput Raw (Controlled)](https://stackblitz.com/edit/pin-input-raw?file=src%2FApp.tsx)
- [PinInput Raw (Uncontrolled)](https://stackblitz.com/edit/pin-input-raw-uncontolled?file=src%2FApp.tsx)

## Author

Crafted with 🤍 by [Sat Naing](https://satnaing.dev). The design of the website is inspired by [https://time.openstatus.dev](https://time.openstatus.dev)

## License

Licensed under the [MIT License](https://choosealicense.com/licenses/mit/)