]> _ Git - pmi.git/commitdiff
Tabs / accordion component for product details page. WIP #2867 @5.5
authorStephen Cameron <stephen@cubedesigners.com>
Mon, 8 Jul 2019 17:57:34 +0000 (19:57 +0200)
committerStephen Cameron <stephen@cubedesigners.com>
Mon, 8 Jul 2019 17:57:34 +0000 (19:57 +0200)
public/images/product-details/arrow-down.svg [deleted file]
resources/js/components/Tab.vue
resources/js/components/Tabs.vue
resources/styles/components/product-details.styl [deleted file]
resources/styles/components/tabs.styl [new file with mode: 0644]
resources/views/pages/product-detail.blade.php

diff --git a/public/images/product-details/arrow-down.svg b/public/images/product-details/arrow-down.svg
deleted file mode 100644 (file)
index 29654f0..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-<svg xmlns="http://www.w3.org/2000/svg" width="16.16" height="9.588" viewBox="0 0 16.16 9.588">
-  <path id="Tracé_29" data-name="Tracé 29" d="M3719.6-783.348l-7.459,7.459-7.278-7.459" transform="translate(-3704.146 784.055)" fill="none" stroke="#6b7287" stroke-miterlimit="10" stroke-width="2"/>
-</svg>
index 326ea1add22bda93882932806fce26cf4655a938..5e73e960a6fe44677dc66d84735cb509f52b80f1 100644 (file)
@@ -26,7 +26,9 @@
 
         computed: {
             computedId() {
-                return this.id ? this.id : this.name.toLowerCase().replace(/ /g, '-');
+                // Create hash slug for URL
+                // Also removes accents (see: https://stackoverflow.com/a/37511463)
+                return this.id ? this.id : this.name.toLowerCase().replace(/ /g, '-').normalize('NFD').replace(/[\u0300-\u036f]/g, '');
             },
             hash() {
                 return '#' + this.computedId;
@@ -37,4 +39,4 @@
             this.isActive = this.selected;
         },
     }
-</script>
\ No newline at end of file
+</script>
index c50134b5e5ccd2442d0d51989558ba278c7fe366..0fa184b079871f20c77c5afd0c120caf9bd8415b 100644 (file)
@@ -1,12 +1,13 @@
 <template>
-    <div class="tabs">
-        <ul role="tablist" class="tabs-list" :class="{ 'flex': this.currentMode === 'tabs' }">
+    <div class="tabs" :class="`mode-${currentMode}`">
+        <ul role="tablist" class="tabs-list">
             <li v-for="(tab, i) in tabs"
                 :key="i"
-                :class="{ 'bg-grey-100': tab.isActive, 'is-disabled': tab.isDisabled }"
+                :class="{ 'is-active': tab.isActive, 'is-disabled': tab.isDisabled }"
+                class="tab-wrapper"
                 role="presentation"
             >
-                <a class="block font-display text-lg text-navy py-4 px-8 mr-1"
+                <a class="tab-title"
                    :aria-controls="tab.hash"
                    :aria-selected="tab.isActive"
                    @click="selectTab(tab.hash, $event)"
                 >
                     {{ tab.name }}
                 </a>
-                <div v-show="currentMode === 'accordion' && tab.isActive">
+                <div v-show="currentMode === 'accordion' && tab.isActive" v-html="tab.$el.innerHTML" class="accordion-content">
                     <!--<slide-toggle :active="tab.isActive" :duration="300">-->
-                        {{ tab.$el.innerHTML }}
+                        <!--{{ tab.$el.innerHTML }}-->
                     <!--</slide-toggle>-->
                 </div>
             </li>
         </ul>
 
-        <div v-show="currentMode === 'tabs'" class="tabs-content bg-grey-100 p-6">
+        <div v-show="currentMode === 'tabs'" class="tabs-content">
             <slot></slot>
         </div>
     </div>
@@ -40,6 +41,8 @@
         },
 
         props: {
+            mode: { default: 'tabs' }, // Tabs mode and responsive by default
+            responsive: { default: true },
             options: {
                 type: Object,
                 required: false,
@@ -47,8 +50,6 @@
                     defaultTabHash: null,
                 }),
             },
