react-native-app-onboard 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/LICENSE +20 -0
  2. package/README.md +187 -0
  3. package/lib/commonjs/components/CustomPages.js +134 -0
  4. package/lib/commonjs/components/CustomPages.js.map +1 -0
  5. package/lib/commonjs/components/OnboardingPages.js +157 -0
  6. package/lib/commonjs/components/OnboardingPages.js.map +1 -0
  7. package/lib/commonjs/components/Page.js +60 -0
  8. package/lib/commonjs/components/Page.js.map +1 -0
  9. package/lib/commonjs/components/Pagination.js +94 -0
  10. package/lib/commonjs/components/Pagination.js.map +1 -0
  11. package/lib/commonjs/components/Swiper.js +56 -0
  12. package/lib/commonjs/components/Swiper.js.map +1 -0
  13. package/lib/commonjs/components/button.js +57 -0
  14. package/lib/commonjs/components/button.js.map +1 -0
  15. package/lib/commonjs/components/index.js +17 -0
  16. package/lib/commonjs/components/index.js.map +1 -0
  17. package/lib/commonjs/context/OnboardingContext.js +65 -0
  18. package/lib/commonjs/context/OnboardingContext.js.map +1 -0
  19. package/lib/commonjs/hooks/useOnboarding.js +18 -0
  20. package/lib/commonjs/hooks/useOnboarding.js.map +1 -0
  21. package/lib/commonjs/index.js +26 -0
  22. package/lib/commonjs/index.js.map +1 -0
  23. package/lib/commonjs/types/index.js +6 -0
  24. package/lib/commonjs/types/index.js.map +1 -0
  25. package/lib/module/components/CustomPages.js +126 -0
  26. package/lib/module/components/CustomPages.js.map +1 -0
  27. package/lib/module/components/OnboardingPages.js +147 -0
  28. package/lib/module/components/OnboardingPages.js.map +1 -0
  29. package/lib/module/components/Page.js +53 -0
  30. package/lib/module/components/Page.js.map +1 -0
  31. package/lib/module/components/Pagination.js +87 -0
  32. package/lib/module/components/Pagination.js.map +1 -0
  33. package/lib/module/components/Swiper.js +48 -0
  34. package/lib/module/components/Swiper.js.map +1 -0
  35. package/lib/module/components/button.js +49 -0
  36. package/lib/module/components/button.js.map +1 -0
  37. package/lib/module/components/index.js +2 -0
  38. package/lib/module/components/index.js.map +1 -0
  39. package/lib/module/context/OnboardingContext.js +57 -0
  40. package/lib/module/context/OnboardingContext.js.map +1 -0
  41. package/lib/module/hooks/useOnboarding.js +10 -0
  42. package/lib/module/hooks/useOnboarding.js.map +1 -0
  43. package/lib/module/index.js +13 -0
  44. package/lib/module/index.js.map +1 -0
  45. package/lib/module/types/index.js +2 -0
  46. package/lib/module/types/index.js.map +1 -0
  47. package/lib/typescript/src/components/CustomPages.d.ts +21 -0
  48. package/lib/typescript/src/components/CustomPages.d.ts.map +1 -0
  49. package/lib/typescript/src/components/OnboardingPages.d.ts +15 -0
  50. package/lib/typescript/src/components/OnboardingPages.d.ts.map +1 -0
  51. package/lib/typescript/src/components/Page.d.ts +17 -0
  52. package/lib/typescript/src/components/Page.d.ts.map +1 -0
  53. package/lib/typescript/src/components/Pagination.d.ts +29 -0
  54. package/lib/typescript/src/components/Pagination.d.ts.map +1 -0
  55. package/lib/typescript/src/components/Swiper.d.ts +4 -0
  56. package/lib/typescript/src/components/Swiper.d.ts.map +1 -0
  57. package/lib/typescript/src/components/button.d.ts +12 -0
  58. package/lib/typescript/src/components/button.d.ts.map +1 -0
  59. package/lib/typescript/src/components/index.d.ts +2 -0
  60. package/lib/typescript/src/components/index.d.ts.map +1 -0
  61. package/lib/typescript/src/context/OnboardingContext.d.ts +28 -0
  62. package/lib/typescript/src/context/OnboardingContext.d.ts.map +1 -0
  63. package/lib/typescript/src/hooks/useOnboarding.d.ts +12 -0
  64. package/lib/typescript/src/hooks/useOnboarding.d.ts.map +1 -0
  65. package/lib/typescript/src/index.d.ts +5 -0
  66. package/lib/typescript/src/index.d.ts.map +1 -0
  67. package/lib/typescript/src/types/index.d.ts +42 -0
  68. package/lib/typescript/src/types/index.d.ts.map +1 -0
  69. package/package.json +160 -0
  70. package/src/components/CustomPages.tsx +160 -0
  71. package/src/components/OnboardingPages.tsx +173 -0
  72. package/src/components/Page.tsx +90 -0
  73. package/src/components/Pagination.tsx +151 -0
  74. package/src/components/Swiper.tsx +56 -0
  75. package/src/components/button.tsx +74 -0
  76. package/src/components/index.ts +1 -0
  77. package/src/context/OnboardingContext.tsx +95 -0
  78. package/src/hooks/useOnboarding.tsx +12 -0
  79. package/src/index.tsx +18 -0
  80. package/src/types/index.ts +40 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Pagination.d.ts","sourceRoot":"","sources":["../../../../src/components/Pagination.tsx"],"names":[],"mappings":"AAAA,OAAO,EAEL,QAAQ,EAER,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAI1B,KAAK,WAAW,GAAG;IACjB,aAAa,EAAE,QAAQ,CAAC,KAAK,CAAC;IAC9B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IACrC,wBAAwB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAChD,yBAAyB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjD,wBAAwB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAChD,kBAAkB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC1C,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,kBAAkB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IACtC,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;CACrB,CAAC;AAEF,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,qBA4E5C"}
