From 66c549c2c66eeb1c5f9e097fe2048d6b8111d88a Mon Sep 17 00:00:00 2001
From: alexisben <alex@noesya.coop>
Date: Thu, 17 Nov 2022 17:46:40 +0100
Subject: [PATCH] program toc

---
 assets/js/theme/design-system/mainMenu.js     |  2 +-
 assets/js/theme/design-system/toc.js          | 56 +++++++++++-----
 assets/js/theme/utils/breakpoints.js          | 11 +++-
 assets/sass/_theme/_configuration.sass        |  1 -
 assets/sass/_theme/design-system/layout.sass  |  3 -
 .../design-system/table_of_content.sass       |  7 --
 assets/sass/_theme/sections/programs.sass     | 66 +------------------
 layouts/partials/GetBodyclass                 |  2 +-
 layouts/partials/programs/hero-single.html    |  1 -
 .../programs/{show.html => single.html}       | 10 ++-
 layouts/partials/programs/toc.html            |  5 ++
 layouts/partials/toc/cta.html                 |  2 +-
 layouts/programs/list.html                    |  2 +-
 13 files changed, 70 insertions(+), 98 deletions(-)
 rename layouts/partials/programs/{show.html => single.html} (81%)

diff --git a/assets/js/theme/design-system/mainMenu.js b/assets/js/theme/design-system/mainMenu.js
index 2fa1c1dd..855bbe6b 100644
--- a/assets/js/theme/design-system/mainMenu.js
+++ b/assets/js/theme/design-system/mainMenu.js
@@ -1,4 +1,4 @@
-import breakpoints from '../utils/breakpoints';
+import { breakpoints } from '../utils/breakpoints';
 
 const CLASSES = {
     mainMenuOpened: 'is-opened',
diff --git a/assets/js/theme/design-system/toc.js b/assets/js/theme/design-system/toc.js
index ba872118..9aa3577d 100644
--- a/assets/js/theme/design-system/toc.js
+++ b/assets/js/theme/design-system/toc.js
@@ -1,23 +1,32 @@
+import { isMobile } from '../utils/breakpoints';
 
 const CLASSES = {
-  // TODO : refacto classnames et modifier le nom de la class pour "is-overlay-visible"
   offcanvasOpened: 'has-offcanvas-opened',
+  linkActive: 'active',
+  isOpened: 'is-opened',
+  fullWidth: 'full-width'
 };
 
 class TableOfContent {
   constructor() {
     this.element = document.querySelector('.toc-container');
     this.content = this.element.querySelector('.toc-content');
+    this.nav = this.element.querySelector('.toc');
     this.links = this.element.querySelectorAll('a');
     this.sections = document.querySelectorAll('section');
+    this.ctaTitle = document.querySelector('.toc-cta-title');
     this.togglers = document.querySelectorAll('.toc-cta, .toc-container button');
     this.state = {
-      opened: false
+      opened: false,
+      currentId: null
     }
     this.listen();
   }
+  isOffcanvas() {
+    return isMobile() || document.body.classList.contains(CLASSES.fullWidth);
+  }
   listen() {
-    window.addEventListener('scroll', this.update.bind(this));
+    window.addEventListener('scroll', this.update.bind(this), false);
 
     this.togglers.forEach(toggler => {
       toggler.addEventListener('click', () => {
@@ -35,32 +44,49 @@ class TableOfContent {
     this.state.opened = typeof open !== 'undefined' ? open : !this.state.opened;
 
     const classAction = this.state.opened ? 'add' : 'remove';
-    this.element.classList[classAction]('is-opened');
+    this.element.classList[classAction](CLASSES.isOpened);
     document.documentElement.classList[classAction](CLASSES.offcanvasOpened);
   }
-  update() {
-    // WIP
+  update(event) {
     const scroll = document.documentElement.scrollTop || document.body.scrollTop;
-
+    console.log(event)
+    let id = null;
     this.sections.forEach(section => {
-      if (section.offsetTop <= scroll - window.innerHeight / 2) {
-        this.activateLink(section.id);
+      if (section.offsetTop <= scroll) {
+        id = section.id;
       }
     });
 
-    this.updateSidebarScroll(scroll);
+    if (id && id !== this.state.currentId) {
+      this.activateLink(id);
+    }
+    this.updateScrollspy(scroll);
   }
   activateLink(id) {
     const currentLink = this.element.querySelector(`[href*=${ id }]`);
-    this.links.forEach(link => link.classList.remove('active'));
+    this.state.id = id;
+    this.links.forEach(link => link.classList.remove(CLASSES.linkActive));
     if (currentLink) {
-      currentLink.classList.add('active');
-      // this.nav.scrollTo(0, currentLink.offsetTop - window.innerHeight/2);
+      currentLink.classList.add(CLASSES.linkActive);
+      this.updateCtaTitle(currentLink);
+    }
+  }
+  updateCtaTitle(link) {
+    if (isMobile()) {
+      this.ctaTitle.innerText = link.innerText;
+    } else {
+      this.ctaTitle.innerText = this.ctaTitle.getAttribute('data-default');
     }
   }
-  updateSidebarScroll(scroll) {
+  updateScrollspy(scroll) {
     const progression = Math.max((scroll - window.innerHeight) / document.body.offsetHeight, 0);
-    this.content.scrollTo(0, progression * window.innerHeight/2)
+    const container = this.isOffcanvas() ? this.nav : this.content;
+    // TODO: ne fonctionne pas avec le  behavior-scroll: smooth
+    container.scrollTop = progression * window.innerHeight/2;
+    // container.scrollTo({
+    //   top: progression * window.innerHeight/2,
+    //   behavior: 'smooth'
+    // });
   }
 }
 
diff --git a/assets/js/theme/utils/breakpoints.js b/assets/js/theme/utils/breakpoints.js
index 5779a036..4bb5c1e3 100644
--- a/assets/js/theme/utils/breakpoints.js
+++ b/assets/js/theme/utils/breakpoints.js
@@ -1,4 +1,4 @@
-export default {
+const breakpoints = {
     xs: 0,
     sm: 576,
     md: 768,
@@ -6,3 +6,12 @@ export default {
     xl: 1200,
     xxl: 1400
 };
+
+const isMobile = function() {
+    return window.innerWidth <= breakpoints.md 
+}
+
+export {
+    breakpoints,
+    isMobile
+}
\ No newline at end of file
diff --git a/assets/sass/_theme/_configuration.sass b/assets/sass/_theme/_configuration.sass
index b622dece..0dcb9236 100644
--- a/assets/sass/_theme/_configuration.sass
+++ b/assets/sass/_theme/_configuration.sass
@@ -87,7 +87,6 @@ $zindex-body-overlay: 51 !default
 $zindex-toc: 60 !default
 $zindex-toc-cta: 49 !default
 
-
 // Header
 $header-color: $main-color !default
 $header-hover-color: rgba($header-color, 0.7) !default // TODO : Réflechir à plus élégant / générique
diff --git a/assets/sass/_theme/design-system/layout.sass b/assets/sass/_theme/design-system/layout.sass
index ccc130eb..baee7ef3 100644
--- a/assets/sass/_theme/design-system/layout.sass
+++ b/assets/sass/_theme/design-system/layout.sass
@@ -18,9 +18,6 @@
 
 // TODO: choisir entre margin top / bottom --> https://matthewjamestaylor.com/css-margin-top-vs-bottom
 
-html
-    scroll-behavior: smooth
-
 body
     color: $body-color
     background: $body-background-color
diff --git a/assets/sass/_theme/design-system/table_of_content.sass b/assets/sass/_theme/design-system/table_of_content.sass
index 2f6b94b9..f586c90e 100644
--- a/assets/sass/_theme/design-system/table_of_content.sass
+++ b/assets/sass/_theme/design-system/table_of_content.sass
@@ -112,10 +112,3 @@
             color: $toc-active-color
             text-decoration: underline
             pointer-events: none
-
-
-                // position: absolute
-                // top: 0
-                // --grid-width: Min(100vw, (#{$grid-max-width}))
-                // margin-left: Max(#{$grid-gutter}, calc(50vw - #{$grid-max-width} / 2 + #{$grid-gutter}))
-                // width: calc((var(--grid-width) + #{$grid-gutter} * 2) / 12 * 4 - #{$grid-gutter} * 2)
\ No newline at end of file
diff --git a/assets/sass/_theme/sections/programs.sass b/assets/sass/_theme/sections/programs.sass
index 279a455d..f8282d73 100644
--- a/assets/sass/_theme/sections/programs.sass
+++ b/assets/sass/_theme/sections/programs.sass
@@ -1,52 +1,3 @@
-//.programs__section
-//     .page-with-blocks
-//         .hero
-//             margin-bottom: 3rem
-
-//     main > article
-//         position: relative
-//         > aside
-//             align-self: flex-start
-//             margin-bottom: $spacing5
-//             pointer-events: none
-//             .toc + p
-//                 margin-top: $grid-gutter
-//             p:last-of-type
-//                 margin-bottom: 0
-//             @include media-breakpoint-down(md)
-//                 position: relative
-//             @include media-breakpoint-up(md)
-//                 height: 100%
-//                 margin-bottom: 0
-//                 position: absolute
-//                 width: 100%
-//                 ~ *
-//                     .container
-//                         > *
-//                             &:not(.call_to_action)
-//                                 padding-left: col(4)
-//                             &.call_to_action
-//                                 margin-left: col(4)
-//                             &:is(picture)
-//                                 display: block
-//             > div
-//                 // @extend .container
-//                 // @extend .sticky
-//                 padding: 0
-//                 > *
-//                     // @extend .col-md-3
-//                     padding-left: #{$grid-gutter / 2}
-//                     padding-right: #{$grid-gutter / 2}
-//                     pointer-events: auto
-//         [itemprop="articleBody"]
-//             margin-bottom: $spacing5
-//     article
-//         .persons
-//             margin-bottom: 3rem
-//             margin-top: -2rem
-//             @include grid(2, lg)
-
-
 .program
     @include article
 
@@ -157,19 +108,6 @@ ol.programs
         overflow: auto
         background: darken($main-background-color, 3)
         z-index: $program-zindex-toc
-    .toc
-        max-width: 100%
-        ol
-            display: flex
-            flex-direction: row
-            flex-wrap: nowrap
-            justify-content: space-between
-            white-space: nowrap
-            margin: 0 #{-$spacing1}
-            padding: px2rem(20) 0
-            li
-                padding: calc(#{$spacing1}/3) calc(#{$spacing1}/2)
-                margin-bottom: 0
     // .blocks
     //     .container
     //         padding-left: 0
@@ -178,13 +116,13 @@ ol.programs
             // @include media-breakpoint-up(md)
                 // padding-left: offset(5)
 
-    article
+    .document-content
         .content
             padding-top: $spacing1
             padding-bottom: $spacing2
 
     @include media-breakpoint-up(md)
-        article
+        .document-content
             .content
                 @include grid(12, md)
                 padding-bottom: $spacing4
diff --git a/layouts/partials/GetBodyclass b/layouts/partials/GetBodyclass
index cddda8f4..95f7618e 100644
--- a/layouts/partials/GetBodyclass
+++ b/layouts/partials/GetBodyclass
@@ -4,7 +4,7 @@
   {{- $bodyclass = printf "page-%s" $bodyclass -}}
 {{- end -}}
 
-{{- if .Params.full_width -}}
+{{- if or .Params.full_width  .Params.diplomas -}}
   {{- $bodyclass = printf "full-width %s" $bodyclass -}}
 {{- end -}}
 
diff --git a/layouts/partials/programs/hero-single.html b/layouts/partials/programs/hero-single.html
index 8214811f..836236a8 100644
--- a/layouts/partials/programs/hero-single.html
+++ b/layouts/partials/programs/hero-single.html
@@ -32,4 +32,3 @@
     </div>
   </div>
 </header>
-{{ partial "programs/document-nav.html" . }}
diff --git a/layouts/partials/programs/show.html b/layouts/partials/programs/single.html
similarity index 81%
rename from layouts/partials/programs/show.html
rename to layouts/partials/programs/single.html
index 95f2297f..027cc43f 100644
--- a/layouts/partials/programs/show.html
+++ b/layouts/partials/programs/single.html
@@ -1,4 +1,10 @@
-<article itemscope itemtype="https://schema.org/EducationalOccupationalCredential">
+{{ partial "toc/container.html"
+    (dict
+        "toc" "programs/toc.html"
+        "context" .
+    )
+}}
+<div class="document-content" itemscope itemtype="https://schema.org/EducationalOccupationalCredential">
   <meta itemprop="name" content="{{ partial "PrepareHTML" .Title }}">
   <meta itemprop="url" content="{{ .Permalink }}">
   {{- if .Params.image -}}
@@ -24,4 +30,4 @@
   {{- partial "programs/results.html" . -}}
   {{- partial "programs/admission.html" . -}}
   {{- partial "hooks/before-program-end.html" . -}}
-</article>
+</div>
diff --git a/layouts/partials/programs/toc.html b/layouts/partials/programs/toc.html
index c37f2f6d..da07a95a 100644
--- a/layouts/partials/programs/toc.html
+++ b/layouts/partials/programs/toc.html
@@ -6,6 +6,11 @@
     </li>
     <li>
       <a href="#presentation">{{ i18n "programs.toc.presentation" }}</a>
+      {{- if .context.Params.blocks -}}
+        <ol>
+          {{- partial "blocks/toc" .context.Params.blocks -}}
+        </ol>
+      {{- end -}}
     </li>
     <li>
       <a href="#pedagogy">{{ i18n "programs.toc.pedagogy" }}</a>
diff --git a/layouts/partials/toc/cta.html b/layouts/partials/toc/cta.html
index b27014dd..8436edf4 100644
--- a/layouts/partials/toc/cta.html
+++ b/layouts/partials/toc/cta.html
@@ -1,6 +1,6 @@
 <div class="toc-cta">
   {{/* TODO : quelle balise pour le titre du toc ? */}}
-  <div data-default="{{ i18n "commons.toc" }}">{{ i18n "commons.toc" }}</div>
+  <div class="toc-cta-title" data-default="{{ i18n "commons.toc" }}">{{ i18n "commons.toc" }}</div>
 
   <button aria-label="{{ i18n "commons.toc" }}">
     <svg width="17" height="13" viewBox="0 0 17 13" fill="none" xmlns="http://www.w3.org/2000/svg">
diff --git a/layouts/programs/list.html b/layouts/programs/list.html
index 56cde966..e511e744 100644
--- a/layouts/programs/list.html
+++ b/layouts/programs/list.html
@@ -1,7 +1,7 @@
 {{ define "main" }}
   {{ if .Params.diplomas }}
     {{ partial "programs/hero-single.html" . }}
-    {{ partial "programs/show.html" . }}
+    {{ partial "programs/single.html" . }}
   {{ else }}
     {{ partial "programs/hero.html" . }}
     {{ partial "programs/index.html" . }}
-- 
GitLab