Skip to content

Commit

Permalink
feat(app): let router maintain state and scroll to top
Browse files Browse the repository at this point in the history
  • Loading branch information
Gerd Müller committed Jun 27, 2020
1 parent 36537c1 commit 3eb6a37
Show file tree
Hide file tree
Showing 5 changed files with 57 additions and 13 deletions.
18 changes: 11 additions & 7 deletions apps/demol/src/app/app.tsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
import React , {useState} from 'react';
import React from 'react';
import { BrowserRouter, Route, Switch } from 'react-router-dom';

import ScrollIntoView from "./scrollintoview";
import usePersistedState from './usepersistedstate';
import { Home } from '@gerdesque/home';
import { Nav, Chapter, AppContext } from '@gerdesque/ui';
import { ChapterProps } from '@gerdesque/data';
import './app.scss';

import app from './app.json';


export const App = () => {
const [character, setCharacter] = useState('default');
const [character, setCharacter] = usePersistedState('character', 'default');

const renderChapter = (routerProps) => {
const chapterId = parseInt(routerProps.match.params.id)
const chapter: ChapterProps = app.chapters.find(chapterObj => chapterObj.id === chapterId)
const chapterLink = routerProps.match.params.link
const chapter: ChapterProps = app.chapters.find(chapterObj => chapterObj.link === chapterLink)
return (chapter && <Chapter {...chapter} />)
}

return (
<AppContext.Provider value={[character, setCharacter]}>
<BrowserRouter basename="/demokratieerleben2020">
<BrowserRouter basename="/demokratieerleben2020">
<div className="app">
<Nav chapters = {app.chapters}/>
<ScrollIntoView>
<div className="app-content">
<Switch>
<Route path="/" exact component={Home} />
<Route path="/chapter/:id" render={renderChapter} />
<Route path="/chapter/:link" render={renderChapter} />
</Switch>
</div>
</ScrollIntoView>
</div>
</BrowserRouter>
</AppContext.Provider>
Expand Down
23 changes: 23 additions & 0 deletions apps/demol/src/app/scrollintoview.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useEffect, useRef } from 'react';
import { withRouter } from 'react-router-dom';
import PropTypes from 'prop-types';

const ScrollIntoView = ({ children, location }) => {
const prevLocation = useRef();

useEffect(() => {
if (prevLocation.current !== location.pathname) {
document.querySelector('.parallax__header').scrollIntoView({ behavior: 'smooth' });
prevLocation.current = location.pathname;
}
}, [location]);

return children;
};

ScrollIntoView.propTypes = {
children: PropTypes.node,
location: PropTypes.object
};

export default withRouter(ScrollIntoView);
12 changes: 12 additions & 0 deletions apps/demol/src/app/usepersistedstate.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import React from 'react';

export default function usePersistedState(key, defaultValue) {
const [state, setState] = React.useState(() => {
const persistedState = localStorage.getItem(key);
return persistedState ? JSON.parse(persistedState) : defaultValue;
});
React.useEffect(() => {
window.localStorage.setItem(key, JSON.stringify(state));
}, [state, key]);
return [state, setState];
}
2 changes: 1 addition & 1 deletion libs/ui/src/lib/nav/nav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export interface NavProps {
export const Nav = (props: NavProps) => {

const renderChapterNav = () => {
return props.chapters.map((chapter, index) => <li className='navigation--item' key={index}><NavLink to = {`/chapter/${chapter.id}`} /></li> )
return props.chapters.map((chapter, index) => <li className='navigation--item' key={index}><NavLink to = {`/chapter/${chapter.link}`} /></li> )
}

return (
Expand Down
15 changes: 10 additions & 5 deletions libs/ui/src/lib/redirect/redirect.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,21 @@
import React from 'react';

import React, {useState} from 'react';
import { Redirect } from "react-router-dom";
import './redirect.scss';

/* eslint-disable-next-line */
export interface RedirectProps {
value: string
layer: string
}

export const Redirect = (props: RedirectProps) => {
export const RedirectComponent = (props: RedirectProps) => {
const [redirect, setRedirect] = useState(false);
return (
<button type='button' className='link-button redirect'>{props.value}</button>
<>
<button type='button' className='link-button redirect' onClick={() => setRedirect(true)}>{props.value}</button>
{redirect && <Redirect exact to={props.layer} />}
</>
);
};

export default Redirect;
export default RedirectComponent;

0 comments on commit 3eb6a37

Please sign in to comment.