From f4efd511d38a1ad17d4e4b652c9e69e4a6304924 Mon Sep 17 00:00:00 2001 From: Phuoc Nguyen Date: Sun, 17 Nov 2019 15:37:17 +0700 Subject: [PATCH 1/3] Add useInterval hook --- client/hooks/useInterval.js | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 client/hooks/useInterval.js diff --git a/client/hooks/useInterval.js b/client/hooks/useInterval.js new file mode 100644 index 0000000..cb441ad --- /dev/null +++ b/client/hooks/useInterval.js @@ -0,0 +1,16 @@ +import { useEffect } from 'react'; + +const useInterval = (callback, delay) => { + useEffect( + () => { + const handler = () => callback(); + if (delay !== null) { + const id = setInterval(handler, delay); + return () => clearInterval(id); + } + }, + [delay] + ); +}; + +export default useInterval; From 87e18d0333c3a495f3d9638725d9e943e95320e1 Mon Sep 17 00:00:00 2001 From: Phuoc Nguyen Date: Sun, 17 Nov 2019 15:37:29 +0700 Subject: [PATCH 2/3] Add progress bar --- client/App.jsx | 2 + client/Home.jsx | 7 +++ client/layouts/progress-bar/Cover.jsx | 17 +++++++ client/layouts/progress-bar/Details.jsx | 68 +++++++++++++++++++++++++ 4 files changed, 94 insertions(+) create mode 100644 client/layouts/progress-bar/Cover.jsx create mode 100644 client/layouts/progress-bar/Details.jsx diff --git a/client/App.jsx b/client/App.jsx index f211598..c11643c 100644 --- a/client/App.jsx +++ b/client/App.jsx @@ -11,6 +11,7 @@ import InputAddon from './layouts/input-add-on/Details'; import MediaObject from './layouts/media-object/Details'; import Menu from './layouts/menu/Details'; import PreviousNextButtons from './layouts/previous-next-buttons/Details'; +import ProgressBar from './layouts/progress-bar/Details'; import SameHeightColumns from './layouts/same-height-columns/Details'; import Sidebar from './layouts/sidebar/Details'; import SplitScreen from './layouts/split-screen/Details'; @@ -32,6 +33,7 @@ const App = () => { + diff --git a/client/Home.jsx b/client/Home.jsx index 5b33cef..b4900dd 100644 --- a/client/Home.jsx +++ b/client/Home.jsx @@ -10,6 +10,7 @@ import InputAddonCover from './layouts/input-add-on/Cover'; import MediaObjectCover from './layouts/media-object/Cover'; import MenuCover from './layouts/menu/Cover'; import PreviousNextButtonCover from './layouts/previous-next-buttons/Cover'; +import ProgressBarCover from './layouts/progress-bar/Cover'; import SameHeightColumnsCover from './layouts/same-height-columns/Cover'; import SidebarCover from './layouts/sidebar/Cover'; import SplitScreenCover from './layouts/split-screen/Cover'; @@ -125,6 +126,12 @@ const Home = () => {

Previous next buttons

+
+ + +

Progress bar

+ +
diff --git a/client/layouts/progress-bar/Cover.jsx b/client/layouts/progress-bar/Cover.jsx new file mode 100644 index 0000000..78bc62e --- /dev/null +++ b/client/layouts/progress-bar/Cover.jsx @@ -0,0 +1,17 @@ +import React from 'react'; + +import Frame from '../../placeholders/Frame'; + +const Cover = () => { + return ( + +
+
+
+
+
+ + ); +}; + +export default Cover; diff --git a/client/layouts/progress-bar/Details.jsx b/client/layouts/progress-bar/Details.jsx new file mode 100644 index 0000000..072964c --- /dev/null +++ b/client/layouts/progress-bar/Details.jsx @@ -0,0 +1,68 @@ +import React, { useState } from 'react'; + +import DetailsLayout from '../../DetailsLayout'; +import BrowserFrame from '../../placeholders/BrowserFrame'; +import SampleCode from '../../SampleCode'; +import useDocumentTitle from '../../useDocumentTitle'; +import useInterval from '../../hooks/useInterval'; + +const Details = () => { + useDocumentTitle('CSS Layout ∙ Progress bar'); + const [progress, setProgress] = useState(0); + useInterval(() => { + setProgress(v => v === 100 ? 0 : v + 1); + }, 1 * 100); + + return ( + +

Progress bar

+ +
+
+ {progress}% +
+
+
+ } + source={ + +
+ + 40% +
+
+`} +/> + } + /> + + ); +}; + +export default Details; From 2876976c63f8efc61acd80e6429828af1c69c07c Mon Sep 17 00:00:00 2001 From: Phuoc Nguyen Date: Sun, 17 Nov 2019 15:40:15 +0700 Subject: [PATCH 3/3] Move useDocumentTitle to hooks --- client/Home.jsx | 2 +- client/{ => hooks}/useDocumentTitle.js | 0 client/layouts/badge/Details.jsx | 2 +- client/layouts/button-with-icon/Details.jsx | 2 +- client/layouts/centering/Details.jsx | 2 +- client/layouts/fixed-at-corner/Details.jsx | 2 +- client/layouts/holy-grail/Details.jsx | 2 +- client/layouts/input-add-on/Details.jsx | 2 +- client/layouts/media-object/Details.jsx | 2 +- client/layouts/menu/Details.jsx | 2 +- client/layouts/previous-next-buttons/Details.jsx | 2 +- client/layouts/progress-bar/Details.jsx | 2 +- client/layouts/same-height-columns/Details.jsx | 2 +- client/layouts/sidebar/Details.jsx | 2 +- client/layouts/split-screen/Details.jsx | 2 +- client/layouts/stepper-input/Details.jsx | 2 +- client/layouts/sticky-footer/Details.jsx | 2 +- client/layouts/sticky-header/Details.jsx | 2 +- 18 files changed, 17 insertions(+), 17 deletions(-) rename client/{ => hooks}/useDocumentTitle.js (100%) diff --git a/client/Home.jsx b/client/Home.jsx index b4900dd..07132c3 100644 --- a/client/Home.jsx +++ b/client/Home.jsx @@ -18,7 +18,7 @@ import StepperInputCover from './layouts/stepper-input/Cover'; import StickyFooterCover from './layouts/sticky-footer/Cover'; import StickyHeaderCover from './layouts/sticky-header/Cover'; import Layout from './Layout'; -import useDocumentTitle from './useDocumentTitle'; +import useDocumentTitle from './hooks/useDocumentTitle'; const Home = () => { useDocumentTitle('CSS Layout'); diff --git a/client/useDocumentTitle.js b/client/hooks/useDocumentTitle.js similarity index 100% rename from client/useDocumentTitle.js rename to client/hooks/useDocumentTitle.js diff --git a/client/layouts/badge/Details.jsx b/client/layouts/badge/Details.jsx index b4ac309..5a5895e 100644 --- a/client/layouts/badge/Details.jsx +++ b/client/layouts/badge/Details.jsx @@ -3,7 +3,7 @@ import React from 'react'; import DetailsLayout from '../../DetailsLayout'; import BrowserFrame from '../../placeholders/BrowserFrame'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Badge'); diff --git a/client/layouts/button-with-icon/Details.jsx b/client/layouts/button-with-icon/Details.jsx index 56951f0..142831f 100644 --- a/client/layouts/button-with-icon/Details.jsx +++ b/client/layouts/button-with-icon/Details.jsx @@ -5,7 +5,7 @@ import BrowserFrame from '../../placeholders/BrowserFrame'; import Circle from '../../placeholders/Circle'; import Rectangle from '../../placeholders/Rectangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Button with icon'); diff --git a/client/layouts/centering/Details.jsx b/client/layouts/centering/Details.jsx index 05e55d5..64faacd 100644 --- a/client/layouts/centering/Details.jsx +++ b/client/layouts/centering/Details.jsx @@ -5,7 +5,7 @@ import BrowserFrame from '../../placeholders/BrowserFrame'; import Circle from '../../placeholders/Circle'; import Rectangle from '../../placeholders/Rectangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Centering'); diff --git a/client/layouts/fixed-at-corner/Details.jsx b/client/layouts/fixed-at-corner/Details.jsx index 062bcc8..8a37913 100644 --- a/client/layouts/fixed-at-corner/Details.jsx +++ b/client/layouts/fixed-at-corner/Details.jsx @@ -4,7 +4,7 @@ import DetailsLayout from '../../DetailsLayout'; import BrowserFrame from '../../placeholders/BrowserFrame'; import Triangle from '../../placeholders/Triangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Fixed at corner'); diff --git a/client/layouts/holy-grail/Details.jsx b/client/layouts/holy-grail/Details.jsx index 1c467ac..dba00b9 100644 --- a/client/layouts/holy-grail/Details.jsx +++ b/client/layouts/holy-grail/Details.jsx @@ -5,7 +5,7 @@ import Block from '../../placeholders/Block'; import BrowserFrame from '../../placeholders/BrowserFrame'; import Rectangle from '../../placeholders/Rectangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Holy grail'); diff --git a/client/layouts/input-add-on/Details.jsx b/client/layouts/input-add-on/Details.jsx index 414dd12..55b4a4a 100644 --- a/client/layouts/input-add-on/Details.jsx +++ b/client/layouts/input-add-on/Details.jsx @@ -4,7 +4,7 @@ import DetailsLayout from '../../DetailsLayout'; import BrowserFrame from '../../placeholders/BrowserFrame'; import Rectangle from '../../placeholders/Rectangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Input add-on'); diff --git a/client/layouts/media-object/Details.jsx b/client/layouts/media-object/Details.jsx index 7e8cf92..b7a4bbe 100644 --- a/client/layouts/media-object/Details.jsx +++ b/client/layouts/media-object/Details.jsx @@ -6,7 +6,7 @@ import BrowserFrame from '../../placeholders/BrowserFrame'; import Rectangle from '../../placeholders/Rectangle'; import Square from '../../placeholders/Square'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Media object'); diff --git a/client/layouts/menu/Details.jsx b/client/layouts/menu/Details.jsx index e8875bd..fe48eb9 100644 --- a/client/layouts/menu/Details.jsx +++ b/client/layouts/menu/Details.jsx @@ -5,7 +5,7 @@ import BrowserFrame from '../../placeholders/BrowserFrame'; import Circle from '../../placeholders/Circle'; import Rectangle from '../../placeholders/Rectangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Menu'); diff --git a/client/layouts/previous-next-buttons/Details.jsx b/client/layouts/previous-next-buttons/Details.jsx index 841974b..2d75a97 100644 --- a/client/layouts/previous-next-buttons/Details.jsx +++ b/client/layouts/previous-next-buttons/Details.jsx @@ -4,7 +4,7 @@ import DetailsLayout from '../../DetailsLayout'; import BrowserFrame from '../../placeholders/BrowserFrame'; import Rectangle from '../../placeholders/Rectangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Previous and next buttons'); diff --git a/client/layouts/progress-bar/Details.jsx b/client/layouts/progress-bar/Details.jsx index 072964c..97ea89b 100644 --- a/client/layouts/progress-bar/Details.jsx +++ b/client/layouts/progress-bar/Details.jsx @@ -3,7 +3,7 @@ import React, { useState } from 'react'; import DetailsLayout from '../../DetailsLayout'; import BrowserFrame from '../../placeholders/BrowserFrame'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; import useInterval from '../../hooks/useInterval'; const Details = () => { diff --git a/client/layouts/same-height-columns/Details.jsx b/client/layouts/same-height-columns/Details.jsx index be1285b..1001dea 100644 --- a/client/layouts/same-height-columns/Details.jsx +++ b/client/layouts/same-height-columns/Details.jsx @@ -5,7 +5,7 @@ import Block from '../../placeholders/Block'; import BrowserFrame from '../../placeholders/BrowserFrame'; import Rectangle from '../../placeholders/Rectangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Same height columns'); diff --git a/client/layouts/sidebar/Details.jsx b/client/layouts/sidebar/Details.jsx index 0ff1d91..d2dbced 100644 --- a/client/layouts/sidebar/Details.jsx +++ b/client/layouts/sidebar/Details.jsx @@ -4,7 +4,7 @@ import DetailsLayout from '../../DetailsLayout'; import BrowserFrame from '../../placeholders/BrowserFrame'; import Block from '../../placeholders/Block'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Sidebar'); diff --git a/client/layouts/split-screen/Details.jsx b/client/layouts/split-screen/Details.jsx index 2f445d9..a43740a 100644 --- a/client/layouts/split-screen/Details.jsx +++ b/client/layouts/split-screen/Details.jsx @@ -6,7 +6,7 @@ import Block from '../../placeholders/Block'; import Circle from '../../placeholders/Circle'; import Rectangle from '../../placeholders/Rectangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Split screen'); diff --git a/client/layouts/stepper-input/Details.jsx b/client/layouts/stepper-input/Details.jsx index c8d133d..27f4302 100644 --- a/client/layouts/stepper-input/Details.jsx +++ b/client/layouts/stepper-input/Details.jsx @@ -4,7 +4,7 @@ import { Link } from 'react-router-dom'; import DetailsLayout from '../../DetailsLayout'; import BrowserFrame from '../../placeholders/BrowserFrame'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Stepper input'); diff --git a/client/layouts/sticky-footer/Details.jsx b/client/layouts/sticky-footer/Details.jsx index 5d5f6f9..e656869 100644 --- a/client/layouts/sticky-footer/Details.jsx +++ b/client/layouts/sticky-footer/Details.jsx @@ -5,7 +5,7 @@ import Block from '../../placeholders/Block'; import BrowserFrame from '../../placeholders/BrowserFrame'; import Rectangle from '../../placeholders/Rectangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Sticky footer'); diff --git a/client/layouts/sticky-header/Details.jsx b/client/layouts/sticky-header/Details.jsx index 57a1903..e1440bc 100644 --- a/client/layouts/sticky-header/Details.jsx +++ b/client/layouts/sticky-header/Details.jsx @@ -5,7 +5,7 @@ import Block from '../../placeholders/Block'; import BrowserFrame from '../../placeholders/BrowserFrame'; import Rectangle from '../../placeholders/Rectangle'; import SampleCode from '../../SampleCode'; -import useDocumentTitle from '../../useDocumentTitle'; +import useDocumentTitle from '../../hooks/useDocumentTitle'; const Details = () => { useDocumentTitle('CSS Layout ∙ Sticky header');