]> _ Git - ccv-wordpress.git/commitdiff
WIP #3882 @9.5
authorStephen Cameron <stephen@cubedesigners.com>
Tue, 29 Sep 2020 18:11:31 +0000 (20:11 +0200)
committerStephen Cameron <stephen@cubedesigners.com>
Tue, 29 Sep 2020 18:11:31 +0000 (20:11 +0200)
wp-content/mu-plugins/cube/src/Elementor/Widgets/TimelineHorizontal.php
wp-content/themes/CCV/resources/assets/scripts/timeline-horizontal.js [new file with mode: 0644]
wp-content/themes/CCV/resources/assets/styles/widgets/header-slideshow.styl
wp-content/themes/CCV/resources/assets/styles/widgets/timeline-horizontal.styl
wp-content/themes/CCV/resources/views/widgets/timeline-horizontal.blade.php
wp-content/themes/CCV/webpack.mix.js

index 78a9627ee2b92ea4fb788704ac0117080a2393f6..3925fc9bcc24be1250309ad5a515b026e2b72d93 100644 (file)
@@ -5,6 +5,7 @@ namespace Cube\Elementor\Widgets;
 use Elementor\Controls_Manager;
 use Elementor\Utils;
 
+use function Roots\asset;
 use function Roots\view;
 
 
@@ -34,7 +35,18 @@ class TimelineHorizontal extends _Base {
      * @return array Widget scripts dependencies.
      */
     public function get_script_depends() {
-        return [];
+
+        wp_register_script(
+            'cube-timeline-horizontal',
+            asset('scripts/timeline-horizontal.js'),
+            ['jquery', 'swiper'], // Dependencies
+            null, // Version
+            true // In footer?
+        );
+
+        // Using Swiper because it is already included and heavily used by Elementor
+
+        return [ 'cube-timeline-horizontal' ];
     }
 
     /**
@@ -53,34 +65,20 @@ class TimelineHorizontal extends _Base {
             ]
         );
 
-        $this->add_control(
-            'image_desktop',
-            [
-                'label' => __( 'Image pour grands écrans', 'cube' ),
-                'type' => Controls_Manager::MEDIA,
-                'default' => [
-                    'url' => Utils::get_placeholder_image_src(),
-                ],
-            ]
-        );
-
-        $this->add_control(
-            'image_mobile',
-            [
-                'label' => __( 'Image pour petits écrans', 'cube' ),
-                'type' => Controls_Manager::MEDIA,
-                'default' => [
-                    'url' => Utils::get_placeholder_image_src(),
-                ],
-            ]
-        );
-
         $this->add_control(
             'items',
             [
                 'label' => __('Items', 'cube'),
                 'type' => Controls_Manager::REPEATER,
                 'fields' => [
+                    [
+                        'name' => 'image',
+                        'label' => __('Image', 'cube'),
+                        'type' => Controls_Manager::MEDIA,
+                        'default' => [
+                            'url' => Utils::get_placeholder_image_src(),
+                        ],
+                    ],
                     [
                         'name' => 'title',
                         'label' => __('Title', 'cube'),
@@ -89,22 +87,12 @@ class TimelineHorizontal extends _Base {
                         'default' => '',
                     ],
                     [
-                        'name' => 'cta_text',
-                        'label' => __('Call to Action text', 'cube'),
-                        'type' => Controls_Manager::TEXT,
+                        'name' => 'content',
+                        'label' => __('Contenu', 'cube'),
+                        'type' => Controls_Manager::WYSIWYG,
                         'label_block' => true,
                         'default' => ''
                     ],
-                    [
-                        'name' => 'cta_link',
-                        'label' => __('Call to Action link', 'cube'),
-                        'type' => Controls_Manager::URL,
-                        'default' => [
-                            'url' => '',
-                            'is_external' => false,
-                        ],
-                        'show_external' => true
-                    ]
                 ],
                 'title_field' => '{{{ title }}}',
             ]
@@ -122,10 +110,13 @@ class TimelineHorizontal extends _Base {
      * @access protected
      */
     protected function render() {
-        $image_desktop = $this->get_settings('image_desktop');
-        $image_mobile = $this->get_settings('image_mobile');
         $items = $this->get_settings('items');
-        echo view('widgets/timeline-horizontal', compact('image_desktop', 'image_mobile', 'items'));
+
+        foreach ($items as $item) {
+            $item['content'] = $this->parse_text_editor($item['content']);
+        }
+
+        echo view('widgets/timeline-horizontal', compact('items'));
     }
 
 }
