Skip to content

Commit d899d63

Browse files
committed
feat(hooks): implement useNavigation hook
- chore(typescript): cleanup tsconfig.json file - feat(hooks): create a context to hold componentId value - feat(hooks): create HOC to provide compoent id context - feat(hooks): create navigation helpers to reduce boilerplate - feat(hooks): create useNavigation hook to expose navigationHelpers - feat(hooks): create useComponentId hook
1 parent b491c86 commit d899d63

22 files changed

+1316
-24
lines changed

package.json

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,18 +23,26 @@
2323
"react-native-navigation": ">=6.5.0"
2424
},
2525
"scripts": {
26+
"build": "tsc",
27+
"clean:dist": "rm -rf dist",
2628
"lint": "eslint src",
27-
"build": "rm -rf ./dist && tsc",
29+
"prebuild": "yarn clean:dist",
30+
"prepare": "yarn build",
2831
"test": "jest src",
2932
"test:coverage": "jest --coverage",
3033
"release": "semantic-release"
3134
},
35+
"dependencies": {
36+
"hoist-non-react-statics": "3.3.2"
37+
},
3238
"devDependencies": {
3339
"@react-native-community/eslint-config": "2.0.0",
3440
"@semantic-release/changelog": "5.0.1",
3541
"@semantic-release/git": "9.0.0",
3642
"@semantic-release/npm": "7.0.5",
3743
"@testing-library/react-hooks": "3.4.1",
44+
"@testing-library/react-native": "7.0.1",
45+
"@types/hoist-non-react-statics": "3.3.1",
3846
"@types/jest": "26.0.9",
3947
"@types/react": "16.9.19",
4048
"@types/react-native": "0.63.6",
@@ -46,6 +54,7 @@
4654
"eslint-plugin-react-native": "3.8.1",
4755
"husky": "4.2.5",
4856
"jest": "26.2.2",
57+
"lint-staged": "10.2.11",
4958
"metro-react-native-babel-preset": "0.61.0",
5059
"prettier": "2.0.5",
5160
"react": "16.13.1",
@@ -71,10 +80,14 @@
7180
"jest": {
7281
"preset": "react-native"
7382
},
83+
"lint-staged": {
84+
"**/*.{js,jsx,ts,tsx}": "yarn eslint"
85+
},
7486
"husky": {
7587
"hooks": {
7688
"prepare-commit-msg": "exec < /dev/tty && git cz --hook || true",
77-
"pre-push": "yarn lint && yarn test"
89+
"pre-commit": "yarn lint-staged && yarn test",
90+
"pre-push": "yarn tsc && yarn lint --quiet && yarn test"
7891
}
7992
},
8093
"config": {

src/contexts/ComponentIdContext.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { createContext } from 'react'
2+
3+
const ComponentIdContext = createContext<string | undefined>(undefined)
4+
5+
export const ComponentIdProvider = ComponentIdContext.Provider
6+
export const ComponentIdConsumer = ComponentIdContext.Consumer
7+
8+
export default ComponentIdContext

src/contexts/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { default as ComponentIdContext } from './ComponentIdContext'

src/helpers/createLayout.test.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
import createLayout from './createLayout'
2+
3+
describe('createLayout', () => {
4+
it('should create a layout passing name', () => {
5+
const layout = createLayout('componentName')
6+
7+
expect(layout).toEqual({
8+
component: {
9+
name: 'componentName',
10+
},
11+
})
12+
})
13+
14+
it('should create a layout passing name and props', () => {
15+
const layout = createLayout('componentName', { prop1: 'value1' })
16+
expect(layout).toEqual({
17+
component: {
18+
name: 'componentName',
19+
passProps: {
20+
prop1: 'value1',
21+
},
22+
},
23+
})
24+
})
25+
26+
it('should create a layout passing name and options', () => {
27+
const layout = createLayout('componentName', undefined, { popGesture: true })
28+
29+
expect(layout).toEqual({
30+
component: {
31+
name: 'componentName',
32+
options: {
33+
popGesture: true,
34+
},
35+
},
36+
})
37+
})
38+
39+
it('should create a layout passing name props and options', () => {
40+
const layout = createLayout('componentName', { prop1: 'value1' }, { popGesture: true })
41+
42+
expect(layout).toEqual({
43+
component: {
44+
name: 'componentName',
45+
passProps: {
46+
prop1: 'value1',
47+
},
48+
options: {
49+
popGesture: true,
50+
},
51+
},
52+
})
53+
})
54+
55+
it('should create a layout and remove the passProps and options when fields are null', () => {
56+
const layout = createLayout('componentName', null, null)
57+
58+
expect(layout).toEqual({
59+
component: {
60+
name: 'componentName',
61+
},
62+
})
63+
})
64+
})

src/helpers/createLayout.ts

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { Options, Layout } from 'react-native-navigation'
2+
3+
/**
4+
* Creates basic navigation Layout only with component field.
5+
* [more info](https://wix.github.io/react-native-navigation/api/layout-component)
6+
*/
7+
function createLayout<P>(
8+
/**
9+
* Name of your component
10+
*/
11+
name: string,
12+
/**
13+
* Properties to pass down to the component
14+
*/
15+
passProps?: P,
16+
/**
17+
* Styling options
18+
*/
19+
options?: Options
20+
): Layout<P> {
21+
return {
22+
component: {
23+
name,
24+
passProps: passProps ? passProps : undefined,
25+
options: options ? options : undefined,
26+
},
27+
}
28+
}
29+
30+
export default createLayout

0 commit comments

Comments
 (0)