UX Enhancer
npm install @karrotframe/navigator


Light-weight stack navigator for React
- 🗂 History support
- 💅 Beautiful page transition animation designed for each platform (Android/iOS)
- ⚙️ Navigation bar designed for each platform
- 🪄 Automatically attach close or back button for each circumstance
> Core logic of Navigator depends on react-router-dom
---
- Setup
- Support old versions
- Components
- Navigator
- Screen
- ScreenHelmet
- Hooks
- useNavigator
- useCurrentScreen
- useParams
- useQueryParams
- Advance
- Nested Routes
- await push()
- react-router-dom APIs
---
``bash`
$ yarn add @karrotframe/navigator
Should import the CSS of your app
`typescript
import '@karrotframe/navigator/index.css'
import { ... } from '@karrotframe/navigator'
`
Now, @karrotframe/navigator is provided from version 0.23.2 or higher.
If you need old versions from version 0.23.1 to lower, you should use @karrotframe/navigator-legacy instead. Link
It is recommended that you should update to the latest version because it would have a subtle difference for @karrotframe/navigator-legacy.
And yarn add command would be helpful, if you decide to use @karrotframe/navigator-legacy instead of @karrotframe/navigator.
The Navigator component includes elements that are necessary to express the screen. Please include it at the top of the component tree
> All the props is typed and commented in TypeScript
`tsx
import { Navigator } from '@karrotframe/navigator'
const App: React.FC = () => {
return (
onClose={() => {
console.log('Close button is pressed')
}}
>
{/.../}
)
}
`
> If you use the useCustomRouter option, you can provide a router other than HashRouter.
`tsx
import { Navigator } from '@karrotframe/navigator'
import { HashRouter } from 'react-router-dom'
const App = () => {
return (
)
}
`
The Screen component is used to declare a screen. Declare it inside Navigator.
> All the props is typed and commented in TypeScript
`tsx
import { Navigator, Screen } from '@karrotframe/navigator'
const App: React.FC = () => {
return (
onClose={() => {
console.log('Close button is pressed')
}}
>
{/ or /}
)
}
`
Be sure to use component or children (if both props are declared at the same time, component takes precedence)
By default, Screen does not include a top navigation bar. To add or modify the built-in top navigation bar, use the ScreenHelmet component.
> All the props is typed and commented in TypeScript
`tsx
import { ScreenHelmet } from '@karrotframe/navigator'
const MyComponent: React.FC = () => {
return (
Hooks
$3
Trigger a screen transition.
> All arguments are typed and commented in TypeScript
`tsx
import { useNavigator } from '@karrotframe/navigator'const Posts: React.FC = () => {
const { push, pop, replace } = useNavigator()
const goPost = (postId: string) => () => {
// Go to a specific path
push(
/posts/${postId}) // Opens a specific path with some options
push(
/posts/${postId}, {
present: true, // option to prevent swipe back (Cupertino theme only)
animate: false, // option to control animation effect (default: true)
})
} const goBack = () => {
// Go one step back
pop()
// Multiple levels can be popped through the depth argument
pop(1)
// declare option to control animation effect (default: true)
pop(1, { animate: false })
}
useEffect(() => {
if (!user) {
// Move to a specific path (replace)
// It moves without animation, so it is suitable for redirect behavior.
replace('/login')
}
})
return (
{posts.map((post) => {
return (
{/ ... /}
)
})}
{/ ... /}
)
}
`$3
Get current screen's information
> All arguments are typed and commented in TypeScript
`tsx
import { useCurrentScreen } from '@karrotframe/navigator'const Posts: React.FC = () => {
const { isTop, isRoot } = useCurrentScreen()
return (
{isTop && This screen is in top}
{isRoot && This screen is in root}
)
}
`$3
To prevent unintentional screen changes due to changes in the path between screen transitions, you can use a path parameter through
useParams.> All arguments are typed and commented in TypeScript
`tsx
import { useParams } from '@karrotframe/navigator'const Post: React.FC = () => {
/**
* Value entered as path parameter (not changed in screen transitions)
*/
const params = useParams()
return / ... /
}
`$3
To prevent unintentional screen changes due to changes in the path between screen transitions, you can use a querystring through
useQueryParams.> All arguments are typed and commented in TypeScript
`tsx
import { useQueryParams } from '@karrotframe/navigator'const Post: React.FC = () => {
/**
* Value entered as querystring (not changed in screen transitions)
*/
const querystring = useQueryParams()
return / ... /
}
`Advance
$3
Use
Route in react-router-dom`tsx
// import { Route, useHistory } from 'react-router-dom'
const ExampleScreen = () => {
const history = useHistory()
const moveToInside2 = () => {
history.push('/example/inside2')
}
const goBack = () => {
history.goBack()
}
const goBackFurther = () => {
// You can go back by integrating the current internal routing
// with the previous Karrotframe screen transitions.
history.go(-4)
}
return (
...
...
)
}
`> If the
_si query string is not included in the path, Karrotframe recognizes it as an internal routing and does not perform any separate animation processing.$3
You can transfer data between screens through
pop().send() and await push() of useNavigator.> When the
depth argument in the pop() function is set to 2 or more, it is possible to send over multiple screens.`tsx
import { useNavigator } from '@karrotframe/navigator'const Posts: React.FC = () => {
const { push } = useNavigator()
const writePost = () => {
// Wait for the data to be sent from the next screen
const data = await push('/posts/write')
console.log(data)
// {
// hello: 'world',
// }
}
return (
)
}const PostWriteForm: React.FC = () => {
const { pop } = useNavigator()
const onSubmit = () => {
// Transfer data to previous screen
pop().send({
hello: 'world',
})
// It is also possible to transfer data by skipping several steps as shown below.
pop(3).send({
hello: 'world',
})
}
return / ... /
}
`$3
You can use
useLocation, useRouteMatch and useHistory that exist in react-router-dom.`tsx
import { useLocation, useHistory, useRouteMatch } from 'react-router-dom'const Post: React.FC = () => {
/**
* Current location information
*/
const location = useLocation()
/**
* History API
*/
const history = useHistory()
/**
* Compares the current location with a specific path regex and returns the parsed value.
*/
const match = useRouteMatch({
path: '/:post_id',
})
return / ... /
}
``