diff --git a/wp-content/themes/CCV/resources/assets/scripts/timeline-horizontal.js b/wp-content/themes/CCV/resources/assets/scripts/timeline-horizontal.js
new file mode 100644 (file)
index 0000000..e15d0b1
--- /dev/null
@@ -0,0 +1,18 @@
+// ELEMENTOR Trigger
+(function($) {
+  $(window).on('elementor/frontend/init', function () {
+    elementorFrontend.hooks.addAction('frontend/element_ready/cube-timeline-horizontal.default', function ($scope) {
+      const elementSelector = `[data-id="${$scope.data('id')}"] .timeline-horizontal`;
+      const swiperSettings = $(elementSelector).data('swiper'); // Get parameters from data-swiper attribute in HTML
+
+      // Custom paging bullets
+      swiperSettings.pagination.renderBullet = function (index, className) {
+        // In loop mode, Swiper duplicates slides so the collection really starts from 1 instead of 0
+        const title = this.slides[index + 1 ].dataset.title;
+        return '<div class="' + className + '"><span class="bullet">' + (index + 1) +'</span><span class="timeline-horizontal-pagination-bullet-title">'+ title +'</span></div>';
+      };
+
+      const swiper = new Swiper(elementSelector, swiperSettings);
+    });
+  });
+})(jQuery);
index da06e27099085bef9815fe56118d3cab18dcd28c..6bab9d43c67643d6bbab216f6c7f7252ad90e4e7 100644 (file)
@@ -80,7 +80,7 @@ $title_bg = rgba(#fff, 0.88)
   &-content
     .header-slideshow & // Need some extra specificity to override H1 CSS
       @apply text-purple-dark px-5 py-3
-      background: rgba(#fff, 0.8)
+      background: $title_bg
       width: 50% // Size ratio for intermediate screens
       max-width: 870px
       z-index: 10
index bdba007b5b82c30bda31aad5dc79f42623200da3..401e59d6dcfcbaf53814a89956bdc291bf8236fe 100644 (file)
 $breakpoint-timeline-horizontal = 900px // When timeline changes to mobile view
 
 .timeline-horizontal
-  +below($breakpoint-timeline-horizontal)
-    @apply flex flex-row
 
-    // Scale all em children
-    font-size: 22px fixed
-
-  +below(550px)
-    font-size: 18px fixed
-  +below(450px)
-    font-size: 14px fixed
-  +below(380px)
-    font-size: 12px fixed
-
-  &-items
-    @apply flex justify-between items-start
-    @apply mb-6
-
-    +below($breakpoint-timeline-horizontal)
-      @apply flex-col items-center
-      flex: 1 1 75%
-      margin-bottom: 3em
-
-      > * + *
-        margin-top: 1.5em
+  .swiper-wrapper
+    @apply items-center
 
   &-item
-    @apply flex flex-col justify-center items-center
-    @apply text-center
-    flex-basis: 22% // ~1/5 columns to match horizontal image
-    max-width: 345px
-
-    +below(1100px)
-      flex-basis: 25%
-
-  &-number
-    @apply flex items-center justify-center
-    @apply bg-purple-dark rounded-full mb-2
-    @apply text-white
-    font-size: (54/22)em // Relative units so size can be controlled from parent
-    width: 1.5em
-    height: @width
-
-    +below(1280px)
-      font-size: (36/22)em
-
-  &-title
-    @apply font-normal
-    font-size: (30/22)em
-
-    +below(1280px)
-      font-size: 1em
-
-  &-btn
-    font-size: (18/22)em
-    padding: 0.5em 1em !important
-
-  &-image
-
-    &-desktop
-      +below($breakpoint-timeline-horizontal)
-        display: none
-
-    &-mobile
-      width: 100%
-      max-width: 250px !important;
-      padding-left: 2em;
-
-      +above($breakpoint-timeline-horizontal)
-        display: none
+    @apply bg-white flex items-center
+    horizontal-spacing(12.5vw)
+
+    &-image-wrapper
+      display: flex
+      flex: 1 1 40%
+      align-items: center
+      justify-content: center
+      constrain(margin-right, 5vw)
+
+    &-content
+      flex: 1 1 60%
+
+      a
+        @apply text-pink
+
+  // Timeline Pagination
+  &-pagination
+    position: relative
+    display: flex
+    justify-content: space-between
+    align-items: flex-start
+    width: 80% !important
+    left: 10% !important
+    padding: 0
+    margin: 0
+    z-index: 1
+
+    // Timeline horizontal line
+    &:before
+      content: ''
+      position: absolute
+      top: r(32px)
+      left: 0
+      right: 0
+      height: r(10px)
+      background: #EDEDF4
+      z-index: -1
+
+
+    &-bullet
+      @apply font-display font-normal
+      font-size: 24px
+      display: flex
+      flex-direction: column
+      justify-content: center
+      align-items: center
+      width: auto
+      height: auto
+      border-radius: 0
+      background: transparent
+      opacity: 1
+      text-transform: uppercase
+      outline: none
+      position: relative
+      transition: color 0.3s
+
+      &:first-child:before
+        content: ''
+        background: #fff
+        position: absolute
+        width: 50%
+        height: 100%
+        left: 0
+        top: 0
+        z-index: 0
+
+      &:last-child:before
+        content: ''
+        background: #fff
+        position: absolute
+        width: 50%
+        height: 100%
+        right: 0
+        top: 0
+        z-index: 0
+
+      .bullet
+        height: r(68px)
+        width: @height
+        line-height: @height
+        font-size: 52px
+        display: inline-block
+        border-radius: 50%
+        margin-right: 0.5em
+        margin-bottom: 0.5em
+        text-align: center
+        color: transparent
+        background: transparent
+        position: relative
+        transition: all 0.15s
+        z-index: 1
+
+        // Non-active timeline node
+        &:before
+          content: ''
+          position: absolute
+          top: 50%
+          left: 50%
+          transform: translate(-50%, -50%)
+          width: r(32px)
+          height: @width
+          background: #fff
+          border-radius: 50%
+          border: r(10px) solid #EDEDF4
+          z-index: 0
+          transition: opacity 0.15s
+
+      &-title
+        display: block
+        text-align: center
+        max-width: 8em
+        z-index: 1
+
+      &-active
+        @apply font-bold text-teal bg-transparent
+
+        .bullet
+          @apply text-white bg-teal
+
+          &:before
+            opacity: 0
+
+
+  // Navigation Arrows
+  &-prev, &-next
+    position: absolute
+    top: 50%
+    transform: translateY(-50%)
+    z-index: 10
+    stroke: currentColor
+    transition: color 0.25s
+    outline: none
+
+    &:hover
+      @apply text-pink
+
+    +below(900px)
+      svg
+        width: 20px
+
+  &-prev
+    constrain(left, 5vw)
+  &-next
+    constrain(right, 5vw)
index 7d681667436401b475e89fd09ae3d17729b38f4d..b588ab21d15d2cfac26dfd9263f8346421c34bcd 100644 (file)
@@ -1,32 +1,51 @@
 {{-- TIMELINE --}}
-<div class="timeline-horizontal">
-  <div class="timeline-horizontal-items">
+@php
+  $settings = [
+    'slidesPerView' => 1,
+    'loop' => true,
+    //'effect' => 'fade', // TODO: try to make this work properly so slides are all the same height
+    'touchEventsTarget' => 'wrapper', // Fix pagination links sometimes going to wrong place
+    'pagination' => [
+      'el' => '.timeline-horizontal-pagination',
+      'modifierClass' => 'timeline-horizontal-pagination-',
+      'bulletClass' => 'timeline-horizontal-pagination-bullet',
+      'bulletActiveClass' => 'timeline-horizontal-pagination-bullet-active',
+      'clickable' => true,
+      // renderBullet => NOTE: this is handled in timeline-horizontal.js since we can't easily encode a JS function in JSON.
+    ],
+    'navigation' => [
+      'nextEl' => '.timeline-horizontal-next',
+      'prevEl' => '.timeline-horizontal-prev',
+    ],
+  ];
+
+  $swiper = json_encode($settings);
+
+@endphp
+
+<div class="timeline-horizontal-pagination mb-2v"></div>
+<div class="timeline-horizontal swiper-container" data-swiper="{{ $swiper }}">
+  <div class="swiper-wrapper">
     @foreach ($items as $item)
-      <div class="timeline-horizontal-item">
+      <div class="timeline-horizontal-item swiper-slide" data-title="{{ $item['title'] }}">
 
-        <div class="timeline-horizontal-number">
-          {{ $loop->iteration }}
-        </div>
+        {{-- TODO: mobile title
+          <div class="timeline-horizontal-number">
+            {{ $loop->iteration }}
+          </div>
+         --}}
 
-        <div class="timeline-horizontal-title">
-          {{ $item['title'] }}
+        <div class="timeline-horizontal-item-image-wrapper">
+          @image($item['image']['id'], 'full', ['class' => 'timeline-horizontal-item-image'])
         </div>
 
-        @if ($item['cta_text'])
-          @php
-            $target = $item['cta_link']['is_external'] ? ' target="_blank"' : '';
-            $rel = $item['cta_link']['nofollow'] ? ' rel="nofollow"' : '';
-          @endphp
-          <a class="timeline-horizontal-btn btn px-4 py-2 mt-4" href="{{ $item['cta_link']['url'] }}"{!! $target !!}{!! $rel !!}>
-            {{ $item['cta_text'] }}
-          </a>
-        @endif
-
+        <div class="timeline-horizontal-item-content">
+          <h3 class="text-2xl uppercase">{{ $item['title'] }}</h3>
+          {!! $item['content'] !!}
+        </div>
       </div>
     @endforeach
   </div>
-  <div class="timeline-horizontal-image">
-    @image($image_desktop['id'], 'full', ['class' => 'timeline-horizontal-image-desktop'])
-    @image($image_mobile['id'], 'full', ['class' => 'timeline-horizontal-image-mobile'])
-  </div>
+  <div class="timeline-horizontal-prev">@svg('carousel-prev', 'stroke-current')</div>
+  <div class="timeline-horizontal-next">@svg('carousel-next', 'stroke-current')</div>
 </div>
index b9c990a7f1c3e7b13004dd40d8d5815e533d01fd..35a9dda9d81821be6e82009345d3c966d6bd7104 100644 (file)
@@ -72,6 +72,7 @@ mix.stylus(src`styles/components/lity-lightbox.styl`, 'styles/lity.css', stylusC
 mix.js(src`scripts/app.js`, 'scripts')
   .js(src`scripts/consultation.js`, 'scripts')
   .js(src`scripts/header-slideshow.js`, 'scripts')
+  .js(src`scripts/timeline-horizontal.js`, 'scripts')
   .js(src`scripts/link-carousel.js`, 'scripts')
   .js(src`scripts/testimonial-carousel.js`, 'scripts')
   .js(src`scripts/customizer.js`, 'scripts')