{"_id":"@campino/frontend-interactions","_rev":"2-7440ba1c0f21924434661071ae7bcd12","name":"@campino/frontend-interactions","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@campino/frontend-interactions","version":"1.0.0","keywords":["accessibility","dnd","drag-and-drop","focus-management","frontend","gesture","grid","interactions","keyboard-navigation","overlay","selection","sortable","swipe","typescript"],"author":{"name":"Henric Söderlind","email":"henric.soderlind@outlook.com"},"license":"MIT","_id":"@campino/frontend-interactions@1.0.0","maintainers":[{"name":"campino","email":"henric.soderlind@outlook.com"}],"homepage":"https://github.com/hynek-systems/campino-frontend-interactions#readme","bugs":{"url":"https://github.com/hynek-systems/campino-frontend-interactions/issues"},"dist":{"shasum":"7f1f5b3092eff77a77c4ab3b6a4e47426854c514","tarball":"https://registry.npmjs.org/@campino/frontend-interactions/-/frontend-interactions-1.0.0.tgz","fileCount":4,"integrity":"sha512-za3MC7F7ahlSkXjLVVbOgm5bhE3INPUx7kmUEWgZA93++Z5FDziLwtbopK3Dg13gwZQzHKPTU8riwX4N0csAhA==","signatures":[{"sig":"MEQCIAn+jSxB+HqCErJCcFoAGO79vXnxAUAzdAqOsnc0hnuXAiAuIEbXSVL77jI2C1+O6WVIZu45gA+rkaKOQtyDP1BJyQ==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":83106},"type":"module","exports":{".":"./dist/index.mjs","./package.json":"./package.json"},"gitHead":"876a9ae9f395b5c32c664080f5bcfea1cac8f2a7","scripts":{"dev":"vp pack --watch","test":"vp test","build":"vp pack","check":"vp check","prepare":"vp config","prepublishOnly":"vp run build"},"_npmUser":{"name":"campino","email":"henric.soderlind@outlook.com"},"overrides":{"vite":"npm:@voidzero-dev/vite-plus-core@0.2.4"},"devEngines":{"packageManager":{"name":"npm","onFail":"download","version":"12.0.1"}},"repository":{"url":"git+https://github.com/hynek-systems/campino-frontend-interactions.git","type":"git"},"_npmVersion":"12.0.1","description":"A package of frontend interactions.","directories":{},"_nodeVersion":"24.18.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"vite":"npm:@voidzero-dev/vite-plus-core@0.2.4","bumpp":"^11.1.0","jsdom":"^29.1.1","vite-plus":"^0.2.4","typescript":"^6.0.3","@types/node":"^26.1.1","@typescript/native-preview":"^7.0.0-dev.20260707.2"},"_npmOperationalInternal":{"tmp":"tmp/frontend-interactions_1.0.0_1784632019634_0.1261625917902398","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@campino/frontend-interactions","version":"1.0.1","description":"A package of frontend interactions.","keywords":["accessibility","dnd","drag-and-drop","focus-management","frontend","gesture","grid","interactions","keyboard-navigation","overlay","selection","sortable","swipe","typescript"],"homepage":"https://github.com/hynek-systems/campino-frontend-interactions#readme","bugs":{"url":"https://github.com/hynek-systems/campino-frontend-interactions/issues"},"license":"MIT","author":{"name":"Henric Söderlind","email":"henric.soderlind@outlook.com"},"repository":{"type":"git","url":"git+https://github.com/hynek-systems/campino-frontend-interactions.git"},"type":"module","exports":{".":"./dist/index.mjs","./package.json":"./package.json"},"publishConfig":{"access":"public"},"scripts":{"build":"vp pack","dev":"vp pack --watch","test":"vp test","check":"vp check","prepublishOnly":"vp run build","prepare":"vp config"},"devDependencies":{"@types/node":"^26.1.1","@typescript/native-preview":"^7.0.0-dev.20260707.2","bumpp":"^11.1.0","jsdom":"^29.1.1","typescript":"^6.0.3","vite":"npm:@voidzero-dev/vite-plus-core@0.2.4","vite-plus":"^0.2.4"},"overrides":{"vite":"npm:@voidzero-dev/vite-plus-core@0.2.4"},"devEngines":{"packageManager":{"name":"npm","version":"12.0.1","onFail":"download"}},"gitHead":"43c667daac318797043ba5c944c34f11e8e571c7","_id":"@campino/frontend-interactions@1.0.1","_nodeVersion":"24.18.0","_npmVersion":"12.0.1","dist":{"integrity":"sha512-ra/Ky29QMK1jcJLdBOfINqcGNu7ZyTunTziHDm8qGyLJ2t7WHBdB2mUkop144zRjLvmLZpFg82notTQ5SzkJgA==","shasum":"2012a9461874031d89fc18d243ccfa32d8e56a12","tarball":"https://registry.npmjs.org/@campino/frontend-interactions/-/frontend-interactions-1.0.1.tgz","fileCount":4,"unpackedSize":84020,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCsIgl6IEl3NRb+9xDodYHpQKawuzOoL3yQv4tPQ8EtGAIgHWVePf7CnLjZGPAls7csDXPnZQolmPG3zjnh7QMgHoI="}]},"_npmUser":{"name":"campino","email":"henric.soderlind@outlook.com"},"directories":{},"maintainers":[{"name":"campino","email":"henric.soderlind@outlook.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/frontend-interactions_1.0.1_1784833915871_0.9252044322393029"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-21T11:06:59.497Z","modified":"2026-07-23T19:11:56.193Z","1.0.0":"2026-07-21T11:06:59.770Z","1.0.1":"2026-07-23T19:11:56.031Z"},"bugs":{"url":"https://github.com/hynek-systems/campino-frontend-interactions/issues"},"author":{"name":"Henric Söderlind","email":"henric.soderlind@outlook.com"},"license":"MIT","homepage":"https://github.com/hynek-systems/campino-frontend-interactions#readme","keywords":["accessibility","dnd","drag-and-drop","focus-management","frontend","gesture","grid","interactions","keyboard-navigation","overlay","selection","sortable","swipe","typescript"],"repository":{"type":"git","url":"git+https://github.com/hynek-systems/campino-frontend-interactions.git"},"description":"A package of frontend interactions.","maintainers":[{"name":"campino","email":"henric.soderlind@outlook.com"}],"readme":"# @campino/frontend-interactions\n\nComposable interaction primitives for sortable layouts, input gestures, keyboard focus patterns, and accessible UI behavior.\n\n## Table of contents\n\n- [V1 scope](#v1-scope)\n- [Installation](#installation)\n- [Development](#development)\n- [Quick start](#quick-start)\n- [Exported modules](#exported-modules)\n- [Sortable](#sortable)\n- [Resizable](#resizable)\n- [RovingFocus](#rovingfocus)\n- [Overlay](#overlay)\n- [Selection](#selection)\n- [SwipeReveal](#swipereveal)\n- [Press](#press)\n- [Pan](#pan)\n- [Typeahead](#typeahead)\n- [RepeatPress](#repeatpress)\n- [Playgrounds](#playgrounds)\n\n## V1 scope\n\nThe following APIs are considered stable in v1.0.0:\n\n- `Sortable`\n- `Resizable`\n- `RovingFocus`\n- `Overlay`\n- `Selection`\n- `SwipeReveal`\n- `Press`\n- `Pan`\n- `Typeahead`\n- `RepeatPress`\n\n## Installation\n\n```bash\nvp install\n```\n\n## Development\n\n```bash\nvp test\nvp check\nvp pack\n```\n\n## Quick start\n\n```ts\nimport { Sortable } from \"@campino/frontend-interactions\";\n\nconst list = document.querySelector(\"#my-list\") as HTMLElement;\n\nnew Sortable(list);\n```\n\n## Exported modules\n\n```ts\nimport {\n  Overlay,\n  Pan,\n  Press,\n  RepeatPress,\n  Resizable,\n  RovingFocus,\n  Selection,\n  Sortable,\n  SwipeReveal,\n  Typeahead,\n} from \"@campino/frontend-interactions\";\n```\n\n## Sortable\n\nDrag-and-drop sorting for single lists, connected lists, nested lists, and grids.\n\n### Key options\n\n- `itemSelector?: string` default `\"[data-sortable-item]\"`\n- `handleSelector?: string` default `\"[data-sortable-handle]\"`\n- `direction?: \"vertical\" | \"horizontal\" | \"grid\"` default `\"vertical\"`\n- `dragThreshold?: number` default `4`\n- `dragThresholdByPointerType?: { mouse?: number; touch?: number; pen?: number }`\n- `axisLock?: false | \"x\" | \"y\" | \"auto\"` default `false`\n- `collisionStrategy?: \"midpoint\" | \"nearest-center\"` default `\"midpoint\"`\n- `autoScroll?: boolean`\n- `group?: { name: string; pull?: boolean; put?: boolean }`\n- `placeholderClass?: string`\n- `ariaLive?: boolean`\n\n### Events\n\n- Lifecycle: `beforeDragStart`, `onDragStart`, `onDragMove`, `onDragEnd`\n- Reordering: `onSort`, `onUpdate`\n- Cross-list: `onAdd`, `onRemove`\n- Target transitions: `onEnterTarget`, `onLeaveTarget`, `onChangeTarget`\n\n### Keyboard\n\n- `Space` picks up and drops focused item\n- `Enter` drops current drag\n- `Escape` cancels and restores\n- Arrow keys reorder within same container\n- `Alt + Arrow` transfers between compatible connected lists\n\n## Resizable\n\nPointer and keyboard resizing with min/max, snap, and optional announcements.\n\n### Key options\n\n- `handleSelector?: string` default `\"[data-resize-handle]\"`\n- `axis?: \"x\" | \"y\" | \"both\"` default `\"both\"`\n- `minWidth?: number`\n- `maxWidth?: number`\n- `minHeight?: number`\n- `maxHeight?: number`\n- `snap?: number`\n- `keyboardStep?: number` default `8`\n- `ariaLive?: boolean`\n\n### Events\n\n- `onResizeStart(event)`\n- `onResize(event)`\n- `onResizeEnd(event)`\n- `event.context.input` is `\"pointer\"` or `\"keyboard\"`\n\n## RovingFocus\n\nRoving tab index behavior for toolbars, menus, and composite controls.\n\n### Key options\n\n- `itemSelector?: string` default `\"[data-roving-item]\"`\n- `direction?: \"horizontal\" | \"vertical\" | \"both\"` default `\"both\"`\n- `loop?: boolean` default `true`\n- `onActiveChange?(event)`\n\n### Methods\n\n- `refresh()` to rescan items and resync tabindex\n- `setActiveIndex(index)` to programmatically move active item\n- `activeIndex` and `activeElement` getters\n\n## Overlay\n\nSimple overlay/dialog control with outside click close and optional focus trap.\n\n### Key options\n\n- `closeOnEscape?: boolean` default `true`\n- `closeOnOutside?: boolean` default `true`\n- `trapFocus?: boolean` default `true`\n- `contentSelector?: string` default `\"[data-overlay-content]\"`\n- `initialFocusSelector?: string`\n- `onOpen?()`\n- `onClose?({ reason })` where reason is `\"escape\" | \"outside\" | \"programmatic\"`\n\n### Methods\n\n- `open()`\n- `close(reason?)`\n- `toggle()`\n- `isOpen` getter\n\n## Selection\n\nSingle, multi, range, and keyboard selection behavior for list-like UIs.\n\n### Key options\n\n- `itemSelector?: string` default `\"[data-select-item]\"`\n- `multi?: boolean` default `true`\n- `onChange?(event)`\n\n### Event payload\n\n- `selectedIndices: number[]`\n- `selectedElements: HTMLElement[]`\n- `anchorIndex: number`\n\n### Methods\n\n- `refresh()`\n- `clear()`\n- `selectOnly(index)`\n- `toggle(index)`\n- `selectRange(index)`\n- `selectedIndices` and `selectedElements` getters\n\n## SwipeReveal\n\nSwipe rows horizontally to reveal trailing or leading actions.\n\n### Key options\n\n- `itemSelector?: string` default `\"[data-swipe-item]\"`\n- `contentSelector?: string` default `\"[data-swipe-content]\"`\n- `direction?: \"left\" | \"right\" | \"both\"` default `\"left\"`\n- `revealWidth?: number` default `88`\n- `openThreshold?: number` default `0.4`\n- `onSwipeMove?(event)`\n- `onOpen?(event)`\n- `onClose?(event)`\n\n### Methods\n\n- `open(index, side?)`\n- `closeAll()`\n\n## Press\n\nTap and long-press gesture detection with movement cancellation.\n\n### Key options\n\n- `itemSelector?: string` default `\"[data-press-item]\"`\n- `longPressDelay?: number` default `450`\n- `moveThreshold?: number` default `8`\n- `onPress?(event)`\n- `onLongPress?(event)`\n- `onCancel?({ item, index, reason })`\n\n### Cancel reasons\n\n- `\"move\"`\n- `\"pointercancel\"`\n- `\"destroy\"`\n\n## Pan\n\nConstrained drag-to-move primitive for cards, canvases, and mini map handles.\n\n### Key options\n\n- `handleSelector?: string`\n- `axis?: \"both\" | \"x\" | \"y\"` default `\"both\"`\n- `bounds?: false | { minX, maxX, minY, maxY }` default `false`\n- `onStart?(event)`\n- `onMove?(event)`\n- `onEnd?(event)`\n\n### Methods\n\n- `setPosition(x, y)`\n- `position` getter\n\n## Typeahead\n\nKeyboard quick-match that focuses the first item whose text starts with the typed buffer.\n\n### Key options\n\n- `itemSelector?: string` default `\"[data-typeahead-item]\"`\n- `bufferResetMs?: number` default `500`\n- `ignoreCase?: boolean` default `true`\n- `onMatch?(event)`\n- `onMiss?(event)`\n\n### Methods\n\n- `reset()`\n- `query` getter\n\n## RepeatPress\n\nHold-to-repeat pointer interaction, useful for steppers and press-and-hold controls.\n\n### Key options\n\n- `itemSelector?: string` default `\"[data-repeat-item]\"`\n- `initialDelayMs?: number` default `350`\n- `repeatIntervalMs?: number` default `75`\n- `onStart?(event)`\n- `onRepeat?({ item, index, count })`\n- `onStop?({ item, index, count, reason })`\n\n### Stop reasons\n\n- `\"pointerup\"`\n- `\"pointercancel\"`\n- `\"destroy\"`\n\n## Playgrounds\n\n- `playground/index.html` lists all available examples\n- `playground/sortable.html` focuses on sortable-only examples\n- `playground/multiple-lists.html` focuses on connected sortable scenarios\n- `playground/resizable.html` shows resize behaviors\n- `playground/roving-focus.html` shows arrow-key roving focus\n- `playground/overlay.html` shows overlay and focus trap behavior\n- `playground/selection.html` shows single/multi/range selection\n- `playground/swipe-reveal.html` shows swipe-to-reveal row actions\n- `playground/press.html` shows tap and long-press handling\n- `playground/pan.html` shows constrained drag-to-move behavior\n- `playground/typeahead.html` shows keyboard quick-find focusing\n- `playground/repeat-press.html` shows hold-to-repeat actions\n","readmeFilename":"README.md"}