{"id":13452510,"url":"https://github.com/satya164/react-native-tab-view","last_synced_at":"2025-09-30T09:30:48.663Z","repository":{"id":37604000,"uuid":"61242660","full_name":"satya164/react-native-tab-view","owner":"satya164","description":"A cross-platform Tab View component for React Native","archived":true,"fork":false,"pushed_at":"2022-11-27T18:40:20.000Z","size":9736,"stargazers_count":5123,"open_issues_count":47,"forks_count":1060,"subscribers_count":59,"default_branch":"main","last_synced_at":"2025-09-22T06:06:20.385Z","etag":null,"topics":["hacktoberfest","pager-component","react-native","swipe","swipeview","tabbar","tabs"],"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/satya164.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-06-15T21:38:19.000Z","updated_at":"2025-09-20T14:26:48.000Z","dependencies_parsed_at":"2023-01-21T13:18:21.198Z","dependency_job_id":null,"html_url":"https://github.com/satya164/react-native-tab-view","commit_stats":null,"previous_names":["react-native-community/react-native-tab-view","satya164/react-native-tabview"],"tags_count":133,"template":false,"template_full_name":null,"purl":"pkg:github/satya164/react-native-tab-view","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/satya164%2Freact-native-tab-view","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/satya164%2Freact-native-tab-view/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/satya164%2Freact-native-tab-view/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/satya164%2Freact-native-tab-view/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/satya164","download_url":"https://codeload.github.com/satya164/react-native-tab-view/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/satya164%2Freact-native-tab-view/sbom","scorecard":{"id":765550,"data":{"date":"2025-08-11","repo":{"name":"github.com/satya164/react-native-tab-view","commit":"edb6bcc0d473c26d7029b486d7b60d706333be04"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.3,"checks":[{"name":"Maintained","score":0,"reason":"project is archived","details":["Warn: Repository is archived."],"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Code-Review","score":5,"reason":"Found 17/30 approved changesets -- score normalized to 5","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Warn: no topLevel permission defined: .github/workflows/check-labels.yml:1","Warn: no topLevel permission defined: .github/workflows/check-repro.yml:1","Warn: no topLevel permission defined: .github/workflows/expo-preview.yml:1","Warn: no topLevel permission defined: .github/workflows/expo.yml:1","Warn: no topLevel permission defined: .github/workflows/first-pull-request.yml:1","Warn: no topLevel permission defined: .github/workflows/rebase.yml:1","Warn: no topLevel permission defined: .github/workflows/stale.yml:1","Warn: no topLevel permission defined: .github/workflows/triage.yml:1","Warn: no topLevel permission defined: .github/workflows/versions.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/check-labels.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/check-labels.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/check-repro.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/check-repro.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/expo-preview.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/expo-preview.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/expo-preview.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/expo-preview.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/expo-preview.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/expo-preview.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/expo-preview.yml:25: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/expo-preview.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/expo-preview.yml:47: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/expo-preview.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/expo.yml:14: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/expo.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/expo.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/expo.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/expo.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/expo.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/expo.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/expo.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/first-pull-request.yml:8: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/first-pull-request.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/rebase.yml:13: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/rebase.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/rebase.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/rebase.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/stale.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/stale.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/triage.yml:56: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/triage.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/triage.yml:11: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/triage.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/triage.yml:26: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/triage.yml/main?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/triage.yml:41: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/triage.yml/main?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/versions.yml:10: update your workflow using https://app.stepsecurity.io/secureworkflow/satya164/react-native-tab-view/versions.yml/main?enable=pin","Info:   0 out of  16 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   4 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE.md:0","Info: FSF or OSI recognized license: MIT License: LICENSE.md:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"Branch-Protection","score":-1,"reason":"internal error: error during branchesHandler.setup: internal error: githubv4.Query: Resource not accessible by integration","details":null,"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 18 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"85 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-c2jc-4fpr-4vhg","Warn: Project is vulnerable to: GHSA-crh6-fp67-6883","Warn: Project is vulnerable to: GHSA-whgm-jr23-g3j9","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-fwr7-v2mv-hh25","Warn: Project is vulnerable to: GHSA-cph5-m8f7-6c5x","Warn: Project is vulnerable to: GHSA-wf5p-g6vw-rhxx","Warn: Project is vulnerable to: GHSA-jr5f-v2jv-69x6","Warn: Project is vulnerable to: GHSA-qwcr-r2fm-qrc7","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5","Warn: Project is vulnerable to: GHSA-pxg6-pf52-xh8x","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-6h5x-7c5m-7cr7","Warn: Project is vulnerable to: GHSA-rv95-896h-c2vc","Warn: Project is vulnerable to: GHSA-qw6h-vgh9-j6wx","Warn: Project is vulnerable to: GHSA-pw2r-vq6v-hr8c","Warn: Project is vulnerable to: GHSA-jchw-25xp-jwwc","Warn: Project is vulnerable to: GHSA-cxjh-pqwp-8mfp","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-pfrx-2q88-qq97","Warn: Project is vulnerable to: GHSA-rc47-6667-2j5j","Warn: Project is vulnerable to: GHSA-c7qv-q95q-8v27","Warn: Project is vulnerable to: GHSA-33f9-j839-rf8h","Warn: Project is vulnerable to: GHSA-c36v-fmgq-m8hx","Warn: Project is vulnerable to: GHSA-78xj-cgh5-2h22","Warn: Project is vulnerable to: GHSA-2p57-rm9w-gvfp","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-5rrq-pxf6-6jx5","Warn: Project is vulnerable to: GHSA-8fr3-hfg3-gpgp","Warn: Project is vulnerable to: GHSA-gf8q-jrpm-jvxq","Warn: Project is vulnerable to: GHSA-2r2c-g63r-vccr","Warn: Project is vulnerable to: GHSA-cfm4-qjh2-4765","Warn: Project is vulnerable to: GHSA-x4jg-mjrx-434g","Warn: Project is vulnerable to: GHSA-rp65-9cf3-cjxr","Warn: Project is vulnerable to: GHSA-76c9-3jph-rj3q","Warn: Project is vulnerable to: GHSA-9wv6-86v2-598j","Warn: Project is vulnerable to: GHSA-rhx6-c78j-4q9w","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-rxrc-rgv4-jpvx","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-m6fv-jmcg-4jfg","Warn: Project is vulnerable to: GHSA-cm22-4g7w-348p","Warn: Project is vulnerable to: GHSA-g4rg-993r-mgx7","Warn: Project is vulnerable to: GHSA-gff7-g5r8-mg8m","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-52f5-9888-hmc6","Warn: Project is vulnerable to: GHSA-fhg7-m89q-25r3","Warn: Project is vulnerable to: GHSA-wr3j-pwj9-hqq6","Warn: Project is vulnerable to: GHSA-4v9v-hfq4-rm2v","Warn: Project is vulnerable to: GHSA-9jgg-88mc-972h","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-776f-qx25-q3cc","Warn: Project is vulnerable to: GHSA-h5c3-5r3r-rr8q","Warn: Project is vulnerable to: GHSA-rmvr-2pp2-xj38","Warn: Project is vulnerable to: GHSA-xx4v-prfh-6cgc","Warn: Project is vulnerable to: GHSA-7jxr-cg7f-gpgv","Warn: Project is vulnerable to: GHSA-xj72-wvfv-8985","Warn: Project is vulnerable to: GHSA-ch3r-j5x3-6q2m","Warn: Project is vulnerable to: GHSA-p5gc-c584-jj6v","Warn: Project is vulnerable to: GHSA-whpj-8f3w-67p5","Warn: Project is vulnerable to: GHSA-cchq-frgv-rjh5","Warn: Project is vulnerable to: GHSA-g644-9gfx-q4q4","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-23T00:39:59.721Z","repository_id":37604000,"created_at":"2025-08-23T00:39:59.721Z","updated_at":"2025-08-23T00:39:59.721Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":277095803,"owners_count":25760028,"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-26T02:00:09.010Z","response_time":78,"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":["hacktoberfest","pager-component","react-native","swipe","swipeview","tabbar","tabs"],"created_at":"2024-07-31T07:01:26.143Z","updated_at":"2025-09-30T09:30:48.244Z","avatar_url":"https://github.com/satya164.png","language":"TypeScript","funding_links":[],"categories":["TypeScript","Components"],"sub_categories":["Tab"],"readme":"\u003e The repo has been moved to \u003chttps://github.com/react-navigation/react-navigation/tree/main/packages/react-native-tab-view\u003e. Please open issues and pull requests there.\n\n# React Native Tab View\n\n[![Build Status][build-badge]][build]\n[![Version][version-badge]][package]\n[![MIT License][license-badge]][license]\n\nA cross-platform Tab View component for React Native. Implemented using [`react-native-pager-view`](https://github.com/callstack/react-native-viewpager) on Android \u0026 iOS, and [PanResponder](https://reactnative.dev/docs/panresponder) on Web, macOS, and Windows.\n\n- [Run the example app to see it in action](https://expo.io/@satya164/react-native-tab-view-demos).\n- Checkout the [example/](https://github.com/satya164/react-native-tab-view/tree/main/example) folder for source code.\n\n## Features\n\n- Smooth animations and gestures\n- Scrollable tabs\n- Supports both top and bottom tab bars\n- Follows Material Design spec\n- Highly customizable\n- Fully typed with [TypeScript](https://typescriptlang.org)\n\n## Demo\n\n\u003ca href=\"https://raw.githubusercontent.com/satya164/react-native-tab-view/main/demo/demo.mp4\"\u003e\u003cimg src=\"https://raw.githubusercontent.com/satya164/react-native-tab-view/main/demo/demo.gif\" width=\"360\"\u003e\u003c/a\u003e\n\n## React Native Compatibility\n\nTo use this library you need to ensure you are using the correct version of React Native. If you are using a version of React Native that is lower than `0.63` you will need to upgrade that before attempting to use this library.\n\n| `react-native-tab-view` Version | Required React Native Version |\n| ------------------------------- | ----------------------------- |\n| `2.x.x`                         | `\u003c 0.63`                      |\n| `3.x.x`                         | `\u003e= 0.63`                     |\n\n## Installation\n\nOpen a Terminal in the project root and run:\n\n```sh\nyarn add react-native-tab-view\n```\n\nNow we need to install [`react-native-pager-view`](https://github.com/callstack/react-native-viewpager) if you plan to support iOS and Android.\n\nIf you are using Expo, to ensure that you get the compatible versions of the libraries, run:\n\n```sh\nexpo install react-native-pager-view\n```\n\nIf you are not using Expo, run the following:\n\n```sh\nyarn add react-native-pager-view\n```\n\nWe're done! Now you can build and run the app on your device/simulator.\n\n## Quick Start\n\n```js\nimport * as React from 'react';\nimport { View, useWindowDimensions } from 'react-native';\nimport { TabView, SceneMap } from 'react-native-tab-view';\n\nconst FirstRoute = () =\u003e (\n  \u003cView style={{ flex: 1, backgroundColor: '#ff4081' }} /\u003e\n);\n\nconst SecondRoute = () =\u003e (\n  \u003cView style={{ flex: 1, backgroundColor: '#673ab7' }} /\u003e\n);\n\nconst renderScene = SceneMap({\n  first: FirstRoute,\n  second: SecondRoute,\n});\n\nexport default function TabViewExample() {\n  const layout = useWindowDimensions();\n\n  const [index, setIndex] = React.useState(0);\n  const [routes] = React.useState([\n    { key: 'first', title: 'First' },\n    { key: 'second', title: 'Second' },\n  ]);\n\n  return (\n    \u003cTabView\n      navigationState={{ index, routes }}\n      renderScene={renderScene}\n      onIndexChange={setIndex}\n      initialLayout={{ width: layout.width }}\n    /\u003e\n  );\n}\n```\n\n[Try this example on Snack](https://snack.expo.io/@satya164/react-native-tab-view-quick-start)\n\n## More examples on Snack\n\n- [Custom Tab Bar](https://snack.expo.io/@satya164/react-native-tab-view-custom-tabbar)\n- [Lazy Load](https://snack.expo.io/@satya164/react-native-tab-view-lazy-load)\n\n## API reference\n\nThe package exports a `TabView` component which is the one you'd use to render the tab view, and a `TabBar` component which is the default tab bar implementation.\n\n### `TabView`\n\nContainer component responsible for rendering and managing tabs. Follows material design styles by default.\n\nBasic usage look like this:\n\n```js\n\u003cTabView\n  navigationState={{ index, routes }}\n  onIndexChange={setIndex}\n  renderScene={SceneMap({\n    first: FirstRoute,\n    second: SecondRoute,\n  })}\n/\u003e\n```\n\n#### TabView Props\n\n##### `navigationState` (`required`)\n\nState for the tab view. The state should contain the following properties:\n\n- `index`: a number representing the index of the active route in the `routes` array\n- `routes`: an array containing a list of route objects used for rendering the tabs\n\nEach route object should contain the following properties:\n\n- `key`: a unique key to identify the route (required)\n- `title`: title for the route to display in the tab bar\n- `icon`: icon for the route to display in the tab bar\n- `accessibilityLabel`: accessibility label for the tab button\n- `testID`: test id for the tab button\n\nExample:\n\n```js\n{\n  index: 1,\n  routes: [\n    { key: 'music', title: 'Music' },\n    { key: 'albums', title: 'Albums' },\n    { key: 'recents', title: 'Recents' },\n    { key: 'purchased', title: 'Purchased' },\n  ]\n}\n```\n\n`TabView` is a controlled component, which means the `index` needs to be updated via the `onIndexChange` callback.\n\n##### `onIndexChange` (`required`)\n\nCallback which is called on tab change, receives the index of the new tab as argument.\nThe navigation state needs to be updated when it's called, otherwise the change is dropped.\n\n##### `renderScene` (`required`)\n\nCallback which returns a react element to render as the page for the tab. Receives an object containing the route as the argument:\n\n```js\nconst renderScene = ({ route, jumpTo }) =\u003e {\n  switch (route.key) {\n    case 'music':\n      return \u003cMusicRoute jumpTo={jumpTo} /\u003e;\n    case 'albums':\n      return \u003cAlbumsRoute jumpTo={jumpTo} /\u003e;\n  }\n};\n```\n\nYou need to make sure that your individual routes implement a `shouldComponentUpdate` to improve the performance. To make it easier to specify the components, you can use the `SceneMap` helper.\n\n`SceneMap` takes an object with the mapping of `route.key` to React components and returns a function to use with `renderScene` prop.\n\n```js\nimport { SceneMap } from 'react-native-tab-view';\n\n...\n\nconst renderScene = SceneMap({\n  music: MusicRoute,\n  albums: AlbumsRoute,\n});\n```\n\nSpecifying the components this way is easier and takes care of implementing a `shouldComponentUpdate` method.\n\nEach scene receives the following props:\n\n- `route`: the current route rendered by the component\n- `jumpTo`: method to jump to other tabs, takes a `route.key` as it's argument\n- `position`: animated node which represents the current position\n\nThe `jumpTo` method can be used to navigate to other tabs programmatically:\n\n```js\nthis.props.jumpTo('albums');\n```\n\nAll the scenes rendered with `SceneMap` are optimized using `React.PureComponent` and don't re-render when parent's props or states change. If you need more control over how your scenes update (e.g. - triggering a re-render even if the `navigationState` didn't change), use `renderScene` directly instead of using `SceneMap`.\n\n**IMPORTANT:** **Do not** pass inline functions to `SceneMap`, for example, don't do the following:\n\n```js\nSceneMap({\n  first: () =\u003e \u003cFirstRoute foo={this.props.foo} /\u003e,\n  second: SecondRoute,\n});\n```\n\nAlways define your components elsewhere in the top level of the file. If you pass inline functions, it'll re-create the component every render, which will cause the entire route to unmount and remount every change. It's very bad for performance and will also cause any local state to be lost.\n\nIf you need to pass additional props, use a custom `renderScene` function:\n\n```js\nconst renderScene = ({ route }) =\u003e {\n  switch (route.key) {\n    case 'first':\n      return \u003cFirstRoute foo={this.props.foo} /\u003e;\n    case 'second':\n      return \u003cSecondRoute /\u003e;\n    default:\n      return null;\n  }\n};\n```\n\n##### `renderTabBar`\n\nCallback which returns a custom React Element to use as the tab bar:\n\n```js\nimport { TabBar } from 'react-native-tab-view';\n\n...\n\n\u003cTabView\n  renderTabBar={props =\u003e \u003cTabBar {...props} /\u003e}\n  ...\n/\u003e\n```\n\nIf this is not specified, the default tab bar is rendered. You pass this props to customize the default tab bar, provide your own tab bar, or disable the tab bar completely.\n\n```js\n\u003cTabView\n  renderTabBar={() =\u003e null}\n  ...\n/\u003e\n```\n\n##### `tabBarPosition`\n\nPosition of the tab bar in the tab view. Possible values are `'top'` and `'bottom'`. Defaults to `'top'`.\n\n##### `lazy`\n\nFunction which takes an object with the current route and returns a boolean to indicate whether to lazily render the scenes.\n\nBy default all scenes are rendered to provide a smoother swipe experience. But you might want to defer the rendering of unfocused scenes until the user sees them. To enable lazy rendering for a particular scene, return `true` from `getLazy` for that `route`:\n\n```js\n\u003cTabView\n  lazy={({ route }) =\u003e route.name === 'Albums'}\n  ...\n/\u003e\n```\n\nWhen you enable lazy rendering for a screen, it will usually take some time to render when it comes into focus. You can use the `renderLazyPlaceholder` prop to customize what the user sees during this short period.\n\nYou can also pass a boolean to enable lazy for all of the scenes:\n\n```js\n\u003cTabView\n  lazy\n/\u003e\n```\n\n##### `lazyPreloadDistance`\n\nWhen `lazy` is enabled, you can specify how many adjacent routes should be preloaded with this prop. This value defaults to `0` which means lazy pages are loaded as they come into the viewport.\n\n##### `renderLazyPlaceholder`\n\nCallback which returns a custom React Element to render for routes that haven't been rendered yet. Receives an object containing the route as the argument. The `lazy` prop also needs to be enabled.\n\nThis view is usually only shown for a split second. Keep it lightweight.\n\nBy default, this renders `null`.\n\n##### `keyboardDismissMode`\n\nString indicating whether the keyboard gets dismissed in response to a drag gesture. Possible values are:\n\n- `'auto'` (default): the keyboard is dismissed when the index changes.\n- `'on-drag'`: the keyboard is dismissed when a drag begins.\n- `'none'`: drags do not dismiss the keyboard.\n\n##### `swipeEnabled`\n\nBoolean indicating whether to enable swipe gestures. Swipe gestures are enabled by default. Passing `false` will disable swipe gestures, but the user can still switch tabs by pressing the tab bar.\n\n#### `animationEnabled`\n\nEnables animation when changing tab. By default it's true.\n\n##### `onSwipeStart`\n\nCallback which is called when the swipe gesture starts, i.e. the user touches the screen and moves it.\n\n##### `onSwipeEnd`\n\nCallback which is called when the swipe gesture ends, i.e. the user lifts their finger from the screen after the swipe gesture.\n\n##### `initialLayout`\n\nObject containing the initial height and width of the screens. Passing this will improve the initial rendering performance. For most apps, this is a good default:\n\n```js\n\u003cTabView\n  initialLayout={{ width: Dimensions.get('window').width }}\n  ...\n/\u003e\n```\n\n##### `sceneContainerStyle`\n\nStyle to apply to the view wrapping each screen. You can pass this to override some default styles such as overflow clipping:\n\n##### `pagerStyle`\n\nStyle to apply to the pager view wrapping all the scenes.\n\n##### `style`\n\nStyle to apply to the tab view container.\n\n### `TabBar`\n\nMaterial design themed tab bar. To customize the tab bar, you'd need to use the `renderTabBar` prop of `TabView` to render the `TabBar` and pass additional props.\n\nFor example, to customize the indicator color and the tab bar background color, you can pass `indicatorStyle` and `style` props to the `TabBar` respectively:\n\n```js\nconst renderTabBar = props =\u003e (\n  \u003cTabBar\n    {...props}\n    indicatorStyle={{ backgroundColor: 'white' }}\n    style={{ backgroundColor: 'pink' }}\n  /\u003e\n);\n\n//...\n\n\nreturn (\n  \u003cTabView\n    renderTabBar={renderTabBar}\n    ...\n  /\u003e\n);\n```\n\n#### TabBar Props\n\n##### `getLabelText`\n\nFunction which takes an object with the current route and returns the label text for the tab. Uses `route.title` by default.\n\n```js\n\u003cTabBar\n  getLabelText={({ route }) =\u003e route.title}\n  ...\n/\u003e\n```\n\n##### `getAccessible`\n\nFunction which takes an object with the current route and returns a boolean to indicate whether to mark a tab as `accessible`. Defaults to `true`.\n\n##### `getAccessibilityLabel`\n\nFunction which takes an object with the current route and returns a accessibility label for the tab button. Uses `route.accessibilityLabel` by default if specified, otherwise uses the route title.\n\n```js\n\u003cTabBar\n  getAccessibilityLabel={({ route }) =\u003e route.accessibilityLabel}\n  ...\n/\u003e\n```\n\n##### `getTestID`\n\nFunction which takes an object with the current route and returns a test id for the tab button to locate this tab button in tests. Uses `route.testID` by default.\n\n```js\n\u003cTabBar\n  getTestID={({ route }) =\u003e route.testID}\n  ...\n/\u003e\n```\n\n##### `renderIcon`\n\nFunction which takes an object with the current route, focused status and color and returns a custom React Element to be used as a icon.\n\n```js\n\u003cTabBar\n  renderIcon={({ route, focused, color }) =\u003e (\n    \u003cIcon\n      name={focused ? 'albums' : 'albums-outlined'}\n      color={color}\n    /\u003e\n  )}\n  ...\n/\u003e\n```\n\n##### `renderLabel`\n\nFunction which takes an object with the current route, focused status and color and returns a custom React Element to be used as a label.\n\n```js\n\u003cTabBar\n  renderLabel={({ route, focused, color }) =\u003e (\n    \u003cText style={{ color, margin: 8 }}\u003e\n      {route.title}\n    \u003c/Text\u003e\n  )}\n  ...\n/\u003e\n```\n\n##### `renderTabBarItem`\n\nFunction which takes a `TabBarItemProps` object and returns a custom React Element to be used as a tab button.\n\n##### `renderIndicator`\n\nFunction which takes an object with the current route and returns a custom React Element to be used as a tab indicator.\n\n##### `renderBadge`\n\nFunction which takes an object with the current route and returns a custom React Element to be used as a badge.\n\n##### `onTabPress`\n\nFunction to execute on tab press. It receives the scene for the pressed tab, useful for things like scroll to top.\n\nBy default, tab press also switches the tab. To prevent this behavior, you can call `preventDefault`:\n\n```js\n\u003cTabBar\n  onTabPress={({ route, preventDefault }) =\u003e {\n    if (route.key === 'home') {\n      preventDefault();\n\n      // Do something else\n    }\n  }}\n  ...\n/\u003e\n```\n\n##### `onTabLongPress`\n\nFunction to execute on tab long press, use for things like showing a menu with more options\n\n##### `activeColor`\n\nCustom color for icon and label in the active tab.\n\n##### `inactiveColor`\n\nCustom color for icon and label in the inactive tab.\n\n##### `pressColor`\n\nColor for material ripple (Android \u003e= 5.0 only).\n\n##### `pressOpacity`\n\nOpacity for pressed tab (iOS and Android \u003c 5.0 only).\n\n##### `scrollEnabled`\n\nBoolean indicating whether to make the tab bar scrollable.\n\nIf you set `scrollEnabled` to `true`, you should also specify a `width` in `tabStyle` to improve the initial render.\n\n##### `bounces`\n\nBoolean indicating whether the tab bar bounces when scrolling.\n\n##### `tabStyle`\n\nStyle to apply to the individual tab items in the tab bar.\n\nBy default, all tab items take up the same pre-calculated width based on the width of the container. If you want them to take their original width, you can specify `width: 'auto'` in `tabStyle`.\n\n##### `indicatorStyle`\n\nStyle to apply to the active indicator.\n\n##### `indicatorContainerStyle`\n\nStyle to apply to the container view for the indicator.\n\n##### `labelStyle`\n\nStyle to apply to the tab item label.\n\n##### `contentContainerStyle`\n\nStyle to apply to the inner container for tabs.\n\n##### `style`\n\nStyle to apply to the tab bar container.\n\n### `gap`\n\nDefine a spacing between tabs.\n\n##### `testID`\n\nTest id for the tabBar. Can be used for scrolling the tab bar in tests\n\n## Using with other libraries\n\n### [React Navigation](https://github.com/react-navigation/react-navigation)\n\nIf you want to integrate the tab view with React Navigation's navigation system, e.g. want to be able to navigate to a tab using `navigation.navigate` etc, you can use the following official integrations:\n\n- [@react-navigation/material-top-tabs](https://github.com/react-navigation/react-navigation/tree/main/packages/material-top-tabs) for React Navigation 5 \u0026 6\n- [react-navigation-tabs](https://github.com/react-navigation/react-navigation-tabs) for React Navigation 4\n\nNote that some functionalities are not available with the React Navigation 4 integration because of the limitations in React Navigation. For example, it's possible to dynamically change the rendered tabs.\n\n## Optimization Tips\n\n### Avoid unnecessary re-renders\n\nThe `renderScene` function is called every time the index changes. If your `renderScene` function is expensive, it's good idea move each route to a separate component if they don't depend on the index, and use `shouldComponentUpdate` or `React.memo` in your route components to prevent unnecessary re-renders.\n\nFor example, instead of:\n\n```js\nconst renderScene = ({ route }) =\u003e {\n  switch (route.key) {\n    case 'home':\n      return (\n        \u003cView style={styles.page}\u003e\n          \u003cAvatar /\u003e\n          \u003cNewsFeed /\u003e\n        \u003c/View\u003e\n      );\n    default:\n      return null;\n  }\n};\n```\n\nDo the following:\n\n```js\nconst renderScene = ({ route }) =\u003e {\n  switch (route.key) {\n    case 'home':\n      return \u003cHomeComponent /\u003e;\n    default:\n      return null;\n  }\n};\n```\n\nWhere `\u003cHomeComponent /\u003e` is a `PureComponent` if you're using class components:\n\n```js\nexport default class HomeComponent extends React.PureComponent {\n  render() {\n    return (\n      \u003cView style={styles.page}\u003e\n        \u003cAvatar /\u003e\n        \u003cNewsFeed /\u003e\n      \u003c/View\u003e\n    );\n  }\n}\n```\n\nOr, wrapped in `React.memo` if you're using function components:\n\n```js\nfunction HomeComponent() {\n  return (\n    \u003cView style={styles.page}\u003e\n      \u003cAvatar /\u003e\n      \u003cNewsFeed /\u003e\n    \u003c/View\u003e\n  );\n}\n\nexport default React.memo(HomeComponent);\n```\n\n### Avoid one frame delay\n\nWe need to measure the width of the container and hence need to wait before rendering some elements on the screen. If you know the initial width upfront, you can pass it in and we won't need to wait for measuring it. Most of the time, it's just the window width.\n\nFor example, pass the following `initialLayout` to `TabView`:\n\n```js\nconst initialLayout = {\n  height: 0,\n  width: Dimensions.get('window').width,\n};\n```\n\nThe tab view will still react to changes in the dimension and adjust accordingly to accommodate things like orientation change.\n\n### Optimize large number of routes\n\nIf you've a large number of routes, especially images, it can slow the animation down a lot. You can instead render a limited number of routes.\n\nFor example, do the following to render only 2 routes on each side:\n\n```js\nconst renderScene = ({ route }) =\u003e {\n  if (Math.abs(index - routes.indexOf(route)) \u003e 2) {\n    return \u003cView /\u003e;\n  }\n\n  return \u003cMySceneComponent route={route} /\u003e;\n};\n```\n\n### Avoid rendering TabView inside ScrollView\n\nNesting the `TabView` inside a vertical `ScrollView` will disable the optimizations in the `FlatList` components rendered inside the `TabView`. So avoid doing it if possible.\n\n### Use `lazy` and `renderLazyPlaceholder` props to render routes as needed\n\nThe `lazy` option is disabled by default to provide a smoother tab switching experience, but you can enable it and provide a placeholder component for a better lazy loading experience. Enabling `lazy` can improve initial load performance by rendering routes only when they come into view. Refer the [prop reference](#lazy) for more details.\n\n## Contributing\n\nWhile developing, you can run the [example app](/example/README.md) to test your changes.\n\nMake sure your code passes TypeScript and ESLint. Run the following to verify:\n\n```sh\nyarn typescript\nyarn lint\n```\n\nTo fix formatting errors, run the following:\n\n```sh\nyarn lint -- --fix\n```\n\nRemember to add tests for your change if possible.\n\n\u003c!-- badges --\u003e\n\n[build-badge]: https://img.shields.io/circleci/project/github/satya164/react-native-tab-view/main.svg?style=flat-square\n[build]: https://circleci.com/gh/satya164/react-native-tab-view\n[version-badge]: https://img.shields.io/npm/v/react-native-tab-view.svg?style=flat-square\n[package]: https://www.npmjs.com/package/react-native-tab-view\n[license-badge]: https://img.shields.io/npm/l/react-native-tab-view.svg?style=flat-square\n[license]: https://opensource.org/licenses/MIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsatya164%2Freact-native-tab-view","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsatya164%2Freact-native-tab-view","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsatya164%2Freact-native-tab-view/lists"}