-            mode: { default: 'tabs' }, // Tabs mode and responsive by default
-            responsive: { default: true },
             breakpoint: {
                 type: Number,
                 required: false,
diff --git a/resources/styles/components/product-details.styl b/resources/styles/components/product-details.styl
deleted file mode 100644 (file)
index 26d8379..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-$h3 = 24px
-$barlow = 'Barlow', sans-serif
-$muli = 'Muli', sans-serif
-$dark = #6B7287
-$lightgrey = #F7F8FC
-$darkblue = #152F4E
-
-
-#product-tabs
-  max-width: 1536px
-  margin: 0 auto
-
-  .content
-    @media (max-width 940px)
-      display none
-      max-width 1536px
-      padding 55px 48px 48px 48px
-      background $lightgrey
-
-  .product-nav
-    @media (max-width 940px)
-      flex-direction column
-
-    &-item
-      //padding : 25px 50px
-      font-family $barlow
-      font-size: 18px
-      color: $darkblue
-      position: relative
-      transition 400ms all ease
-      @media (max-width 940px)
-        &:last-child::after
-          height: 0
-        &::after
-          content ''
-          background #E7E9F3
-          left 48px
-          right 48px
-          bottom 0
-          position absolute
-          height 1px
-
-    .section-title
-      font-family $barlow
-      display flex
-      padding: 25px 50px
-      cursor pointer
-
-      + div
-        padding: 0px 50px 25px 50px
-        @media (min-width 940px)
-          display none !important
-
-      .product-nav-arrow
-        display flex
-        transition 400ms all ease
-        @media (min-width 940px)
-          display none
-
-  .active-nav
-    background $lightgrey
-    @media (max-width 940px)
-      background white
-
-  .active-content
-    display flex !important
-
-  .rotate
-    transform: rotate(180deg)
-    transition 400ms all ease
diff --git a/resources/styles/components/tabs.styl b/resources/styles/components/tabs.styl
new file mode 100644 (file)
index 0000000..4ac272f
--- /dev/null
@@ -0,0 +1,50 @@
+// Tabs / Accordion Vue Component
+.tabs
+
+  .tab-title
+    @apply block font-display text-lg text-navy
+
+  //=== TABS MODE
+  &.mode-tabs
+    .tabs-list // The actual tabs
+      @apply flex
+
+    .tab-title
+      @apply py-4 px-8 mr-1
+
+    .tab-wrapper.is-active // Current tab
+      @apply bg-grey-100
+
+    .tabs-content // The content area for the tabs
+      @apply bg-grey-100 p-8
+
+  //=== ACCORDION MODE
+  &.mode-accordion
+
+    .tab-wrapper
+      &.is-active
+        .tab-title:after
+          transform: rotate(180deg)
+
+    .tab-title
+      @apply relative py-6 border-b border-grey-300
+
+      // Arrow
+      &:after
+        content: ''
+        width: 16px
+        height: @width
+        position: absolute
+        right: 0
+        top: 50%
+        transform: translateY(-50%)
+        background: url(/images/arrow-down.svg) center no-repeat
+        background-size: contain
+        transition: transform 0.4s ease
+        transform-origin: center
+
+    .accordion-content
+      @apply pt-6 pb-4
+
+
+
index 732ceff7e59e06d59f856b0c3e7927f69d5f279e..2f2b15b0dd46d69391faeb067af6a47d8324ea10 100644 (file)
 
             </text-block>
 
-
         </div>
 
-    </content>
+        {{-- Product detail tabs --}}
+        <tabs :breakpoint="1060" class="mb-3v">
 
-    @push('scripts')
-        <script src="{{mix('js/product-details.js')}}"></script>
-    @endpush
-
-    <div id="product-tabs">
-        <ul class="flex product-nav">
-            @if($product->descriptions)
-                <li class="product-nav-item ">
-                    <div data-nav="0" class="section-title justify-between items-center active-nav">
-                        {{__('Description')}}
-                        <img class="product-nav-arrow" src="{{asset('images/product-details/arrow-down.svg')}}" alt="">
-                    </div>
+            @if ($product->descriptions)
+                <tab name="{{ __('Description') }}">
+                    {!! Markdown::parse($product->descriptions) !!}
+                </tab>
+            @endif
 
-                    <div>
-                        {!! Markdown::parse($product->descriptions) !!}
-                    </div>
-                </li>
+            @if ($product->specifications)
+                <tab name="{{ __('Spécifications') }}">
+                    TODO: specifications
+                </tab>
             @endif
-            <li class="product-nav-item">
-                <div data-nav="1" class="section-title justify-between items-center">
-                    {{__('Spécifications')}}
-                    <img class="product-nav-arrow" src="{{asset('images/product-details/arrow-down.svg')}}" alt="">
-                </div>
-                <div>
-                    <ul class="specification-list">
-                        <li class=" flex justify-between">
-                            <div class="specification-info">Etendue de mesure (kN)</div>
-                            <div class="specification-value">1.5 / 2.5 / 5 / 10</div>
-                        </li>
-                        <li class="flex justify-between mt-6">
-                            <div class="specification-info">Précision (erreur totale)</div>
-                            <div class="specification-value">± 0.04</div>
-                        </li>
-
-                        <li class="flex justify-between mt-6">
-                            <div class="specification-info">Non-linéarité, % PE</div>
-                            <div class="specification-value">± 0.04</div>
-                        </li>
-                        <li class="flex justify-between mt-6">
-                            <div class="specification-info">Hystérésis, % PE</div>
-                            <div class="specification-value">± 0.03</div>
-                        </li>
-                        <li class="flex justify-between mt-6">
-                            <div class="specification-info">Non-répétabilité, % PE</div>
-                            <div class="specification-value">± 0.01</div>
-                        </li>
-                        <li class="flex justify-between mt-6">
-                            <div class="specification-info">Dérive sous charge (20 mins)</div>
-                            <div class="specification-value">± 0.025</div>
-                        </li>
-                        <li class="flex justify-between mt-6">
-                            <div class="specification-info">Sensibilité transverse %</div>
-                            <div class="specification-value">± 0.25</div>
-                        </li>
-                        <li class="flex justify-between mt-6">
-                            <div class="specification-info">Gamme de compensation °C</div>
-                            <div class="specification-value">-10 à + 45</div>
-                        </li>
-                        <li class="flex justify-between mt-6">
-                            <div class="specification-info">Gamme d'utilisation °C</div>
-                            <div class="specification-value">-55 à 90</div>
-                        </li>
-                        <li class="flex justify-between mt-6">
-                            <div class="specification-info">Sensibilité au Zéro (%PE/°C)</div>
-                            <div class="specification-value">± 0.0015</div>
-                        </li>
+
+            @if ($product->hasDocuments())
+                <tab name="{{ __('Documents') }}">
+                    <ul>
+                        @foreach($product->getDocuments() as $document)
+                            <li>
+                                <a href="{{$document['media']->getUrl()}}" target="_blank" class="flex items-center text-grey-dark hover:text-blue">
+                                    <img class="mr-4 mb-2"
+                                         src="{{asset('images/product-details/icon-'.$document['type'].'.svg')}}"
+                                         alt="">
+                                    {{$document['label']}}
+                                </a>
+                            </li>
+                        @endforeach
                     </ul>
-                </div>
-            </li>
-            @if($product->hasDocuments())
-                <li class="product-nav-item">
-                    <div data-nav="2" class="section-title justify-between items-center">
-                        {{__('Documents')}}
-                        <img class="product-nav-arrow" src="{{asset('images/product-details/arrow-down.svg')}}" alt="">
-                    </div>
-                    <div>
-                        <ul class="text-grey-dark">
-                            @foreach($product->getDocuments() as $document)
-                                <li class="flex items-center ">
-                                    <a href="{{$document['media']->getUrl()}}" target="_blank">
-                                        <img class="mr-4 mb-2"
-                                             src="{{asset('images/product-details/icon-'.$document['type'].'.svg')}}"
-                                             alt="">
-                                        {{$document['label']}}
-                                    </a>
-                                </li>
-                            @endforeach
-                        </ul>
-                    </div>
-                </li>
+                </tab>
             @endif
 
-            @if($product->dimensions)
-                <li class="product-nav-item">
-                    <div data-nav="3" class="section-title justify-between items-center">
-                        {{__('Dimensions')}}
-                        <img class="product-nav-arrow" src="{{asset('images/product-details/arrow-down.svg')}}" alt="">
-                    </div>
-                    <div data-content="3" class="option">
-                        {!! Markdown::parse($product->dimensions) !!}
-                    </div>
-                </li>
+            @if ($product->dimensions)
+                <tab name="{{ __('Dimensions') }}">
+                    {!! Markdown::parse($product->dimensions) !!}
+                </tab>
             @endif
-            @if($product->options)
-                <li class="product-nav-item">
-                    <div class="section-title justify-between items-center">
-                        {{__('Options')}}
-                        <img class="product-nav-arrow" src="{{asset('images/product-details/arrow-down.svg')}}" alt="">
-                    </div>
-                    <div>
-                        {!! Markdown::parse($product->options) !!}
-                    </div>
-                </li>
+
+            @if ($product->options)
+                <tab name="{{ __('Options') }}">
+                    {!! Markdown::parse($product->options) !!}
+                </tab>
             @endif
-            @if($product->accessories)
-                <li class="product-nav-item">
-                    <div class="section-title justify-between items-center">
-                        {{__('Accessoires')}}
-                        <img class="product-nav-arrow" src="{{asset('images/product-details/arrow-down.svg')}}" alt="">
-                    </div>
-                    <div>
-                        {!! Markdown::parse($product->accessories) !!}
-                    </div>
-                </li>
+
+            @if ($product->accessories)
+                <tab name="{{ __('Accessoires') }}">
+                    {!! Markdown::parse($product->accessories) !!}
+                </tab>
             @endif
-        </ul>
-    </div>
+
+        </tabs>
+
+    </content>
+
+
 
     <full-width class="bg-grey-100">
         <content>