@@ -0,0 +1,4 @@
1
+ import React from 'react';
2
+ import type { OnboardingProps } from '../types';
3
+ export declare const Swiper: React.FC<OnboardingProps>;
4
+ //# sourceMappingURL=Swiper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Swiper.d.ts","sourceRoot":"","sources":["../../../../src/components/Swiper.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAK1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAEhD,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,eAAe,CAgD5C,CAAC"}
@@ -0,0 +1,12 @@
1
+ import { type StyleProp, type TextStyle, type ViewStyle } from 'react-native';
2
+ import React from 'react';
3
+ type ButtonProps = {
4
+ onPress?: () => void;
5
+ label?: string | React.ReactNode;
6
+ color?: string;
7
+ buttonStyle?: StyleProp<ViewStyle>;
8
+ buttonTextStyle?: StyleProp<TextStyle>;
9
+ };
10
+ export declare const Button: (props: ButtonProps) => number | boolean | Iterable<React.ReactNode> | React.JSX.Element | null | undefined;
11
+ export {};
12
+ //# sourceMappingURL=button.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"button.d.ts","sourceRoot":"","sources":["../../../../src/components/button.tsx"],"names":[],"mappings":"AAAA,OAAO,EAIL,KAAK,SAAS,EACd,KAAK,SAAS,EACd,KAAK,SAAS,EACf,MAAM,cAAc,CAAC;AACtB,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,KAAK,WAAW,GAAG;IACjB,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,KAAK,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IACjC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACnC,eAAe,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;CACxC,CAAC;AAEF,eAAO,MAAM,MAAM,UAAW,WAAW,wFAkBxC,CAAC"}
@@ -0,0 +1,2 @@
1
+ export * from './Swiper';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/components/index.ts"],"names":[],"mappings":"AAAA,cAAc,UAAU,CAAC"}
@@ -0,0 +1,28 @@
1
+ import React from 'react';
2
+ import { type FlatList } from 'react-native';
3
+ export type SliderProps = {
4
+ currentPage: number;
5
+ numberOfScreens: number;
6
+ nextPage: (animated?: boolean) => void;
7
+ scrollTo: (index: number, animated?: boolean) => void;
8
+ };
9
+ type OnboardingContextType = SliderProps & {
10
+ setCurrentPage: (index: number) => void;
11
+ flatListRef: React.RefObject<FlatList>;
12
+ width?: number;
13
+ numberOfScreens: number;
14
+ progress: number;
15
+ scrollEnabled?: boolean;
16
+ enableScroll: React.Dispatch<React.SetStateAction<boolean | undefined>>;
17
+ isDone: boolean;
18
+ };
19
+ type OnboardingProviderProps = {
20
+ children: React.ReactNode;
21
+ width?: number;
22
+ numberOfScreens: number;
23
+ scrollEnabled?: boolean;
24
+ };
25
+ export declare const OnboardingContext: React.Context<OnboardingContextType | undefined>;
26
+ export declare const OnboardingProvider: React.FC<OnboardingProviderProps>;
27
+ export {};
28
+ //# sourceMappingURL=OnboardingContext.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"OnboardingContext.d.ts","sourceRoot":"","sources":["../../../../src/context/OnboardingContext.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,EAAc,KAAK,QAAQ,EAAE,MAAM,cAAc,CAAC;AAEzD,MAAM,MAAM,WAAW,GAAG;IACxB,WAAW,EAAE,MAAM,CAAC;IACpB,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,CAAC,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,OAAO,KAAK,IAAI,CAAC;CACvD,CAAC;AAEF,KAAK,qBAAqB,GAAG,WAAW,GAAG;IACzC,cAAc,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,WAAW,EAAE,KAAK,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;IACvC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC,cAAc,CAAC,OAAO,GAAG,SAAS,CAAC,CAAC,CAAC;IACxE,MAAM,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,uBAAuB,GAAG;IAC7B,QAAQ,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,CAAC;AAEF,eAAO,MAAM,iBAAiB,kDAElB,CAAC;AAEb,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CA8DhE,CAAC"}
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ export declare const useOnboarding: () => import("../context/OnboardingContext").SliderProps & {
3
+ setCurrentPage: (index: number) => void;
4
+ flatListRef: React.RefObject<import("react-native").FlatList<any>>;
5
+ width?: number | undefined;
6
+ numberOfScreens: number;
7
+ progress: number;
8
+ scrollEnabled?: boolean | undefined;
9
+ enableScroll: React.Dispatch<React.SetStateAction<boolean | undefined>>;
10
+ isDone: boolean;
11
+ };
12
+ //# sourceMappingURL=useOnboarding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useOnboarding.d.ts","sourceRoot":"","sources":["../../../../src/hooks/useOnboarding.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,eAAO,MAAM,aAAa;;;;;;;;;CAQzB,CAAC"}
@@ -0,0 +1,5 @@
1
+ import React from 'react';
2
+ import type { OnboardingProps } from './types';
3
+ export { useOnboarding } from './hooks/useOnboarding';
4
+ export declare function Onboarding(props: OnboardingProps): React.JSX.Element;
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAE/C,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAEtD,wBAAgB,UAAU,CAAC,KAAK,EAAE,eAAe,qBAUhD"}
@@ -0,0 +1,42 @@
1
+ /// <reference types="react" />
2
+ import type { StyleProp, TextStyle, ViewStyle } from 'react-native';
3
+ import type { Page } from '../components/Page';
4
+ export type OnboardingProps = {
5
+ children?: React.ReactNode[];
6
+ nextLabel?: string | React.ReactNode;
7
+ skipLabel?: string | React.ReactNode;
8
+ doneLabel?: string | React.ReactNode;
9
+ showSkip?: boolean;
10
+ showNext?: boolean;
11
+ showDone?: boolean;
12
+ onDone?: () => void;
13
+ onSkip?: () => void;
14
+ showPagination?: boolean;
15
+ scrollEnabled?: boolean;
16
+ customFooter?: (props: {
17
+ nextPage: () => void;
18
+ }) => React.ReactNode;
19
+ paginationContainerStyle?: StyleProp<ViewStyle>;
20
+ buttonRightContainerStyle?: StyleProp<ViewStyle>;
21
+ buttonLeftContainerStyle?: StyleProp<ViewStyle>;
22
+ dotsContainerStyle?: StyleProp<ViewStyle>;
23
+ doneLabelStyle?: StyleProp<TextStyle>;
24
+ skipLabelStyle?: StyleProp<TextStyle>;
25
+ nextLabelStyle?: StyleProp<TextStyle>;
26
+ containerStyle?: StyleProp<ViewStyle>;
27
+ imageContainerStyle?: StyleProp<ViewStyle>;
28
+ titleContainerStyle?: StyleProp<ViewStyle>;
29
+ titleStyle?: StyleProp<TextStyle>;
30
+ subtitleStyle?: StyleProp<TextStyle>;
31
+ paginationPosition?: 'top' | 'bottom';
32
+ scrollAnimationDuration?: number;
33
+ useNativeDriver?: boolean;
34
+ width?: number;
35
+ color?: string;
36
+ pages?: Page[];
37
+ } & ({
38
+ children?: React.ReactNode[];
39
+ } | {
40
+ pages: Page[];
41
+ });
42
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/types/index.ts"],"names":[],"mappings":";AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AACpE,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAC;AAE/C,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IACrC,SAAS,CAAC,EAAE,MAAM,GAAG,KAAK,CAAC,SAAS,CAAC;IACrC,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,IAAI,CAAC;IACpB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE;QAAE,QAAQ,EAAE,MAAM,IAAI,CAAA;KAAE,KAAK,KAAK,CAAC,SAAS,CAAC;IACpE,wBAAwB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAChD,yBAAyB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACjD,wBAAwB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAChD,kBAAkB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC1C,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,cAAc,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACtC,mBAAmB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC3C,mBAAmB,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAC3C,UAAU,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IAClC,aAAa,CAAC,EAAE,SAAS,CAAC,SAAS,CAAC,CAAC;IACrC,kBAAkB,CAAC,EAAE,KAAK,GAAG,QAAQ,CAAC;IACtC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;CAChB,GAAG,CACA;IACE,QAAQ,CAAC,EAAE,KAAK,CAAC,SAAS,EAAE,CAAC;CAC9B,GACD;IAAE,KAAK,EAAE,IAAI,EAAE,CAAA;CAAE,CACpB,CAAC"}
package/package.json ADDED
@@ -0,0 +1,160 @@
1
+ {
2
+ "name": "react-native-app-onboard",
3
+ "version": "0.1.1",
4
+ "description": "React Native App Onboard is a customizable, easy-to-use, and efficient library for creating compelling onboarding experiences for your React Native applications. It provides smooth, fluid transitions and animations, with a focus on simplicity and usability.",
5
+ "main": "lib/commonjs/index",
6
+ "module": "lib/module/index",
7
+ "types": "lib/typescript/src/index.d.ts",
8
+ "react-native": "src/index",
9
+ "source": "src/index",
10
+ "files": [
11
+ "src",
12
+ "lib",
13
+ "android",
14
+ "ios",
15
+ "cpp",
16
+ "*.podspec",
17
+ "!ios/build",
18
+ "!android/build",
19
+ "!android/gradle",
20
+ "!android/gradlew",
21
+ "!android/gradlew.bat",
22
+ "!android/local.properties",
23
+ "!**/__tests__",
24
+ "!**/__fixtures__",
25
+ "!**/__mocks__",
26
+ "!**/.*"
27
+ ],
28
+ "scripts": {
29
+ "example": "yarn workspace react-native-app-onboard-example",
30
+ "test": "jest",
31
+ "typecheck": "tsc --noEmit",
32
+ "lint": "eslint \"**/*.{js,ts,tsx}\"",
33
+ "clean": "del-cli lib",
34
+ "prepare": "bob build",
35
+ "release": "release-it"
36
+ },
37
+ "keywords": [
38
+ "react-native",
39
+ "ios",
40
+ "android"
41
+ ],
42
+ "repository": {
43
+ "type": "git",
44
+ "url": "git+https://github.com/julekgwa/react-native-app-onboard.git"
45
+ },
46
+ "author": "Junius Lekgwara <phutigravel@gmail.com> (https://github.com/julekgwa)",
47
+ "license": "MIT",
48
+ "bugs": {
49
+ "url": "https://github.com/julekgwa/react-native-app-onboard/issues"
50
+ },
51
+ "homepage": "https://github.com/julekgwa/react-native-app-onboard#readme",
52
+ "publishConfig": {
53
+ "registry": "https://registry.npmjs.org/"
54
+ },
55
+ "devDependencies": {
56
+ "@commitlint/config-conventional": "^17.0.2",
57
+ "@evilmartians/lefthook": "^1.5.0",
58
+ "@react-native/eslint-config": "^0.73.1",
59
+ "@release-it/conventional-changelog": "^5.0.0",
60
+ "@types/jest": "^29.5.5",
61
+ "@types/react": "^18.2.44",
62
+ "@types/tinycolor2": "^1.4.6",
63
+ "commitlint": "^17.0.2",
64
+ "del-cli": "^5.1.0",
65
+ "eslint": "^8.51.0",
66
+ "eslint-config-prettier": "^9.0.0",
67
+ "eslint-plugin-prettier": "^5.0.1",
68
+ "jest": "^29.7.0",
69
+ "prettier": "^3.0.3",
70
+ "react": "18.2.0",
71
+ "react-native": "0.74.2",
72
+ "react-native-builder-bob": "^0.20.0",
73
+ "release-it": "^15.0.0",
74
+ "typescript": "^5.2.2"
75
+ },
76
+ "resolutions": {
77
+ "@types/react": "^18.2.44"
78
+ },
79
+ "peerDependencies": {
80
+ "react": "*",
81
+ "react-native": "*"
82
+ },
83
+ "packageManager": "yarn@3.6.1",
84
+ "jest": {
85
+ "preset": "react-native",
86
+ "modulePathIgnorePatterns": [
87
+ "<rootDir>/example/node_modules",
88
+ "<rootDir>/lib/"
89
+ ]
90
+ },
91
+ "commitlint": {
92
+ "extends": [
93
+ "@commitlint/config-conventional"
94
+ ]
95
+ },
96
+ "release-it": {
97
+ "git": {
98
+ "commitMessage": "chore: release ${version}",
99
+ "tagName": "v${version}"
100
+ },
101
+ "npm": {
102
+ "publish": true
103
+ },
104
+ "github": {
105
+ "release": true
106
+ },
107
+ "plugins": {
108
+ "@release-it/conventional-changelog": {
109
+ "preset": "angular"
110
+ }
111
+ }
112
+ },
113
+ "eslintConfig": {
114
+ "root": true,
115
+ "extends": [
116
+ "@react-native",
117
+ "prettier"
118
+ ],
119
+ "rules": {
120
+ "prettier/prettier": [
121
+ "error",
122
+ {
123
+ "quoteProps": "consistent",
124
+ "singleQuote": true,
125
+ "tabWidth": 2,
126
+ "trailingComma": "es5",
127
+ "useTabs": false
128
+ }
129
+ ]
130
+ }
131
+ },
132
+ "eslintIgnore": [
133
+ "node_modules/",
134
+ "lib/"
135
+ ],
136
+ "prettier": {
137
+ "quoteProps": "consistent",
138
+ "singleQuote": true,
139
+ "tabWidth": 2,
140
+ "trailingComma": "es5",
141
+ "useTabs": false
142
+ },
143
+ "react-native-builder-bob": {
144
+ "source": "src",
145
+ "output": "lib",
146
+ "targets": [
147
+ "commonjs",
148
+ "module",
149
+ [
150
+ "typescript",
151
+ {
152
+ "project": "tsconfig.build.json"
153
+ }
154
+ ]
155
+ ]
156
+ },
157
+ "dependencies": {
158
+ "tinycolor2": "^1.6.0"
159
+ }
160
+ }
@@ -0,0 +1,160 @@
1
+ import { View, Dimensions, Animated, StyleSheet, FlatList } from 'react-native';
2
+ import React from 'react';
3
+ import { Pagination } from './Pagination';
4
+ import type { OnboardingProps } from '../types';
5
+
6
+ const { width } = Dimensions.get('window');
7
+
8
+ type CustomPagesProps = OnboardingProps & {
9
+ children?: React.ReactNode[];
10
+ currentPage: number;
11
+ setPage: (newPageIndex: number) => void;
12
+ flatListRef: React.RefObject<FlatList>;
13
+ scrollX: Animated.Value;
14
+ nextPage: () => void;
15
+ numberOfScreens: number;
16
+ };
17
+
18
+ export type SliderProps = {
19
+ index?: number;
20
+ currentPage: number;
21
+ numberOfScreens: number;
22
+ nextPage: () => void;
23
+ };
24
+
25
+ export const CustomPages = ({
26
+ showPagination = true,
27
+ ...props
28
+ }: CustomPagesProps) => {
29
+ return (
30
+ <View style={[styles.container]}>
31
+ {showPagination && props.paginationPosition === 'top' && (
32
+ <>
33
+ {showPagination &&
34
+ props.customFooter &&
35
+ props.customFooter({ nextPage: props.nextPage })}
36
+ {!props.customFooter && (
37
+ <Pagination
38
+ color={'#fff'}
39
+ backgroundColor={'#333'}
40
+ width={width}
41
+ onNext={props.nextPage}
42
+ onSkip={props.onSkip}
43
+ onDone={props.onDone}
44
+ showDone={props.showDone}
45
+ animatedValue={props.scrollX}
46
+ showSkip={props.showSkip}
47
+ numberOfScreens={props.numberOfScreens}
48
+ skipLabel={props.skipLabel}
49
+ nextLabel={props.nextLabel}
50
+ doneLabel={props.doneLabel}
51
+ paginationContainerStyle={props.paginationContainerStyle}
52
+ buttonRightContainerStyle={props.buttonRightContainerStyle}
53
+ buttonLeftContainerStyle={props.buttonLeftContainerStyle}
54
+ dotsContainerStyle={props.dotsContainerStyle}
55
+ doneLabelStyle={props.doneLabelStyle}
56
+ skipLabelStyle={props.skipLabelStyle}
57
+ nextLabelStyle={props.nextLabelStyle}
58
+ />
59
+ )}
60
+ </>
61
+ )}
62
+ <Animated.FlatList
63
+ ref={props.flatListRef}
64
+ data={React.Children.toArray(props.children)}
65
+ horizontal
66
+ pagingEnabled
67
+ showsHorizontalScrollIndicator={false}
68
+ scrollEnabled={props.scrollEnabled}
69
+ onScroll={Animated.event(
70
+ [{ nativeEvent: { contentOffset: { x: props.scrollX } } }],
71
+ { useNativeDriver: false }
72
+ )}
73
+ scrollEventThrottle={1}
74
+ onMomentumScrollEnd={(event) => {
75
+ const pageIndex = Math.round(
76
+ event.nativeEvent.contentOffset.x / width
77
+ );
78
+ props.setPage(pageIndex || 0);
79
+ }}
80
+ keyExtractor={(_, index) => index.toString()}
81
+ renderItem={({ item, index }) => {
82
+ return React.cloneElement(
83
+ item as React.ReactElement<SliderProps>,
84
+ {
85
+ currentPage: props.currentPage,
86
+ numberOfScreens: props.numberOfScreens,
87
+ nextPage: props.nextPage,
88
+ index,
89
+ } as SliderProps
90
+ );
91
+ }}
92
+ />
93
+
94
+ {showPagination && props.paginationPosition !== 'top' && (
95
+ <>
96
+ {showPagination &&
97
+ props.customFooter &&
98
+ props.customFooter({ nextPage: props.nextPage })}
99
+ {!props.customFooter && (
100
+ <Pagination
101
+ color={'#fff'}
102
+ backgroundColor={'#333'}
103
+ width={width}
104
+ onNext={props.nextPage}
105
+ onSkip={props.onSkip}
106
+ onDone={props.onDone}
107
+ showDone={props.showDone}
108
+ animatedValue={props.scrollX}
109
+ showSkip={props.showSkip}
110
+ numberOfScreens={props.numberOfScreens}
111
+ skipLabel={props.skipLabel}
112
+ nextLabel={props.nextLabel}
113
+ doneLabel={props.doneLabel}
114
+ paginationContainerStyle={props.paginationContainerStyle}
115
+ buttonRightContainerStyle={props.buttonRightContainerStyle}
116
+ buttonLeftContainerStyle={props.buttonLeftContainerStyle}
117
+ dotsContainerStyle={props.dotsContainerStyle}
118
+ doneLabelStyle={props.doneLabelStyle}
119
+ skipLabelStyle={props.skipLabelStyle}
120
+ nextLabelStyle={props.nextLabelStyle}
121
+ />
122
+ )}
123
+ </>
124
+ )}
125
+ </View>
126
+ );
127
+ };
128
+
129
+ const styles = StyleSheet.create({
130
+ container: {
131
+ flex: 1,
132
+ justifyContent: 'center',
133
+ alignItems: 'center',
134
+ },
135
+ screen: {
136
+ width,
137
+ justifyContent: 'center',
138
+ alignItems: 'center',
139
+ backgroundColor: 'blue',
140
+ },
141
+ pagination: {
142
+ flexDirection: 'row',
143
+ alignItems: 'center',
144
+ paddingVertical: 10,
145
+ paddingHorizontal: 20,
146
+ width,
147
+ },
148
+ dot: {
149
+ height: 10,
150
+ width: 10,
151
+ borderRadius: 5,
152
+ backgroundColor: '#333',
153
+ margin: 5,
154
+ },
155
+ dotsContainer: {
156
+ flexDirection: 'row',
157
+ flex: 1,
158
+ justifyContent: 'center',
159
+ },
160
+ });
@@ -0,0 +1,173 @@
1
+ import React, { useRef } from 'react';
2
+ import tinycolor from 'tinycolor2';
3
+ import { Animated, StyleSheet, Dimensions, FlatList } from 'react-native';
4
+ import { Pagination } from './Pagination';
5
+ import { OnboardingPage, type Page } from './Page';
6
+ import type { OnboardingProps } from '../types';
7
+
8
+ const { width } = Dimensions.get('window');
9
+
10
+ type Props = OnboardingProps & {
11
+ pages: Page[];
12
+ currentPage: number;
13
+ setPage: (newPageIndex: number) => void;
14
+ flatListRef: React.RefObject<FlatList>;
15
+ scrollX: Animated.Value;
16
+ nextPage: () => void;
17
+ };
18
+
19
+ export const OnboardingPages = ({ showPagination = true, ...props }: Props) => {
20
+ const backgroundColorAnim = useRef(new Animated.Value(0)).current;
21
+ const [previousPage, setPreviousPage] = React.useState(0);
22
+ const currentPage_ = props.pages[props.currentPage];
23
+ const currentBackgroundColor = currentPage_?.backgroundColor || '';
24
+ const isLight = tinycolor(currentBackgroundColor).getBrightness() > 180;
25
+ const footerBackgroundColor = isLight
26
+ ? tinycolor(currentBackgroundColor).darken(30).toString()
27
+ : tinycolor(currentBackgroundColor).lighten(30).toString();
28
+ const color =
29
+ tinycolor(footerBackgroundColor).getBrightness() > 180
30
+ ? tinycolor(footerBackgroundColor).darken(60).toString()
31
+ : tinycolor(footerBackgroundColor).lighten(60).toString();
32
+
33
+ const previousBackgroundColor =
34
+ props.pages[previousPage]?.backgroundColor || 'white';
35
+ // Interpolating background color based on backgroundColorAnim value
36
+ const interpolatedBackgroundColor = backgroundColorAnim.interpolate({
37
+ inputRange: [0, 1],
38
+ outputRange: [currentBackgroundColor, previousBackgroundColor],
39
+ extrapolate: 'clamp',
40
+ });
41
+
42
+ const setPage_ = (newPageIndex: number) => {
43
+ setPreviousPage(props.currentPage);
44
+ props.setPage(newPageIndex);
45
+ };
46
+
47
+ return (
48
+ <Animated.View
49
+ style={[
50
+ styles.container,
51
+ {
52
+ backgroundColor: interpolatedBackgroundColor,
53
+ },
54
+ ]}
55
+ >
56
+ {props.paginationPosition === 'top' && (
57
+ <>
58
+ {showPagination &&
59
+ props.customFooter &&
60
+ props.customFooter({ nextPage: props.nextPage })}
61
+ {!props.customFooter && (
62
+ <Pagination
63
+ width={width}
64
+ onNext={props.nextPage}
65
+ onSkip={props.onSkip}
66
+ color={color}
67
+ onDone={props.onDone}
68
+ showDone={props.showDone}
69
+ backgroundColor={footerBackgroundColor}
70
+ animatedValue={props.scrollX}
71
+ showSkip={props.showSkip}
72
+ numberOfScreens={props.pages.length}
73
+ skipLabel={props.skipLabel}
74
+ nextLabel={props.nextLabel}
75
+ doneLabel={props.doneLabel}
76
+ paginationContainerStyle={props.paginationContainerStyle}
77
+ buttonRightContainerStyle={props.buttonRightContainerStyle}
78
+ buttonLeftContainerStyle={props.buttonLeftContainerStyle}
79
+ dotsContainerStyle={props.dotsContainerStyle}
80
+ doneLabelStyle={props.doneLabelStyle}
81
+ skipLabelStyle={props.skipLabelStyle}
82
+ nextLabelStyle={props.nextLabelStyle}
83
+ />
84
+ )}
85
+ </>
86
+ )}
87
+ <Animated.FlatList
88
+ ref={props.flatListRef}
89
+ data={props.pages}
90
+ horizontal
91
+ pagingEnabled
92
+ showsHorizontalScrollIndicator={false}
93
+ keyExtractor={(_, index) => index.toString()}
94
+ renderItem={({ item, index }) => (
95
+ <OnboardingPage color={color} width={width} key={index} {...item} />
96
+ )}
97
+ onScroll={Animated.event(
98
+ [{ nativeEvent: { contentOffset: { x: props.scrollX } } }],
99
+ { useNativeDriver: false }
100
+ )}
101
+ scrollEventThrottle={16} // Adjusted for better performance
102
+ onMomentumScrollEnd={(event) => {
103
+ const pageIndex = Math.round(
104
+ event.nativeEvent.contentOffset.x / width
105
+ );
106
+ setPage_(pageIndex || 0);
107
+ }}
108
+ />
109
+ {props.paginationPosition !== 'top' && (
110
+ <>
111
+ {showPagination &&
112
+ props.customFooter &&
113
+ props.customFooter({ nextPage: props.nextPage })}
114
+ <Pagination
115
+ width={width}
116
+ onNext={props.nextPage}
117
+ onSkip={props.onSkip}
118
+ color={color}
119
+ onDone={props.onDone}
120
+ showDone={props.showDone}
121
+ backgroundColor={footerBackgroundColor}
122
+ animatedValue={props.scrollX}
123
+ showSkip={props.showSkip}
124
+ numberOfScreens={props.pages.length}
125
+ skipLabel={props.skipLabel}
126
+ nextLabel={props.nextLabel}
127
+ doneLabel={props.doneLabel}
128
+ paginationContainerStyle={props.paginationContainerStyle}
129
+ buttonRightContainerStyle={props.buttonRightContainerStyle}
130
+ buttonLeftContainerStyle={props.buttonLeftContainerStyle}
131
+ dotsContainerStyle={props.dotsContainerStyle}
132
+ doneLabelStyle={props.doneLabelStyle}
133
+ skipLabelStyle={props.skipLabelStyle}
134
+ nextLabelStyle={props.nextLabelStyle}
135
+ />
136
+ </>
137
+ )}
138
+ </Animated.View>
139
+ );
140
+ };
141
+
142
+ const styles = StyleSheet.create({
143
+ container: {
144
+ flex: 1,
145
+ justifyContent: 'center',
146
+ alignItems: 'center',
147
+ },
148
+ screen: {
149
+ width,
150
+ justifyContent: 'center',
151
+ alignItems: 'center',
152
+ backgroundColor: 'blue',
153
+ },
154
+ pagination: {
155
+ flexDirection: 'row',
156
+ alignItems: 'center',
157
+ paddingVertical: 10,
158
+ paddingHorizontal: 20,
159
+ width,
160
+ },
161
+ dot: {
162
+ height: 10,
163
+ width: 10,
164
+ borderRadius: 5,
165
+ backgroundColor: '#333',
166
+ margin: 5,
167
+ },
168
+ dotsContainer: {
169
+ flexDirection: 'row',
170
+ flex: 1,
171
+ justifyContent: 'center',
172
+ },
173
+ });