{"_id":"@affino/focus-utils","_rev":"2-ae23bb47fa9ac4ff59c1fd5163d3fba4","name":"@affino/focus-utils","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@affino/focus-utils","version":"1.0.0","keywords":["focus","accessibility","trap","sentinel"],"author":{"name":"Anton Pavlov","email":"a.pavlov@affino.dev"},"license":"MIT","_id":"@affino/focus-utils@1.0.0","maintainers":[{"name":"affino","email":"anton.pavlov.personal@gmail.com"}],"homepage":"https://affino.dev","bugs":{"url":"https://github.com/affinio/affinio/issues"},"dist":{"shasum":"707089a442e331058aa046aa5f70a804aa344238","tarball":"https://registry.npmjs.org/@affino/focus-utils/-/focus-utils-1.0.0.tgz","fileCount":6,"integrity":"sha512-o0pAJ9/PFDxxfiwOup9WqclNZVCCN+mQD4CH3RkvoDjs3m0gb5JL6/8N8pS+OX4WDdhO9mTfuMntB9lwY1fYNA==","signatures":[{"sig":"MEUCIFDhjL1+tQgEXzk3n9n39FtdkwFHh8NH++wy0TgaJYsDAiEA1OSuXRnhsLU5hP10lLSIv0XqW+sBnvD+/MSxZ5H4ULc=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":8092},"main":"dist/index.js","type":"module","_from":"file:affino-focus-utils-1.0.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"build":"tsc -p tsconfig.json"},"_npmUser":{"name":"affino","email":"anton.pavlov.personal@gmail.com"},"_resolved":"/tmp/dc77854882b15d5e855636170601c162/affino-focus-utils-1.0.0.tgz","_integrity":"sha512-o0pAJ9/PFDxxfiwOup9WqclNZVCCN+mQD4CH3RkvoDjs3m0gb5JL6/8N8pS+OX4WDdhO9mTfuMntB9lwY1fYNA==","repository":{"url":"git+https://github.com/affinio/affinio.git#main","type":"git"},"_npmVersion":"10.8.2","description":"Cross-framework focus helpers for overlays and menus","directories":{},"sideEffects":false,"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"_npmOperationalInternal":{"tmp":"tmp/focus-utils_1.0.0_1769943257961_0.7271980650286722","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@affino/focus-utils","version":"1.1.0","author":{"name":"Anton Pavlov","email":"a.pavlov@affino.dev"},"type":"module","description":"Cross-framework focus helpers for overlays and menus","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"main":"dist/index.js","types":"dist/index.d.ts","sideEffects":false,"repository":{"type":"git","url":"git+https://github.com/affinio/affinio.git#main"},"homepage":"https://affino.dev","keywords":["focus","accessibility","trap","sentinel"],"license":"MIT","bugs":{"url":"https://github.com/affinio/affinio/issues"},"module":"dist/index.js","scripts":{"build":"tsc -p tsconfig.json"},"_id":"@affino/focus-utils@1.1.0","_integrity":"sha512-DjE9w0WLlqmtjSXbmzf2y0WNGvhQ1hTIhkiRV8DPsCmKKXREr/6sm8Yc5PrCLqzuawdYUDzyDBEPxFqhMJOOCg==","_resolved":"/tmp/5329045e69320858551da93b6ea1e032/affino-focus-utils-1.1.0.tgz","_from":"file:affino-focus-utils-1.1.0.tgz","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-DjE9w0WLlqmtjSXbmzf2y0WNGvhQ1hTIhkiRV8DPsCmKKXREr/6sm8Yc5PrCLqzuawdYUDzyDBEPxFqhMJOOCg==","shasum":"ef540118b7632b1a8634dc92f682128970331575","tarball":"https://registry.npmjs.org/@affino/focus-utils/-/focus-utils-1.1.0.tgz","fileCount":6,"unpackedSize":9231,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIDNSqv7p/TdTcLp7EvPL+MljsvvrTRr1d+pgDRjL3zShAiEAsS4nXe6CnXJZgqVCBT3FAhhgZS8t0i6LsSZv8sGqWBA="}]},"_npmUser":{"name":"affino","email":"anton.pavlov.personal@gmail.com"},"directories":{},"maintainers":[{"name":"affino","email":"anton.pavlov.personal@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/focus-utils_1.1.0_1771584272434_0.06412411718454836"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-01T10:54:17.850Z","modified":"2026-02-20T10:44:32.690Z","1.0.0":"2026-02-01T10:54:18.098Z","1.1.0":"2026-02-20T10:44:32.591Z"},"bugs":{"url":"https://github.com/affinio/affinio/issues"},"author":{"name":"Anton Pavlov","email":"a.pavlov@affino.dev"},"license":"MIT","homepage":"https://affino.dev","keywords":["focus","accessibility","trap","sentinel"],"repository":{"type":"git","url":"git+https://github.com/affinio/affinio.git#main"},"description":"Cross-framework focus helpers for overlays and menus","maintainers":[{"name":"affino","email":"anton.pavlov.personal@gmail.com"}],"readme":"# @affino/focus-utils\n\nFramework-agnostic focus helpers – the same ones we use inside Affino dialogs, menus, and tooltips.\n\n```ts\nimport {\n  FOCUSABLE_SELECTOR,\n  getFocusableElements,\n  trapFocus,\n  focusEdge,\n  hasFocusSentinels,\n} from \"@affino/focus-utils\"\n\nconst nodes = getFocusableElements(dialogEl)\n\nfunction onKeydown(event: KeyboardEvent) {\n  if (event.key === \"Tab\" && !hasFocusSentinels(dialogEl)) {\n    trapFocus(event, dialogEl)\n  }\n}\n```\n\n- `getFocusableElements()` filters tabbables that are actually visible.\n- `trapFocus()` loops focus manually when you can’t rely on sentinels.\n- `focusEdge()` jumps to the first/last focusable – wire it to invisible sentinel buttons.\n- `hasFocusSentinels()` is a convenience predicate so you can short-circuit `trapFocus`.\n\nAll helpers no-op when `window`/`document` are missing, so you can import them in SSR environments.\n","readmeFilename":"README.md"}