{"id":19253230,"url":"https://github.com/pettiboy/react-ui-scrollspy","last_synced_at":"2025-09-20T08:55:07.656Z","repository":{"id":47326983,"uuid":"423331440","full_name":"pettiboy/react-ui-scrollspy","owner":"pettiboy","description":"Customizable Scroll Spy component for react which is Simple, Easy To Use and Lightweight with callback, typescript, auto-update URL hash and throttle support among others.","archived":false,"fork":false,"pushed_at":"2024-05-22T15:55:22.000Z","size":14588,"stargazers_count":82,"open_issues_count":7,"forks_count":12,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-09-04T20:46:43.991Z","etag":null,"topics":["component","javascript","npm-package","react","react-component","react-scrollspy","react-scrollspy-component","react-ui-scrollspy","reactjs","scroll-events","scroll-spy","scrolling","scrollspy","typescript"],"latest_commit_sha":null,"homepage":"https://pettiboy.github.io/react-ui-scrollspy/","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pettiboy.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-11-01T03:59:25.000Z","updated_at":"2025-09-02T10:44:16.000Z","dependencies_parsed_at":"2024-11-16T19:02:46.199Z","dependency_job_id":"363e120f-5623-4d01-83df-0045d4651843","html_url":"https://github.com/pettiboy/react-ui-scrollspy","commit_stats":{"total_commits":47,"total_committers":3,"mean_commits":"15.666666666666666","dds":0.08510638297872342,"last_synced_commit":"4fbe16520909e8066a0239d39a7bce81115f0cd0"},"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/pettiboy/react-ui-scrollspy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pettiboy%2Freact-ui-scrollspy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pettiboy%2Freact-ui-scrollspy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pettiboy%2Freact-ui-scrollspy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pettiboy%2Freact-ui-scrollspy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pettiboy","download_url":"https://codeload.github.com/pettiboy/react-ui-scrollspy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pettiboy%2Freact-ui-scrollspy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":276070741,"owners_count":25580129,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-20T02:00:10.207Z","response_time":63,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["component","javascript","npm-package","react","react-component","react-scrollspy","react-scrollspy-component","react-ui-scrollspy","reactjs","scroll-events","scroll-spy","scrolling","scrollspy","typescript"],"created_at":"2024-11-09T18:29:51.976Z","updated_at":"2025-09-20T08:55:07.598Z","avatar_url":"https://github.com/pettiboy.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n![ScrollSpy Demo](./demo-app/assets/banner.png)\n\n# React UI ScrollSpy\n\n[![npm](https://img.shields.io/npm/v/react-ui-scrollspy.svg)](https://npmjs.com/package/react-ui-scrollspy)\n[![npm](https://img.shields.io/npm/dy/react-ui-scrollspy.svg)](https://npmjs.com/package/react-ui-scrollspy)\n[![License MIT](https://img.shields.io/badge/license-MIT-orange.svg?style=flat)](https://raw.githubusercontent.com/pettiboy/react-ui-scrollspy/main/LICENSE)\n[![PRs Welcome](https://img.shields.io/badge/PRs-Welcome-brightgreen.svg)](https://github.com/pettiboy/react-ui-scrollspy/pulls)\n\n![React](https://img.shields.io/badge/React-20232A?style=for-the-badge\u0026logo=react\u0026logoColor=61DAFB)\n![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?style=for-the-badge\u0026logo=typescript\u0026logoColor=white)\n![NPM](https://img.shields.io/badge/npm-CB3837?style=for-the-badge\u0026logo=npm\u0026logoColor=white)\n\nMake sure you ⭐️ this [`repository`](https://github.com/pettiboy/react-ui-scrollspy) if you find it helpful or interesting :)\n\n\u003c/div\u003e\n\n## ✨ Installation\n\n### React 18\n\n```bash\nnpm install --save react-ui-scrollspy\n```\n\nOR\n\n```bash\nyarn add react-ui-scrollspy\n```\n\n### React 17 and below\n\n```bash\nnpm install --save react-ui-scrollspy@2.2.0\n```\n\nOR\n\n```bash\nyarn add react-ui-scrollspy@2.2.0\n```\n\n## 🎞 Demo\n\n### Try it your self [here](https://pettiboy.github.io/react-ui-scrollspy)!\n\n| [Demo 1](./demo-app/src/pages/Demo1.tsx)      | [Demo 2](./demo-app/src/pages/Demo2.tsx)       |\n| :-------------------------------------------- | :--------------------------------------------- |\n| ![ScrollSpy Demo](./demo-app/assets/demo.gif) | ![ScrollSpy Demo](./demo-app/assets/demo2.gif) |\n\n## ⚙️ Usage\n\n1. In your navigation component\n\n```tsx\n\u003cdiv\u003e\n  \u003cp data-to-scrollspy-id=\"first\"\u003eSection 1\u003c/p\u003e\n  \u003cp data-to-scrollspy-id=\"second\"\u003eSection 2\u003c/p\u003e\n\u003c/div\u003e\n```\n\n2. Wrap the elements you want to spy on in the `\u003cScrollSpy\u003e` component.\n\n\u003c!-- prettier-ignore --\u003e\n```tsx\nimport ScrollSpy from \"react-ui-scrollspy\";\n\n\u003cScrollSpy\u003e\n  \u003cdiv id=\"first\"\u003e\n    Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut dolores\n    veritatis doloremque fugit. Soluta aperiam atque inventore deleniti,\n    voluptatibus non fuga eos magni natus vel, rerum excepturi expedita.\n    Tempore, vero!\n  \u003c/div\u003e\n  \u003cdiv id=\"second\"\u003e\n    Lorem ipsum dolor sit amet consectetur adipisicing elit. Aut dolores\n    veritatis doloremque fugit. Soluta aperiam atque inventore deleniti,\n    voluptatibus non fuga eos magni natus vel, rerum excepturi expedita.\n    Tempore, vero!\n  \u003c/div\u003e\n\u003c/ScrollSpy\u003e\n```\n\n3. Write styles for when the navigation element which is active in your `index.css`\n\n```css\n.active-scroll-spy {\n  background-color: yellowgreen;\n  border-radius: 15px;\n}\n```\n\n## 📝 Notes\n\nIncase the ScrollSpy is not working the way you expected, you can try the following:\n\n- Reduce the value of [`scrollThrottle`](#-throttle).\n\n- If your page contains a `navbar` a `header` consider adding the following `CSS`\n\n```css\nhtml {\n  scroll-padding-top: 120px; /* height of your navbar */\n}\n```\n\n- Try using [`offsets`](#-offsets).\n\n- Go through the [`Props`](#-props).\n\n- See [`demo-app`](./demo-app/src/App.tsx) for example used [here](https://pettiboy.github.io/react-ui-scrollspy).\n\n## 💡 Props\n\n### 🔧 Children\n\n| Attributes | Type        | Description                                        | Default | Required |\n| :--------- | :---------- | :------------------------------------------------- | :------ | :------- |\n| `children` | `ReactNode` | Each direct child `Element` should contain an `id` | -       | yes      |\n\n### 🔧 Refs\n\n| Attributes                 | Type                                              | Description                                                                                             | Default | Required |\n| :------------------------- | :------------------------------------------------ | :------------------------------------------------------------------------------------------------------ | :------ | :------- |\n| `navContainerRef`          | MutableRefObject\u003cbr\u003e\u003cHTMLDivElement \\| null\u003e\u003cbr/\u003e | `ref` to your navigation container containing items with `data-to-scrollspy-id` attributes              | -       | no       |\n| `parentScrollContainerRef` | MutableRefObject\u003cbr\u003e\u003cHTMLDivElement \\| null\u003e\u003cbr/\u003e | If you want to spy only on a particular scrollable `container (Element)` then pass its ref to this prop | -       | no       |\n\n### 🔧 Throttle\n\n| Attributes       | Type     | Description                                                                                                                 | Default | Required |\n| :--------------- | :------- | :-------------------------------------------------------------------------------------------------------------------------- | :------ | :------- |\n| `scrollThrottle` | `number` | In `milliseconds` to throttle the `onscroll` event. Lower the number, better the response time, higher the performance cost | `300`   | no       |\n\n### 🔧 Callback\n\n| Attributes         | Type                   | Description                                                                                                                        | Default | Required |\n| :----------------- | :--------------------- | :--------------------------------------------------------------------------------------------------------------------------------- | :------ | :------- |\n| `onUpdateCallback` | `(id: string) =\u003e void` | Executes this function whenever you scroll to a new ScrollSpy child `Element`, callback returns the `id` of that `Element` as well | -       | no       |\n\n### 🔧 Offsets\n\n| Attributes     | Type     | Description                                                                                                     | Default | Required |\n| :------------- | :------- | :-------------------------------------------------------------------------------------------------------------- | :------ | :------- |\n| `offsetTop`    | `number` | Spy will be fired when it has been scrolled `offsetTop` beyond `50%` to the top of the containing element       | `0`     | no       |\n| `offsetBottom` | `number` | Spy will be fired when it has been scrolled `offsetBottom` beyond `50%` to the bottom of the containing element | `0`     | no       |\n\n### 🔧 Customize Attributes\n\n| Attributes         | Type      | Description                                                                                               | Default               | Required |\n| :----------------- | :-------- | :-------------------------------------------------------------------------------------------------------- | :-------------------- | :------- |\n| `useDataAttribute` | `string`  | To customize the string after `data-`                                                                     | `\"to-scrollspy-id\"`   | no       |\n| `activeClass`      | `string`  | To customize the `class` added when the `Element` in view                                                 | `\"active-scroll-spy\"` | no       |\n| `useBoxMethod`     | `boolean` | Set to `false` if you want your spy to be active only if more than `50%` of that `div` is in the viewport | `true`                | no       |\n| `updateHistoryStack` | `boolean` | Set to `false` to disable the URL getting automatically updated when scrolling                          | `true`                | no\n\n##\n\n## 📝 Authors\n\n- Hussain Pettiwala ([@pettiboy](https://github.com/pettiboy))\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpettiboy%2Freact-ui-scrollspy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpettiboy%2Freact-ui-scrollspy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpettiboy%2Freact-ui-scrollspy/lists"}