/react-router-nested-history

A library to help build React apps with nested tabs and other containers that have their own history, complete with automatic altering of the browser's back and forward history

Primary LanguageTypeScriptMIT LicenseMIT

react-router-nested-history

A library to help build React apps with nested tabs and other containers that have their own history, complete with automatic altering of the browser's back and forward history to make it behave as you would expect a mobile app like Facebook or Twitter to behave.

Live demo

react-router-nested-history.herokuapp.com

Installation

npm install --save kenfehling/react-router-nested-history

react-router

This library is built to support react-router 4.

This library is very new and not battle-tested, although it does have unit tests, end-to-end tests, examples, and is used on my personal webpage. I would very much appreciate any feedback as I continue to solidify it. It's still under very active development.

Right now this library only works with browserHistory (HTML5 History API, not with hash history)

Roadmap

  • Nested container groups
  • End to end tests using Nightwatch.js
  • Support for title libraries like react-helmet
  • Transition animations (slide-in, slide-out)
  • Support for SSR (server-side rendering)
  • Support for components that lazy render (many existing React tab libraries)

API

HistoryRouter

Use this in place of react-router's BrowserRouter component to enable this library.

props (in addition to the existing BrowserRouter props)

name type default description
zeroPage string / The page at the beginning of the history stack

HistoryRoute

Use this in place of react-router's Route component to prevent a match's previous content from disappearing.

HistoryLink

Use this in place of react-router's Link component to enable history tracking for a link.

HeaderLink

Use this for a container's header link (typically a tab-like thing)

props

name type required description
toContainer string The name of the container this links to
className string The CSS class for styling this element
activeClassName string An alternate CSS class for styling the active item
children ReactNode or Function The children of this HeaderLink

children function params

name type description
isActive boolean Is this HeaderLink's associated Container active?

BackLink

Use this to place a back link (which only shows if there is back history)

props

name type required description
children ReactNode or ({params}) => ReactNode Defines what appears in the back link (default: 'Back')

Container

Use this component to wrap one or more HistoryRoute components to enable history for a container (a nested tab or window).

props

name type default required description
name string The name of this container (must be unique)
initialUrl string The path that the container starts on
patterns string[] A list of path patterns that will load in this container from a URL in the address bar
isDefault boolean false Consider this the default tab
animate boolean true Should this container use slide transition animations?
className string The CSS class for styling this element

ContainerGroup

Wraps one or more Container components that act as a group (a group of tabs, etc.)

props

name type default required description
name string The name of this group (must be unique)
isDefault boolean false Consider this the default tab (only for a nested group)
allowInterContainerHistory boolean false Allow history that would cause containers to switch
gotoTopOnSelectActive boolean false Go to the top of a tab if it's selected while already active
hideInactiveContainers boolean true Don't show the content of inactive containers
resetOnLeave boolean false Reset container's history when switching to another container
children ReactNode or Function The children of this ContainerGroup

children function params

name type description
currentContainerIndex number The index of the current container
currentContainerName string The name of the current container
stackOrder Container[] The containers ordered by how recently they were activated
setCurrentContainerIndex (number)=>void Switch the current container by index
setCurrentContainerName (string)=>void Switch the current container by name

WindowGroup

A convenience component that wraps a ContainerGroup and is meant for creating a group of HistoryWindow components that overlap and are layered in the order that they were last accessed.

props

Same as ContainerGroup but with changes in defaults.

name type default required description
hideInactiveContainers boolean false Don't render the content of inactive containers

children function params

Same as ContainerGroup except with these additions:

name type description
openWindow ({name:string}|{index:number}) => void Open a window in this group
resetWindowPositions () => void Restore the positions of the windows in this group to their original values

HistoryWindow

A single window inside a WindowGroup

props

name type default required description
forName string The name of the container or group this window wraps
visible boolean true Is this window visible?
draggable boolean false Uses [react-draggable](https://github.com/mzabriskie/react-draggable) to make window draggable
draggableProps Object {} Props passed to the Draggable component
rememberPosition boolean true if draggable Remember the position this window was dragged to?
left/center/right number (in pixels) Position horizontally based on (only) one of these anchor points
top/middle/bottom number (in pixels) Position vertically based on (only) one of these anchor points
className string The CSS class used to style this window
topClassName string The CSS class used when this window is on top
children ReactNode or Function The children of this HistoryWindow

children function params

name type description
open () => void Make this window visible
close () => void Make this window invisible
switchTo () => void Switch to this window

ScrollArea

Keeps track of scrolling inside a container

props

name type default required description
resetOnLeave boolean false Reset the scroll position when the container is left
horizontal boolean false Use horizontal scrolling
vertical boolean false Use vertical scrolling

WhenActive

Use inside a container to only render something when the container is active. An example use case is with a library like react-helmet. With several windows open Helmet can get confused over which title, etc. to use. Wrapping Helmet in WhenActive makes it only pay attention to the active container.