{"_id":"@dennisamstein/swiper-deck","name":"@dennisamstein/swiper-deck","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@dennisamstein/swiper-deck","version":"0.1.0","type":"module","description":"A headless swipeable card deck (drag / swipe / spring) — bring your own card visuals.","license":"MIT","repository":{"type":"git","url":"git+https://github.com/dennisamstein/swiper-deck.git"},"sideEffects":["**/*.css"],"exports":{".":{"types":"./dist/lib/index.d.ts","import":"./dist/index.js"},"./oblique":{"types":"./dist/lib/oblique.d.ts","import":"./dist/oblique.js"},"./styles.css":"./dist/index.css","./oblique/styles.css":"./dist/oblique.css"},"publishConfig":{"access":"public"},"scripts":{"dev":"vite","build":"tsc -b && vite build","build:lib":"vite build --config vite.lib.config.ts","lint":"eslint .","preview":"vite preview","prepublishOnly":"npm run build:lib"},"peerDependencies":{"motion":">=12","react":">=19","react-dom":">=19"},"devDependencies":{"@eslint/js":"^10.0.1","@types/node":"^24.12.2","@types/react":"^19.2.14","@types/react-dom":"^19.2.3","@vitejs/plugin-react":"^6.0.1","eslint":"^10.2.1","eslint-plugin-react-hooks":"^7.1.1","eslint-plugin-react-refresh":"^0.5.2","globals":"^17.5.0","motion":"^12.38.0","react":"^19.2.5","react-dom":"^19.2.5","typescript":"~6.0.2","typescript-eslint":"^8.58.2","vite":"^8.0.10","vite-plugin-dts":"^5.0.3"},"_id":"@dennisamstein/swiper-deck@0.1.0","gitHead":"e627c23fd70fd426ac1f3c57c1d99d8f672741b1","bugs":{"url":"https://github.com/dennisamstein/swiper-deck/issues"},"homepage":"https://github.com/dennisamstein/swiper-deck#readme","_nodeVersion":"20.20.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-HUlMhrf111zytkzHlh4Gj/KYZoRDDHT14ulshlFq7Eto8dnGHNmQqsTQwa7XFV1L+n7ICE/Huc5Czo0LURb39w==","shasum":"9f4fcb1863d3d9b03778f859f91df4fb3d98a267","tarball":"https://registry.npmjs.org/@dennisamstein/swiper-deck/-/swiper-deck-0.1.0.tgz","fileCount":10,"unpackedSize":15340,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIEsxvFNx8wyF+/rgji1L7oFD8bYxLn5TGmjV26IlOSx+AiEA1bEzCO5Q0gUpmWaWtQad14gQGQyYzeGCBt7AMFLK/qo="}]},"_npmUser":{"name":"dennisamstein","email":"dennis.amstein@gmail.com"},"directories":{},"maintainers":[{"name":"dennisamstein","email":"dennis.amstein@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/swiper-deck_0.1.0_1783785616322_0.6512101682888054"},"_hasShrinkwrap":false}},"time":{"created":"2026-07-11T16:00:16.221Z","0.1.0":"2026-07-11T16:00:16.460Z","modified":"2026-07-11T16:00:16.645Z"},"maintainers":[{"name":"dennisamstein","email":"dennis.amstein@gmail.com"}],"description":"A headless swipeable card deck (drag / swipe / spring) — bring your own card visuals.","homepage":"https://github.com/dennisamstein/swiper-deck#readme","repository":{"type":"git","url":"git+https://github.com/dennisamstein/swiper-deck.git"},"bugs":{"url":"https://github.com/dennisamstein/swiper-deck/issues"},"license":"MIT","readme":"# @dennisamstein/swiper-deck\n\nA headless, swipeable card deck for React — the drag / swipe / spring interaction,\nwith **no opinion about how your cards look**. You supply the card visuals via a\n`renderCard` prop; the deck handles the motion, stacking, keyboard controls, and\nreduced-motion support.\n\nBuilt on [`motion`](https://motion.dev). Peer deps: React 19+, `motion` 12+.\n\n## Install\n\n```sh\nnpm install @dennisamstein/swiper-deck motion react react-dom\n```\n\n## Usage\n\n```tsx\nimport { CardDeck } from '@dennisamstein/swiper-deck'\nimport type { DeckItem } from '@dennisamstein/swiper-deck'\nimport '@dennisamstein/swiper-deck/styles.css'\nimport './BaseballCard.css'\n\ntype Player = DeckItem & { name: string; team: string; avg: number; hr: number }\n\nconst players: Player[] = [\n  { id: '1', name: 'Ada Lovelace', team: 'Analysts', avg: 0.318, hr: 27 },\n  // …\n]\n\nexport function App() {\n  return (\n    <CardDeck\n      items={players}\n      cardWidth={360}\n      cardHeight={504}\n      renderCard={(player, { index, total }) => (\n        <div className=\"bb-card\">\n          <div className=\"bb-card__name\">{player.name}</div>\n          <div className=\"bb-card__team\">{player.team}</div>\n          <div className=\"bb-card__stats\">AVG {player.avg} · HR {player.hr}</div>\n          <div className=\"bb-card__no\">{index + 1}/{total}</div>\n        </div>\n      )}\n    />\n  )\n}\n```\n\n## API\n\n`CardDeck<T extends { id: string }>`\n\n| Prop         | Type                                              | Default | Description                                                                 |\n| ------------ | ------------------------------------------------- | ------- | --------------------------------------------------------------------------- |\n| `items`      | `T[]`                                             | —       | Cards to draw from. Each item needs a stable `id`.                          |\n| `renderCard` | `(item: T, meta: { index; total }) => ReactNode`  | —       | Renders the face of a card. This is where all card visuals live.            |\n| `cardWidth`  | `number` (px)                                     | `400`   | Desktop / maximum width. Drives the deck's sizing contract.                 |\n| `cardHeight` | `number` (px)                                     | `560`   | Desktop height. Together with `cardWidth` defines the card's aspect ratio.  |\n\nThe deck draws a random card on each swipe. Swipe by dragging, tapping the left/right\nedges of the top card, or with the arrow keys (`←` / `→`, and `Space` = next).\n`prefers-reduced-motion` skips the fly-off animation.\n\n## The card you render\n\n- Render at `width: 100%` (the deck sizes the box for you) and match the\n  `cardWidth` / `cardHeight` aspect ratio — e.g. `aspect-ratio: 360 / 504`.\n- The deck exposes `--card-width` / `--card-height` custom properties on its stage,\n  so your card CSS can read them if you prefer explicit dimensions.\n- Import `@dennisamstein/swiper-deck/styles.css` once — it contains **only** the\n  deck's layout (no fonts, colors, or card chrome).\n\nThe deck centers itself in its container. Page-level layout (centering the deck on\nthe screen, background, etc.) is up to you.\n\n## Optional example card\n\nThe Oblique-Strategies card used in the demo is published as an example you can use\ndirectly or copy from:\n\n```tsx\nimport { ObliqueCard } from '@dennisamstein/swiper-deck/oblique'\nimport '@dennisamstein/swiper-deck/oblique/styles.css'\n```\n\n## Note on feel\n\nThe drag thresholds and swipe distances are tuned for a ~400px-wide portrait card.\nSimilar portrait ratios (a 5:7 baseball card, say) feel right out of the box;\ndramatically different sizes may want their own tuning.\n\n## Development\n\nThis repo is also the live demo. `npm run dev` runs the Oblique-Strategies deck\n(see [src/App.tsx](src/App.tsx) for a reference consumer). `npm run build:lib`\nproduces the publishable package in `dist/`.\n","readmeFilename":"README.md","_rev":"1-e25b1b8a97adc90de01d21965ed9dd75"}