{"_id":"@buiducnhat/better-modal","_rev":"6-2c66b4bcbfa005151a41e7ca64c70da1","name":"@buiducnhat/better-modal","dist-tags":{"latest":"0.0.6"},"versions":{"0.0.0":{"name":"@buiducnhat/better-modal","version":"0.0.0","_id":"@buiducnhat/better-modal@0.0.0","maintainers":[{"name":"buiducnhat","email":"nhaths4701@gmail.com"}],"dist":{"shasum":"1967a11d1592336465c92442f4ef4b9fd5789d24","tarball":"https://registry.npmjs.org/@buiducnhat/better-modal/-/better-modal-0.0.0.tgz","fileCount":2,"integrity":"sha512-rHHo/db2dCbHaRqzap779hAZyYVdEE1nJnK2V7kE7Q2Z6cV9/fhlc5nDhOCGzN+6EhV3hI8MTBtJcXnhqtu0DQ==","signatures":[{"sig":"MEQCIFkBAwsj8HcUFy/BJvZMYd6OYWgp7SEhNtP0vFN878n+AiBkRuKD06E8bmUzjcDTxEZAspKOpW/UyU5OxpQz97Qhbg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":597},"type":"module","exports":{".":"./src/index.ts","./*":"./src/*.ts"},"gitHead":"e971d78adbaa18fa52505e8c526e6ffde3e5d73f","scripts":{"build":"tsdown"},"_npmUser":{"name":"buiducnhat","email":"nhaths4701@gmail.com"},"_npmVersion":"11.9.0","directories":{},"_nodeVersion":"25.6.1","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"catalog:","@types/react":"^19","@better-modal/config":"workspace:*"},"peerDependencies":{"react":"^19","zustand":"^5","typescript":"catalog:"},"_npmOperationalInternal":{"tmp":"tmp/better-modal_0.0.0_1772088428415_0.8465271553299418","host":"s3://npm-registry-packages-npm-production"}},"0.0.1":{"name":"@buiducnhat/better-modal","version":"0.0.1","_id":"@buiducnhat/better-modal@0.0.1","maintainers":[{"name":"buiducnhat","email":"nhaths4701@gmail.com"}],"dist":{"shasum":"97138335a0ba4435e9bb8f5d9915dce887390c84","tarball":"https://registry.npmjs.org/@buiducnhat/better-modal/-/better-modal-0.0.1.tgz","fileCount":3,"integrity":"sha512-dPkWVREnZnETQoY7BZAXH4i28LUGN300v4BxNNYvXoVCryd/Jsi/lptMx6n+RSEycglPdWpU6narrAWpyTvmnQ==","signatures":[{"sig":"MEUCIEOi/G3iM7oMDihY3rFgbZGguDQ/3qHAjA1pnRJKCFyVAiEAxLMzFPsZ3cg84yBJrjf+hfIjEZL3gs6jiB53NO4xPdA=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":2351},"type":"module","exports":{".":"./src/index.ts","./*":"./src/*.ts"},"gitHead":"12f458a900e8cea0d90a58f3170ba256c32a445a","scripts":{"build":"tsdown"},"_npmUser":{"name":"buiducnhat","email":"nhaths4701@gmail.com"},"_npmVersion":"11.9.0","description":"A small, headless React utility for declarative modal state management. Register modals once, open them from anywhere in your app, and await their results as Promises.","directories":{},"_nodeVersion":"25.6.1","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"catalog:","@types/react":"^19","@better-modal/config":"workspace:*"},"peerDependencies":{"react":"^19","zustand":"^5","typescript":"catalog:"},"_npmOperationalInternal":{"tmp":"tmp/better-modal_0.0.1_1772088745446_0.8314573579741562","host":"s3://npm-registry-packages-npm-production"}},"0.0.2":{"name":"@buiducnhat/better-modal","version":"0.0.2","keywords":["modal","react","zustand"],"author":{"url":"https://github.com/buiducnhat","name":"Nhat Bui","email":"nhaths4701@gmail.com"},"_id":"@buiducnhat/better-modal@0.0.2","maintainers":[{"name":"buiducnhat","email":"nhaths4701@gmail.com"}],"homepage":"https://github.com/buiducnhat/better-modal#readme","bugs":{"url":"https://github.com/buiducnhat/better-modal/issues"},"dist":{"shasum":"6922b1aeae219ca7b3571f0494aa77ce22fe701e","tarball":"https://registry.npmjs.org/@buiducnhat/better-modal/-/better-modal-0.0.2.tgz","fileCount":3,"integrity":"sha512-d5nIrfeu2pkDcRY49AifVqYMBxCt/QR4fISBsEZA2rDvPyKSODYUtqINeI/HV/ggacCPnicPnFoS/3U2yJVdYw==","signatures":[{"sig":"MEUCIQD4X7wjA+kVSSuR2e6EIIRe8RT4YKzg8pl+bRCxbuIfqgIgYuFMnXYMvCrWxRRQ1yPC10T+Wyev4MTayLpOpAn1KLs=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":3075},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"12f458a900e8cea0d90a58f3170ba256c32a445a","scripts":{"build":"tsdown"},"_npmUser":{"name":"buiducnhat","email":"nhaths4701@gmail.com"},"repository":{"url":"git+https://github.com/buiducnhat/better-modal.git","type":"git","directory":"packages/better-auth"},"_npmVersion":"11.9.0","description":"A small, headless React utility for declarative modal state management. Register modals once, open them from anywhere in your app, and await their results as Promises.","directories":{},"_nodeVersion":"25.6.1","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"catalog:","@types/react":"^19","@better-modal/config":"workspace:*"},"peerDependencies":{"react":"^19","zustand":"^5","typescript":"catalog:"},"_npmOperationalInternal":{"tmp":"tmp/better-modal_0.0.2_1772089487815_0.2226612115410962","host":"s3://npm-registry-packages-npm-production"}},"0.0.4":{"name":"@buiducnhat/better-modal","version":"0.0.4","keywords":["modal","react","zustand"],"author":{"url":"https://github.com/buiducnhat","name":"Nhat Bui","email":"nhaths4701@gmail.com"},"_id":"@buiducnhat/better-modal@0.0.4","maintainers":[{"name":"buiducnhat","email":"nhaths4701@gmail.com"}],"homepage":"https://github.com/buiducnhat/better-modal#readme","bugs":{"url":"https://github.com/buiducnhat/better-modal/issues"},"dist":{"shasum":"428e9d7c08376a595e92545a0b9d830025e7674b","tarball":"https://registry.npmjs.org/@buiducnhat/better-modal/-/better-modal-0.0.4.tgz","fileCount":8,"integrity":"sha512-hvYjI2iS1g6vHHE8ozNKn9S8eEPCYmbDKOdBR5in+/35ASqiXABxeNYLiPjo9BNBzbsFO+WVFWwIeOp9OUhJ6w==","signatures":[{"sig":"MEQCIC6vQah/38BUbAya22YHgAmlsfJiq5N5XZKebeK52MEHAiAJLT/ABKrhxOdo1eock/lxpffeZPPPXctv8F2pg8xQ2g==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24340},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"12f458a900e8cea0d90a58f3170ba256c32a445a","scripts":{"build":"tsdown"},"_npmUser":{"name":"buiducnhat","email":"nhaths4701@gmail.com"},"repository":{"url":"git+https://github.com/buiducnhat/better-modal.git","type":"git","directory":"packages/better-modal"},"_npmVersion":"11.9.0","description":"A small, headless React utility for declarative modal state management. Register modals once, open them from anywhere in your app, and await their results as Promises.","directories":{},"_nodeVersion":"25.6.1","dependencies":{},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"catalog:","@types/react":"^19","@better-modal/config":"workspace:*"},"peerDependencies":{"react":"^19","zustand":"^5","typescript":"catalog:"},"_npmOperationalInternal":{"tmp":"tmp/better-modal_0.0.4_1772089841323_0.5911231821122116","host":"s3://npm-registry-packages-npm-production"}},"0.0.5":{"name":"@buiducnhat/better-modal","version":"0.0.5","keywords":["modal","react","zustand"],"author":{"url":"https://github.com/buiducnhat","name":"Nhat Bui","email":"nhaths4701@gmail.com"},"_id":"@buiducnhat/better-modal@0.0.5","maintainers":[{"name":"buiducnhat","email":"nhaths4701@gmail.com"}],"homepage":"https://github.com/buiducnhat/better-modal#readme","bugs":{"url":"https://github.com/buiducnhat/better-modal/issues"},"dist":{"shasum":"1f2272cc4d67af9937f0b460440f39c52f00e7f1","tarball":"https://registry.npmjs.org/@buiducnhat/better-modal/-/better-modal-0.0.5.tgz","fileCount":8,"integrity":"sha512-IlFNK2AGimyWc6fOE0tcUcEjCWk/K6l0y9z4EI+SmQCR2NGrWNbn8x48VzklHsdTZTj1wkt8ER/48IuJKJrrTA==","signatures":[{"sig":"MEQCIBmK97PRU2Ebv4+gUAPX6RBMMPmoYiVeoL3u33V/aenkAiA7iyKzkkX51wo1crrVUgR4Suur+732AeZ9J/+Y3Hodew==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":24341},"main":"./dist/index.cjs","type":"module","types":"./dist/index.d.mts","module":"./dist/index.mjs","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"gitHead":"134f42885d459433eaa3f086d91408a5b6d4dd98","scripts":{"build":"tsdown"},"_npmUser":{"name":"buiducnhat","email":"nhaths4701@gmail.com"},"repository":{"url":"git+https://github.com/buiducnhat/better-modal.git","type":"git","directory":"packages/better-modal"},"_npmVersion":"11.9.0","description":"A small, headless React utility for declarative modal state management. Register modals once, open them from anywhere in your app, and await their results as Promises.","directories":{},"_nodeVersion":"25.6.1","dependencies":{"zustand":"^5"},"_hasShrinkwrap":false,"devDependencies":{"tsdown":"catalog:","typescript":"catalog:","@better-modal/config":"workspace:*"},"peerDependencies":{"react":"^19","@types/react":"^19"},"_npmOperationalInternal":{"tmp":"tmp/better-modal_0.0.5_1772781489257_0.7623659208354339","host":"s3://npm-registry-packages-npm-production"}},"0.0.6":{"name":"@buiducnhat/better-modal","description":"A small, headless React utility for declarative modal state management. Register modals once, open them from anywhere in your app, and await their results as Promises.","version":"0.0.6","keywords":["modal","react","zustand","headless","state management","declarative","typescript"],"homepage":"https://github.com/buiducnhat/better-modal#readme","bugs":{"url":"https://github.com/buiducnhat/better-modal/issues"},"repository":{"type":"git","url":"git+https://github.com/buiducnhat/better-modal.git","directory":"packages/better-modal"},"author":{"name":"Nhat Bui","email":"nhaths4701@gmail.com","url":"https://github.com/buiducnhat"},"engines":{"node":">=18"},"sideEffects":false,"type":"module","main":"./dist/index.cjs","module":"./dist/index.mjs","types":"./dist/index.d.mts","exports":{".":{"import":{"types":"./dist/index.d.mts","default":"./dist/index.mjs"},"require":{"types":"./dist/index.d.cts","default":"./dist/index.cjs"}}},"scripts":{"build":"tsdown","prepublishOnly":"bun run build","check":"biome check --write"},"devDependencies":{"@better-modal/config":"workspace:*","tsdown":"catalog:","typescript":"catalog:"},"peerDependencies":{"react":"^19","@types/react":"^19"},"dependencies":{"zustand":"^5"},"_id":"@buiducnhat/better-modal@0.0.6","gitHead":"faa67dd28364f63b7c994a43720dda67deb97ebe","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-ssSsxSbG0KdLpcRJizGNcOYilBLIvcr4AMeexulY2XFo48Jk70cqfEaxvTAU5D+AUlX2Pm0K2jDRZBBiLbWwrw==","shasum":"95d4e8bdf410968046fe9f18609d0c3136d465e3","tarball":"https://registry.npmjs.org/@buiducnhat/better-modal/-/better-modal-0.0.6.tgz","fileCount":8,"unpackedSize":35466,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@buiducnhat%2fbetter-modal@0.0.6","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQCapf5hjib7QROwbpWyyPTzAiTekTVXfFfC9+T3RTI6UAIhAIEMF+Hb/j/pGicpNvwlzZGbNWWqg/ixILdknixiqIvM"}]},"_npmUser":{"name":"buiducnhat","email":"nhaths4701@gmail.com"},"directories":{},"maintainers":[{"name":"buiducnhat","email":"nhaths4701@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/better-modal_0.0.6_1773053894037_0.9396789117537516"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-26T06:47:08.335Z","modified":"2026-03-09T10:58:14.470Z","0.0.0":"2026-02-26T06:47:08.568Z","0.0.1":"2026-02-26T06:52:25.603Z","0.0.2":"2026-02-26T07:04:47.990Z","0.0.4":"2026-02-26T07:10:41.509Z","0.0.5":"2026-03-06T07:18:09.394Z","0.0.6":"2026-03-09T10:58:14.174Z"},"bugs":{"url":"https://github.com/buiducnhat/better-modal/issues"},"author":{"name":"Nhat Bui","email":"nhaths4701@gmail.com","url":"https://github.com/buiducnhat"},"homepage":"https://github.com/buiducnhat/better-modal#readme","keywords":["modal","react","zustand","headless","state management","declarative","typescript"],"repository":{"type":"git","url":"git+https://github.com/buiducnhat/better-modal.git","directory":"packages/better-modal"},"description":"A small, headless React utility for declarative modal state management. Register modals once, open them from anywhere in your app, and await their results as Promises.","maintainers":[{"name":"buiducnhat","email":"nhaths4701@gmail.com"}],"readme":"# better-modal\n\nA lightweight React library for declarative modal state management — open modals imperatively from anywhere in your app and await their results as Promises.\n\n**Stack:** TypeScript · React 19 · Zustand 5 · Bun · Turborepo · Biome\n\n---\n\n## Features\n\n- 🔌 **Drop-in** — place `<ModalContainer />` once in your app root, done\n- ⚡ **Imperative API** — call `Modal.show(props)` from anywhere, including outside React\n- 🤝 **Promise-based results** — `await Modal.show()` and get the user's response\n- 🎯 **Selective re-renders** — each modal subscribes only to its own Zustand slice\n- 🧩 **Headless & UI-agnostic** — works with any component library (MUI, shadcn, Radix, etc.)\n- 🔒 **Type-safe** — full TypeScript support for modal props\n\n---\n\n## Prerequisites\n\n- Node.js 18+ or Bun 1.x\n- React 19+\n- Zustand 5+\n\n---\n\n## Installation\n\n```bash\n# npm\nnpm install @buiducnhat/better-modal zustand\n\n# bun\nbun add @buiducnhat/better-modal zustand\n```\n\n---\n\n## Quick Start\n\n### 1. Add `<ModalContainer />` to your app root\n\n```tsx\nimport { ModalContainer } from \"@buiducnhat/better-modal\";\n\nfunction App() {\n  return (\n    <>\n      <YourRoutes />\n      <ModalContainer />\n    </>\n  );\n}\n```\n\n### 2. Create a modal\n\n```tsx\nimport { createModal } from \"@buiducnhat/better-modal\";\n\nconst ConfirmModal = createModal(\n  \"confirm\",\n  ({ modal, title }: { modal: any; title: string }) => (\n    <dialog open={modal.visible}>\n      <p>{title}</p>\n      <button onClick={() => modal.resolve(true)}>Confirm</button>\n      <button onClick={() => modal.resolve(false)}>Cancel</button>\n    </dialog>\n  ),\n);\n```\n\n### 3. Open it from anywhere\n\n```ts\n// Inside or outside React components\nconst confirmed = await ConfirmModal.show({ title: \"Delete this item?\" });\n\nif (confirmed) {\n  deleteItem();\n}\n```\n\n---\n\n## API Reference\n\n### `createModal(id, Component)`\n\nRegisters a modal component and returns a typed controller.\n\n```ts\nconst Modal = createModal(\"my-modal\", MyComponent);\n\nModal.show(props); // → Promise<result>\nModal.hide(); // close without resolving\n```\n\n### `useModal(id)`\n\nHook to access modal state inside a modal component.\n\n```ts\nconst modal = useModal(\"my-modal\");\n\nmodal.visible; // boolean — is the modal open?\nmodal.props; // props passed to show()\nmodal.resolve(val); // close + resolve the Promise\nmodal.reject(err); // close + reject the Promise\nmodal.hide(); // close without resolving\nmodal.remove(); // remove from store entirely\n```\n\n### `<ModalContainer />`\n\nPlace once at your app root. Renders all active modals.\n\n### `registerModal(id, Component)`\n\nLow-level alternative to `createModal` — registers a component without returning the controller.\n\n---\n\n## Documentation\n\n| Doc                                       | Description                             |\n| ----------------------------------------- | --------------------------------------- |\n| [Project PDR](./docs/project-pdr.md)      | Product requirements and roadmap        |\n| [Architecture](./docs/architecture.md)    | System design and data flow             |\n| [Codebase Map](./docs/codebase.md)        | File structure and public API reference |\n| [Code Standards](./docs/code-standard.md) | Conventions, naming, and tooling        |\n\n---\n\n## Development\n\n```bash\n# Install dependencies\nbun install\n\n# Type-check all packages\nbun run check-types\n\n# Lint and format\nbun run check\n\n# Build for publishing\nbun run build\n```\n\n---\n\n## License\n\nMIT\n","readmeFilename":"README.md"}