{"id":13479165,"url":"https://github.com/soywod/react-pin-field","last_synced_at":"2025-04-15T00:40:02.818Z","repository":{"id":39674952,"uuid":"227931658","full_name":"soywod/react-pin-field","owner":"soywod","description":"📟 React component for entering PIN codes.","archived":false,"fork":false,"pushed_at":"2025-04-04T15:33:08.000Z","size":4997,"stargazers_count":414,"open_issues_count":3,"forks_count":24,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-04-15T00:39:40.230Z","etag":null,"topics":["code","component","field","input","pin","react","typescript"],"latest_commit_sha":null,"homepage":"https://soywod.github.io/react-pin-field/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/soywod.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"soywod","ko_fi":"soywod","buy_me_a_coffee":"soywod","liberapay":"soywod","thanks_dev":"soywod","custom":"https://www.paypal.com/paypalme/soywod"}},"created_at":"2019-12-13T22:22:26.000Z","updated_at":"2025-03-17T03:59:55.000Z","dependencies_parsed_at":"2024-01-16T06:21:17.322Z","dependency_job_id":"363e14e1-8183-48c5-8ee0-bd0475d95f63","html_url":"https://github.com/soywod/react-pin-field","commit_stats":{"total_commits":147,"total_committers":11,"mean_commits":"13.363636363636363","dds":0.5850340136054422,"last_synced_commit":"f3679d9b13237f51a6805fe226052f6d57f5674a"},"previous_names":[],"tags_count":38,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soywod%2Freact-pin-field","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soywod%2Freact-pin-field/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soywod%2Freact-pin-field/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soywod%2Freact-pin-field/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/soywod","download_url":"https://codeload.github.com/soywod/react-pin-field/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248986270,"owners_count":21194024,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["code","component","field","input","pin","react","typescript"],"created_at":"2024-07-31T16:02:10.700Z","updated_at":"2025-04-15T00:40:02.802Z","avatar_url":"https://github.com/soywod.png","language":"TypeScript","funding_links":["https://github.com/sponsors/soywod","https://ko-fi.com/soywod","https://buymeacoffee.com/soywod","https://liberapay.com/soywod","https://thanks.dev/soywod","https://www.paypal.com/paypalme/soywod","https://www.buymeacoffee.com/soywod","https://img.shields.io/badge/-thanks.dev-000000?logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQuMDk3IiBoZWlnaHQ9IjE3LjU5NyIgY2xhc3M9InctMzYgbWwtMiBsZzpteC0wIHByaW50Om14LTAgcHJpbnQ6aW52ZXJ0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik05Ljc4MyAxNy41OTdINy4zOThjLTEuMTY4IDAtMi4wOTItLjI5Ny0yLjc3My0uODktLjY4LS41OTMtMS4wMi0xLjQ2Mi0xLjAyLTIuNjA2di0xLjM0NmMwLTEuMDE4LS4yMjctMS43NS0uNjc4LTIuMTk1LS40NTItLjQ0Ni0xLjIzMi0uNjY5LTIuMzQtLjY2OUgwVjcuNzA1aC41ODdjMS4xMDggMCAxLjg4OC0uMjIyIDIuMzQtLjY2OC40NTEtLjQ0Ni42NzctMS4xNzcuNjc3LTIuMTk1VjMuNDk2YzAtMS4xNDQuMzQtMi4wMTMgMS4wMjEtMi42MDZDNS4zMDUuMjk3IDYuMjMgMCA3LjM5OCAwaDIuMzg1djEuOTg3aC0uOTg1Yy0uMzYxIDAtLjY4OC4wMjctLjk4LjA4MmExLjcxOSAxLjcxOSAwIDAgMC0uNzM2LjMwN2MtLjIwNS4xNTYtLjM1OC4zODQtLjQ2LjY4Mi0uMTAzLjI5OC0uMTU0LjY4Mi0uMTU0IDEuMTUxVjUuMjNjMCAuODY3LS4yNDkgMS41ODYtLjc0NSAyLjE1NS0uNDk3LjU2OS0xLjE1OCAxLjAwNC0xLjk4MyAxLjMwNXYuMjE3Yy44MjUuMyAxLjQ4Ni43MzYgMS45ODMgMS4zMDUuNDk2LjU3Ljc0NSAxLjI4Ny43NDUgMi4xNTR2MS4wMjFjMCAuNDcuMDUxLjg1NC4xNTMgMS4xNTIuMTAzLjI5OC4yNTYuNTI1LjQ2MS42ODIuMTkzLjE1Ny40MzcuMjYuNzMyLjMxMi4yOTUuMDUuNjIzLjA3Ni45ODQuMDc2aC45ODVabTE0LjMxNC03LjcwNmgtLjU4OGMtMS4xMDggMC0xLjg4OC4yMjMtMi4zNC42NjktLjQ1LjQ0NS0uNjc3IDEuMTc3LS42NzcgMi4xOTVWMTQuMWMwIDEuMTQ0LS4zNCAyLjAxMy0xLjAyIDIuNjA2LS42OC41OTMtMS42MDUuODktMi43NzQuODloLTIuMzg0di0xLjk4OGguOTg0Yy4zNjIgMCAuNjg4LS4wMjcuOTgtLjA4LjI5Mi0uMDU1LjUzOC0uMTU3LjczNy0uMzA4LjIwNC0uMTU3LjM1OC0uMzg0LjQ2LS42ODIuMTAzLS4yOTguMTU0LS42ODIuMTU0LTEuMTUydi0xLjAyYzAtLjg2OC4yNDgtMS41ODYuNzQ1LTIuMTU1LjQ5Ny0uNTcgMS4xNTgtMS4wMDQgMS45ODMtMS4zMDV2LS4yMTdjLS44MjUtLjMwMS0xLjQ4Ni0uNzM2LTEuOTgzLTEuMzA1LS40OTctLjU3LS43NDUtMS4yODgtLjc0NS0yLjE1NXYtMS4wMmMwLS40Ny0uMDUxLS44NTQtLjE1NC0xLjE1Mi0uMTAyLS4yOTgtLjI1Ni0uNTI2LS40Ni0uNjgyYTEuNzE5IDEuNzE5IDAgMCAwLS43MzctLjMwNyA1LjM5NSA1LjM5NSAwIDAgMC0uOTgtLjA4MmgtLjk4NFYwaDIuMzg0YzEuMTY5IDAgMi4wOTMuMjk3IDIuNzc0Ljg5LjY4LjU5MyAxLjAyIDEuNDYyIDEuMDIgMi42MDZ2MS4zNDZjMCAxLjAxOC4yMjYgMS43NS42NzggMi4xOTUuNDUxLjQ0NiAxLjIzMS42NjggMi4zNC42NjhoLjU4N3oiIGZpbGw9IiNmZmYiLz48L3N2Zz4="],"categories":["TypeScript","🌐 Web Development - Frontend"],"sub_categories":[],"readme":"# 📟 React PIN Field [![tests](https://img.shields.io/github/actions/workflow/status/soywod/react-pin-field/tests.yml?branch=master\u0026label=tests\u0026logo=github\u0026logoColor=ffffff)](https://github.com/soywod/react-pin-field/actions/workflows/tests.yml) [![codecov](https://img.shields.io/codecov/c/github/soywod/react-pin-field?logo=codecov\u0026logoColor=ffffff)](https://app.codecov.io/gh/soywod/react-pin-field) [![npm](https://img.shields.io/npm/v/react-pin-field?logo=npm\u0026label=npm\u0026logoColor=ffffff\u0026color=success)](https://www.npmjs.com/package/react-pin-field)\n\nReact component for entering PIN codes\n\n![demo](demo.gif)\n\n*Live demo available at \u003chttps://soywod.github.io/react-pin-field/\u003e.*\n\n## Features\n\n- Written in TypeScript, tested with Jest and Cypress\n- Relies on `onchange` native event with minimum interaction for better browser compatibility\n- Supports HTML [`dir`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/dir) left-to-right and right-to-left\n- Supports HTML [`autofocus`](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus) by focusing either the first or the last input, depending on `dir`\n- Supports [ARIA](https://developer.mozilla.org/en-US/docs/Web/Accessibility/ARIA) attributes like `aria-required`, `aria-label`…\n- Supports [key composition](https://developer.mozilla.org/en-US/docs/Web/API/Element/compositionstart_event)\n\n## Installation\n\n```\nnpm install react-pin-field\n```\n\n## Usage\n\n```typescript\nimport PinField from \"react-pin-field\";\n```\n\n### Props\n\n```typescript\n// React PIN Field inherits native props from HTMLInputElement,\n// except few event handlers that are overriden:\ntype NativeProps = Omit\u003c\n  InputHTMLAttributes\u003cHTMLInputElement\u003e,\n  \"onChange\" | \"onKeyDown\" | \"onCompositionStart\" | \"onCompositionEnd\"\n\u003e;\n\ntype Props = NativeProps \u0026 {\n  length?: number;\n  format?: (char: string) =\u003e string;\n  formatAriaLabel?: (index: number, total: number) =\u003e string;\n  onChange?: (value: string) =\u003e void;\n  onComplete?: (value: string) =\u003e void;  \n};\n```\n\n#### `length`\n\nThe length of the PIN field, which represents the number of inputs.\n\n*Defaults to `5`*\n\n#### `format`\n\nCharacters can be formatted with any function of type `(char: string) =\u003e string`.\n\n*Defaults to identity function `char =\u003e char`*\n\n#### `formatAriaLabel`\n\nThis function is used to generate accessible labels for each input within the `\u003cPinField /\u003e`. By default it renders the string `PIN field 1 of 6`, `PIN field 2 of 6`, etc., depending on the actual index of the input field and the total length of the pin field.\n\nYou can customize the `aria-label` string by passing your own function. This can be useful for: i) site internationalisation (i18n); ii) simply describing each input with different semantics than the ones provided by `react-pin-field`.\n\n*Defaults to `(n, total) =\u003e \"PIN field ${n} of ${total}\"`*\n\n#### `onChange`\n\nThis function is called everytime the PIN field changes its value.\n\n#### `onComplete`\n\nThis function is called everytime the PIN field is completed. A PIN field is considered complete when:\n\n- Every input has a defined value\n- Every input passed the standard HTML validation (`required`, `pattern` etc)\n\n#### Reference\n\nReact PIN Field exposes a special reference which is an array of `HTMLInputElement`:\n\n```tsx\nconst ref = useRef\u003cHTMLInputElement[]\u003e();\n\n\u003cPinField ref={ref} /\u003e;\n\n// focus the third input\nref.current[2].focus();\n```\n\n#### Style\n\nReact PIN Field can be styled either with `style` or `className`. This last one allows you to use pseudo-classes like `:nth-of-type`, `:focus`, `:hover`, `:valid`, `:invalid`…\n\n### Hook\n\nBy default, React PIN Field is an [uncontrolled](https://react.dev/learn/sharing-state-between-components#controlled-and-uncontrolled-components) component, which means that its internal state cannot be changed. You can only listen to changes via `onChange` and `onComplete`.\n\nTo control the React PIN Field state, you can use the `usePinField()` custom hook:\n\n```tsx\nconst handler = usePinField();\n\n// The handler exposes a value and setValue to control the PIN code,\n// as well as a state and dispatch for advanced usage.\n\n// Let know the PIN field that you want to use this custom state\n// instead of its internal one.\nreturn \u003cPinField handler={handler} /\u003e\n```\n\n*See the controlled section of the [live demo](https://soywod.github.io/react-pin-field/?path=/story/pinfield--controlled).*\n\n## Contributing\n\n*See the [Contributing guide](./CONTRIBUTING.md).*\n\n## Sponsoring\n\nIf you appreciate the project, feel free to donate using one of the following providers:\n\n[![GitHub](https://img.shields.io/badge/-GitHub%20Sponsors-fafbfc?logo=GitHub%20Sponsors)](https://github.com/sponsors/soywod)\n[![Ko-fi](https://img.shields.io/badge/-Ko--fi-ff5e5a?logo=Ko-fi\u0026logoColor=ffffff)](https://ko-fi.com/soywod)\n[![Buy Me a Coffee](https://img.shields.io/badge/-Buy%20Me%20a%20Coffee-ffdd00?logo=Buy%20Me%20A%20Coffee\u0026logoColor=000000)](https://www.buymeacoffee.com/soywod)\n[![Liberapay](https://img.shields.io/badge/-Liberapay-f6c915?logo=Liberapay\u0026logoColor=222222)](https://liberapay.com/soywod)\n[![thanks.dev](https://img.shields.io/badge/-thanks.dev-000000?logo=data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQuMDk3IiBoZWlnaHQ9IjE3LjU5NyIgY2xhc3M9InctMzYgbWwtMiBsZzpteC0wIHByaW50Om14LTAgcHJpbnQ6aW52ZXJ0IiB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciPjxwYXRoIGQ9Ik05Ljc4MyAxNy41OTdINy4zOThjLTEuMTY4IDAtMi4wOTItLjI5Ny0yLjc3My0uODktLjY4LS41OTMtMS4wMi0xLjQ2Mi0xLjAyLTIuNjA2di0xLjM0NmMwLTEuMDE4LS4yMjctMS43NS0uNjc4LTIuMTk1LS40NTItLjQ0Ni0xLjIzMi0uNjY5LTIuMzQtLjY2OUgwVjcuNzA1aC41ODdjMS4xMDggMCAxLjg4OC0uMjIyIDIuMzQtLjY2OC40NTEtLjQ0Ni42NzctMS4xNzcuNjc3LTIuMTk1VjMuNDk2YzAtMS4xNDQuMzQtMi4wMTMgMS4wMjEtMi42MDZDNS4zMDUuMjk3IDYuMjMgMCA3LjM5OCAwaDIuMzg1djEuOTg3aC0uOTg1Yy0uMzYxIDAtLjY4OC4wMjctLjk4LjA4MmExLjcxOSAxLjcxOSAwIDAgMC0uNzM2LjMwN2MtLjIwNS4xNTYtLjM1OC4zODQtLjQ2LjY4Mi0uMTAzLjI5OC0uMTU0LjY4Mi0uMTU0IDEuMTUxVjUuMjNjMCAuODY3LS4yNDkgMS41ODYtLjc0NSAyLjE1NS0uNDk3LjU2OS0xLjE1OCAxLjAwNC0xLjk4MyAxLjMwNXYuMjE3Yy44MjUuMyAxLjQ4Ni43MzYgMS45ODMgMS4zMDUuNDk2LjU3Ljc0NSAxLjI4Ny43NDUgMi4xNTR2MS4wMjFjMCAuNDcuMDUxLjg1NC4xNTMgMS4xNTIuMTAzLjI5OC4yNTYuNTI1LjQ2MS42ODIuMTkzLjE1Ny40MzcuMjYuNzMyLjMxMi4yOTUuMDUuNjIzLjA3Ni45ODQuMDc2aC45ODVabTE0LjMxNC03LjcwNmgtLjU4OGMtMS4xMDggMC0xLjg4OC4yMjMtMi4zNC42NjktLjQ1LjQ0NS0uNjc3IDEuMTc3LS42NzcgMi4xOTVWMTQuMWMwIDEuMTQ0LS4zNCAyLjAxMy0xLjAyIDIuNjA2LS42OC41OTMtMS42MDUuODktMi43NzQuODloLTIuMzg0di0xLjk4OGguOTg0Yy4zNjIgMCAuNjg4LS4wMjcuOTgtLjA4LjI5Mi0uMDU1LjUzOC0uMTU3LjczNy0uMzA4LjIwNC0uMTU3LjM1OC0uMzg0LjQ2LS42ODIuMTAzLS4yOTguMTU0LS42ODIuMTU0LTEuMTUydi0xLjAyYzAtLjg2OC4yNDgtMS41ODYuNzQ1LTIuMTU1LjQ5Ny0uNTcgMS4xNTgtMS4wMDQgMS45ODMtMS4zMDV2LS4yMTdjLS44MjUtLjMwMS0xLjQ4Ni0uNzM2LTEuOTgzLTEuMzA1LS40OTctLjU3LS43NDUtMS4yODgtLjc0NS0yLjE1NXYtMS4wMmMwLS40Ny0uMDUxLS44NTQtLjE1NC0xLjE1Mi0uMTAyLS4yOTgtLjI1Ni0uNTI2LS40Ni0uNjgyYTEuNzE5IDEuNzE5IDAgMCAwLS43MzctLjMwNyA1LjM5NSA1LjM5NSAwIDAgMC0uOTgtLjA4MmgtLjk4NFYwaDIuMzg0YzEuMTY5IDAgMi4wOTMuMjk3IDIuNzc0Ljg5LjY4LjU5MyAxLjAyIDEuNDYyIDEuMDIgMi42MDZ2MS4zNDZjMCAxLjAxOC4yMjYgMS43NS42NzggMi4xOTUuNDUxLjQ0NiAxLjIzMS42NjggMi4zNC42NjhoLjU4N3oiIGZpbGw9IiNmZmYiLz48L3N2Zz4=)](https://thanks.dev/soywod)\n[![PayPal](https://img.shields.io/badge/-PayPal-0079c1?logo=PayPal\u0026logoColor=ffffff)](https://www.paypal.com/paypalme/soywod)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoywod%2Freact-pin-field","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoywod%2Freact-pin-field","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoywod%2Freact-pin-field/lists"}