|
1 |
| -# Relative Links for React Router |
| 1 | +# Restore Scroll |
2 | 2 |
|
3 |
| -This is a WIP with only a couple hours put into the code, but I think it |
4 |
| -works, give it a shot, send some pull requests if you run into issues. |
| 3 | +Restore the scroll positions of `window` and scrollable elements when |
| 4 | +the user navigates around a React Router app. |
5 | 5 |
|
6 |
| -## Installation |
| 6 | + |
7 | 7 |
|
| 8 | +## Temporarily a Plugin |
| 9 | + |
| 10 | +Plan is to put this into React Router directly, but for now you can plug |
| 11 | +it in and help us get the bugs out (and write some tests, there aren't |
| 12 | +any yet!) |
| 13 | + |
| 14 | +## Usage |
| 15 | + |
| 16 | +```js |
| 17 | +import React from 'react' |
| 18 | +import { render } from 'react-dom' |
| 19 | +import { Router, browserHistory, applyRouterMiddleware } from 'react-router' |
| 20 | +import routes from './routes' |
| 21 | + |
| 22 | +import { |
| 23 | + useHistoryRestoreScroll, |
| 24 | + useRouterRestoreScroll |
| 25 | +} from 'react-router-restore-scroll' |
| 26 | + |
| 27 | +// first enhance a history |
| 28 | +const createHistory = useHistoryRestoreScroll(() => browserHistory) |
| 29 | + |
| 30 | +// next create some router middleware |
| 31 | +const routerRender = applyRouterMiddleware( |
| 32 | + useRouterRestoreScroll() |
| 33 | +) |
| 34 | + |
| 35 | +// then plug them into Router |
| 36 | +render( |
| 37 | + <Router |
| 38 | + history={createHistory()} |
| 39 | + render={routerRender} |
| 40 | + routes={routes} |
| 41 | + />, |
| 42 | + document.getElementById('app') |
| 43 | +) |
8 | 44 | ```
|
9 |
| -npm install react-router-relative-links react-router-apply-middleware |
| 45 | + |
| 46 | +Now the window's scroll positions will be automatically restored as you |
| 47 | +navigate around in a React Router app, and even when you navigate out of |
| 48 | +and back into it from external sites. |
| 49 | + |
| 50 | +## Restores Scrollable Elements Too |
| 51 | + |
| 52 | +If you’ve got scrollable elements (`overflow: auto|scroll`) they can |
| 53 | +also be restored with the `RestoreScroll` component. |
| 54 | + |
| 55 | +```js |
| 56 | +import { RestoreScroll } from 'react-router-restore-scroll' |
| 57 | + |
| 58 | +// then in a component's render method, wrap your scrollable element |
| 59 | +// in a `RestoreScroll` component. It needs a `scrollKey`. |
| 60 | +<RestoreScroll scrollKey="one"> |
| 61 | + <div style={{ height: '200px', overflow: 'auto', border: '1px solid' }}> |
| 62 | + <div style={{ height: '100px', background: 'hsl(0, 50%, 90%)' }}>scroll me</div> |
| 63 | + <div style={{ height: '100px', background: 'hsl(100, 50%, 90%)' }}>two</div> |
| 64 | + <div style={{ height: '100px', background: 'hsl(200, 50%, 90%)' }}>three</div> |
| 65 | + </div> |
| 66 | +</RestoreScroll> |
10 | 67 | ```
|
11 | 68 |
|
12 |
| -## Usage |
| 69 | +## Non-React usage |
| 70 | + |
| 71 | +The `useHistoryRestoreScroll` enhancer gives you a history with a |
| 72 | +`restoreScroll` property with three methods that you can use to |
| 73 | +integrate into any view layer that uses `history` (cycle.js, etc.). |
13 | 74 |
|
14 | 75 | ```js
|
15 |
| -import applyMiddleware from 'react-router-apply-middleware' |
16 |
| -import { useRelativeLinks, RelativeLink } from 'react-router-relative-links' |
17 |
| - |
18 |
| -// use it like other router middleware |
19 |
| -<Router render={applyMiddleware(useRelativeLinks())}/> |
20 |
| - |
21 |
| -// now you can use `RelativeLink` anywhere \o/ |
22 |
| -<RelativeLink to="../">Up</RelativeLink> |
23 |
| -<RelativeLink to="./down">Down</RelativeLink> |
24 |
| -<RelativeLink to="../sideways">Sideways</RelativeLink> |
25 |
| -<RelativeLink to={{ pathname: 'foo', query: { bar: 'baz' } }}>location descriptors</RelativeLink> |
26 |
| -<RelativeLink to={{ query: { bar: 'baz' } }}>just the query</RelativeLink> |
| 76 | +import createBrowserHistory from 'history/lib/createBrowserHistory' |
| 77 | + |
| 78 | +const history = useHistoryRestoreScroll(createBrowserHistory)() |
| 79 | + |
| 80 | +// call this when a scrollable element is inserted into the dom, where |
| 81 | +// `scrollKey` is a globally unique identifier for the node |
| 82 | +history.registerScroller(scrollKey, domNode) |
| 83 | + |
| 84 | +// call this when it's removed from the dom |
| 85 | +history.unregisterScroller(scrollKey) |
| 86 | + |
| 87 | +// call this |
| 88 | +// - when the app first renders |
| 89 | +// - after the app re-renders after a location change |
| 90 | +history.restoreWindow() |
27 | 91 | ```
|
28 | 92 |
|
| 93 | +You can look at `modules/RestoreWindowScroll.js` and `modules/RestoreScroll.js` |
| 94 | +to see at which points in a React app these methods are all called. |
| 95 | + |
0 commit comments