├── .gitignore ├── README.md ├── images └── cover.png ├── package-lock.json ├── package.json ├── public ├── favicon.ico ├── index.html └── manifest.json └── src ├── App.css ├── App.js ├── App.test.js ├── Components ├── Navbar.js └── Section.js ├── DummyText.js ├── index.css ├── index.js ├── logo.svg └── serviceWorker.js /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | 6 | # testing 7 | /coverage 8 | 9 | # production 10 | /build 11 | 12 | # misc 13 | .DS_Store 14 | .env.local 15 | .env.development.local 16 | .env.test.local 17 | .env.production.local 18 | 19 | npm-debug.log* 20 | yarn-debug.log* 21 | yarn-error.log* 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # React With Smooth Scrolling 2 | 3 | ![React with Smooth Scrolling](./images/cover.png) 4 | 5 | This project was bootstrapped with [Create React App](https://github.com/facebook/create-react-app). 6 | 7 | ## To Run 8 | 9 | - clone this repository 10 | - run `npm install` 11 | - run `npm start` 12 | -------------------------------------------------------------------------------- /images/cover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/do-community/React-With-Smooth-Scrolling/74876d416c5ad5be93dcbd474e720430b95db8eb/images/cover.png -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "react-smooth-scrolling", 3 | "version": "0.1.0", 4 | "private": true, 5 | "dependencies": { 6 | "react": "^16.6.0", 7 | "react-dom": "^16.6.0", 8 | "react-scripts": "2.0.5", 9 | "react-scroll": "^1.7.10" 10 | }, 11 | "scripts": { 12 | "start": "react-scripts start", 13 | "build": "react-scripts build", 14 | "test": "react-scripts test", 15 | "eject": "react-scripts eject" 16 | }, 17 | "eslintConfig": { 18 | "extends": "react-app" 19 | }, 20 | "browserslist": [ 21 | ">0.2%", 22 | "not dead", 23 | "not ie <= 11", 24 | "not op_mini all" 25 | ] 26 | } 27 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/do-community/React-With-Smooth-Scrolling/74876d416c5ad5be93dcbd474e720430b95db8eb/public/favicon.ico -------------------------------------------------------------------------------- /public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 12 | 13 | 22 | React App 23 | 24 | 25 | 28 |
29 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /public/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "short_name": "React App", 3 | "name": "Create React App Sample", 4 | "icons": [ 5 | { 6 | "src": "favicon.ico", 7 | "sizes": "64x64 32x32 24x24 16x16", 8 | "type": "image/x-icon" 9 | } 10 | ], 11 | "start_url": ".", 12 | "display": "standalone", 13 | "theme_color": "#000000", 14 | "background_color": "#ffffff" 15 | } 16 | -------------------------------------------------------------------------------- /src/App.css: -------------------------------------------------------------------------------- 1 | :root { 2 | --off-white: #fafafa; 3 | } 4 | .nav { 5 | background-color: var(--off-white); 6 | position: sticky; 7 | top: 0px; 8 | width: 100%; 9 | height: 80px; 10 | z-index: 1000; 11 | box-shadow: 0 4px 14px 0 rgba(0, 0, 0, 0.15); 12 | } 13 | 14 | .nav-logo { 15 | height: 60px; 16 | width: 60px; 17 | } 18 | 19 | .nav-logo:hover { 20 | cursor: pointer; 21 | } 22 | 23 | .nav .nav-content { 24 | max-width: 900px; 25 | padding: 0rem 3rem; 26 | margin: 0 auto; 27 | display: flex; 28 | justify-content: space-between; 29 | align-items: center; 30 | height: 100%; 31 | } 32 | 33 | .nav-item { 34 | display: inline; 35 | margin-left: 2rem; 36 | color: #333; 37 | } 38 | 39 | .nav-item:hover { 40 | color: black; 41 | cursor: pointer; 42 | } 43 | 44 | .section { 45 | } 46 | 47 | .section-dark { 48 | background: #333; 49 | color: white; 50 | } 51 | 52 | .section-content { 53 | max-width: 800px; 54 | margin: 0 auto; 55 | padding: 40px; 56 | } 57 | -------------------------------------------------------------------------------- /src/App.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import logo from "./logo.svg"; 3 | import "./App.css"; 4 | import Navbar from "./Components/Navbar"; 5 | import Section from "./Components/Section"; 6 | import dummyText from "./DummyText"; 7 | class App extends Component { 8 | render() { 9 | return ( 10 |
11 | 12 |
18 |
24 |
30 |
36 |
42 |
43 | ); 44 | } 45 | } 46 | 47 | export default App; 48 | -------------------------------------------------------------------------------- /src/App.test.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import App from './App'; 4 | 5 | it('renders without crashing', () => { 6 | const div = document.createElement('div'); 7 | ReactDOM.render(, div); 8 | ReactDOM.unmountComponentAtNode(div); 9 | }); 10 | -------------------------------------------------------------------------------- /src/Components/Navbar.js: -------------------------------------------------------------------------------- 1 | import React, { Component } from "react"; 2 | import logo from "../logo.svg"; 3 | import { Link, animateScroll as scroll } from "react-scroll"; 4 | 5 | export default class Navbar extends Component { 6 | scrollToTop = () => { 7 | scroll.scrollToTop(); 8 | }; 9 | 10 | render() { 11 | return ( 12 | 84 | ); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/Components/Section.js: -------------------------------------------------------------------------------- 1 | import React from "react"; 2 | 3 | export default function Section({ title, subtitle, dark, id }) { 4 | return ( 5 |
6 |
7 |

{title}

8 |

{subtitle}

9 |
10 |
11 | ); 12 | } 13 | -------------------------------------------------------------------------------- /src/DummyText.js: -------------------------------------------------------------------------------- 1 | const dummyText = `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Id nibh tortor id aliquet. Sed lectus vestibulum mattis ullamcorper velit sed. Nec nam aliquam sem et tortor. Elit eget gravida cum sociis natoque. Ipsum a arcu cursus vitae. Massa sapien faucibus et molestie ac feugiat sed. Turpis egestas maecenas pharetra convallis posuere morbi leo. Duis at consectetur lorem donec massa sapien faucibus et molestie. Purus sit amet luctus venenatis lectus. Pellentesque nec nam aliquam sem et tortor consequat id porta. Sapien et ligula ullamcorper malesuada. Fringilla ut morbi tincidunt augue interdum velit euismod. Vitae turpis massa sed elementum tempus egestas sed. Netus et malesuada fames ac turpis egestas integer eget aliquet. Blandit cursus risus at ultrices mi tempus imperdiet nulla malesuada. Aliquam eleifend mi in nulla posuere sollicitudin aliquam ultrices sagittis. 2 | 3 | Nisi est sit amet facilisis. Vitae congue eu consequat ac felis. Facilisis mauris sit amet massa vitae tortor condimentum lacinia. Nisl condimentum id venenatis a condimentum. Rutrum tellus pellentesque eu tincidunt tortor. Semper auctor neque vitae tempus quam. Pellentesque adipiscing commodo elit at imperdiet dui accumsan sit. Mi ipsum faucibus vitae aliquet nec ullamcorper sit. Enim lobortis scelerisque fermentum dui faucibus. Volutpat ac tincidunt vitae semper quis lectus nulla at. 4 | 5 | Pellentesque id nibh tortor id aliquet lectus proin. Blandit cursus risus at ultrices mi. Iaculis eu non diam phasellus vestibulum lorem. Et odio pellentesque diam volutpat commodo. Sodales ut etiam sit amet nisl purus in. Adipiscing elit ut aliquam purus sit. Bibendum enim facilisis gravida neque convallis a cras. Duis at consectetur lorem donec massa sapien faucibus et molestie. Massa tincidunt nunc pulvinar sapien et ligula ullamcorper malesuada proin. Non odio euismod lacinia at quis risus sed vulputate odio. Vel turpis nunc eget lorem dolor sed viverra ipsum. A lacus vestibulum sed arcu. 6 | 7 | Odio aenean sed adipiscing diam. Volutpat ac tincidunt vitae semper quis lectus. Tristique magna sit amet purus. Euismod in pellentesque massa placerat duis. Tellus molestie nunc non blandit massa enim nec dui nunc. Faucibus pulvinar elementum integer enim neque volutpat ac tincidunt vitae. Tempus quam pellentesque nec nam aliquam sem et tortor consequat. Ac felis donec et odio pellentesque diam volutpat commodo sed. Orci sagittis eu volutpat odio. Purus faucibus ornare suspendisse sed nisi lacus. Nulla facilisi etiam dignissim diam quis enim lobortis scelerisque. Habitant morbi tristique senectus et netus et. Porta non pulvinar neque laoreet suspendisse. Nunc scelerisque viverra mauris in aliquam sem fringilla ut morbi. Tellus integer feugiat scelerisque varius. Pulvinar pellentesque habitant morbi tristique senectus et netus et malesuada. Pharetra et ultrices neque ornare aenean euismod. Proin sagittis nisl rhoncus mattis rhoncus. 8 | 9 | Nisi quis eleifend quam adipiscing vitae. Eget mauris pharetra et ultrices neque ornare aenean euismod elementum. Non arcu risus quis varius quam quisque id diam. Pharetra magna ac placerat vestibulum. Lobortis feugiat vivamus at augue eget arcu dictum varius duis. Sed id semper risus in hendrerit gravida. Ultrices eros in cursus turpis massa. Non tellus orci ac auctor augue mauris augue. Arcu vitae elementum curabitur vitae nunc. Convallis a cras semper auctor neque vitae tempus quam. Varius quam quisque id diam vel.`; 10 | 11 | export default dummyText; 12 | -------------------------------------------------------------------------------- /src/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | margin: 0; 3 | padding: 0; 4 | font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen", 5 | "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", 6 | sans-serif; 7 | -webkit-font-smoothing: antialiased; 8 | -moz-osx-font-smoothing: grayscale; 9 | } 10 | 11 | code { 12 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", 13 | monospace; 14 | } 15 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import './index.css'; 4 | import App from './App'; 5 | import * as serviceWorker from './serviceWorker'; 6 | 7 | ReactDOM.render(, document.getElementById('root')); 8 | 9 | // If you want your app to work offline and load faster, you can change 10 | // unregister() to register() below. Note this comes with some pitfalls. 11 | // Learn more about service workers: http://bit.ly/CRA-PWA 12 | serviceWorker.unregister(); 13 | -------------------------------------------------------------------------------- /src/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /src/serviceWorker.js: -------------------------------------------------------------------------------- 1 | // This optional code is used to register a service worker. 2 | // register() is not called by default. 3 | 4 | // This lets the app load faster on subsequent visits in production, and gives 5 | // it offline capabilities. However, it also means that developers (and users) 6 | // will only see deployed updates on subsequent visits to a page, after all the 7 | // existing tabs open on the page have been closed, since previously cached 8 | // resources are updated in the background. 9 | 10 | // To learn more about the benefits of this model and instructions on how to 11 | // opt-in, read http://bit.ly/CRA-PWA. 12 | 13 | const isLocalhost = Boolean( 14 | window.location.hostname === 'localhost' || 15 | // [::1] is the IPv6 localhost address. 16 | window.location.hostname === '[::1]' || 17 | // 127.0.0.1/8 is considered localhost for IPv4. 18 | window.location.hostname.match( 19 | /^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ 20 | ) 21 | ); 22 | 23 | export function register(config) { 24 | if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { 25 | // The URL constructor is available in all browsers that support SW. 26 | const publicUrl = new URL(process.env.PUBLIC_URL, window.location); 27 | if (publicUrl.origin !== window.location.origin) { 28 | // Our service worker won't work if PUBLIC_URL is on a different origin 29 | // from what our page is served on. This might happen if a CDN is used to 30 | // serve assets; see https://github.com/facebook/create-react-app/issues/2374 31 | return; 32 | } 33 | 34 | window.addEventListener('load', () => { 35 | const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; 36 | 37 | if (isLocalhost) { 38 | // This is running on localhost. Let's check if a service worker still exists or not. 39 | checkValidServiceWorker(swUrl, config); 40 | 41 | // Add some additional logging to localhost, pointing developers to the 42 | // service worker/PWA documentation. 43 | navigator.serviceWorker.ready.then(() => { 44 | console.log( 45 | 'This web app is being served cache-first by a service ' + 46 | 'worker. To learn more, visit http://bit.ly/CRA-PWA' 47 | ); 48 | }); 49 | } else { 50 | // Is not localhost. Just register service worker 51 | registerValidSW(swUrl, config); 52 | } 53 | }); 54 | } 55 | } 56 | 57 | function registerValidSW(swUrl, config) { 58 | navigator.serviceWorker 59 | .register(swUrl) 60 | .then(registration => { 61 | registration.onupdatefound = () => { 62 | const installingWorker = registration.installing; 63 | installingWorker.onstatechange = () => { 64 | if (installingWorker.state === 'installed') { 65 | if (navigator.serviceWorker.controller) { 66 | // At this point, the updated precached content has been fetched, 67 | // but the previous service worker will still serve the older 68 | // content until all client tabs are closed. 69 | console.log( 70 | 'New content is available and will be used when all ' + 71 | 'tabs for this page are closed. See http://bit.ly/CRA-PWA.' 72 | ); 73 | 74 | // Execute callback 75 | if (config && config.onUpdate) { 76 | config.onUpdate(registration); 77 | } 78 | } else { 79 | // At this point, everything has been precached. 80 | // It's the perfect time to display a 81 | // "Content is cached for offline use." message. 82 | console.log('Content is cached for offline use.'); 83 | 84 | // Execute callback 85 | if (config && config.onSuccess) { 86 | config.onSuccess(registration); 87 | } 88 | } 89 | } 90 | }; 91 | }; 92 | }) 93 | .catch(error => { 94 | console.error('Error during service worker registration:', error); 95 | }); 96 | } 97 | 98 | function checkValidServiceWorker(swUrl, config) { 99 | // Check if the service worker can be found. If it can't reload the page. 100 | fetch(swUrl) 101 | .then(response => { 102 | // Ensure service worker exists, and that we really are getting a JS file. 103 | if ( 104 | response.status === 404 || 105 | response.headers.get('content-type').indexOf('javascript') === -1 106 | ) { 107 | // No service worker found. Probably a different app. Reload the page. 108 | navigator.serviceWorker.ready.then(registration => { 109 | registration.unregister().then(() => { 110 | window.location.reload(); 111 | }); 112 | }); 113 | } else { 114 | // Service worker found. Proceed as normal. 115 | registerValidSW(swUrl, config); 116 | } 117 | }) 118 | .catch(() => { 119 | console.log( 120 | 'No internet connection found. App is running in offline mode.' 121 | ); 122 | }); 123 | } 124 | 125 | export function unregister() { 126 | if ('serviceWorker' in navigator) { 127 | navigator.serviceWorker.ready.then(registration => { 128 | registration.unregister(); 129 | }); 130 | } 131 | } 132 | --------------------------------------------------------------------------------