$elementor->widgets_manager->register_widget_type( new Widgets\HeaderSlideshow() );
$elementor->widgets_manager->register_widget_type( new Widgets\NewsBanner() );
$elementor->widgets_manager->register_widget_type( new Widgets\LinkCarousel() );
+ $elementor->widgets_manager->register_widget_type( new Widgets\TestimonialCarousel() );
$elementor->widgets_manager->register_widget_type( new Widgets\PictoGrid() );
$elementor->widgets_manager->register_widget_type( new Widgets\PhotoGrid() );
$elementor->widgets_manager->register_widget_type( new Widgets\PeopleGrid() );
--- /dev/null
+<?php
+
+namespace Cube\Elementor\Widgets;
+
+use Elementor\Controls_Manager;
+
+use function Roots\view;
+use function Roots\asset;
+
+
+class TestimonialCarousel extends _Base {
+
+ // Widget name / ID
+ public function get_name() {
+ return 'cube-testimonial-carousel';
+ }
+
+ // Elementor widget title
+ public function get_title() {
+ return __( 'Testimonial Carousel', 'cube' );
+ }
+
+ // Elementor interface icon
+ public function get_icon() {
+ return 'eicon-slider-device';
+ }
+
+ /**
+ * List of scripts the widget depends on.
+ * Used to set scripts dependencies required to run the widget.
+ *
+ * @since 1.0.0
+ * @access public
+ * @return array Widget scripts dependencies.
+ */
+ public function get_script_depends() {
+
+ wp_register_script(
+ 'cube-testimonial-carousel',
+ asset('scripts/testimonial-carousel.js'),
+ ['jquery', 'swiper'], // Dependencies
+ null, // Version
+ true // In footer?
+ );
+
+ // Using Swiper because it is already included and heavily used by Elementor
+
+ return [ 'cube-testimonial-carousel' ];
+ }
+ /**
+ * Register the widget controls.
+ * Adds different input fields to allow the user to change and customize the widget settings.
+ *
+ * @since 1.0.0
+ * @access protected
+ */
+ protected function _register_controls() {
+
+ $this->start_controls_section(
+ 'section_content',
+ [
+ 'label' => __( 'Testimonial Carousel', 'cube' ),
+ ]
+ );
+
+ $this->add_control(
+ 'testimonials',
+ [
+ 'label' => __( 'Testimonials', 'cube' ),
+ 'type' => Controls_Manager::REPEATER,
+ 'fields' => [
+ [
+ 'name' => 'name',
+ 'label' => __( 'Name', 'cube' ),
+ 'type' => Controls_Manager::TEXT,
+ 'label_block' => true,
+ 'default' => '',
+ ],
+ [
+ 'name' => 'testimonial',
+ 'label' => __( 'Testimonial', 'cube' ),
+ 'type' => Controls_Manager::TEXTAREA,
+ 'label_block' => true,
+ ],
+ [
+ 'name' => 'notes',
+ 'label' => __( 'Notes', 'cube' ),
+ 'type' => Controls_Manager::TEXT,
+ 'label_block' => true,
+ ],
+ ],
+ 'title_field' => '{{{ name }}}',
+ ]
+ );
+ $this->end_controls_section();
+
+ $this->common_controls();
+ }
+ /**
+ * Render the widget output on the frontend.
+ * Written in PHP and used to generate the final HTML.
+ *
+ * @since 1.0.0
+ * @access protected
+ */
+ protected function render() {
+ $testimonials = $this->get_settings('testimonials');
+ echo view('widgets/testimonial-carousel', compact('testimonials'));
+ }
+}
'title' => __( 'Center', 'elementor' ),
'icon' => 'fa fa-align-center',
],
+ /*
'right' => [
'title' => __( 'Right', 'elementor' ),
'icon' => 'fa fa-align-right',
'title' => __( 'Justified', 'elementor' ),
'icon' => 'fa fa-align-justify',
],
+ */
],
- 'default' => '',
- 'selectors' => [
- '{{WRAPPER}}' => 'text-align: {{VALUE}}; margin: 0 auto;',
- ],
+ 'default' => 'left',
+ 'prefix_class' => 'text-block-align-',
]
);
],
],
'selectors' => [
- '{{WRAPPER}} .text-block' => 'max-width: {{SIZE}}{{UNIT}};',
+ '{{WRAPPER}} .text-block' => 'max-width: {{SIZE}}{{UNIT}}; margin-left: auto; margin-right: auto;',
],
]
);
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" width="202.369" height="36.72" viewBox="0 0 202.369 36.72">
+ <g opacity="0.5">
+ <path d="M189.5,12.5c1.82-.151,3.793-.2,5.7-.2,4.49,0,7.169,1.736,7.169,6.64v12.27H198.6l-.187-1.837h-.049a7.315,7.315,0,0,1-5.569,2.2c-3.182,0-5.71-2.061-5.71-6.144,0-3.8,3.167-7.334,11.093-5.652V18.678c0-2.188-1.283-2.8-3.811-2.8-1.552,0-2.868.105-4.869.276Zm8.68,10.191c-3.358-.854-6.716.2-6.716,2.791a2.505,2.505,0,0,0,2.846,2.657,6.536,6.536,0,0,0,3.87-1.585Zm-14.019-9.836-4.188.027V31.212h4.188Zm-2.075-2.59a2.377,2.377,0,1,0-2.377-2.377A2.377,2.377,0,0,0,182.087,10.262Zm-6.141-4.754-4.188.486V31.212h4.188ZM154.893,12.5c1.82-.151,3.793-.2,5.7-.2,4.49,0,7.169,1.736,7.169,6.64v12.27h-3.766l-.187-1.837h-.049a7.315,7.315,0,0,1-5.569,2.2c-3.182,0-5.71-2.061-5.71-6.144,0-3.8,3.167-7.334,11.093-5.652V18.678c0-2.188-1.283-2.8-3.811-2.8-1.552,0-2.868.105-4.869.276Zm8.68,10.191c-3.358-.854-6.716.2-6.716,2.791a2.505,2.505,0,0,0,2.846,2.657,6.536,6.536,0,0,0,3.87-1.585V22.688Zm-22.148-9.836v18.36h4.188V22.026c0-2.3,1.758-4.845,5.589-5.593V12.577a8.111,8.111,0,0,0-5.815,3.232h-.038l-.3-2.956ZM121.3,22.126v-.188c0-6.136,2.823-9.637,8.658-9.637,5.8,0,8.62,3.5,8.62,9.637v.188c0,6.136-2.823,9.637-8.62,9.637C124.123,31.763,121.3,28.262,121.3,22.126Zm8.648-6.336c-2.965,0-4.334,2.012-4.334,6.215s1.368,6.178,4.334,6.178,4.3-1.968,4.3-6.178S132.913,15.79,129.948,15.79Zm-19.237-7.96V25.2c0,4.226,1.283,6.565,6.075,6.565a12.963,12.963,0,0,0,2.4-.256V28.052a7.031,7.031,0,0,1-1.649.223c-1.656,0-2.641-.38-2.641-3.584V16.249h4.29v-3.4H114.9V7.344l-4.188.485Zm-12.77,14.2c.012-4.011,1.749-6.151,5.208-6.151a32.591,32.591,0,0,1,4.3.363V12.852a26.3,26.3,0,0,0-4.825-.459c-5.159,0-9.039,2.839-9.055,9.639.016,6.8,3.9,9.639,9.055,9.639a26.306,26.306,0,0,0,4.825-.459V27.82a32.593,32.593,0,0,1-4.3.363c-3.459,0-5.2-2.139-5.208-6.151Zm-24.317.094v-.188c0-6.136,2.823-9.637,8.658-9.637,5.8,0,8.62,3.5,8.62,9.637v.188c0,6.136-2.823,9.637-8.62,9.637C76.447,31.763,73.624,28.262,73.624,22.126Zm8.648-6.336c-2.965,0-4.334,2.012-4.334,6.215s1.368,6.178,4.334,6.178,4.3-1.968,4.3-6.178S85.237,15.79,82.272,15.79ZM51.408,31.212V5.508h6.456c9,0,13.183,2.7,13.183,12.852S66.86,31.212,57.864,31.212ZM66.238,18.36c0-5.779-1.173-8.7-7.372-8.7H55.992v17.39h2.874c6.2,0,7.372-2.916,7.372-8.7ZM21.383,29.678l6.059,7.042,6.04-4.389-5.9-9.756a17.477,17.477,0,0,0-6.2,7.1Zm-8.711,7.032A36.833,36.833,0,0,1,38.556,16.789L36.24,9.656A41.5,41.5,0,0,0,4.358,31.362l8.314,5.348Zm1.814-24.217L2.305,9.624,0,16.737l8.458,3.57a30.693,30.693,0,0,1,5.8-4.591A43.978,43.978,0,0,1,23.955,11.3L23.006,0H15.538L14.487,12.492Z" fill="#2e2c40"/>
+ </g>
+</svg>
--- /dev/null
+<svg xmlns="http://www.w3.org/2000/svg" width="25.543" height="24.268" viewBox="0 0 25.543 24.268">
+ <path id="Path_617" data-name="Path 617" d="M24.432,11.436,17.4,10.771a1.216,1.216,0,0,1-1.008-.746L13.87,3.918a1.206,1.206,0,0,0-2.237,0l-2.5,6.107a1.191,1.191,0,0,1-1.008.746l-7.034.665a1.216,1.216,0,0,0-.685,2.116l5.3,4.656A1.205,1.205,0,0,1,6.09,19.4L4.5,25.927a1.216,1.216,0,0,0,1.794,1.33l5.865-3.447a1.219,1.219,0,0,1,1.229,0l5.865,3.447a1.212,1.212,0,0,0,1.794-1.33L19.473,19.4a1.205,1.205,0,0,1,.383-1.189l5.3-4.656A1.231,1.231,0,0,0,24.432,11.436Z" transform="translate(0 -3.162)" fill="#2e2c40"/>
+</svg>
--- /dev/null
+// ELEMENTOR Trigger
+(function($) {
+ $(window).on('elementor/frontend/init', function () {
+ elementorFrontend.hooks.addAction('frontend/element_ready/cube-testimonial-carousel.default', function ($scope) {
+ const elementSelector = `[data-id="${$scope.data('id')}"] .testimonial-carousel`;
+ const swiperSettings = $(elementSelector).data('swiper'); // Get parameters from data-swiper attribute in HTML
+ const swiper = new Swiper(elementSelector, swiperSettings);
+ });
+ });
+})(jQuery);
a
@apply font-display font-medium subpixel-antialiased
display: flex
- padding-left: 1em
+ padding: 1em
font-size: inherit
- //img
- // height: 20px
+ img
+ width: 24px
// Sibling selector to add margin above first normal menu item
+ .menu-item
--- /dev/null
+.testimonial-carousel
+
+ &-item
+ @apply text-center
+ //height: auto !important // Needed to make equal heights, otherwise Swiper's 100% height breaks this
+ //display: flex
+ //align-items: center
+ //flex-direction: column
+ //cursor: pointer
+
+ &-name
+ font-style: italic
+ margin-bottom: 0 !important
+
+ &-text
+ font-style: italic
+ margin-bottom: 2em
+
+ &-pagination
+ @apply text-center
+
+ &-dot
+ @apply bg-purple-dark rounded-full inline-block
+ width: r(18px)
+ height: @width
+ margin: 0 r(6.5px)
+
+ &-dot-active
+ @apply bg-pink
horizontal-spacing(5vw, margin)
.text-block
+ .text-block-align-center &
+ text-align: center
+
> * + * // Automatic spacing between direct child elements
margin-top: 1.5em
@apply text-2xl antialiased
white-space: pre-line
+ // When text is centred, dash on left should go under the text instead
+ .text-block-align-center &
+ padding-bottom: 0.75em
+ margin-bottom: @padding-bottom
+
+ &:before
+ top: auto
+ bottom: 0
+ left: 50%
+ transform: translateX(-50%)
+
+
+below(1150px)
white-space: normal // Avoid strange gaps caused by pre-line breaks wrapping
font-size: 4.25vw // Using vw units so headings scale instead of wrapping further
--- /dev/null
+{{-- TESTIMONIALS CAROUSEL --}}
+@php
+ $settings = [
+ 'slidesPerView' => 1,
+ 'loop' => true,
+ 'autoplay' => [
+ 'delay' => '5000',
+ ],
+ 'pagination' => [
+ 'el' => '.testimonial-carousel-pagination',
+ 'type' => 'bullets',
+ 'bulletElement' => 'span',
+ 'bulletClass' => 'testimonial-carousel-pagination-dot',
+ 'bulletActiveClass' => 'testimonial-carousel-pagination-dot-active',
+ 'clickable' => true,
+ ],
+ ];
+
+ $swiper = json_encode($settings);
+
+@endphp
+
+<div class="testimonial-carousel swiper-container" data-swiper="{{ $swiper }}">
+ <div class="swiper-wrapper">
+ @foreach ($testimonials as $testimonial)
+ <div class="testimonial-carousel-item swiper-slide px-4v">
+
+ <div class="flex justify-center mb-1v">
+ @for($i = 1; $i <= 5; $i++)
+ <img src="@asset('images/star.svg')" alt="star" class="mx-1">
+ @endfor
+ </div>
+ <p class="testimonial-carousel-text">"{{ trim($testimonial['testimonial']) }}"</p>
+ <p class="testimonial-carousel-name">{{ $testimonial['name'] }}</p>
+ <p class="testimonial-carousel-notes">{{ $testimonial['notes'] }}</p>
+ </div>
+ @endforeach
+ </div>
+
+ <img src="@asset('images/logo-doctoralia.svg')" class="block mx-auto my-1v" alt="Doctoralia">
+
+ <div class="testimonial-carousel-pagination"></div>
+</div>
mix.js(src`scripts/app.js`, 'scripts')
.js(src`scripts/header-slideshow.js`, 'scripts')
.js(src`scripts/link-carousel.js`, 'scripts')
+ .js(src`scripts/testimonial-carousel.js`, 'scripts')
.js(src`scripts/customizer.js`, 'scripts')
.extract();