Browse Source

responsive almost done

Bachir Soussi Chiadmi 3 years ago
parent
commit
682d4686ad

+ 183 - 29
assets/css/app.scss

@@ -70,7 +70,7 @@ header[role="banner"]{
           overflow: hidden;
         }
       }
-      &:hover{
+      &:hover, &.opened{
         >ul>li{
           height:1em;
         }
@@ -109,10 +109,33 @@ section[role="main-content"]{
         }
       }
     }
-    $filet_space:8em;
-    $decallage: 0.5em;
+    // $filet_space:8em;
+    // $decallage: 0.5em;
     section{
-      padding-top: $filet_space;
+      padding-top: 8em;
+    }
+    @mixin teasersfilet($filet_space, $decallage){
+      &:before, &:after{
+        z-index: 0;
+        content: "";
+        position: absolute;
+        opacity: 0.4;
+      }
+      &:before{
+        border:1px solid $or;
+        width:calc(100% + #{$filet_space*2 + $decallage*2});
+        left:- $filet_space - $default_gap/2 -$decallage;
+        height:calc(100% + #{$filet_space});
+        top:- $filet_space / 2;
+      }
+      &:after{
+        border:1px solid $rouge;
+        width:calc(100% + #{$filet_space*2});
+        left:- $filet_space - $default_gap/2;
+        height:calc(100% + #{$filet_space + $decallage*2});
+        top:- $filet_space / 2 - $decallage;
+      }
+
     }
     div.teasers{
       display: flex;
@@ -139,25 +162,26 @@ section[role="main-content"]{
         }
       }
       // filets decoratif
-      &:before, &:after{
-        z-index: 0;
-        content: "";
-        position: absolute;
-        opacity: 0.4;
+      @include teasersfilet(8em, 0.5em);
       }
-      &:before{
-        border:1px solid $or;
-        width:calc(100% + #{$filet_space*2 + $decallage*2});
-        left:- $filet_space - $default_gap/2 -$decallage;
-        height:calc(100% + #{$filet_space});
-        top:- $filet_space / 2;
+    // responsive
+    @media only screen and (max-width: $small-bp) {
+      header{
+        h1{
+          font-size: 5em;
+          margin:7vh 0 0;
+        }
+        h2{
+          font-size: 1em;
+        }
       }
-      &:after{
-        border:1px solid $rouge;
-        width:calc(100% + #{$filet_space*2});
-        left:- $filet_space - $default_gap/2;
-        height:calc(100% + #{$filet_space + $decallage*2});
-        top:- $filet_space / 2 - $decallage;
+      section{
+        padding-top: 4em;
+      }
+      div.teasers{
+        flex-direction: column;
+        // filets decoratif
+        @include teasersfilet(4em, 0.5em);
       }
     }
   }
@@ -334,6 +358,14 @@ section[role="main-content"]{
         time{
           font-weight: 600;
         }
+        @media only screen and (max-width: $small-bp) {
+          background-color: #fff;
+          padding: 1em;
+          box-shadow: 0 0 10px $gris;
+          *{
+            pointer-events: none;
+          }
+        }
       }
     }
 
@@ -344,12 +376,13 @@ section[role="main-content"]{
           overflow: hidden;
         }
         div.tei{
-          border-left: 1px dotted $grisclair;
-          padding-left: 1em;
-          &.active{
-            border-left: 1px dotted $grisfonce;
+          @media only screen and (min-width: $small-bp + 1) {
+            border-left: 1px dotted $grisclair;
+            padding-left: 1em;
+            &.active{
+              border-left: 1px dotted $grisfonce;
+            }
           }
-
           >h1{@include title1blue;}
           span.placeName,
           span.objectName,
@@ -363,6 +396,9 @@ section[role="main-content"]{
     >nav{
       padding-bottom: 0;
       $pager_h:2em;
+
+      span.nav-title{ display:none; }
+
       section#toc{
         box-sizing: content-box;
         padding:0 0 1em 1.5em;
@@ -421,6 +457,7 @@ section[role="main-content"]{
           span.toc-title{font-size: 0.882em;}
         }
       }
+
       div#page-nav{
         height:$pager_h;
         overflow: hidden;
@@ -433,6 +470,58 @@ section[role="main-content"]{
         }
       }
     }
+    // responsive
+    @media only screen and (max-width: $small-bp) {
+      position: relative;
+      >nav{
+        $top: 45px;
+        z-index: 2;
+        position: absolute;
+        top:$top;
+        right:0;
+        background-color: #fff;
+        width:40%;
+        box-sizing: border-box;
+        padding-top: 1em;
+        padding-bottom: 1em;
+        height:calc(100% - #{$top});
+
+        transform: translateX(100%);
+        transition: transform 0.3s ease-in-out;
+
+        span.nav-title{
+          display: block;
+          position: absolute;
+          top:4.5em; left:-1.8em;
+          transform: rotateZ(-90deg);
+          transform-origin: center;
+          @include fontsans;
+          font-size: 0.600em;
+          cursor: pointer;
+          color: $bleuroi;
+          svg{
+            vertical-align: bottom;
+            transform-origin: center;
+            transform: scale(0.8) rotate(180deg);
+            transition: transform 0.3s ease-in-out;
+            path{
+              fill: $bleuroi;
+            }
+          }
+        }
+
+        &.opened{
+          box-shadow: -3px -3px 5px $grisclair;
+          transform: translateX(0);
+          span.nav-title{
+            svg{
+              transform: scale(0.7) rotate(0);
+            }
+          }
+        }
+
+      }
+    }
   }
 
   #text{
@@ -621,6 +710,9 @@ footer[role="tools"]{
     z-index: 9;
     background-color: $gris;
     padding:1.2em $side-padding;
+    @media only screen and (max-width: $small-bp) {
+      padding:1.2em $side-padding/2;
+    }
     max-height: $list-item-h * 3;
     @include accordeon-transition($list-item-h * 3);
     >header{
@@ -666,10 +758,38 @@ footer[role="tools"]{
         pointer-events: none;
       }
     }
+
+    // responsive
+    @media only screen and (max-width: $small-bp) {
+      position: relative;
+      >header{
+        padding:0 0 1em 0;
+        >*{
+          display: inline-block;
+          margin-right: 1em;
+        }
+        #sorting{
+          width:10em;
+        }
+      }
+      >section.results-list{
+        max-height: 15em;
+        li.result{
+          flex-basis: 33%;
+        }
+      }
+      >nav{
+        position: absolute;
+        top:1.2em; right:1.2em;
+      }
+    }
   }
   #footer-bottom{
     z-index: 10;
     padding:0 $side-padding;
+    @media only screen and (max-width: $small-bp) {
+      padding:0 $side-padding/2;
+    }
     background-color: $bleuroi;
     &>*{
       // disable grid gap
@@ -720,7 +840,7 @@ footer[role="tools"]{
           box-sizing:border-box;
           // width correction as row is not the same width as others in the page
           // flex-basis: percentage(2/($default_sum - 1));
-          flex-basis: 17.667%;
+          // flex-basis: 17.667%;
           // flex-basis: percentage(2 / 11);
           &:not(:first-of-type){
             border-left: 1px solid $grisclair;
@@ -736,13 +856,13 @@ footer[role="tools"]{
             display: none;
           }
           input[type="text"]{
-            padding:0.3em;
+            padding:0em 0.3em;
             margin:0 0 0.3em 0;
             box-sizing: border-box;
             font-size: 0.756em;
             line-height: 1;
             width:100%;
-            height:1.2em;
+            height:1.4em;
             border:none;
             border-radius: 2px;
           }
@@ -780,6 +900,40 @@ footer[role="tools"]{
           pointer-events: none;
         }
       }
+
+      // responsive
+      @media only screen and (max-width: $small-bp) {
+        form{
+          fieldset{
+            &.search{
+              >div{
+                display: inline-flex;
+                flex-wrap: nowrap;
+                width:84%;
+                >*{
+                  flex-basis: 45%;
+                  margin: 0 0.5em 0 0;
+                  // box-sizing: content-box;
+                  // width:auto!important;
+                  &#keys[type="text"]{
+                    margin-right:1.5em;
+                  }
+                }
+              }
+              span.mdi{
+                width:1em; height:1em;
+                margin-top: -0.1em;
+                margin-left: 0;
+              }
+            }
+            &.filters{
+              border-left: none;
+              flex-basis: 32%;
+              padding: 0.2em 0 1em 1em;
+            }
+          }
+        }
+      }
     }
   }
   h2{

+ 3 - 5
assets/css/base/_grid-flex.scss

@@ -6,11 +6,9 @@
   flex-direction: row;
   flex-wrap: nowrap;
   align-items: stretch;
-  // &:after{
-  //   content:"";
-  //   clear:both;
-  //   display: block;
-  // }
+  @media only screen and (max-width: $small-bp) {
+    flex-wrap:wrap;
+  }
 }
 
 .row{

+ 15 - 1
assets/css/base/_layout.scss

@@ -27,19 +27,27 @@ body{
     flex: 0 0 auto;
     @extend %layout-element;
     padding:1em $side-padding 0 $side-padding;
+    @media only screen and (max-width: $small-bp) {
+      padding:1em $side-padding/2 0 $side-padding/2;
+    }
   }
   section[role="main-content"]{
     flex:1 1 auto;
     @extend %layout-element;
     overflow: hidden;
     >.wrapper{
+      position: relative;
       padding:0 $side-padding 0 $side-padding;
       height:100%; max-height:100%;
       overflow-y: hidden;
       overflow-x: hidden;
+      @media only screen and (max-width: $small-bp) {
+        overflow-y: auto;
+        padding:0 $side-padding/2 0 $side-padding/2;
+      }
     }
     .main-content-layout{
-      max-height: 100%;
+      height: 100%;
       >header,
       >section,
       >nav{
@@ -54,6 +62,12 @@ body{
         overflow-y: auto;
       }
     }
+    @media only screen and (max-width: $small-bp) {
+      .main-content-layout{
+        display: flex;
+        flex-direction: column;
+      }
+    }
   }
   footer[role="tools"]{
     flex:0 0 auto;

+ 5 - 0
package-lock.json

@@ -12151,6 +12151,11 @@
       "integrity": "sha512-4gDntzrifFnCEvyoO8PqyJDmguXgVPxKiIxrBKjIowvL9l+N66196+72XVYR8BBf1Uv1Fgt3bGevJ+sEmxfZzw==",
       "dev": true
     },
+    "vue2-touch-events": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/vue2-touch-events/-/vue2-touch-events-2.2.1.tgz",
+      "integrity": "sha512-tdAWuPhFWm2C4nuTRYDb1LtP2288LVDUXgGDAtQgYcMgF9K/Igns0r61NYgPHrRxN548U4wUdYgIDy4+XCxu2w=="
+    },
     "vuex": {
       "version": "3.1.1",
       "resolved": "https://registry.npmjs.org/vuex/-/vuex-3.1.1.tgz",

+ 1 - 0
package.json

@@ -26,6 +26,7 @@
     "vue-router": "^3.1.3",
     "vue-scrollto": "^2.18.1",
     "vue-select": "^3.10.7",
+    "vue2-touch-events": "^2.2.1",
     "vuex": "^3.1.1",
     "vuex-router-sync": "^5.0.0"
   },

+ 17 - 4
src/components/Content/EdText.vue

@@ -77,6 +77,9 @@ export default {
               ` @keyup.enter="onClickRef"` +
               ` @mouseover="onHoverLink"` +
               ` @mouseleave="onLeaveLink"` +
+              // prevent click on this one
+              ` v-touch:tap.prevent="onTapLink"` +
+              ` v-touch-class="'tapped'"` +
               `>${linkparts[4]}` +
               `<sup class="mdi mdi-message-text-outline" />` +
               `</a>`
@@ -114,10 +117,12 @@ export default {
     // },
     onClickRef (e) {
       console.log('onClickRef(e)', e)
-      this.$router.push({
-        name: e.target.dataset.index,
-        params: { id: e.target.dataset.uuid }
-      })
+      if (e.target.classList.contains('tapped')) {
+        this.$router.push({
+          name: e.target.dataset.index,
+          params: { id: e.target.dataset.uuid }
+        })
+      }
     },
     onHoverLink (e) {
       console.log('EdText onHoverLink(e)', e)
@@ -127,6 +132,14 @@ export default {
         rect: e.target.getBoundingClientRect()
       })
     },
+    onTapLink (e) {
+      console.log('EdText onTapLink(e)', e)
+      this.$emit('onHoverLink', {
+        uuid: e.target.dataset.uuid,
+        index: e.target.dataset.index,
+        rect: e.target.getBoundingClientRect()
+      })
+    },
     onLeaveLink (e) {
       // console.log('EdText onLeaveLink(e)', e)
       this.$emit('onLeaveLink')

+ 6 - 5
src/components/Layouts/MainContentLayout.vue

@@ -1,17 +1,17 @@
 <template>
   <div
     :id="id"
-    class="full-width row main-content-layout"
+    class="full-width med-row large-row main-content-layout"
   >
-    <header class="col-3">
+    <header class="med-col-3 large-col-3">
       <slot name="header" />
     </header>
 
-    <section ref="scrollablecenter" class="col-6" @scroll.passive="onScrollCenter">
+    <section ref="scrollablecenter" class="med-col-6 large-col-6" @scroll.passive="onScrollCenter">
       <slot />
     </section>
 
-    <nav class="col-3">
+    <nav class="med-col-3 large-col-3" :class="{ opened: navopened }">
       <slot name="nav" />
     </nav>
 
@@ -26,7 +26,8 @@ export default {
       type: String,
       required: true
     },
-    reftoscrollto: { type: String }
+    reftoscrollto: { type: String },
+    navopened: { type: Boolean }
   },
   watch: {
     reftoscrollto: function (newref, oldref) {

+ 14 - 3
src/components/nav/HeaderMenu.vue

@@ -2,8 +2,13 @@
   <nav id="header-menu">
     <ul v-if="corpusLoaded">
       <li><router-link to="/corpus">Corpus</router-link></li>
-      <li>
-        <span>Indexs</span>
+      <li :class="{ opened: indexOpened }">
+        <span
+          @click.prevent="onClickIndex"
+          @keyup.enter="onClickIndex"
+        >
+          Indexs
+        </span>
         <ul>
           <li><router-link to="/nominum">Personnes</router-link></li>
           <li><router-link to="/locorum">Lieux</router-link></li>
@@ -28,12 +33,18 @@ import { mapState } from 'vuex'
 export default {
   name: 'HeaderMenu',
   data: () => ({
-
+    indexOpened: false
   }),
   computed: {
     ...mapState({
       corpusLoaded: state => state.Corpus.corpusLoaded
     })
+  },
+  methods: {
+    onClickIndex (e) {
+      console.log('onClickIndex')
+      this.indexOpened = !this.indexOpened
+    }
   }
 }
 

+ 3 - 3
src/components/nav/Results.vue

@@ -6,9 +6,9 @@
       class="row"
       :class="{ loading: isloading }"
     >
-      <header class="col-1">
+      <header class="small-col-12 med-col-1 large-col-1">
         <h2>Resultats</h2>
-        <span class="search-keys">{{ searchedKeys }}</span><br>
+        <span class="search-keys">{{ searchedKeys }}</span>
         <span v-if="resultsQuantity" class="results-count">{{ resultsCount }}</span>
         <v-select
           id="sorting"
@@ -21,7 +21,7 @@
           @input="onSortingSelected"
         />
       </header>
-      <section class="col-10 results-list">
+      <section class="small-col-12 med-col-10 large-col-10 results-list">
         <div class="wrapper">
           <ul v-if="results.length">
             <li v-for="result in results" :key="result.uuid" class="result">

+ 4 - 4
src/components/nav/Search.vue

@@ -1,7 +1,7 @@
 <template>
   <div id="search" class="col-11" :class="{ loading: isloading }">
     <form class="search-form row">
-      <fieldset class="search">
+      <fieldset class="search small-col-10 med-col-2 large-col-2">
         <div>
           <label for="keys">Search</label>
           <input
@@ -37,7 +37,7 @@
           title="chargement"
         />
       </fieldset>
-      <fieldset v-if="filters.persons.length" class="filters filters-nominum col-2">
+      <fieldset v-if="filters.persons.length" class="filters filters-nominum small-col-4 med-col-2 large-col-2">
         <v-select
           id="filters-nominum"
           type="select"
@@ -50,7 +50,7 @@
           @input="onFiltersNominumSelected"
         />
       </fieldset>
-      <fieldset v-if="filters.places.length" class="filters filters-locorum col-2">
+      <fieldset v-if="filters.places.length" class="filters filters-locorum small-col-4 med-col-2 large-col-2">
         <v-select
           id="filters-locorum"
           type="select"
@@ -63,7 +63,7 @@
           @input="onFiltersLocorumSelected"
         />
       </fieldset>
-      <fieldset v-if="filters.objects.length" class="filters filters-operum col-2">
+      <fieldset v-if="filters.objects.length" class="filters filters-operum small-col-4 med-col-2 large-col-2">
         <v-select
           id="filters-operum"
           type="select"

+ 2 - 3
src/index.js

@@ -6,6 +6,7 @@ import Meta from 'vue-meta'
 import InfiniteLoading from 'vue-infinite-loading'
 import VueScrollTo from 'vue-scrollto'
 import VueSelect from 'vue-select'
+import Vue2TouchEvents from 'vue2-touch-events'
 
 import App from './App'
 
@@ -15,7 +16,6 @@ import 'vue-select/src/scss/vue-select.scss'
 import 'assets/css/app.scss'
 
 Vue.use(Meta)
-
 Vue.use(InfiniteLoading, {
   props: {
     spinner: 'spiral'
@@ -30,10 +30,9 @@ Vue.use(InfiniteLoading, {
   //   /* other settings need to configure */
   // }
 })
-
 Vue.use(VueScrollTo)
-
 Vue.component('v-select', VueSelect)
+Vue.use(Vue2TouchEvents)
 
 window.apipath = process.env === 'prod' ? `http://${window.location.hostname}/api` : 'http://localhost:8984'
 

+ 1 - 1
src/pages/Bibliographie.vue

@@ -29,7 +29,7 @@
 
     <!-- default slot -->
     <!-- expressions or manifestations list -->
-    <template v-if="!this.uuid">
+    <template v-if="!uuid">
       <ul class="item-list">
         <li v-for="item in content" :key="item.uuid">
           <h2>

+ 33 - 2
src/pages/Edition.vue

@@ -1,5 +1,10 @@
 <template>
-  <MainContentLayout id="edition" :reftoscrollto="reftoscrollto" @onCenterScrolled="onCenterScrolled">
+  <MainContentLayout
+    id="edition"
+    :reftoscrollto="reftoscrollto"
+    :navopened="navopened"
+    @onCenterScrolled="onCenterScrolled"
+  >
     <template v-if="!content" #header>
       <span>Loading ...</span>
     </template>
@@ -13,6 +18,10 @@
         v-if="indexitem"
         class="index-tooltip"
         :style="{ top:tooltip_top + 'px' }"
+        :data-index="indexitem.index"
+        :data-uuid="indexitem.uuid"
+        @click.prevent="onClickTooltip"
+        @keyup.enter="onClickTooltip"
       >
         <span v-if="indexitem == 'loading'">Loading ...</span>
         <template v-if="indexitem !== 'loading'">
@@ -61,6 +70,14 @@
     </div>
 
     <template #nav>
+      <span
+        class="nav-title"
+        @click.prevent="onOpenCloseNav"
+        @keyup.enter="onOpenCloseNav"
+      >
+        <svg xmlns="http://www.w3.org/2000/svg" width="14" height="10" role="presentation" class="vs__open-indicator"><path d="M9.211364 7.59931l4.48338-4.867229c.407008-.441854.407008-1.158247 0-1.60046l-.73712-.80023c-.407008-.441854-1.066904-.441854-1.474243 0L7 5.198617 2.51662.33139c-.407008-.441853-1.066904-.441853-1.474243 0l-.737121.80023c-.407008.441854-.407008 1.158248 0 1.600461l4.48338 4.867228L7 10l2.211364-2.40069z" /></svg>
+        Sommaire
+      </span>
       <EdToc
         id="toc"
         :toc="toc"
@@ -126,7 +143,9 @@ export default {
     toc: null,
     flattoc: null,
     //
-    pagination: null
+    pagination: null,
+    //
+    navopened: false
   }),
   computed: {
     ...mapState({
@@ -307,6 +326,7 @@ export default {
           console.log('index tooltip REST: data', data)
           if (this.indexitem === 'loading') {
             this.indexitem = data.content
+            this.indexitem.index = item.index
           }
         })
         .catch((error) => {
@@ -350,6 +370,17 @@ export default {
     scrollToPage (p) {
       // console.log('scrollToPage', p)
       this.reftoscrollto = `span[role="pageBreak"][id="${p.code}"]`
+    },
+    onOpenCloseNav (e) {
+      console.log('onOpenCloseNav', e)
+      this.navopened = !this.navopened
+    },
+    onClickTooltip (e) {
+      console.log(`onClickTooltip index: ${e.target.dataset.index}, uuid: ${e.target.dataset.uuid}`)
+      this.$router.push({
+        name: e.target.dataset.index,
+        params: { id: e.target.dataset.uuid }
+      })
     }
   }
 }