{"_id":"@casino-ui/slot-machine","_rev":"2-05c4c4a5a2ac82d0cc1bb751ecbbb031","name":"@casino-ui/slot-machine","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@casino-ui/slot-machine","version":"1.0.0","keywords":["react","slot-machine","reel","slot","animation","gaming"],"author":"","license":"MIT","_id":"@casino-ui/slot-machine@1.0.0","maintainers":[{"name":"mfs-razan","email":"ritesh21633@gmail.com"}],"homepage":"https://github.com/huberco/slot-machine#readme","bugs":{"url":"https://github.com/huberco/slot-machine/issues"},"dist":{"shasum":"c687eacf1138b04f7451a640dd354ec2a3271434","tarball":"https://registry.npmjs.org/@casino-ui/slot-machine/-/slot-machine-1.0.0.tgz","fileCount":8,"integrity":"sha512-vCIG9ynflRKwK81wdM3l2lvqSNvVFBCStIpZVJvegeRCiluRQUhiW58BQUWRIc1rnQGqOsyhgTLBixLok/Qv2Q==","signatures":[{"sig":"MEUCICZ/PsknX4Wi5hds4ifzGATSKfnXHtivPIMzfMiQFWadAiEAvdPaUyCHy969HYy4Spm/aiNnCXcfxlz4XtbeWqdiAzM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":109009},"main":"./dist/index.js","types":"./dist/index.d.ts","module":"./dist/index.mjs","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"scripts":{"dev":"tsup --watch","build":"tsup"},"_npmUser":{"name":"mfs-razan","email":"ritesh21633@gmail.com"},"repository":{"url":"git+https://github.com/huberco/slot-machine.git","type":"git"},"_npmVersion":"11.6.2","description":"Responsive, configurable React slot machine / reel component with customizable item rendering","directories":{},"_nodeVersion":"24.12.0","publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"tsup":"^8.0.0","react":"^18.2.0","react-dom":"^18.2.0","typescript":"^5.0.0","@types/react":"^18.0.0","@types/react-dom":"^18.0.0"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/slot-machine_1.0.0_1770064498567_0.24210188678873745","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@casino-ui/slot-machine","version":"1.0.1","description":"Responsive, configurable React slot machine / reel component with customizable item rendering","main":"./dist/index.js","module":"./dist/index.mjs","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"}},"repository":{"type":"git","url":"git+https://github.com/huberco/slot-machine.git"},"publishConfig":{"access":"public"},"scripts":{"build":"tsup","dev":"tsup --watch"},"peerDependencies":{"react":">=18.0.0","react-dom":">=18.0.0"},"devDependencies":{"@types/react":"^18.0.0","@types/react-dom":"^18.0.0","react":"^18.2.0","react-dom":"^18.2.0","tsup":"^8.0.0","typescript":"^5.0.0"},"keywords":["react","slot-machine","reel","slot","animation","gaming"],"author":"","license":"MIT","gitHead":"3b179466582390d81cba6fe85cf7ed68e56eb362","_id":"@casino-ui/slot-machine@1.0.1","bugs":{"url":"https://github.com/huberco/slot-machine/issues"},"homepage":"https://github.com/huberco/slot-machine#readme","_nodeVersion":"24.12.0","_npmVersion":"11.6.2","dist":{"integrity":"sha512-Mo7IhhnMg4iBhkyKbqWE7c/d3VldYbnkuLKkyq6WO/h63zORUS3IEo1tQmB1xA7wwOlcmZJQi1KUJGo9J0qLfQ==","shasum":"c28d9acb540eae06e06bdd4231ed74b2d7bba566","tarball":"https://registry.npmjs.org/@casino-ui/slot-machine/-/slot-machine-1.0.1.tgz","fileCount":8,"unpackedSize":114346,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDsT9tHIud5f3jvxpB41rpuUi18yY7aZKyfckoKyC7r5QIhAPe2Lb5Cnw2PPbYMie/JH08GPuoxbl07ZOmj1IaV6bHd"}]},"_npmUser":{"name":"mfs-razan","email":"ritesh21633@gmail.com"},"directories":{},"maintainers":[{"name":"mfs-razan","email":"ritesh21633@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/slot-machine_1.0.1_1770088609025_0.3561661414795436"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-02T20:34:58.451Z","modified":"2026-02-03T03:16:49.305Z","1.0.0":"2026-02-02T20:34:58.737Z","1.0.1":"2026-02-03T03:16:49.172Z"},"bugs":{"url":"https://github.com/huberco/slot-machine/issues"},"license":"MIT","homepage":"https://github.com/huberco/slot-machine#readme","keywords":["react","slot-machine","reel","slot","animation","gaming"],"repository":{"type":"git","url":"git+https://github.com/huberco/slot-machine.git"},"description":"Responsive, configurable React slot machine / reel component with customizable item rendering","maintainers":[{"name":"mfs-razan","email":"ritesh21633@gmail.com"}],"readme":"# slot-machine\r\n\r\nA responsive, configurable React slot machine / reel component. Use one component per reel; combine multiple reels for a full slot grid. No external UI or state library required—bring your own items and styling.\r\n\r\n**Framework-agnostic:** All layout uses inline styles (no Tailwind or CSS required). Works in Vite, Next.js, CRA, or any React app. **Give the wrapper a defined size** (e.g. `height: 400px` or `width: 100%; height: 100%` inside a sized parent) so the reel centers and displays correctly.\r\n\r\n## Install\r\n\r\n```bash\r\nnpm install slot-machine\r\n# or\r\nyarn add slot-machine\r\npnpm add slot-machine\r\n```\r\n\r\n## Peer dependencies\r\n\r\n- `react` >= 18\r\n- `react-dom` >= 18\r\n\r\n## Basic usage\r\n\r\n```tsx\r\nimport { SlotMachine, type SlotItem, type SlotMachineHandle } from \"slot-machine\";\r\nimport { useRef } from \"react\";\r\n\r\nconst items: SlotItem[] = [\r\n  { id: \"1\", image: \"/cherry.png\", name: \"Cherry\" },\r\n  { id: \"2\", image: \"/lemon.png\", name: \"Lemon\" },\r\n  { id: \"3\", image: \"/seven.png\", name: \"Seven\" },\r\n];\r\n\r\nfunction App() {\r\n  const ref = useRef<SlotMachineHandle>(null);\r\n\r\n  return (\r\n    <div style={{ width: \"100%\", height: \"400px\" }}>\r\n      <SlotMachine\r\n        ref={ref}\r\n        items={items}\r\n        onSpinEnd={(result) => console.log(\"Landed on\", result)}\r\n      />\r\n      <button onClick={() => ref.current?.spin()}>Spin</button>\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n## Multiple reels (slot count)\r\n\r\nRender one `SlotMachine` per reel and control spin via refs:\r\n\r\n```tsx\r\nconst SLOT_COUNT = 6;\r\nconst refs = useRef<(SlotMachineHandle | null)[]>([]);\r\n\r\n<div style={{ display: \"flex\", gap: 8, width: \"100%\", height: 450 }}>\r\n  {Array.from({ length: SLOT_COUNT }).map((_, i) => (\r\n    <div key={i} style={{ flex: 1, minWidth: 0 }}>\r\n      <SlotMachine\r\n        ref={(r) => { refs.current[i] = r; }}\r\n        items={items}\r\n        slotIndex={i}\r\n        forcedResult={serverResults[i]} // optional: fix outcome per reel\r\n        onSpinEnd={(result) => handleReelEnd(i, result)}\r\n      />\r\n    </div>\r\n  ))}\r\n</div>\r\n<button onClick={() => refs.current.forEach((r) => r?.spin())}>\r\n  Spin all\r\n</button>\r\n```\r\n\r\n## Props (input data & settings)\r\n\r\n| Prop | Type | Default | Description |\r\n|------|------|---------|-------------|\r\n| `items` | `T[]` | required | Pool of items for the reel (and optional forced result). |\r\n| `slotIndex` | `number` | `0` | Index of this reel (e.g. 0..5 for 6 reels). |\r\n| `forcedResult` | `T \\| null` | `null` | If set, this reel stops on this item (e.g. from server). |\r\n| `duration` | `number` | `2500` | Spin duration in ms. |\r\n| `twistDuration` | `number` | `400` | Twist-back (snap to center) duration in ms. |\r\n| `orientation` | `\"vertical\" \\| \"horizontal\"` | `\"vertical\"` | Reel direction. |\r\n| `itemSize` | `number` | derived | Item size in px. Omit for responsive (size from container). |\r\n| `itemGap` | `number` | `20` | Gap around each item in px. |\r\n| `reelItemCount` | `number` | `35` | Number of items in the reel (longer = longer spin feel). |\r\n| `forcedTargetIndex` | `number` | `30` | Index in reel where `forcedResult` is placed. |\r\n| `onSpinStart` | `() => void` | - | Called when spin starts. |\r\n| `onSpinEnd` | `(result: T) => void` | - | Called when reel stops with selected item. |\r\n| `renderItem` | `(item, options) => ReactNode` | - | Custom render per item (see below). |\r\n| `itemClassName` | `string` | - | Class for default item wrapper. |\r\n| `itemStyle` | `CSSProperties` | - | Style for default item wrapper. |\r\n| `className` | `string` | - | Root wrapper class. |\r\n| `style` | `CSSProperties` | - | Root wrapper style. |\r\n| `overlayGradient` | `\"none\" \\| \"top-bottom\" \\| \"left-right\"` | auto | Fade overlay; default by orientation. |\r\n| `placeholderImage` | `string` | `\"\"` | Image URL when item has no image. |\r\n| `getItemImage` | `(item: T) => string` | `item => item.image` | Resolve image URL from item. |\r\n| `getItemName` | `(item: T) => string` | `item => item.name` | Resolve name (e.g. alt text). |\r\n\r\n## Custom item style\r\n\r\n- **Simple:** use `itemClassName` and `itemStyle` to style the default image wrapper.\r\n- **Full control:** use `renderItem` to render each cell yourself. You receive `(item, { isCenter, index, centerScale })` and return any `ReactNode`. The component handles position and animation; you control content and style.\r\n\r\n```tsx\r\n<SlotMachine\r\n  items={items}\r\n  itemClassName=\"rounded-lg shadow-md\"\r\n  itemStyle={{ border: \"2px solid gold\" }}\r\n/>\r\n```\r\n\r\n```tsx\r\n<SlotMachine\r\n  items={items}\r\n  renderItem={(item, { isCenter, centerScale }) => (\r\n    <div style={{ transform: `scale(${isCenter ? centerScale : 1})` }}>\r\n      <img src={item.image} alt={item.name} />\r\n      {isCenter && <span className=\"badge\">Selected</span>}\r\n    </div>\r\n  )}\r\n/>\r\n```\r\n\r\n## Responsive behavior\r\n\r\n- Root wrapper is `width: 100%`, `height: 100%`, and uses `containerType: \"size\"` so you can size it from a parent (e.g. flex, grid, or fixed height).\r\n- If you don’t pass `itemSize`, the component uses a default and adjusts with container size (ResizeObserver). For full control, pass `itemSize` from your own breakpoints or layout.\r\n\r\nExample: full-width row of reels that scales with viewport:\r\n\r\n```tsx\r\n<div className=\"slot-grid\" style={{\r\n  display: \"flex\",\r\n  gap: \"clamp(4px, 1vw, 16px)\",\r\n  width: \"100%\",\r\n  height: \"clamp(200px, 40vmin, 450px)\",\r\n}}>\r\n  {reels.map((_, i) => (\r\n    <div key={i} style={{ flex: 1, minWidth: 0 }}>\r\n      <SlotMachine items={items} />\r\n    </div>\r\n  ))}\r\n</div>\r\n```\r\n\r\n## Types\r\n\r\n- **SlotItem**: `{ id: string; image: string; name?: string; [key: string]: unknown }`. Extend this in your app (e.g. add `price`, `rarity`).\r\n- **SlotMachineHandle**: `{ spin: () => void }` for imperative spin.\r\n- **SlotMachineProps&lt;T&gt;**: props type; `T` must extend `SlotItem`.\r\n- **SlotItemRenderOptions**: `{ isCenter: boolean; index: number; centerScale: number }` passed to `renderItem`.\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}