{"id":13670784,"url":"https://github.com/bmcmahen/react-page-controller","last_synced_at":"2025-04-14T05:10:30.992Z","repository":{"id":34862069,"uuid":"184988374","full_name":"bmcmahen/react-page-controller","owner":"bmcmahen","description":"horizontal, swipeable gesture views for react","archived":false,"fork":false,"pushed_at":"2022-12-09T22:11:25.000Z","size":5261,"stargazers_count":41,"open_issues_count":27,"forks_count":1,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-14T03:48:34.069Z","etag":null,"topics":["carousel","gesture","react","swipeable","tabs"],"latest_commit_sha":null,"homepage":"https://codesandbox.io/embed/gesture-pagination-with-tabs-hpcst","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bmcmahen.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-05T06:21:09.000Z","updated_at":"2023-03-15T17:12:40.000Z","dependencies_parsed_at":"2023-01-15T09:45:16.079Z","dependency_job_id":null,"html_url":"https://github.com/bmcmahen/react-page-controller","commit_stats":null,"previous_names":["bmcmahen/react-gesture-view"],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmcmahen%2Freact-page-controller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmcmahen%2Freact-page-controller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmcmahen%2Freact-page-controller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bmcmahen%2Freact-page-controller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bmcmahen","download_url":"https://codeload.github.com/bmcmahen/react-page-controller/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248824681,"owners_count":21167345,"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","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":["carousel","gesture","react","swipeable","tabs"],"created_at":"2024-08-02T09:00:49.494Z","updated_at":"2025-04-14T05:10:30.956Z","avatar_url":"https://github.com/bmcmahen.png","language":"TypeScript","funding_links":[],"categories":["Uncategorized"],"sub_categories":["Uncategorized"],"readme":"\u003cdiv align=\"center\"\u003e\n \u003cimg \n    max-width=\"300px\"\n    alt=\"A demo showing views being swiped left and right.\"\n     src=\"https://raw.githubusercontent.com/bmcmahen/react-page-controller/master/demo.gif\"\u003e\n\u003c/div\u003e\n\n# react-page-controller\n\n[![npm package](https://img.shields.io/npm/v/react-page-controller/latest.svg)](https://www.npmjs.com/package/react-page-controller)\n[![Follow on Twitter](https://img.shields.io/twitter/follow/benmcmahen.svg?style=social\u0026logo=twitter)](https://twitter.com/intent/follow?screen_name=benmcmahen)\n\nReact-page-controller is a react library for providing views that can be swiped left or right. It was originally built for use in [Sancho UI](https://github.com/bmcmahen/sancho) and is inspired by the iOS library of the same name.\n\n## Features\n\n- **Built with [react-gesture-responder](https://github.com/bmcmahen/react-gesture-responder) to enable better control over gesture delegation.** This means that you can embed gesture based controls within this gesture view (or embed multiple gesture views within eachother) and delegate between them.\n- **Configurable**. Configure the animation spring, enable mouse support, use child render callbacks, etc.\n- **Optional lazy loading**.\n\n## Install\n\nInstall `react-page-controller` and its peer dependency `react-gesture-responder` using yarn or npm.\n\n```\nyarn add react-page-controller react-gesture-responder\n```\n\n## Basic usage\n\nThe gesture view should be provided with a collection of children, each representing a panel. By default, each child will be wrapped in an element wiith the recommended props. If you'd rather render the element yourself, provide a render callback for each child instead.\n\n```jsx\nimport Pager from \"react-page-controller\";\n\nfunction TabContent() {\n  const [index, setIndex] = React.useState(0);\n  return (\n    \u003cPager value={index} onRequestChange={i =\u003e setIndex(i)}\u003e\n      \u003cdiv\u003eFirst panel\u003c/div\u003e\n      \u003cdiv\u003eSecond panel\u003c/div\u003e\n      \u003cdiv\u003eThird panel\u003c/div\u003e\n      {(props, active, load) =\u003e \u003cdiv {...props}\u003efourth panel\u003c/div\u003e}\n    \u003c/Pager\u003e\n  );\n}\n```\n\n## API\n\n| Name                 | Type                              | Default Value                             | Description                                                                                             |\n| -------------------- | --------------------------------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------- |\n| value\\*              | number                            |                                           | The current index to show                                                                               |\n| onRequestChange\\*    | (value: number) =\u003e void;          |                                           | A callback for handling index changes                                                                   |\n| lazyLoad             | boolean                           | false                                     | Lazy load pane contents                                                                                 |\n| enableMouse          | boolean                           | false                                     | By default mouse gestures are not enabled                                                               |\n| enableGestures       | boolean                           | true                                      | By default gestures are enabled                                                                         |\n| animationConfig      | SpringConfig                      | { tension: 190, friction: 20, mass: 0.4 } | A react-spring config for animations                                                                    |\n| onTerminationRequest | (state) =\u003e boolean;               |                                           | Optionally prevent parent views from claiming the pan-responder. Useful for embedded gesture views      |\n| onMoveShouldSet      | (state, e, suggested) =\u003e boolean; |                                           | Optionally override the default onMoveShouldSet behaviour. Useful for embedding multiple gesture views. |\n| enableScrollLock     | boolean                           | true                                      | Lock all page scrolling when making swiping gestures. This is generally the desired behaviour.          |\n\n## Imperative API\n\nYou can use the imperative API to manually focus the active panel, which is something you'll likely want to do for accessibility reasons.\n\n```jsx\nfunction TabContent() {\n  const [index, setIndex] = React.useState(0);\n  const ref = React.useRef();\n\n  function focusCurrentIndex() {\n    ref.current.focus();\n  }\n\n  return (\n    \u003cPager ref={ref} value={index} onRequestChange={i =\u003e setIndex(i)}\u003e\n      \u003cdiv\u003eFirst panel\u003c/div\u003e\n      \u003cdiv\u003eSecond panel\u003c/div\u003e\n      \u003cdiv\u003eThird panel\u003c/div\u003e\n    \u003c/Pager\u003e\n  );\n}\n```\n\n## Embedding Views\n\nEach Pager exposes the `react-gesture-responder` `onTerminationRequest` function which allows you to negotiate between gesture views competing for the responder. Typically, you'll want the child view to prevent the parent from claiming the responder.\n\n```jsx\n\u003cPager\u003e\n  \u003cdiv\u003eLeft parent pane\u003c/div\u003e\n  \u003cPager onTerminationRequest={() =\u003e false}\u003e\n    \u003cdiv\u003echild pane\u003c/div\u003e\n    \u003cdiv\u003eanother child\u003c/div\u003e\n  \u003c/Pager\u003e\n\u003c/Pager\u003e\n```\n\nThe logic can become more sophisticated. In the gif at the top of the readme, our parent claims the responder (and prevents the child from stealing it) when showing the first child pane and moving left. The code will look something like this:\n\n```jsx\nconst [childIndex, setChildIndex] = React.useState(0);\nconst [parentIndex, setParentIndex] = React.useState(0);\n\nfunction onMoveShouldSet(state, e, suggested) {\n  if (suggested) {\n    if (parentIndex === 0 || (state.delta[0] \u003e 0 \u0026\u0026 childIndex === 0)) {\n      return true;\n    }\n  }\n\n  return false;\n}\n\nfunction onTerminationRequest(state) {\n  if (state.delta[0] \u003e 0 \u0026\u0026 childIndex === 0) {\n    return false;\n  }\n\n  return true;\n}\n\n\u003cPager\n  onMoveShouldSet={onMoveShouldSet}\n  onTerminationRequest={onTerminationRequest}\n  value={parentIndex}\n  onRequestChange={i =\u003e setParentIndex(i)}\n\u003e\n  \u003cdiv\u003eLeft parent pane\u003c/div\u003e\n  \u003cPager value={childIndex} onRequestChange={i =\u003e setChildIndex(i)}\u003e\n    \u003cdiv\u003echild pane\u003c/div\u003e\n    \u003cdiv\u003eanother child\u003c/div\u003e\n  \u003c/Pager\u003e\n\u003c/Pager\u003e;\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbmcmahen%2Freact-page-controller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbmcmahen%2Freact-page-controller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbmcmahen%2Freact-page-controller/lists"}