{"id":30368414,"url":"https://github.com/candidia/react-router-busy","last_synced_at":"2026-02-09T07:31:34.681Z","repository":{"id":257788678,"uuid":"859561833","full_name":"candidia/react-router-busy","owner":"candidia","description":"A simple and performant react-router/remix package for accessible form input, button, and link loading states.","archived":false,"fork":false,"pushed_at":"2024-10-02T22:21:20.000Z","size":2475,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-01-12T09:53:58.481Z","etag":null,"topics":["react","react-router","reactjs","remix","remix-run"],"latest_commit_sha":null,"homepage":"https://stackblitz.com/edit/remix-run-remix-obreke","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/candidia.png","metadata":{"files":{"readme":".github/README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2024-09-18T22:01:11.000Z","updated_at":"2024-10-02T22:21:22.000Z","dependencies_parsed_at":null,"dependency_job_id":"ed860890-f244-4472-8f11-f7ec23ab24e3","html_url":"https://github.com/candidia/react-router-busy","commit_stats":null,"previous_names":["bitofbreeze/react-router-busy"],"tags_count":3,"template":false,"template_full_name":null,"purl":"pkg:github/candidia/react-router-busy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/candidia%2Freact-router-busy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/candidia%2Freact-router-busy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/candidia%2Freact-router-busy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/candidia%2Freact-router-busy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/candidia","download_url":"https://codeload.github.com/candidia/react-router-busy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/candidia%2Freact-router-busy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29258740,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-09T04:11:57.159Z","status":"ssl_error","status_checked_at":"2026-02-09T04:11:56.117Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["react","react-router","reactjs","remix","remix-run"],"created_at":"2025-08-20T01:04:34.031Z","updated_at":"2026-02-09T07:31:34.541Z","avatar_url":"https://github.com/candidia.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# react-router-busy\n\n[![Build Size](https://img.shields.io/bundlephobia/minzip/react-router-busy?label=bundle%20size\u0026style=flat\u0026colorA=000000\u0026colorB=000000)](https://bundlephobia.com/package/react-router-busy)\n[![Version](https://img.shields.io/npm/v/react-router-busy?style=flat\u0026colorA=000000\u0026colorB=000000)](https://www.npmjs.com/package/react-router-busy)\n[![Downloads](https://img.shields.io/npm/dt/react-router-busy.svg?style=flat\u0026colorA=000000\u0026colorB=000000)](https://www.npmjs.com/package/react-router-busy)\n\nImprove your app's UX with just an import. A simple and performant package for accessible form input, button, and link **loading states**.\n\nFor use with [react-router](https://github.com/remix-run/react-router) 6+ or [remix](https://github.com/remix-run/remix) 2+.\n\n\u003e [!IMPORTANT]  \n\u003e [Vite currently throws an error when trying to import the CSS module](https://github.com/vitejs/vite/issues/9487) this library uses to change the cursor, so please add the following to your vite.config for now, which will be fixed in the future:\n\u003e ```\n\u003e ssr: {\n\u003e   noExternal: ['react-router-busy'],\n\u003e },\n\u003e ```\n\n## The problem\n\n![Editing input after submitting](https://github.com/user-attachments/assets/cc6f5a95-c2c8-4877-82ce-7dee317e063e)\n\n## The solution\n\nIf you'd like to see an example, check it out live on https://gitsell.dev. Also see react-router-busy/src/busy.module.css for an example of what to target to style the various busy states.\n\n### BusyForm\n\nRender `BusyForm` instead of `Form` or `fetcher.Form`:\n* All the form's inputs will become `readonly` during submission to prevent someone from changing input data during submission and causing themselves confusion. The `cursor` will be `wait` if hovering over an input.\n* The form's submit button will become `aria-busy=\"true\"` during submission to prevent double-clicking and causing extraneous requests. The `cursor` will be `wait` if hovering over the button, and `pointer-events` will be `none` to actually prevent clicking.\n\nThis library doesn't make inputs `disabled` because it causes the field to not be sent in the form data and it's not accessibility friendly to dynamically toggle.\n\n#### With navigation\n\n```tsx\nimport { BusyForm } from 'react-router-busy';\n\n...\n\nreturn (\n  \u003cBusyForm\n    action=\"/action\"\n    method=\"POST\"\n  \u003e\n    {...inputs}\n    \u003cbutton\u003eSubmit\u003c/button\u003e\n  \u003c/BusyForm\u003e\n)\n```\n\n#### With fetcher\n\n```tsx\nimport { BusyForm } from 'react-router-busy';\n\n...\n\nconst fetcher = useFetcher({ key: \"key\" });\n\nreturn (\n  \u003cBusyForm\n    action=\"/action\"\n    method=\"POST\"\n    navigate={false}\n    fetcherKey=\"key\"\n  \u003e\n    {...inputs}\n    \u003cbutton\u003eSubmit\u003c/button\u003e\n  \u003c/BusyForm\u003e\n)\n```\n\n### BusyLink\n\nThis library assumes all your buttons are in forms. But links are another story, so `BusyLink` is a replacement for `Link` to add this functionality for URLs to your app.\n\n```tsx\nimport { BusyLink } from 'react-router-busy';\n\n...\n\nreturn (\n  \u003cBusyLink\n    to=\"\"\n  \u003e\n    Link\n  \u003c/BusyLink\u003e\n)\n```\n\n## To do\n\n- Fix CSS module import error \"TypeError [ERR_UNKNOWN_FILE_EXTENSION]: Unknown file extension \".css\" for node_modules/react-router-busy/build/busy.module.css\"\n- Fix a keyboard user still being able re-press the button\n- NavLink, Better not to have all that extra code for the `as` prop\n- Also export as Form and Link in case consumers prefer not replacing name\n- Make an option where you can edit the inputs after submission which cancels the current submission\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcandidia%2Freact-router-busy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcandidia%2Freact-router-busy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcandidia%2Freact-router-busy/lists"}