{"id":15551360,"url":"https://github.com/pixelass/react-stickyroll","last_synced_at":"2025-08-26T15:16:32.500Z","repository":{"id":33764426,"uuid":"159015806","full_name":"pixelass/react-stickyroll","owner":"pixelass","description":"A react implementation of stickyroll (original)","archived":false,"fork":false,"pushed_at":"2023-01-03T13:34:31.000Z","size":11451,"stargazers_count":150,"open_issues_count":0,"forks_count":6,"subscribers_count":3,"default_branch":"main","last_synced_at":"2025-08-16T01:15:36.766Z","etag":null,"topics":["cross-browser","cross-device","event-listener","parallax","react","scroll","scrollable","scrollview","slideshow","sticky-elements"],"latest_commit_sha":null,"homepage":"","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/pixelass.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":".github/CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":["pixelass"],"custom":["https://paypal.me/pixelass"]}},"created_at":"2018-11-25T09:23:38.000Z","updated_at":"2024-10-08T17:19:54.000Z","dependencies_parsed_at":"2023-01-15T02:31:09.255Z","dependency_job_id":null,"html_url":"https://github.com/pixelass/react-stickyroll","commit_stats":null,"previous_names":["stickyroll/react-stickyroll"],"tags_count":16,"template":false,"template_full_name":null,"purl":"pkg:github/pixelass/react-stickyroll","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelass%2Freact-stickyroll","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelass%2Freact-stickyroll/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelass%2Freact-stickyroll/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelass%2Freact-stickyroll/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pixelass","download_url":"https://codeload.github.com/pixelass/react-stickyroll/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pixelass%2Freact-stickyroll/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":272233075,"owners_count":24896734,"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-08-26T02:00:07.904Z","response_time":60,"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":["cross-browser","cross-device","event-listener","parallax","react","scroll","scrollable","scrollview","slideshow","sticky-elements"],"created_at":"2024-10-02T14:04:33.980Z","updated_at":"2025-08-26T15:16:32.452Z","avatar_url":"https://github.com/pixelass.png","language":"TypeScript","readme":"# Stickyroll\n\n\u003cp align=\"center\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/pixelass/react-stickyroll/6fff51d8c4716410a4370e53ebe52e53996436da/resources/logo.svg\" width=\"400\" alt=\"logo\"/\u003e\u003c/p\u003e\n\n\u003cp\u003eA sticky view with scroll listener API for parallax style views.\u003c/p\u003e\n\n![Codacy coverage](https://img.shields.io/codacy/coverage/7c2869c31a824536b44725f79dcfa02e?style=for-the-badge)\n![Codacy grade](https://img.shields.io/codacy/grade/7c2869c31a824536b44725f79dcfa02e?style=for-the-badge)\n\n## Table of Contents\n\n\u003c!-- toc --\u003e\n\n- [Getting started](#getting-started)\n- [Basic usage](#basic-usage)\n- [Adjusting pages and factor usage](#adjusting-pages-and-factor-usage)\n- [Using listeners](#using-listeners)\n- [Using CSS variables](#using-css-variables)\n- [Using ClassNames](#using-classnames)\n- [Using the hook](#using-the-hook)\n- [Advanced usage](#advanced-usage)\n- [Why we don't use States](#why-we-dont-use-states)\n- [Typescript](#typescript)\n- [Testing](#testing)\n\n\u003c!-- tocstop --\u003e\n\n## Getting started\n\nPlease install stickyroll and react. Stickyroll does not have any additional dependencies.\n\n**With NPM**\n\n```shell\nnpm install @stickyroll/react react react-dom\n```\n\n**With Yarn**\n\n```shell\nyarn add @stickyroll/react react react-dom\n```\n\n## Basic usage\n\n```jsx\nimport Stickyroll from \"@stickyroll/react/stickyroll\";\n\nexport default function App() {\n  return \u003cStickyroll pages={1}\u003eScroll here.\u003c/Stickyroll\u003e;\n}\n```\n\n## Adjusting pages and factor usage\n\n```jsx\nimport Stickyroll from \"@stickyroll/react/stickyroll\";\n\nexport default function App() {\n  return (\n    // Uses 10 pages of 300vh each\n    \u003cStickyroll pages={10} factor={3}\u003e\n      Scroll here.\n    \u003c/Stickyroll\u003e\n  );\n}\n```\n\n## Using listeners\n\n```jsx\nimport Stickyroll from \"@stickyroll/react/stickyroll\";\n\nexport default function App() {\n  return (\n    \u003cStickyroll\n      pages={1}\n      onStart={() =\u003e {\n        console.log(\"onStart\");\n      }}\n      onPage={(page, index) =\u003e {\n        console.log(\"onPage\", page, index);\n      }}\n      onProgress={(progress, page, index) =\u003e {\n        console.log(\"onProgress\", progress, page, index);\n      }}\n      onEnd={() =\u003e {\n        console.log(\"onEnd\");\n      }}\n    \u003e\n      Scroll here.\n    \u003c/Stickyroll\u003e\n  );\n}\n```\n\n## Using CSS variables\n\n- height: `CSS_VARS.height`\n- pages: `CSS_VARS.pages`\n- factor: `CSS_VARS.factor`\n- progress: `CSS_VARS.progress`\n- page: `CSS_VARS.page`\n\n```jsx\nimport Stickyroll from \"@stickyroll/react/stickyroll\";\nimport { CSS_VARS } from \"@stickyroll/react/constants\";\n\nexport default function App() {\n  return (\n    \u003cStickyroll pages={1}\u003e\n      \u003cdiv\n        style={{\n          height: 10,\n          background: \"red\",\n          transform: `scaleX(var(${CSS_VARS.progress}, 0))`,\n        }}\n      /\u003e\n    \u003c/Stickyroll\u003e\n  );\n}\n```\n\n## Using ClassNames\n\n- root: `CLASS_NAMES.root`\n- above: `CLASS_NAMES.above`\n- below: `CLASS_NAMES.below`\n- sticky: `CLASS_NAMES.sticky`\n- nonSticky: `CLASS_NAMES.nonSticky`\n- page: `CLASS_NAMES.page` (`type: function`)\n\n```jsx\nimport styled from \"@emotion/styled\";\nimport Stickyroll from \"@stickyroll/react/stickyroll\";\nimport { CLASS_NAMES } from \"@stickyroll/react/constants\";\n\nconst StyledComponent = styled.div`\n  height: 10px;\n  background: red;\n\n  /* Active while in sticky mode */\n  \u0026.${CLASS_NAMES.sticky} {\n    background: yellow;\n  }\n\n  /* Active before sticky mode */\n  \u0026.${CLASS_NAMES.above} {\n    background: blue;\n  }\n\n  /* Active after sticky mode */\n  \u0026.${CLASS_NAMES.below} {\n    background: hotpink;\n  }\n\n  /* Active while on page 0 (index) */\n  \u0026.${CLASS_NAMES.page(0)} {\n    background: rebeccapurple;\n  }\n`;\n\nexport default function App() {\n  return (\n    \u003cStickyroll pages={1}\u003e\n      \u003cStyledComponent /\u003e\n    \u003c/Stickyroll\u003e\n  );\n}\n```\n\n## Using the hook\n\n```jsx\nimport { CSS_VARS, STYLE } from \"@stickyroll/react/constants\";\nimport useStickyroll from \"@stickyroll/react/use-stickyroll\";\nimport { useRef } from \"react\";\n\nexport default function App() {\n  const ref = useRef();\n  useStickyroll(ref, { pages: 1 });\n  return (\n    \u003cdiv\n      ref={ref}\n      style={{\n        height: `var(${CSS_VARS.height}, var(--100vh, 100vh))`,\n      }}\n    \u003e\n      \u003cdiv style={STYLE}\u003eScroll here.\u003c/div\u003e\n    \u003c/div\u003e\n  );\n}\n```\n\n## Advanced usage\n\nYou can provide your own styles and behavior to adjust stickyroll to your needs. Take a look at the\nexamples:\n\n- [Demo](https://react-stickyroll.vercel.app/?path=/story/examples--apple)\n- [Source](https://github.com/pixelass/react-stickyroll/blob/main/stories/examples.stories.tsx)\n\n## Why we don't use States\n\nWhile you can write the output of stickyroll to a state we recommend to work without states, to\noptimize performance.\n\nYou can access the ref (see\n[the example](https://github.com/pixelass/react-stickyroll/blob/main/stories/examples.stories.tsx))\nand modify the styles and additional behavior from there.\n\nIf you still need a state, we recommend using a global state that can then be accessed in child\ncomponents to prevent re-rendering the top level component.\n\nYou can take a look at these state management libraries or use your own preferred library:\n\n- [Zustand](https://github.com/pmndrs/zustand)\n- [Jotai](https://github.com/pmndrs/jotai)\n\n## Typescript\n\nStickyroll provides types and is fully typed. Use them, don't use them… if you ever need them, we've\ngot you covered.\n\n## Testing\n\nWe test stickyroll in real browsers with real interactions to ensure full coverage and reliability\nof this library.\n","funding_links":["https://github.com/sponsors/pixelass","https://paypal.me/pixelass"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpixelass%2Freact-stickyroll","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpixelass%2Freact-stickyroll","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpixelass%2Freact-stickyroll/lists"}