{"_id":"ink-scroll-list","_rev":"8-81e2ab77e131e5851681fc01111ca0db","name":"ink-scroll-list","dist-tags":{"latest":"0.5.0"},"versions":{"0.1.0":{"name":"ink-scroll-list","version":"0.1.0","keywords":["react","ink","cli","terminal","scrolllist","component","ui"],"author":{"name":"ByteLand Technology","email":"github@byteland.app"},"license":"MIT","_id":"ink-scroll-list@0.1.0","maintainers":[{"name":"byteland-technology","email":"npm@byteland.app"}],"homepage":"https://www.byteland.app/opensource/ink-scroll-list","bugs":{"url":"https://github.com/ByteLandTechnology/ink-scroll-list/issues"},"dist":{"shasum":"4968d101597f6b485633b845cb6c4f36c3bf649c","tarball":"https://registry.npmjs.org/ink-scroll-list/-/ink-scroll-list-0.1.0.tgz","fileCount":5,"integrity":"sha512-e/+VxbcAwVMLM2U5a/fPzE8QdSHYr18PioQB/08BqqAopJ+jXST1mb/zRrDyb54RyCBxpH+NS1GXc4wYSy+GYw==","signatures":[{"sig":"MEYCIQCrW2s35fuB9089hfG30g0O+f2guU/TZmn0cjoSK/lFYQIhANpgl+b2Crssweai+Ell/X2prBlC9M7dSoDHHCH2M5NE","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":34598},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","source":"src/index.tsx","gitHead":"8528d15e986f97d482359aedf69c36cf834fed9a","scripts":{"docs":"typedoc && prettier --write docs/api","test":"vitest run","build":"tsup","prepare":"husky"},"_npmUser":{"name":"byteland-technology","email":"npm@byteland.app"},"repository":{"url":"git+https://github.com/ByteLandTechnology/ink-scroll-list.git","type":"git"},"_npmVersion":"11.6.0","description":"A ScrollList component for Ink CLI applications","directories":{},"_nodeVersion":"24.10.0","_hasShrinkwrap":false,"devDependencies":{"ink":"^6.5.1","tsup":"^8.5.1","husky":"^9.1.7","react":"^19.2.1","typedoc":"^0.28.15","prettier":"^3.7.4","@types/ink":"^0.5.2","@types/node":"^24.10.1","lint-staged":"^16.2.7","@types/react":"^19.2.7","@commitlint/cli":"^20.2.0","ink-scroll-view":"^0.1.0","@sindresorhus/tsconfig":"^8.1.0","typedoc-plugin-markdown":"^4.9.0","@commitlint/config-conventional":"^20.2.0"},"peerDependencies":{"ink":">=6","react":">=19","ink-scroll-view":"^0.1.0"},"_npmOperationalInternal":{"tmp":"tmp/ink-scroll-list_0.1.0_1765024117494_0.7277618137754087","host":"s3://npm-registry-packages-npm-production"}},"0.3.0":{"name":"ink-scroll-list","version":"0.3.0","keywords":["react","ink","cli","terminal","scrolllist","component","ui"],"author":{"name":"ByteLand Technology","email":"github@byteland.app"},"license":"MIT","_id":"ink-scroll-list@0.3.0","maintainers":[{"name":"byteland-technology","email":"npm@byteland.app"}],"homepage":"https://www.byteland.app/opensource/ink-scroll-list","bugs":{"url":"https://github.com/ByteLandTechnology/ink-scroll-list/issues"},"dist":{"shasum":"8bf152a1a0ada61fbf248304c3bc10d73c8424de","tarball":"https://registry.npmjs.org/ink-scroll-list/-/ink-scroll-list-0.3.0.tgz","fileCount":5,"integrity":"sha512-h44mprSD7WvYUH16E0ua5c3MEMdQU671wMqYAdTp14YJUAQz+fzBlxRxpMvAU1hGXb33Sgt7IXDmp83bJq8uHg==","signatures":[{"sig":"MEQCIAE1nIUpxDtzQr2Ah9YbPhWTcDQb1itprzPoH9kBKcxBAiAi2q80EjOCpOv734SoF/QURFOSIuiV4geqhBGfe0sKQA==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":33975},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","source":"src/index.tsx","gitHead":"38240c06d2fa44e215e2b8b71c15ac11ce58e6f3","scripts":{"docs":"typedoc && prettier --write docs/api","test":"vitest run","build":"tsup","prepare":"husky"},"_npmUser":{"name":"byteland-technology","email":"npm@byteland.app"},"repository":{"url":"git+https://github.com/ByteLandTechnology/ink-scroll-list.git","type":"git"},"_npmVersion":"11.6.2","description":"A ScrollList component for Ink CLI applications","directories":{},"_nodeVersion":"25.2.0","_hasShrinkwrap":false,"devDependencies":{"ink":"^6.5.1","tsup":"^8.5.1","husky":"^9.1.7","react":"^19.2.1","typedoc":"^0.28.15","prettier":"^3.7.4","@types/ink":"^0.5.2","@types/node":"^24.10.1","lint-staged":"^16.2.7","@types/react":"^19.2.7","@commitlint/cli":"^20.2.0","ink-scroll-view":"^0.3.0","@sindresorhus/tsconfig":"^8.1.0","typedoc-plugin-markdown":"^4.9.0","@commitlint/config-conventional":"^20.2.0"},"peerDependencies":{"ink":">=6","react":">=19","ink-scroll-view":"^0.3.0"},"_npmOperationalInternal":{"tmp":"tmp/ink-scroll-list_0.3.0_1765175327820_0.9896513360545214","host":"s3://npm-registry-packages-npm-production"}},"0.3.1":{"name":"ink-scroll-list","version":"0.3.1","keywords":["react","ink","cli","terminal","scrolllist","component","ui"],"author":{"name":"ByteLand Technology","email":"github@byteland.app"},"license":"MIT","_id":"ink-scroll-list@0.3.1","maintainers":[{"name":"byteland-technology","email":"npm@byteland.app"}],"homepage":"https://www.byteland.app/opensource/ink-scroll-list","bugs":{"url":"https://github.com/ByteLandTechnology/ink-scroll-list/issues"},"dist":{"shasum":"1f4b32d14cd49ab2ef44aafa05c7ecf99b6baac1","tarball":"https://registry.npmjs.org/ink-scroll-list/-/ink-scroll-list-0.3.1.tgz","fileCount":5,"integrity":"sha512-XDFmPH+tKFp3nm4SB9eA+PG+mYiTCWs1cuxeC8iLSXL7kMSn/ig4+DRdd22/a+MNgtVqS8oNWthOPqSlxk1arg==","signatures":[{"sig":"MEYCIQD566EJcsJKD8r18bfu1t+4yb3HHWwuo6GlP7pfzfXQFAIhAMj7Jx+/heROg5kcCUXx8Axok9w9ClvHep9iMHirGrvJ","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35527},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","source":"src/index.tsx","gitHead":"23c2d2c0915391af32f7c0f98a0d708f16e3fe9a","scripts":{"docs":"typedoc && prettier --write docs/api","test":"vitest run","build":"tsup","prepare":"husky"},"_npmUser":{"name":"byteland-technology","email":"npm@byteland.app"},"repository":{"url":"git+https://github.com/ByteLandTechnology/ink-scroll-list.git","type":"git"},"_npmVersion":"11.6.2","description":"A ScrollList component for Ink CLI applications","directories":{},"_nodeVersion":"25.2.0","dependencies":{"ink-scroll-view":"^0.3.1"},"_hasShrinkwrap":false,"devDependencies":{"ink":"^6.5.1","tsup":"^8.5.1","husky":"^9.1.7","react":"^19.2.1","typedoc":"^0.28.15","prettier":"^3.7.4","@types/ink":"^0.5.2","@types/node":"^24.10.1","lint-staged":"^16.2.7","@types/react":"^19.2.7","@commitlint/cli":"^20.2.0","@sindresorhus/tsconfig":"^8.1.0","typedoc-plugin-markdown":"^4.9.0","@commitlint/config-conventional":"^20.2.0"},"peerDependencies":{"ink":">=6","react":">=19"},"_npmOperationalInternal":{"tmp":"tmp/ink-scroll-list_0.3.1_1765425801300_0.6292301151449238","host":"s3://npm-registry-packages-npm-production"}},"0.3.2":{"name":"ink-scroll-list","version":"0.3.2","keywords":["react","ink","cli","terminal","scrolllist","component","ui"],"author":{"name":"ByteLand Technology","email":"github@byteland.app"},"license":"MIT","_id":"ink-scroll-list@0.3.2","maintainers":[{"name":"byteland-technology","email":"npm@byteland.app"}],"homepage":"https://www.byteland.app/opensource/ink-scroll-list","bugs":{"url":"https://github.com/ByteLandTechnology/ink-scroll-list/issues"},"dist":{"shasum":"1a4b2d71b7346c262e890d77a7bd9869ada640f3","tarball":"https://registry.npmjs.org/ink-scroll-list/-/ink-scroll-list-0.3.2.tgz","fileCount":5,"integrity":"sha512-aF+a6zwo4kUk0tA42u/GT3jxSq2blMPIlESCIqskv26qklgKhVHJgEEFse7PvheWygQJJF/5JgykzwT1h6gIqQ==","signatures":[{"sig":"MEYCIQCES+1v/ap7W5mWVHONT9XYoWDKNflqtW98ISS0jnB77AIhANgqdsn1ol7cAt+0LXxzlSGPNzmIgKPFXEY/J55IxphM","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":35696},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","source":"src/index.tsx","gitHead":"9c223daffc519dfdeaa1ed5bd2c15bb85c380571","scripts":{"docs":"typedoc && prettier --write docs/api","test":"vitest run","build":"tsup","prepare":"husky"},"_npmUser":{"name":"byteland-technology","email":"npm@byteland.app"},"repository":{"url":"git+https://github.com/ByteLandTechnology/ink-scroll-list.git","type":"git"},"_npmVersion":"11.6.2","description":"A ScrollList component for Ink CLI applications","directories":{},"_nodeVersion":"25.2.0","dependencies":{"ink-scroll-view":"^0.3.1"},"_hasShrinkwrap":false,"devDependencies":{"ink":"^6.5.1","tsup":"^8.5.1","husky":"^9.1.7","react":"^19.2.1","typedoc":"^0.28.15","prettier":"^3.7.4","@types/ink":"^0.5.2","@types/node":"^24.10.1","lint-staged":"^16.2.7","@types/react":"^19.2.7","@commitlint/cli":"^20.2.0","@sindresorhus/tsconfig":"^8.1.0","typedoc-plugin-markdown":"^4.9.0","@commitlint/config-conventional":"^20.2.0"},"peerDependencies":{"ink":">=6","react":">=19"},"_npmOperationalInternal":{"tmp":"tmp/ink-scroll-list_0.3.2_1765771063827_0.8211585078958352","host":"s3://npm-registry-packages-npm-production"}},"0.3.3":{"name":"ink-scroll-list","version":"0.3.3","keywords":["react","ink","cli","terminal","scrolllist","component","ui"],"author":{"name":"ByteLand Technology","email":"github@byteland.app"},"license":"MIT","_id":"ink-scroll-list@0.3.3","maintainers":[{"name":"byteland-technology","email":"npm@byteland.app"}],"homepage":"https://www.byteland.app/opensource/ink-scroll-list","bugs":{"url":"https://github.com/ByteLandTechnology/ink-scroll-list/issues"},"dist":{"shasum":"b740a3316f0a5ed15b1ed390dcbf4e99f68b23c3","tarball":"https://registry.npmjs.org/ink-scroll-list/-/ink-scroll-list-0.3.3.tgz","fileCount":5,"integrity":"sha512-iarzLAD6U9lvx6Yb/80ASUm+TXMH25hzHzw/AnOI039gznr6Gy+G7Um7HEndR+BxX83caSql12vSzMYLaAT+WQ==","signatures":[{"sig":"MEUCIQCWbDqWmpTUy4KMpjwyXG5tUBO8H0Hew5CJVgzhKLjLbwIgGasCc4BiqU2KJWnlg48BuR6anSwDZmfE/JOj1vGSB9Q=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":36589},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","source":"src/index.tsx","gitHead":"0e48e30722ec40d14119e93cfca63a065f656ae1","scripts":{"docs":"typedoc && prettier --write docs/api","test":"vitest run","build":"tsup","prepare":"husky"},"_npmUser":{"name":"byteland-technology","email":"npm@byteland.app"},"repository":{"url":"git+https://github.com/ByteLandTechnology/ink-scroll-list.git","type":"git"},"_npmVersion":"11.6.2","description":"A ScrollList component for Ink CLI applications","directories":{},"_nodeVersion":"25.2.0","dependencies":{"ink-scroll-view":"^0.3.2"},"_hasShrinkwrap":false,"devDependencies":{"ink":"^6.5.1","tsup":"^8.5.1","husky":"^9.1.7","react":"^19.2.1","typedoc":"^0.28.15","prettier":"^3.7.4","@types/ink":"^0.5.2","@types/node":"^24.10.1","lint-staged":"^16.2.7","@types/react":"^19.2.7","@commitlint/cli":"^20.2.0","@sindresorhus/tsconfig":"^8.1.0","typedoc-plugin-markdown":"^4.9.0","@commitlint/config-conventional":"^20.2.0"},"peerDependencies":{"ink":">=6","react":">=19"},"_npmOperationalInternal":{"tmp":"tmp/ink-scroll-list_0.3.3_1765776642745_0.6146355520681446","host":"s3://npm-registry-packages-npm-production"}},"0.4.0":{"name":"ink-scroll-list","version":"0.4.0","keywords":["react","ink","cli","terminal","scrolllist","component","ui"],"author":{"name":"ByteLand Technology","email":"github@byteland.app"},"license":"MIT","_id":"ink-scroll-list@0.4.0","maintainers":[{"name":"byteland-technology","email":"npm@byteland.app"}],"homepage":"https://www.byteland.app/opensource/ink-scroll-list","bugs":{"url":"https://github.com/ByteLandTechnology/ink-scroll-list/issues"},"dist":{"shasum":"51b34d58828851d325cc18347c870eddfa4a1c1c","tarball":"https://registry.npmjs.org/ink-scroll-list/-/ink-scroll-list-0.4.0.tgz","fileCount":5,"integrity":"sha512-E1d7TGEJYOwkjFaf88UgCfKkV3NwqanpaKQaHoKjU/ol8bpp468AcfT2YKcLc/Cgk+fwCN8XUxvIbzt12dfnYg==","signatures":[{"sig":"MEUCIA1QRtpdhbaEQef8vS4cnw64r4YbQiqLSZbeGrBg3Ds6AiEAph/aXhPS4YrxCXbUjGtOwwV46GIhjZ7rCMo83QJK4Lk=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":64548},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","source":"src/index.tsx","gitHead":"462e93dce9849ea3af6469638be908783a4132a5","scripts":{"docs":"typedoc && prettier --write docs/api","test":"vitest run","build":"tsup","prepare":"husky"},"_npmUser":{"name":"byteland-technology","email":"npm@byteland.app"},"repository":{"url":"git+https://github.com/ByteLandTechnology/ink-scroll-list.git","type":"git"},"_npmVersion":"11.6.2","description":"A ScrollList component for Ink CLI applications","directories":{},"_nodeVersion":"25.2.0","dependencies":{"ink-scroll-view":"^0.3.4"},"_hasShrinkwrap":false,"devDependencies":{"ink":"^6.5.1","tsup":"^8.5.1","husky":"^9.1.7","react":"^19.2.1","vitest":"^4.0.16","typedoc":"^0.28.15","prettier":"^3.7.4","@types/ink":"^0.5.2","@types/node":"^24.10.1","lint-staged":"^16.2.7","@types/react":"^19.2.7","@commitlint/cli":"^20.2.0","@sindresorhus/tsconfig":"^8.1.0","typedoc-plugin-markdown":"^4.9.0","@commitlint/config-conventional":"^20.2.0"},"peerDependencies":{"ink":">=6","react":">=19"},"_npmOperationalInternal":{"tmp":"tmp/ink-scroll-list_0.4.0_1767264739294_0.6740523632913251","host":"s3://npm-registry-packages-npm-production"}},"0.4.1":{"name":"ink-scroll-list","version":"0.4.1","keywords":["react","ink","cli","terminal","scrolllist","component","ui"],"author":{"name":"ByteLand Technology","email":"github@byteland.app"},"license":"MIT","_id":"ink-scroll-list@0.4.1","maintainers":[{"name":"byteland-technology","email":"npm@byteland.app"}],"homepage":"https://www.byteland.app/opensource/ink-scroll-list","bugs":{"url":"https://github.com/ByteLandTechnology/ink-scroll-list/issues"},"dist":{"shasum":"5fdfd9bb27a0d917642228543b33cb576d558249","tarball":"https://registry.npmjs.org/ink-scroll-list/-/ink-scroll-list-0.4.1.tgz","fileCount":6,"integrity":"sha512-2GcjnBXRe0sTSMC03SCKX6IkNAsYYgcpvAN+ggAiaqeg+s+qA9Ls0iVTOmB+Ize/9AVts8xloG4aRcrOy/7Xxg==","signatures":[{"sig":"MEYCIQCoUatS+C0U+tXz4K2ytWuS9v+7GDu/7uzSzYBKCG7fKgIhAIbiXXQHpAxxzMLExdSCizBMJZV+cQzorMVTcvI1YBOf","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":70513},"main":"dist/index.js","type":"module","types":"dist/index.d.ts","source":"src/index.tsx","gitHead":"ce9def9a171e32cc5dd027d19df05e12f6d51c71","scripts":{"docs":"typedoc && prettier --write docs/api","test":"vitest run","build":"tsup","prepare":"husky"},"_npmUser":{"name":"byteland-technology","email":"npm@byteland.app"},"repository":{"url":"git+https://github.com/ByteLandTechnology/ink-scroll-list.git","type":"git"},"_npmVersion":"11.6.2","description":"A ScrollList component for Ink CLI applications","directories":{},"_nodeVersion":"25.2.0","dependencies":{"ink-scroll-view":"^0.3.5"},"_hasShrinkwrap":false,"devDependencies":{"ink":"^6.5.1","tsup":"^8.5.1","husky":"^9.1.7","react":"^19.2.1","vitest":"^4.0.16","typedoc":"^0.28.15","prettier":"^3.7.4","@types/ink":"^0.5.2","@types/node":"^24.10.1","lint-staged":"^16.2.7","@types/react":"^19.2.7","@commitlint/cli":"^20.2.0","@sindresorhus/tsconfig":"^8.1.0","typedoc-plugin-markdown":"^4.9.0","@commitlint/config-conventional":"^20.2.0"},"peerDependencies":{"ink":">=6","react":">=19"},"_npmOperationalInternal":{"tmp":"tmp/ink-scroll-list_0.4.1_1767404990435_0.4214111321375069","host":"s3://npm-registry-packages-npm-production"}},"0.5.0":{"name":"ink-scroll-list","version":"0.5.0","description":"A ScrollList component for Ink CLI applications","keywords":["react","ink","cli","terminal","scrolllist","component","ui"],"homepage":"https://www.byteland.app/opensource/ink-scroll-list","bugs":{"url":"https://github.com/ByteLandTechnology/ink-scroll-list/issues"},"repository":{"type":"git","url":"git+https://github.com/ByteLandTechnology/ink-scroll-list.git"},"license":"MIT","author":{"name":"ByteLand Technology","email":"github@byteland.app"},"type":"module","main":"dist/index.js","types":"dist/index.d.ts","source":"src/index.tsx","scripts":{"test":"vitest run","prepare":"husky","build":"tsup","docs":"typedoc && prettier --write docs/api"},"dependencies":{"ink-scroll-view":"^0.4.0"},"peerDependencies":{"ink":"^7","react":">=19.2.0"},"devDependencies":{"@commitlint/cli":"^20.2.0","@commitlint/config-conventional":"^20.2.0","@sindresorhus/tsconfig":"^8.1.0","@types/ink":"^0.5.2","@types/node":"^24.10.1","@types/react":"^19.2.7","husky":"^9.1.7","ink":"^7.0.1","lint-staged":"^16.2.7","prettier":"^3.7.4","react":"^19.2.1","tsup":"^8.5.1","typedoc":"^0.28.15","typedoc-plugin-markdown":"^4.9.0","vitest":"^4.0.16"},"gitHead":"4b032e76658610c5fc4974004a60e9d2fc16ec9b","_id":"ink-scroll-list@0.5.0","_nodeVersion":"26.8.1","_npmVersion":"11.13.0","dist":{"integrity":"sha512-kndcA0KIcTzgv9a0Phv3XIwBNMm+IS8tmpaz4yu/4zPVLAerPODIN+z/4PYUhYC93+C8zDJwNKD3MHmy5s15mw==","shasum":"8b4f6a2a0556f48586235d8f6375271f873793a4","tarball":"https://registry.npmjs.org/ink-scroll-list/-/ink-scroll-list-0.5.0.tgz","fileCount":6,"unpackedSize":74444,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIFhEY+HKIYtRnb8kmuA652I9cw0pp//hu1ZXgiY5UNSVAiEArB1l1LRUJFzDieBdkbg+5AyYWnM1KcFyfpDCnY660Aw="}]},"_npmUser":{"name":"byteland-technology","email":"npm@byteland.app"},"directories":{},"maintainers":[{"name":"byteland-technology","email":"npm@byteland.app"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/ink-scroll-list_0.5.0_1789007794575_0.03631061202616426"},"_hasShrinkwrap":false}},"time":{"created":"2025-12-06T12:28:37.418Z","modified":"2026-09-10T02:36:34.896Z","0.1.0":"2025-12-06T12:28:37.637Z","0.3.0":"2025-12-08T06:28:47.965Z","0.3.1":"2025-12-11T04:03:21.445Z","0.3.2":"2025-12-15T03:57:43.974Z","0.3.3":"2025-12-15T05:30:42.886Z","0.4.0":"2026-01-01T10:52:19.432Z","0.4.1":"2026-01-03T01:49:50.600Z","0.5.0":"2026-09-10T02:36:34.705Z"},"bugs":{"url":"https://github.com/ByteLandTechnology/ink-scroll-list/issues"},"author":{"name":"ByteLand Technology","email":"github@byteland.app"},"license":"MIT","homepage":"https://www.byteland.app/opensource/ink-scroll-list","keywords":["react","ink","cli","terminal","scrolllist","component","ui"],"repository":{"type":"git","url":"git+https://github.com/ByteLandTechnology/ink-scroll-list.git"},"description":"A ScrollList component for Ink CLI applications","maintainers":[{"name":"byteland-technology","email":"npm@byteland.app"}],"readme":"# ink-scroll-list\n\nA high-level ScrollList component for [Ink](https://github.com/vadimdemedes/ink) CLI applications, built on top of [ink-scroll-view](https://github.com/BytelandTechnology/ink-scroll-view).\n\n![License](https://img.shields.io/npm/l/ink-scroll-list)\n![Version](https://img.shields.io/npm/v/ink-scroll-list)\n\n📖 **[Documentation Website](https://ink-scroll-list.byteland.app)**\n\n## ✨ Features\n\n- **Controlled Selection**: Selection state is managed by the parent via `selectedIndex` prop.\n- **Auto-Scrolling**: Automatically scrolls to ensure the selected item is visible.\n- **Flexible Alignment**: Control how the selected item aligns in the viewport (`auto`, `top`, `bottom`, `center`).\n- **Performance**: Optimized to track selection position efficiently without full re-layouts.\n- **Responsive**: Maintains selection visibility when viewport or content changes.\n\n## 🎬 Demos\n\n### Selection & Navigation\n\n![Selection Demo](docs/_media/selection.svg)\n\n### Scroll Alignment Modes\n\n![Alignment Demo](docs/_media/alignment.svg)\n\n### Expand/Collapse\n\n![Expand Demo](docs/_media/expand.svg)\n\n### Dynamic Items\n\n![Dynamic Demo](docs/_media/dynamic.svg)\n\n## 📦 Installation\n\n```bash\nnpm install ink-scroll-list\n# Peer dependencies\nnpm install ink@^7 react@\">=19.2.0\"\n```\n\nRequires Node.js 22 or newer, Ink 7, and React 19.2 or newer; uses `ink-scroll-view` 0.4.x.\n\n## 🚀 Usage\n\n`ScrollList` is a **controlled component** - the parent component owns and manages the selection state via the `selectedIndex` prop.\n\n```tsx\nimport React, { useRef, useState } from \"react\";\nimport { render, Text, Box, useInput } from \"ink\";\nimport { ScrollList, ScrollListRef } from \"ink-scroll-list\";\n\nconst App = () => {\n  const listRef = useRef<ScrollListRef>(null);\n  const [selectedIndex, setSelectedIndex] = useState(0);\n  const items = Array.from({ length: 20 }).map((_, i) => `Item ${i + 1}`);\n\n  // Handle keyboard navigation in the parent\n  useInput((input, key) => {\n    if (key.upArrow) {\n      setSelectedIndex((prev) => Math.max(prev - 1, 0));\n    }\n    if (key.downArrow) {\n      setSelectedIndex((prev) => Math.min(prev + 1, items.length - 1));\n    }\n    if (input === \"g\") {\n      setSelectedIndex(0); // Jump to first\n    }\n    if (input === \"G\") {\n      setSelectedIndex(items.length - 1); // Jump to last\n    }\n    if (key.return) {\n      console.log(`Selected: ${items[selectedIndex]}`);\n    }\n  });\n\n  return (\n    <Box borderStyle=\"single\" height={10}>\n      <ScrollList ref={listRef} selectedIndex={selectedIndex}>\n        {items.map((item, i) => (\n          <Box key={i}>\n            <Text color={i === selectedIndex ? \"green\" : \"white\"}>\n              {i === selectedIndex ? \"> \" : \"  \"}\n              {item}\n            </Text>\n          </Box>\n        ))}\n      </ScrollList>\n    </Box>\n  );\n};\n\nrender(<App />);\n```\n\n## 📚 API Reference\n\nFor detailed API documentation, see [API Reference](docs/api/README.md).\n\n### Props (`ScrollListProps`)\n\nExtends `ScrollViewProps` from `ink-scroll-view`.\n\n| Prop              | Type                                      | Description                                          |\n| :---------------- | :---------------------------------------- | :--------------------------------------------------- |\n| `selectedIndex`   | `number`                                  | The currently selected item index (controlled).      |\n| `scrollAlignment` | `'auto' \\| 'top' \\| 'bottom' \\| 'center'` | Alignment mode for selected item. Default: `'auto'`. |\n| ...               | `ScrollViewProps`                         | All props from `ScrollView`.                         |\n\n#### Scroll Alignment Modes\n\n- **`'auto'`** (default): Minimal scrolling to bring the item into view. Best for keyboard navigation.\n- **`'top'`**: Always aligns the selected item to the top of the viewport.\n- **`'bottom'`**: Always aligns the selected item to the bottom of the viewport.\n- **`'center'`**: Always centers the selected item in the viewport. Best for search/spotlight UX.\n\n### Ref Methods (`ScrollListRef`)\n\nExtends `ScrollViewRef` from `ink-scroll-view`. Access these via `ref.current`.\n\n**Note**: When a `selectedIndex` is set, all scroll methods are constrained to keep the selected item visible. This prevents accidentally scrolling the selection out of view.\n\n| Method              | Signature                                  | Description                                                          |\n| :------------------ | :----------------------------------------- | :------------------------------------------------------------------- |\n| `scrollTo`          | `(y: number) => void`                      | Scroll to a specific offset (constrained to keep selection visible). |\n| `scrollBy`          | `(delta: number) => void`                  | Scroll by a relative amount (constrained).                           |\n| `scrollToTop`       | `() => void`                               | Scroll as far up as possible while keeping selection visible.        |\n| `scrollToBottom`    | `() => void`                               | Scroll as far down as possible while keeping selection visible.      |\n| `getScrollOffset`   | `() => number`                             | Get current scroll offset.                                           |\n| `getContentHeight`  | `() => number`                             | Get total content height.                                            |\n| `getViewportHeight` | `() => number`                             | Get viewport height.                                                 |\n| `getBottomOffset`   | `() => number`                             | Get distance from bottom.                                            |\n| `getItemHeight`     | `(index: number) => number`                | Get a specific item's height.                                        |\n| `getItemPosition`   | `(index: number) => {top, height} \\| null` | Get a specific item's position.                                      |\n| `remeasure`         | `() => void`                               | Re-check viewport dimensions. See note below.                        |\n| `remeasureItem`     | `(index: number) => void`                  | Force remeasurement of a single item. See note below.                |\n\n**Large Items**: For items that are larger than the viewport, scrolling is allowed within the item's bounds. This lets users scroll to see different parts of the large item while at least part of it remains visible.\n\n**Manual measurement**: `remeasure()` re-checks viewport dimensions; it does not force all items to be measured. Viewport layout changes are tracked automatically. Item measurement runs when the measuring wrapper's inputs change, such as new child elements or a new viewport width. If an item changes height through its own internal state while those inputs stay unchanged, call `remeasureItem(index)` after the update has committed.\n\n## 💡 Tips\n\n1. **Controlled Component Pattern**: `ScrollList` is a fully controlled component. The parent must manage `selectedIndex` and update it based on user input.\n\n2. **Input Handling**: Use `useInput` from Ink to handle keyboard events and update `selectedIndex` accordingly. The component does NOT handle input internally.\n\n3. **Layout Changes**: With Ink 7 and `ink-scroll-view` 0.4.x, viewport dimensions are measured automatically when the surrounding layout changes, including terminal resizes. Remove resize listeners whose only job is to call `remeasure()`.\n\n   **Keep your existing layout.** The upgrade does not require a new `height` prop or a terminal-sized container. A fixed-height parent such as `<Box height={10}>` still works. Percentage and flex dimensions (`height=\"100%\"`, `flexGrow={1}`) still use the space provided by their parent. Automatic measurement observes that space; it does not choose the container's height.\n\n4. **Dynamic Items**: When items are added or removed, the parent should update `selectedIndex` if necessary:\n   - When adding items at the beginning: `setSelectedIndex(prev => prev + addedCount)`\n   - When removing items: Clamp to valid range: `setSelectedIndex(prev => Math.min(prev, newLength - 1))`\n\n5. **Performance**: `ScrollList` uses `ink-scroll-view` under the hood, so it benefits from the same performance optimizations (item height caching, efficient re-layouts).\n\n## ⚠️ Breaking Changes: Ink 7\n\nThis release requires **Ink 7**, **React 19.2+**, and **Node.js 22+** (required by Ink 7). The peer range narrowed from `ink >=6` to `ink ^7`, so projects still on Ink 6 must upgrade Ink before upgrading this package.\n\n**What changed:** Previously, the documentation instructed you to listen for terminal resizes and call `remeasure()`. With Ink 7 and `ink-scroll-view` 0.4.x, viewport measurement follows layout changes automatically, including changes driven by a parent container or terminal resize.\n\n**Migration:** Keep your existing height, percentage, or flex layout. Delete the listener below if its only purpose is to trigger remeasurement:\n\n```diff\n- useEffect(() => {\n-   const handleResize = () => listRef.current?.remeasure();\n-   process.stdout.on(\"resize\", handleResize);\n-   return () => process.stdout.off(\"resize\", handleResize);\n- }, []);\n```\n\nNo new height prop or layout change is required. If a resize listener also updates app-specific dimensions or performs other work, remove only its `remeasure()` call and keep that other behavior.\n\nThe component's props and ref methods remain available; manual remeasurement is no longer required to track viewport layout changes.\n\n## ⚠️ Breaking Changes in v0.4.0\n\nThis version introduces a **major architectural change**: `ScrollList` is now a **fully controlled component**.\n\n### Removed Features\n\nThe following props have been removed:\n\n- `onSelectionChange` - No longer needed; parent owns the state directly.\n\nThe following ref methods have been removed:\n\n- `select(index, mode)` - Use `setSelectedIndex(index)` + `scrollAlignment` prop instead.\n- `selectNext()` - Use `setSelectedIndex(prev => Math.min(prev + 1, length - 1))` instead.\n- `selectPrevious()` - Use `setSelectedIndex(prev => Math.max(prev - 1, 0))` instead.\n- `selectFirst()` - Use `setSelectedIndex(0)` instead.\n- `selectLast()` - Use `setSelectedIndex(length - 1)` instead.\n- `scrollToItem(index, mode)` - Use `selectedIndex` prop instead.\n- `getSelectedIndex()` - Parent already knows the index.\n- `getItemCount()` - Parent already knows the item count.\n\n### Migration Guide\n\n**Before (v0.3.x):**\n\n```tsx\nconst listRef = useRef<ScrollListRef>(null);\nconst [selectedIndex, setSelectedIndex] = useState(0);\n\nuseInput((input, key) => {\n  if (key.downArrow) {\n    const newIndex = listRef.current?.selectNext() ?? 0;\n    setSelectedIndex(newIndex);\n  }\n});\n\n<ScrollList ref={listRef} selectedIndex={selectedIndex} onSelectionChange={setSelectedIndex}>\n  {items.map(...)}\n</ScrollList>\n```\n\n**After (v0.4.0):**\n\n```tsx\nconst listRef = useRef<ScrollListRef>(null);\nconst [selectedIndex, setSelectedIndex] = useState(0);\n\nuseInput((input, key) => {\n  if (key.downArrow) {\n    setSelectedIndex((prev) => Math.min(prev + 1, items.length - 1));\n  }\n});\n\n<ScrollList ref={listRef} selectedIndex={selectedIndex}>\n  {items.map(...)}\n</ScrollList>\n```\n\n### Why This Change?\n\nThe controlled component pattern provides:\n\n- **Predictability**: The parent always knows the exact selection state.\n- **Simplicity**: No need to sync internal state with external state.\n- **Flexibility**: The parent has full control over how selection changes.\n- **Testability**: Selection logic lives in the parent and is easy to unit test.\n\n## 🔗 Related Packages\n\nThis package is part of a family of Ink scroll components:\n\n| Package                                                                  | Description                                                               |\n| :----------------------------------------------------------------------- | :------------------------------------------------------------------------ |\n| [ink-scroll-view](https://github.com/ByteLandTechnology/ink-scroll-view) | Core scroll container component                                           |\n| [ink-scroll-list](https://github.com/ByteLandTechnology/ink-scroll-list) | A scrollable list with focus management and item selection (this package) |\n| [ink-scroll-bar](https://github.com/ByteLandTechnology/ink-scroll-bar)   | A standalone scrollbar component for any scroll container                 |\n\n## License\n\nMIT\n","readmeFilename":"README.md"}