{"_id":"@affino/surface-core","_rev":"3-0d61df6bf2937b9d2241d2035d59fc7c","name":"@affino/surface-core","dist-tags":{"alpha":"1.0.0-alpha.1","latest":"1.1.0"},"versions":{"1.0.0-alpha.1":{"name":"@affino/surface-core","version":"1.0.0-alpha.1","keywords":["surface","tooltip","menu","popover","headless","ui-core","accessibility","positioning","state-machine"],"author":{"name":"Anton Pavlov","email":"a.pavlov@affino.dev"},"license":"MIT","_id":"@affino/surface-core@1.0.0-alpha.1","maintainers":[{"name":"affino","email":"anton.pavlov.personal@gmail.com"}],"homepage":"https://affino.dev","bugs":{"url":"https://github.com/affinio/affinio/issues"},"dist":{"shasum":"fbcb68835e39f5d817dcebda335326c2d56f2d7e","tarball":"https://registry.npmjs.org/@affino/surface-core/-/surface-core-1.0.0-alpha.1.tgz","fileCount":27,"integrity":"sha512-5XI1FU39BjeWnZaq6PR1+dUpaNEqbl74BKRCKvGkD2F6chg2iNeqChiG4QrXqRz2gZfEC/kO7lQytmIp1YLJtg==","signatures":[{"sig":"MEUCIFuWhSt3/l2OPWjVGw7siEa7Fw81CeFVBkRI7E/wzTROAiEAxCJhwUnqPWa01HcwZRnNLwsajq2f2YNIwFvSD1/1Mvo=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":26196},"main":"dist/index.js","type":"module","_from":"file:affino-surface-core-1.0.0-alpha.1.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"affino","email":"anton.pavlov.personal@gmail.com"},"_resolved":"/tmp/5e88bbac70d8b8a51942a79ef58d14a4/affino-surface-core-1.0.0-alpha.1.tgz","_integrity":"sha512-5XI1FU39BjeWnZaq6PR1+dUpaNEqbl74BKRCKvGkD2F6chg2iNeqChiG4QrXqRz2gZfEC/kO7lQytmIp1YLJtg==","repository":{"url":"git+https://github.com/affinio/affinio.git#main","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic interaction kernel for floating surfaces (menus, tooltips, popovers)","directories":{},"sideEffects":false,"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.15","@vitest/coverage-v8":"^4.0.15"},"_npmOperationalInternal":{"tmp":"tmp/surface-core_1.0.0-alpha.1_1768945107245_0.6921721210740475","host":"s3://npm-registry-packages-npm-production"}},"1.0.0":{"name":"@affino/surface-core","version":"1.0.0","keywords":["surface","tooltip","menu","popover","headless","ui-core","accessibility","positioning","state-machine"],"author":{"name":"Anton Pavlov","email":"a.pavlov@affino.dev"},"license":"MIT","_id":"@affino/surface-core@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":"e03b6fc45022b595d518942b18d5e8c7ae8b63da","tarball":"https://registry.npmjs.org/@affino/surface-core/-/surface-core-1.0.0.tgz","fileCount":30,"integrity":"sha512-K+7XzAFvcpXv262pe68kxq6fw51TgckbI2CyOLjKOthZPzXF7V0IJBZ5gTNq53vEqNh4qq4C5BrOKR0unbilPw==","signatures":[{"sig":"MEQCIBdlK6w234lsdRwl6L2M7fHOx8U8+CWHxAcXNkpWjtcNAiA0u3Wi9uK9SLsHRN44FYTAXEKgKnKWPJBi3lAYVln5zw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35474},"main":"dist/index.js","type":"module","_from":"file:affino-surface-core-1.0.0.tgz","types":"dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"scripts":{"test":"vitest run","build":"tsc -p tsconfig.json"},"_npmUser":{"name":"affino","email":"anton.pavlov.personal@gmail.com"},"_resolved":"/tmp/b6f5f1c7ace625b3ca69c10dd8a6961a/affino-surface-core-1.0.0.tgz","_integrity":"sha512-K+7XzAFvcpXv262pe68kxq6fw51TgckbI2CyOLjKOthZPzXF7V0IJBZ5gTNq53vEqNh4qq4C5BrOKR0unbilPw==","repository":{"url":"git+https://github.com/affinio/affinio.git#main","type":"git"},"_npmVersion":"10.8.2","description":"Framework-agnostic interaction kernel for floating surfaces (menus, tooltips, popovers)","directories":{},"sideEffects":false,"_nodeVersion":"20.19.6","_hasShrinkwrap":false,"devDependencies":{"vitest":"^4.0.15","@vitest/coverage-v8":"^4.0.15"},"_npmOperationalInternal":{"tmp":"tmp/surface-core_1.0.0_1769943452686_0.5477579198637503","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"name":"@affino/surface-core","version":"1.1.0","author":{"name":"Anton Pavlov","email":"a.pavlov@affino.dev"},"type":"module","description":"Framework-agnostic interaction kernel for floating surfaces (menus, tooltips, popovers)","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":["surface","tooltip","menu","popover","headless","ui-core","accessibility","positioning","state-machine"],"license":"MIT","devDependencies":{"@vitest/coverage-v8":"^4.0.15","vitest":"^4.0.15"},"bugs":{"url":"https://github.com/affinio/affinio/issues"},"module":"dist/index.js","scripts":{"build":"tsc -p tsconfig.json","test":"vitest run"},"_id":"@affino/surface-core@1.1.0","_integrity":"sha512-9BtgLjWR6brOMMb+QQc6nlX0dY5nS1IgYZL3BhTO56Dt9XJpy0/uu00AW5dHnAIqku5VlZx1hmIW3vEBd/CWCw==","_resolved":"/tmp/10a6f66574c0cc44ca76865bba79955a/affino-surface-core-1.1.0.tgz","_from":"file:affino-surface-core-1.1.0.tgz","_nodeVersion":"20.20.0","_npmVersion":"10.8.2","dist":{"integrity":"sha512-9BtgLjWR6brOMMb+QQc6nlX0dY5nS1IgYZL3BhTO56Dt9XJpy0/uu00AW5dHnAIqku5VlZx1hmIW3vEBd/CWCw==","shasum":"2542d58abb1618cf7ae09e828807a219d154e929","tarball":"https://registry.npmjs.org/@affino/surface-core/-/surface-core-1.1.0.tgz","fileCount":30,"unpackedSize":34590,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQC7m+5Y1xYvOo7nCNYTYcXbS1eXoa5zMHhCBz+3lH+3UQIhAMACWj9GZZMAvaeFhtAdluudJbHlGn2i1dGMsBnJQ19l"}]},"_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/surface-core_1.1.0_1771584558066_0.2965422003859446"},"_hasShrinkwrap":false}},"time":{"created":"2026-01-20T21:38:27.102Z","modified":"2026-02-20T10:49:18.321Z","1.0.0-alpha.1":"2026-01-20T21:38:27.385Z","1.0.0":"2026-02-01T10:57:32.830Z","1.1.0":"2026-02-20T10:49:18.221Z"},"bugs":{"url":"https://github.com/affinio/affinio/issues"},"author":{"name":"Anton Pavlov","email":"a.pavlov@affino.dev"},"license":"MIT","homepage":"https://affino.dev","keywords":["surface","tooltip","menu","popover","headless","ui-core","accessibility","positioning","state-machine"],"repository":{"type":"git","url":"git+https://github.com/affinio/affinio.git#main"},"description":"Framework-agnostic interaction kernel for floating surfaces (menus, tooltips, popovers)","maintainers":[{"name":"affino","email":"anton.pavlov.personal@gmail.com"}],"readme":"# @affino/surface-core\n\nHeadless interaction kernel for floating surfaces.\n\n`surface-core` provides deterministic state transitions, timer orchestration primitives, and positioning utilities used by menu/tooltip/popover/dialog adapters.\n\n## Installation\n\n```bash\npnpm add @affino/surface-core\n```\n\n## Core timing semantics\n\n`open`, `close`, and `toggle` are immediate state transitions.\n\n- `open()` sets `open: true` immediately.\n- `close()` sets `open: false` immediately.\n- `toggle()` flips state immediately.\n\nConfigured delays (`openDelay`, `closeDelay`) are used only when adapters explicitly schedule timers through `SurfaceTimers`-backed flows (for example pointer-leave hover behavior).\n\n## Quick start\n\n```ts\nimport { SurfaceCore } from \"@affino/surface-core\"\n\nclass TooltipCore extends SurfaceCore {\n  protected composeState(surface) {\n    return surface\n  }\n\n  getTriggerProps() {\n    return {\n      onPointerEnter: () => this.open(\"pointer\"),\n      onPointerLeave: () => this.close(\"pointer\"),\n    }\n  }\n}\n```\n\n## Reason mapping guidance\n\nUse `SurfaceReason` consistently in adapters:\n\n- `\"pointer\"`: pointer-enter/leave or outside pointer dismiss\n- `\"keyboard\"`: Escape/keyboard initiated close/open\n- `\"programmatic\"`: external imperative control\n\nAvoid mixing synthetic reason aliases; keep one reason contract through all adapter layers.\n\n## API\n\n- `open(reason?)`\n- `close(reason?)`\n- `toggle()`\n- `getSnapshot()`\n- `subscribe(listener)`\n- `cancelPendingClose()`\n- `computePosition(anchorRect, surfaceRect, options?)`\n- `destroy()`\n\n## Snapshot guarantees\n\n- `getSnapshot()` returns a runtime-frozen object.\n- Snapshot reference remains stable across no-op transitions (`open` on open, `close` on closed).\n\n## Adapter guardrails\n\n- Keep one canonical surface state source in adapter state.\n- Treat snapshots as immutable outputs.\n- If delayed behavior is needed, schedule timers in adapter/derived controller explicitly.\n- Always clear/destroy controllers on unmount to avoid leaked timers/subscribers.\n","readmeFilename":"README.md"}