From 168983e5137b0d6828674fa497cd1d8e56aeaa17 Mon Sep 17 00:00:00 2001
From: peter_rabbit <pierrejarriges@gmail.com>
Date: Fri, 8 Jan 2021 11:31:19 +0100
Subject: [PATCH] nav submenu

---
 public/education/education.js                 | 65 ++++++++++++-------
 public/games/games.js                         | 53 +++++++++------
 public/main.js                                | 53 +++++++++------
 .../software-development.js                   | 53 +++++++++------
 .../education/components/game-studio-club.js  |  1 +
 .../{vugarisation.js => popularization.js}    |  5 +-
 src/pages/education/education.js              |  4 +-
 src/style.scss                                | 22 +++++++
 src/template/template.js                      | 53 +++++++++------
 style/style.css                               | 21 ++++++
 style/style.css.map                           |  2 +-
 11 files changed, 227 insertions(+), 105 deletions(-)
 rename src/pages/education/components/{vugarisation.js => popularization.js} (98%)

diff --git a/public/education/education.js b/public/education/education.js
index 498e5d2..a258948 100644
--- a/public/education/education.js
+++ b/public/education/education.js
@@ -193,6 +193,7 @@ class GameStudioClub {
                 {
                     tag: "div",
                     class: "title-banner",
+                    id: "game-studio-club", // anchor id
                     contents: [{ tag: "h2", contents: "Game Studio Club" }],
                 },
                 {
@@ -479,7 +480,7 @@ const VULGARISATION_THEMES = [
     },
 ];
 
-class Vulgarisation {
+class Popularization {
     render() {
         return {
             tag: "section",
@@ -487,6 +488,7 @@ class Vulgarisation {
                 {
                     tag: "div",
                     class: "title-banner",
+                    id: "popularization", // anchor id
                     contents: [{ tag: "h2", contents: "Ateliers de vulgarisation" }],
                 },
                 {
@@ -580,13 +582,13 @@ class Vulgarisation {
     }
 }
 
-module.exports = Vulgarisation;
+module.exports = Popularization;
 
 },{"../../../../constants":2}],6:[function(require,module,exports){
 "use strict";
 
 const GameStudioClub = require("./components/game-studio-club");
-const Vulgarisation = require("./components/vugarisation");
+const Popularization = require("./components/popularization");
 
 class EducationPage {
     constructor(args) {
@@ -607,7 +609,7 @@ class EducationPage {
                     avant tout par la pédagogie et le partage de connaissances. Nous proposons blablabla`,
                 },
                 new GameStudioClub().render(),
-                new Vulgarisation().render(),
+                new Popularization().render(),
             ],
         };
     }
@@ -615,7 +617,7 @@ class EducationPage {
 
 module.exports = EducationPage;
 
-},{"./components/game-studio-club":4,"./components/vugarisation":5}],7:[function(require,module,exports){
+},{"./components/game-studio-club":4,"./components/popularization":5}],7:[function(require,module,exports){
 "use strict";
 
 "use strict";
@@ -638,11 +640,44 @@ module.exports = function runPage(PageComponent) {
 },{"./lib/object-html-renderer":3,"./template/template":9}],9:[function(require,module,exports){
 "use strict";
 
+const NAV_MENU_ITEMS = [
+    ["/public/", "Accueil"],
+    ["/public/games/", "Jeux"],
+    ["/public/software-development/", "Software"],
+    [
+        "/public/education/",
+        "Pédagogie",
+        [
+            // submenu
+            ["/public/education/#game-studio-club", "Game Studio Club"],
+            ["/public/education/#popularization", "Animations vulgarisation"],
+        ],
+    ],
+];
+
 class Template {
     constructor(props) {
         this.props = props;
     }
 
+    renderMenu(menuItemsArray, isSubmenu = false) {
+        const r = {
+            tag: "ul",
+            class: isSubmenu ? "submenu" : "",
+            contents: menuItemsArray.map(link => {
+                const [href, text, submenu] = link;
+                return {
+                    tag: "li",
+                    class: !isSubmenu && window.location.pathname === href ? "active" : "",
+                    contents: [{ tag: "a", href, contents: text }].concat(
+                        submenu ? [this.renderMenu(submenu, true)] : []
+                    ),
+                };
+            }),
+        };
+        return r;
+    }
+
     render() {
         return {
             tag: "main",
@@ -652,25 +687,7 @@ class Template {
                     contents: [
                         {
                             tag: "nav",
-                            contents: [
-                                {
-                                    tag: "ul",
-                                    contents: [
-                                        ["/public/", "Accueil"],
-                                        ["/public/games/", "Jeux"],
-                                        ["/public/software-development/", "Software"],
-                                        ["/public/education/", "Pédagogie"],
-                                    ].map(link => {
-                                        const [href, text] = link;
-                                        return {
-                                            tag: "li",
-                                            class:
-                                                window.location.pathname === href ? "active" : "",
-                                            contents: [{ tag: "a", href, contents: text }],
-                                        };
-                                    }),
-                                },
-                            ],
+                            contents: [this.renderMenu(NAV_MENU_ITEMS)],
                         },
                     ],
                 },
diff --git a/public/games/games.js b/public/games/games.js
index f1761f0..f901236 100644
--- a/public/games/games.js
+++ b/public/games/games.js
@@ -130,11 +130,44 @@ module.exports = function runPage(PageComponent) {
 },{"./lib/object-html-renderer":1,"./template/template":5}],5:[function(require,module,exports){
 "use strict";
 
+const NAV_MENU_ITEMS = [
+    ["/public/", "Accueil"],
+    ["/public/games/", "Jeux"],
+    ["/public/software-development/", "Software"],
+    [
+        "/public/education/",
+        "Pédagogie",
+        [
+            // submenu
+            ["/public/education/#game-studio-club", "Game Studio Club"],
+            ["/public/education/#popularization", "Animations vulgarisation"],
+        ],
+    ],
+];
+
 class Template {
     constructor(props) {
         this.props = props;
     }
 
+    renderMenu(menuItemsArray, isSubmenu = false) {
+        const r = {
+            tag: "ul",
+            class: isSubmenu ? "submenu" : "",
+            contents: menuItemsArray.map(link => {
+                const [href, text, submenu] = link;
+                return {
+                    tag: "li",
+                    class: !isSubmenu && window.location.pathname === href ? "active" : "",
+                    contents: [{ tag: "a", href, contents: text }].concat(
+                        submenu ? [this.renderMenu(submenu, true)] : []
+                    ),
+                };
+            }),
+        };
+        return r;
+    }
+
     render() {
         return {
             tag: "main",
@@ -144,25 +177,7 @@ class Template {
                     contents: [
                         {
                             tag: "nav",
-                            contents: [
-                                {
-                                    tag: "ul",
-                                    contents: [
-                                        ["/public/", "Accueil"],
-                                        ["/public/games/", "Jeux"],
-                                        ["/public/software-development/", "Software"],
-                                        ["/public/education/", "Pédagogie"],
-                                    ].map(link => {
-                                        const [href, text] = link;
-                                        return {
-                                            tag: "li",
-                                            class:
-                                                window.location.pathname === href ? "active" : "",
-                                            contents: [{ tag: "a", href, contents: text }],
-                                        };
-                                    }),
-                                },
-                            ],
+                            contents: [this.renderMenu(NAV_MENU_ITEMS)],
                         },
                     ],
                 },
diff --git a/public/main.js b/public/main.js
index a9911c8..d3cd269 100644
--- a/public/main.js
+++ b/public/main.js
@@ -130,11 +130,44 @@ module.exports = function runPage(PageComponent) {
 },{"./lib/object-html-renderer":2,"./template/template":5}],5:[function(require,module,exports){
 "use strict";
 
+const NAV_MENU_ITEMS = [
+    ["/public/", "Accueil"],
+    ["/public/games/", "Jeux"],
+    ["/public/software-development/", "Software"],
+    [
+        "/public/education/",
+        "Pédagogie",
+        [
+            // submenu
+            ["/public/education/#game-studio-club", "Game Studio Club"],
+            ["/public/education/#popularization", "Animations vulgarisation"],
+        ],
+    ],
+];
+
 class Template {
     constructor(props) {
         this.props = props;
     }
 
+    renderMenu(menuItemsArray, isSubmenu = false) {
+        const r = {
+            tag: "ul",
+            class: isSubmenu ? "submenu" : "",
+            contents: menuItemsArray.map(link => {
+                const [href, text, submenu] = link;
+                return {
+                    tag: "li",
+                    class: !isSubmenu && window.location.pathname === href ? "active" : "",
+                    contents: [{ tag: "a", href, contents: text }].concat(
+                        submenu ? [this.renderMenu(submenu, true)] : []
+                    ),
+                };
+            }),
+        };
+        return r;
+    }
+
     render() {
         return {
             tag: "main",
@@ -144,25 +177,7 @@ class Template {
                     contents: [
                         {
                             tag: "nav",
-                            contents: [
-                                {
-                                    tag: "ul",
-                                    contents: [
-                                        ["/public/", "Accueil"],
-                                        ["/public/games/", "Jeux"],
-                                        ["/public/software-development/", "Software"],
-                                        ["/public/education/", "Pédagogie"],
-                                    ].map(link => {
-                                        const [href, text] = link;
-                                        return {
-                                            tag: "li",
-                                            class:
-                                                window.location.pathname === href ? "active" : "",
-                                            contents: [{ tag: "a", href, contents: text }],
-                                        };
-                                    }),
-                                },
-                            ],
+                            contents: [this.renderMenu(NAV_MENU_ITEMS)],
                         },
                     ],
                 },
diff --git a/public/software-development/software-development.js b/public/software-development/software-development.js
index c5ed1f0..2651a13 100644
--- a/public/software-development/software-development.js
+++ b/public/software-development/software-development.js
@@ -130,11 +130,44 @@ module.exports = function runPage(PageComponent) {
 },{"./lib/object-html-renderer":1,"./template/template":5}],5:[function(require,module,exports){
 "use strict";
 
+const NAV_MENU_ITEMS = [
+    ["/public/", "Accueil"],
+    ["/public/games/", "Jeux"],
+    ["/public/software-development/", "Software"],
+    [
+        "/public/education/",
+        "Pédagogie",
+        [
+            // submenu
+            ["/public/education/#game-studio-club", "Game Studio Club"],
+            ["/public/education/#popularization", "Animations vulgarisation"],
+        ],
+    ],
+];
+
 class Template {
     constructor(props) {
         this.props = props;
     }
 
+    renderMenu(menuItemsArray, isSubmenu = false) {
+        const r = {
+            tag: "ul",
+            class: isSubmenu ? "submenu" : "",
+            contents: menuItemsArray.map(link => {
+                const [href, text, submenu] = link;
+                return {
+                    tag: "li",
+                    class: !isSubmenu && window.location.pathname === href ? "active" : "",
+                    contents: [{ tag: "a", href, contents: text }].concat(
+                        submenu ? [this.renderMenu(submenu, true)] : []
+                    ),
+                };
+            }),
+        };
+        return r;
+    }
+
     render() {
         return {
             tag: "main",
@@ -144,25 +177,7 @@ class Template {
                     contents: [
                         {
                             tag: "nav",
-                            contents: [
-                                {
-                                    tag: "ul",
-                                    contents: [
-                                        ["/public/", "Accueil"],
-                                        ["/public/games/", "Jeux"],
-                                        ["/public/software-development/", "Software"],
-                                        ["/public/education/", "Pédagogie"],
-                                    ].map(link => {
-                                        const [href, text] = link;
-                                        return {
-                                            tag: "li",
-                                            class:
-                                                window.location.pathname === href ? "active" : "",
-                                            contents: [{ tag: "a", href, contents: text }],
-                                        };
-                                    }),
-                                },
-                            ],
+                            contents: [this.renderMenu(NAV_MENU_ITEMS)],
                         },
                     ],
                 },
diff --git a/src/pages/education/components/game-studio-club.js b/src/pages/education/components/game-studio-club.js
index 2749a4c..fcbbeb5 100644
--- a/src/pages/education/components/game-studio-club.js
+++ b/src/pages/education/components/game-studio-club.js
@@ -84,6 +84,7 @@ class GameStudioClub {
                 {
                     tag: "div",
                     class: "title-banner",
+                    id: "game-studio-club", // anchor id
                     contents: [{ tag: "h2", contents: "Game Studio Club" }],
                 },
                 {
diff --git a/src/pages/education/components/vugarisation.js b/src/pages/education/components/popularization.js
similarity index 98%
rename from src/pages/education/components/vugarisation.js
rename to src/pages/education/components/popularization.js
index 9a65271..a4cf8ec 100644
--- a/src/pages/education/components/vugarisation.js
+++ b/src/pages/education/components/popularization.js
@@ -46,7 +46,7 @@ const VULGARISATION_THEMES = [
     },
 ];
 
-class Vulgarisation {
+class Popularization {
     render() {
         return {
             tag: "section",
@@ -54,6 +54,7 @@ class Vulgarisation {
                 {
                     tag: "div",
                     class: "title-banner",
+                    id: "popularization", // anchor id
                     contents: [{ tag: "h2", contents: "Ateliers de vulgarisation" }],
                 },
                 {
@@ -147,4 +148,4 @@ class Vulgarisation {
     }
 }
 
-module.exports = Vulgarisation;
+module.exports = Popularization;
diff --git a/src/pages/education/education.js b/src/pages/education/education.js
index a1bb552..a53f633 100644
--- a/src/pages/education/education.js
+++ b/src/pages/education/education.js
@@ -1,7 +1,7 @@
 "use strict";
 
 const GameStudioClub = require("./components/game-studio-club");
-const Vulgarisation = require("./components/vugarisation");
+const Popularization = require("./components/popularization");
 
 class EducationPage {
     constructor(args) {
@@ -22,7 +22,7 @@ class EducationPage {
                     avant tout par la pédagogie et le partage de connaissances. Nous proposons blablabla`,
                 },
                 new GameStudioClub().render(),
-                new Vulgarisation().render(),
+                new Popularization().render(),
             ],
         };
     }
diff --git a/src/style.scss b/src/style.scss
index d1bf204..472df3e 100644
--- a/src/style.scss
+++ b/src/style.scss
@@ -27,6 +27,7 @@ main {
                 margin: 0;
                 list-style-type: none;
                 li {
+                    position: relative;
                     a {
                         display: flex;
                         padding: 10px 20px;
@@ -34,6 +35,19 @@ main {
                         font-weight: 500;
                         text-decoration: none;
                     }
+
+                    .submenu {
+                        visibility: hidden;
+                        position: absolute;
+                        height: auto;
+                        max-height: 0;
+                        transition: max-height .5s;
+                        top: 100%;
+                        left: 50%;
+                        flex-direction: column;
+                        background-image: url("../assets/images/wallpaper_binary.png");
+                        white-space: nowrap;
+                    }
                     &:hover,
                     &.active {
                         background-color: #fff2;
@@ -41,6 +55,12 @@ main {
                             color: white;
                         }
                     }
+                    &:hover {
+                        .submenu {
+                            visibility: unset;
+                            max-height: 1000px;
+                        }
+                    }
                 }
             }
         }
@@ -54,5 +74,7 @@ main {
     }
     footer {
         width: 100%;
+        background-color: #fff1;
+        padding: 20px;
     }
 }
diff --git a/src/template/template.js b/src/template/template.js
index dec780a..eae8317 100644
--- a/src/template/template.js
+++ b/src/template/template.js
@@ -1,10 +1,43 @@
 "use strict";
 
+const NAV_MENU_ITEMS = [
+    ["/public/", "Accueil"],
+    ["/public/games/", "Jeux"],
+    ["/public/software-development/", "Software"],
+    [
+        "/public/education/",
+        "Pédagogie",
+        [
+            // submenu
+            ["/public/education/#game-studio-club", "Game Studio Club"],
+            ["/public/education/#popularization", "Animations vulgarisation"],
+        ],
+    ],
+];
+
 class Template {
     constructor(props) {
         this.props = props;
     }
 
+    renderMenu(menuItemsArray, isSubmenu = false) {
+        const r = {
+            tag: "ul",
+            class: isSubmenu ? "submenu" : "",
+            contents: menuItemsArray.map(link => {
+                const [href, text, submenu] = link;
+                return {
+                    tag: "li",
+                    class: !isSubmenu && window.location.pathname === href ? "active" : "",
+                    contents: [{ tag: "a", href, contents: text }].concat(
+                        submenu ? [this.renderMenu(submenu, true)] : []
+                    ),
+                };
+            }),
+        };
+        return r;
+    }
+
     render() {
         return {
             tag: "main",
@@ -14,25 +47,7 @@ class Template {
                     contents: [
                         {
                             tag: "nav",
-                            contents: [
-                                {
-                                    tag: "ul",
-                                    contents: [
-                                        ["/public/", "Accueil"],
-                                        ["/public/games/", "Jeux"],
-                                        ["/public/software-development/", "Software"],
-                                        ["/public/education/", "Pédagogie"],
-                                    ].map(link => {
-                                        const [href, text] = link;
-                                        return {
-                                            tag: "li",
-                                            class:
-                                                window.location.pathname === href ? "active" : "",
-                                            contents: [{ tag: "a", href, contents: text }],
-                                        };
-                                    }),
-                                },
-                            ],
+                            contents: [this.renderMenu(NAV_MENU_ITEMS)],
                         },
                     ],
                 },
diff --git a/style/style.css b/style/style.css
index 8049f61..382adc2 100644
--- a/style/style.css
+++ b/style/style.css
@@ -30,6 +30,9 @@ main header nav ul {
   margin: 0;
   list-style-type: none;
 }
+main header nav ul li {
+  position: relative;
+}
 main header nav ul li a {
   display: flex;
   padding: 10px 20px;
@@ -37,12 +40,28 @@ main header nav ul li a {
   font-weight: 500;
   text-decoration: none;
 }
+main header nav ul li .submenu {
+  visibility: hidden;
+  position: absolute;
+  height: auto;
+  max-height: 0;
+  transition: max-height 0.5s;
+  top: 100%;
+  left: 50%;
+  flex-direction: column;
+  background-image: url("../assets/images/wallpaper_binary.png");
+  white-space: nowrap;
+}
 main header nav ul li:hover, main header nav ul li.active {
   background-color: #fff2;
 }
 main header nav ul li:hover a, main header nav ul li.active a {
   color: white;
 }
+main header nav ul li:hover .submenu {
+  visibility: unset;
+  max-height: 1000px;
+}
 main #page-container {
   background-color: white;
   width: 1200px;
@@ -197,6 +216,8 @@ main #page-container #education-page .section-contents .infos-inscriptions .pric
 }
 main footer {
   width: 100%;
+  background-color: #fff1;
+  padding: 20px;
 }
 
 /*# sourceMappingURL=style.css.map */
diff --git a/style/style.css.map b/style/style.css.map
index d723e10..cdf7290 100644
--- a/style/style.css.map
+++ b/style/style.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["../src/style.scss","../src/pages/education/education.scss"],"names":[],"mappings":"AAAA;EAII;EACA;;AAJA;EACI;;AAIJ;EACI;EACA;EACA;;;AAIR;EACI;EACA;EACA;EACA;EACA;;AACA;EACI;;AACA;EACI;;AACA;EACI;EACA;EACA;EACA;;AAEI;EACI;EACA;EACA;EACA;EACA;;AAEJ;EAEI;;AACA;EACI;;AAOxB;EACI;EACA;EACA;EACA;;AClDJ;EACI;EACA;;AAEJ;EACI;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;;AAGR;EACI;EACA;EACA;EACA;EACA;;AACA;EACI;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EAEA;;AACA;EACI;EACA;EACA;EACA;;AACA;EACI;;AAEJ;AAAA;EAEI;EACA;;AAIZ;EACI;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;;AAGR;EACI;EACA;;AACA;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAMhB;EACI;EACA;;AACA;AAAA;EAEI;EAKA;EACA;EACA;;AACA;AAAA;EACI;EACA;EACA;;AAEJ;AAAA;EACI;EACA;;AAEJ;AAAA;EACI;EACA;;AAEJ;AAAA;EACI;EACA;;AACA;AAAA;EACI;EACA;;AACA;AAAA;EACI;EACA;;ADtFxB;EACI","file":"style.css"}
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["../src/style.scss","../src/pages/education/education.scss"],"names":[],"mappings":"AAAA;EAII;EACA;;AAJA;EACI;;AAIJ;EACI;EACA;EACA;;;AAIR;EACI;EACA;EACA;EACA;EACA;;AACA;EACI;;AACA;EACI;;AACA;EACI;EACA;EACA;EACA;;AACA;EACI;;AACA;EACI;EACA;EACA;EACA;EACA;;AAGJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AAEJ;EAEI;;AACA;EACI;;AAIJ;EACI;EACA;;AAOxB;EACI;EACA;EACA;EACA;;ACtEJ;EACI;EACA;;AAEJ;EACI;EACA;EACA;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;;AAGR;EACI;EACA;EACA;EACA;EACA;;AACA;EACI;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;EAEA;;AACA;EACI;EACA;EACA;EACA;;AACA;EACI;;AAEJ;AAAA;EAEI;EACA;;AAIZ;EACI;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;EACA;EACA;EACA;EACA;;AACA;EACI;EACA;EACA;;AAGR;EACI;EACA;;AACA;EACI;EACA;;AAEJ;EACI;;AAEJ;EACI;EACA;EACA;EACA;EACA;EACA;;AAMhB;EACI;EACA;;AACA;AAAA;EAEI;EAKA;EACA;EACA;;AACA;AAAA;EACI;EACA;EACA;;AAEJ;AAAA;EACI;EACA;;AAEJ;AAAA;EACI;EACA;;AAEJ;AAAA;EACI;EACA;;AACA;AAAA;EACI;EACA;;AACA;AAAA;EACI;EACA;;ADlExB;EACI;EACA;EACA","file":"style.css"}
\ No newline at end of file
-- 
GitLab