diff options
author | 2018-12-10 15:46:33 +0300 | |
---|---|---|
committer | 2023-01-13 10:37:54 +0300 | |
commit | 05f1cd52732b1fc57e13ea41239fbc10299a0e01 (patch) | |
tree | 2a3c8d99cb7b7a76319def26cc9ef1bb5703b3b4 /vnext/src | |
parent | 231f880af5634885bfa1a494eccef92bbf72c214 (diff) |
ReactDOM.createPortal
Diffstat (limited to 'vnext/src')
-rw-r--r-- | vnext/src/App.js | 97 | ||||
-rw-r--r-- | vnext/src/components/Header.js | 16 | ||||
-rw-r--r-- | vnext/src/index.js | 27 | ||||
-rw-r--r-- | vnext/src/style/main.css | 5 | ||||
-rw-r--r-- | vnext/src/views/index.html | 2 |
5 files changed, 61 insertions, 86 deletions
diff --git a/vnext/src/App.js b/vnext/src/App.js index 0764281a..e59fdb40 100644 --- a/vnext/src/App.js +++ b/vnext/src/App.js @@ -20,6 +20,8 @@ import cookies from 'react-cookies'; import { me } from './api'; +const app = document.getElementById('app'); + export default class App extends React.Component { constructor(props) { super(props); @@ -91,16 +93,18 @@ export default class App extends React.Component { toggleSidebar = () => { let width = this.sidebar.current.style.width; this.sidebar.current.style.width = width === '248px' ? '0' : '248px'; + let leftMargin = this.state.appMarginLeft === 'inherit' ? '250px' : 'inherit'; this.setState({ - appMarginLeft: this.state.appMarginLeft === 'inherit' ? '250px' : 'inherit' + appMarginLeft: leftMargin }); + app.style.marginLeft = leftMargin; } render() { const user = this.state.visitor; return ( <Router> <> - <Header style={{ marginLeft: this.state.appMarginLeft }}> + <Header> <div id="header_wrapper"> <NavigationIcon onToggle={this.toggleSidebar} /> <div id="logo" className="desktop"><Link to="/">Juick</Link></div> @@ -138,56 +142,45 @@ export default class App extends React.Component { </nav> </div> </Header> - <div id="wrapper" style={{ marginLeft: this.state.appMarginLeft }}> - <section id="content"> - <Switch> - <Route exact path="/" render={(props) => <Discussions visitor={user} {...props} />} /> - <Route exact path="/home" render={(props) => <Home visitor={user} {...props} />} /> - <Route exact path="/discover" render={(props) => - <Discover visitor={user} {...props} /> - } /> - <Route exact path="/settings" render={(props) => - <Settings visitor={user} {...props} /> - } /> - <Route exact path="/post" render={(props) => <Post visitor={user} {...props} />} /> - <Route exact path="/pm" render={(props) => <Contacts visitor={user} {...props} />} /> - <Route exact path="/pm/:user" render={(props) => <Chat ref={this.pm} visitor={user} {...props} />} /> - <Route exact path="/:user/friends" render={(props) => <Friends visitor={user} {...props} />} /> - <Route exact path="/:user/readers" render={(props) => <Readers visitor={user} {...props} />} /> - <Route exact path="/:user" render={(props) => <Blog key={props.match.params.user} visitor={user} {...props} />} /> - <Route exact path="/tag/:tag" render={(props) => <Tag visitor={user} {...props} />} /> - <Route exact path="/:user/:mid" render={(props) => <Thread ref={this.thread} visitor={user} {...props} />} /> - </Switch> - </section> - <aside id="sidebar" ref={this.sidebar}> - <Avatar user={user} /> - <Link to="/?show=my"> - <Icon name="ei-clock" size="s" /> - <span className="desktop">My feed</span> - </Link> - <Link to="/pm"> - <Icon name="ei-envelope" size="s" /> - <span className="desktop">Messages</span> - </Link> - <Link to="/?show=discuss"> - <Icon name="ei-bell" size="s" /> - <span className="desktop">Discussions</span> - </Link> - <Link to="/settings" rel="nofollow"> - <Icon name="ei-gear" size="s" /> - <span className="desktop">Settings</span> - </Link> - </aside> - </div> - <div id="footer" style={{ marginLeft: this.state.appMarginLeft }}> - <div id="footer-right"> · - <a href="/help/contacts" rel="nofollow">Contacts</a> · - <a href="/help/tos" rel="nofollow">TOS</a> - </div> - <div id="footer-left">juick.com © 2008-2018 - <br /> - </div> - </div> + <section id="content"> + <Switch> + <Route exact path="/" render={(props) => <Discussions visitor={user} {...props} />} /> + <Route exact path="/home" render={(props) => <Home visitor={user} {...props} />} /> + <Route exact path="/discover" render={(props) => + <Discover visitor={user} {...props} /> + } /> + <Route exact path="/settings" render={(props) => + <Settings visitor={user} {...props} /> + } /> + <Route exact path="/post" render={(props) => <Post visitor={user} {...props} />} /> + <Route exact path="/pm" render={(props) => <Contacts visitor={user} {...props} />} /> + <Route exact path="/pm/:user" render={(props) => <Chat ref={this.pm} visitor={user} {...props} />} /> + <Route exact path="/:user/friends" render={(props) => <Friends visitor={user} {...props} />} /> + <Route exact path="/:user/readers" render={(props) => <Readers visitor={user} {...props} />} /> + <Route exact path="/:user" render={(props) => <Blog key={props.match.params.user} visitor={user} {...props} />} /> + <Route exact path="/tag/:tag" render={(props) => <Tag visitor={user} {...props} />} /> + <Route exact path="/:user/:mid" render={(props) => <Thread ref={this.thread} visitor={user} {...props} />} /> + </Switch> + </section> + <aside id="sidebar" ref={this.sidebar}> + <Avatar user={user} /> + <Link to="/?show=my"> + <Icon name="ei-clock" size="s" /> + <span className="desktop">My feed</span> + </Link> + <Link to="/pm"> + <Icon name="ei-envelope" size="s" /> + <span className="desktop">Messages</span> + </Link> + <Link to="/?show=discuss"> + <Icon name="ei-bell" size="s" /> + <span className="desktop">Discussions</span> + </Link> + <Link to="/settings" rel="nofollow"> + <Icon name="ei-gear" size="s" /> + <span className="desktop">Settings</span> + </Link> + </aside> </> </Router> ); diff --git a/vnext/src/components/Header.js b/vnext/src/components/Header.js index 91fa02fd..282724b8 100644 --- a/vnext/src/components/Header.js +++ b/vnext/src/components/Header.js @@ -1,8 +1,10 @@ import React from 'react'; +import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; const elClassHidden = 'header--hidden'; -const elClassBackground = 'header--background'; + +const header = document.getElementById('header'); export default class Header extends React.Component { constructor(props) { @@ -12,21 +14,21 @@ export default class Header extends React.Component { this.wScrollCurrent = 0; this.wScrollBefore = 0; this.wScrollDiff = 0; - this.header = React.createRef(); } componentDidMount() { + header.removeChild(document.getElementById('header_wrapper')); window.addEventListener('scroll', () => (!window.requestAnimationFrame) ? this.throttle(250, this.updateHeader) : window.requestAnimationFrame(this.updateHeader), false); } throttle(delay, fn) { var last, deferTimer; - return function () { + return function() { var context = this, args = arguments, now = +new Date; if (last && now < last + delay) { clearTimeout(deferTimer); deferTimer = setTimeout( - function () { + function() { last = now; fn.apply(context, args); }, @@ -38,7 +40,6 @@ export default class Header extends React.Component { }; } updateHeader = () => { - const header = this.header.current; this.dHeight = document.body.offsetHeight; this.wHeight = window.innerHeight; this.wScrollCurrent = window.pageYOffset; @@ -47,17 +48,14 @@ export default class Header extends React.Component { if (this.wScrollCurrent <= 0) { // scrolled to the very top; element sticks to the top header.classList.remove(elClassHidden); - header.classList.remove(elClassBackground); } else if (this.wScrollDiff > 0 && header.classList.contains(elClassHidden)) { // scrolled up; element slides in header.classList.remove(elClassHidden); - header.classList.add(elClassBackground); } else if (this.wScrollDiff < 0) { // scrolled down if (this.wScrollCurrent + this.wHeight >= this.dHeight && header.classList.contains(elClassHidden)) { // scrolled to the very bottom; element slides in header.classList.remove(elClassHidden); - header.classList.add(elClassBackground); } else { // scrolled down; element slides out header.classList.add(elClassHidden); @@ -66,7 +64,7 @@ export default class Header extends React.Component { this.wScrollBefore = this.wScrollCurrent; } render() { - return (<header id="header" ref={this.header} style={this.props.style || {}}>{this.props.children}</header>); + return ReactDOM.createPortal(this.props.children, header); } } diff --git a/vnext/src/index.js b/vnext/src/index.js index c2d2b6b7..482591c9 100644 --- a/vnext/src/index.js +++ b/vnext/src/index.js @@ -3,28 +3,9 @@ import ReactDOM from 'react-dom'; function LoadingView(props) { return ( - <> - <div id="header"> - <div id="header_wrapper"> - <div id="logo"> - <a href="/">Juick</a> - </div> - <div id="search"> - <form> - <input name="search" className="text" placeholder="Search..." /> - </form> - </div> - <nav id="global"> - <a href="/">Loading...</a> - </nav> - </div> - </div> - <div id="wrapper"> - <div id="content"> - <div className="lds-ripple"><div></div><div></div></div> - </div> - </div> - </> + <div id="content"> + <div className="lds-ripple"><div></div><div></div></div> + </div> ); } @@ -36,4 +17,4 @@ const JuickApp = () => ( </Suspense> ); -ReactDOM.render(<JuickApp />, document.getElementById('app')); +ReactDOM.render(<JuickApp />, document.getElementById('wrapper')); diff --git a/vnext/src/style/main.css b/vnext/src/style/main.css index 964890c2..67527c37 100644 --- a/vnext/src/style/main.css +++ b/vnext/src/style/main.css @@ -55,9 +55,12 @@ img, hr { grid-area: header; background: #fff; box-shadow: 0 0 3px rgba(0, 0, 0, 0.28); - transition: margin-left 0.4s; + transition: transform 0.4s; overflow-x: hidden; } +.header--hidden { + transform: translateY(-100%); +} #header_wrapper, .footer_container { display: flex; diff --git a/vnext/src/views/index.html b/vnext/src/views/index.html index 792424e2..3e0ddf6a 100644 --- a/vnext/src/views/index.html +++ b/vnext/src/views/index.html @@ -35,7 +35,7 @@ <div id="header_wrapper"> <div id="logo"><a href="/">Juick</a></div> <nav id="global"> - <a href="/">Loading..</a> + <a href="/">Loading...</a> </nav> </div> </div> |