{"_id":"@andersseen/behaviors","_rev":"2-d0b7dc9afb51279b5ce85920a29f3556","name":"@andersseen/behaviors","dist-tags":{"latest":"0.2.0"},"versions":{"0.1.0":{"name":"@andersseen/behaviors","version":"0.1.0","keywords":["behaviors","web-components","progressive-enhancement","attributes","directives","tooltip","dialog","splitter","drag-and-drop","typescript","accessibility"],"author":{"name":"Andersseen"},"license":"MIT","_id":"@andersseen/behaviors@0.1.0","maintainers":[{"name":"andriipap","email":"andriipap01@gmail.com"}],"homepage":"https://github.com/Andersseen/and-web-components#readme","bugs":{"url":"https://github.com/Andersseen/and-web-components/issues"},"dist":{"shasum":"8fb973ce875be121d0670e3e3f79f0f214880f8d","tarball":"https://registry.npmjs.org/@andersseen/behaviors/-/behaviors-0.1.0.tgz","fileCount":159,"integrity":"sha512-PtIJELyvGk/7Zp5zvZvMd6YXrBNRNMBdikOZ8PiKlid6LdzH6QJmXPufCodxLqM9IhaCuz0SjnxYCwrYEa50qw==","signatures":[{"sig":"MEQCIALA0AjElZ1AlvJdcS+S1pHMMbC0SfTCiTCaMsYAR4MdAiAQMn275TqGS+p69y6qCZoWiZHxTL+pTZGQ5jMAucEggw==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":193859},"main":"./dist/index.js","type":"module","_from":"file:andersseen-behaviors-0.1.0.tgz","types":"./dist/index.d.ts","module":"./dist/index.js","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist-cjs/index.js"},"./dialog":{"types":"./dist/dialog/index.d.ts","import":"./dist/dialog/index.js"},"./tooltip":{"types":"./dist/tooltip/index.d.ts","import":"./dist/tooltip/index.js"},"./splitter":{"types":"./dist/splitter/index.d.ts","import":"./dist/splitter/index.js"},"./drag-drop":{"types":"./dist/drag-drop/index.d.ts","import":"./dist/drag-drop/index.js"}},"scripts":{"dev":"tsc --watch","lint":"eslint src --ext .ts,.tsx","test":"vitest run","build":"rm -rf dist dist-cjs && tsc && node ../../scripts/fix-esm-extensions.cjs dist && tsc -p tsconfig.cjs.json","format":"prettier --write \"src/**/*.{ts,tsx}\"","lint:fix":"eslint src --ext .ts,.tsx --fix","test:watch":"vitest","format:check":"prettier --check \"src/**/*.{ts,tsx}\"","test:coverage":"vitest run --coverage"},"_npmUser":{"name":"andriipap","email":"andriipap01@gmail.com"},"_resolved":"/private/var/folders/wq/4bgf9dy51d5776cl3qgg362h0000gn/T/2bb66b9af184f38a515c069d0c938d5f/andersseen-behaviors-0.1.0.tgz","_integrity":"sha512-PtIJELyvGk/7Zp5zvZvMd6YXrBNRNMBdikOZ8PiKlid6LdzH6QJmXPufCodxLqM9IhaCuz0SjnxYCwrYEa50qw==","repository":{"url":"git+https://github.com/Andersseen/and-web-components.git","type":"git","directory":"packages/behaviors"},"_npmVersion":"10.9.8","description":"Framework-agnostic DOM behaviors driven by `and-*` attributes (splitter, drag & drop, tooltip, dialog). Progressive enhancement, no framework required.","directories":{},"_nodeVersion":"22.23.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"eslint":"^10.1.0","vitest":"^4.1.0","@eslint/js":"^10.0.1","typescript":"^5.9.3","@types/node":"^22.13.5","typescript-eslint":"^8.57.1","@vitest/coverage-v8":"^4.0.18"},"_npmOperationalInternal":{"tmp":"tmp/behaviors_0.1.0_1783712393744_0.6034101052505614","host":"s3://npm-registry-packages-npm-production"}},"0.2.0":{"name":"@andersseen/behaviors","version":"0.2.0","sideEffects":false,"description":"Framework-agnostic DOM behaviors driven by `and-*` attributes (splitter, drag & drop, tooltip, dialog). Progressive enhancement, no framework required.","type":"module","main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js","require":"./dist-cjs/index.js"},"./splitter":{"types":"./dist/splitter/index.d.ts","import":"./dist/splitter/index.js"},"./drag-drop":{"types":"./dist/drag-drop/index.d.ts","import":"./dist/drag-drop/index.js"},"./tooltip":{"types":"./dist/tooltip/index.d.ts","import":"./dist/tooltip/index.js"},"./dialog":{"types":"./dist/dialog/index.d.ts","import":"./dist/dialog/index.js"},"./overlay":{"types":"./dist/overlay/index.d.ts","import":"./dist/overlay/index.js"}},"keywords":["behaviors","web-components","progressive-enhancement","attributes","directives","tooltip","dialog","splitter","drag-and-drop","typescript","accessibility"],"author":{"name":"Andersseen"},"license":"MIT","devDependencies":{"@eslint/js":"^10.0.1","@types/node":"^22.13.5","@vitest/coverage-v8":"4.1.0","eslint":"^10.1.0","typescript":"^5.9.3","typescript-eslint":"^8.57.1","vitest":"^4.1.0"},"publishConfig":{"access":"public"},"repository":{"type":"git","url":"git+https://github.com/Andersseen/and-web-components.git","directory":"packages/behaviors"},"scripts":{"build":"rm -rf dist dist-cjs && tsc && node ../../scripts/fix-esm-extensions.cjs dist && tsc -p tsconfig.cjs.json","dev":"tsc --watch","test":"vitest run","test:watch":"vitest","test:coverage":"vitest run --coverage","lint":"eslint src --ext .ts,.tsx","lint:fix":"eslint src --ext .ts,.tsx --fix","format":"prettier --write \"src/**/*.{ts,tsx}\"","format:check":"prettier --check \"src/**/*.{ts,tsx}\""},"_id":"@andersseen/behaviors@0.2.0","bugs":{"url":"https://github.com/Andersseen/and-web-components/issues"},"homepage":"https://github.com/Andersseen/and-web-components#readme","_integrity":"sha512-XRcYu9vJteQQhdoXIfkyasPB2Zx4Ddx/hUzTrHHqnv7Bc6hWiCl/PaAGejoaLmLVRLarqL3OBk2+aSYNWRPqBA==","_resolved":"/tmp/209117c593d7338c65933151021ec290/andersseen-behaviors-0.2.0.tgz","_from":"file:andersseen-behaviors-0.2.0.tgz","_nodeVersion":"22.23.1","_npmVersion":"10.9.8","dist":{"integrity":"sha512-XRcYu9vJteQQhdoXIfkyasPB2Zx4Ddx/hUzTrHHqnv7Bc6hWiCl/PaAGejoaLmLVRLarqL3OBk2+aSYNWRPqBA==","shasum":"9fa53455763ca49112254d39bfc36be261884a63","tarball":"https://registry.npmjs.org/@andersseen/behaviors/-/behaviors-0.2.0.tgz","fileCount":165,"unpackedSize":203615,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIGRAoSlU0pnbA85++lZRi7SM2s9ykZFnpd28YNPn4q/tAiAdp1X0ZMhzNn/xS9VPl/aIHv8Q2VbTWreMyaEL169ZxQ=="}]},"_npmUser":{"name":"andriipap","email":"andriipap01@gmail.com"},"directories":{},"maintainers":[{"name":"andriipap","email":"andriipap01@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/behaviors_0.2.0_1784814154819_0.6702522434514948"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-10T19:39:53.568Z","modified":"2026-07-23T13:42:35.093Z","0.1.0":"2026-07-10T19:39:53.898Z","0.2.0":"2026-07-23T13:42:34.945Z"},"bugs":{"url":"https://github.com/Andersseen/and-web-components/issues"},"author":{"name":"Andersseen"},"license":"MIT","homepage":"https://github.com/Andersseen/and-web-components#readme","keywords":["behaviors","web-components","progressive-enhancement","attributes","directives","tooltip","dialog","splitter","drag-and-drop","typescript","accessibility"],"repository":{"type":"git","url":"git+https://github.com/Andersseen/and-web-components.git","directory":"packages/behaviors"},"description":"Framework-agnostic DOM behaviors driven by `and-*` attributes (splitter, drag & drop, tooltip, dialog). Progressive enhancement, no framework required.","maintainers":[{"name":"andriipap","email":"andriipap01@gmail.com"}],"readme":"# @andersseen/behaviors\n\nFramework-agnostic **DOM behaviors** driven by `and-*` attributes. Progressive\nenhancement for the browser — no framework runtime required. Attach interaction\npatterns (splitter, drag & drop, tooltip, dialog) to existing HTML using either\ndeclarative attributes or low-level imperative APIs.\n\n> Sibling packages: [`@andersseen/headless-components`](../headless-core) are\n> pure state machines with **no** DOM; `@andersseen/behaviors` is the layer that\n> wires interaction directly onto elements already in the page.\n\n## Installation\n\n```bash\npnpm add @andersseen/behaviors\n```\n\n## Usage\n\n### Declarative attributes\n\nCall `defineBehaviors()` once after your DOM is ready. It scans for `[and-*]`\nattributes and wires up the corresponding behaviors.\n\n```html\n<!doctype html>\n<html>\n  <body>\n    <div and-splitter=\"horizontal\" and-splitter-default-position=\"30\">\n      <div and-splitter-panel=\"primary\">Left</div>\n      <div and-splitter-handle></div>\n      <div and-splitter-panel=\"secondary\">Right</div>\n    </div>\n\n    <button and-tooltip=\"Save changes\" and-tooltip-placement=\"top\">Save</button>\n\n    <button and-dialog-trigger=\"my-dialog\">Open dialog</button>\n    <div id=\"my-dialog\" and-dialog-position=\"center\">\n      <h2>Hello</h2>\n      <button and-dialog-close>Close</button>\n    </div>\n\n    <script type=\"module\">\n      import { defineBehaviors } from '@andersseen/behaviors';\n      const cleanup = defineBehaviors({ observe: true });\n      // cleanup() destroys every behavior and stops observing.\n    </script>\n  </body>\n</html>\n```\n\n`defineBehaviors({ observe: true })` uses a `MutationObserver` so elements added\nafter the initial scan are wired up automatically.\n\n### Imperative APIs\n\nFor advanced use cases you can create and destroy behaviors manually. Import the\nwhole surface or a per-behavior subpath for tighter tree-shaking:\n\n```ts\nimport { createSplitter } from '@andersseen/behaviors';\nimport { createTooltip } from '@andersseen/behaviors/tooltip';\n\nconst splitter = createSplitter(document.getElementById('splitter')!, {\n  orientation: 'vertical',\n});\n// ...later\nsplitter.destroy();\n```\n\n## Behaviors\n\n| Attribute            | Behavior                          | Imperative API                         | Subpath                           |\n| -------------------- | --------------------------------- | -------------------------------------- | --------------------------------- |\n| `and-splitter`       | Resizable panel container         | `createSplitter(container, options)`   | `@andersseen/behaviors/splitter`  |\n| `and-draggable`      | HTML5 drag source                 | `createDraggable(element, config)`     | `@andersseen/behaviors/drag-drop` |\n| `and-drop-zone`      | Drop target with optional sorting | `createDropZone(element, config)`      | `@andersseen/behaviors/drag-drop` |\n| `and-tooltip`        | Hover/focus tooltip               | `createTooltip(element, options)`      | `@andersseen/behaviors/tooltip`   |\n| `and-dialog-trigger` | Modal/drawer trigger              | `createDialog(targetElement, options)` | `@andersseen/behaviors/dialog`    |\n\n### Attribute reference\n\n**Splitter** — on the container: `and-splitter=\"horizontal|vertical\"`,\n`and-splitter-min`, `and-splitter-max`, `and-splitter-step`,\n`and-splitter-default-position`. Children need `and-splitter-panel=\"primary\"`,\n`and-splitter-handle`, `and-splitter-panel=\"secondary\"`. Emits\n`and-splitter-change`, `and-splitter-dragstart`, `and-splitter-dragend`.\n\n**Drag & drop** — `and-draggable` (+ `and-draggable-data`,\n`and-draggable-handle`, `and-draggable-disabled`, `and-draggable-type`),\n`and-drop-zone` (+ `and-drop-zone-accept`, `and-drop-zone-sortable`,\n`and-drop-zone-disabled`). Emits `and-dragstart`, `and-dragend`,\n`and-dragenter`, `and-dragover`, `and-dragleave`, `and-drop`. Sortable zones\nauto-reorder on drop.\n\n**Tooltip** — `and-tooltip=\"text\"` (+ `and-tooltip-placement`,\n`and-tooltip-delay` / `and-tooltip-show-delay`, `and-tooltip-hide-delay`,\n`and-tooltip-offset`, `and-tooltip-disabled`, `and-tooltip-interactive`).\nDismissable with `Escape` (WCAG 1.4.13).\n\n**Dialog** — trigger with `and-dialog-trigger=\"target-id\"`; the target and/or\ntrigger accept `and-dialog-position`, `and-dialog-backdrop`,\n`and-dialog-close-on-backdrop`, `and-dialog-close-on-escape`,\n`and-dialog-width`, `and-dialog-height`, `and-dialog-panel-class`,\n`and-dialog-backdrop-class`. Any `[and-dialog-close]` inside closes it. Focus is\ntrapped (disabled/hidden controls skipped) and restored on close.\n\n## Accessibility\n\n- **Splitter** handle gets `role=\"separator\"`, `aria-orientation`,\n  `aria-valuemin/max/now`, keyboard resize (arrows / `Home` / `End`), and a\n  default `aria-label` when the author supplies none.\n- **Tooltip** wires `aria-describedby` and can be dismissed with `Escape`\n  without moving the pointer.\n- **Dialog** sets `role=\"dialog\"`, `aria-modal`, traps focus (skipping\n  `[disabled]` / `[aria-hidden=\"true\"]`), locks body scroll, and restores focus\n  to the trigger on close.\n\n## Browser support\n\nAll behaviors touch the DOM and are browser-only. Call `defineBehaviors()` only\nafter `document.body` is available (e.g. inside a `DOMContentLoaded` handler or\nat the end of `<body>`).\n\n## Development\n\n```bash\npnpm -C packages/behaviors test        # Vitest (jsdom)\npnpm -C packages/behaviors lint\npnpm -C packages/behaviors build       # ESM + CJS\n```\n\n## License\n\nMIT\n","readmeFilename":"README.md"}